aboutsummaryrefslogtreecommitdiffstats
path: root/notes
ModeNameSize
-rw-r--r--.cvsignore33logstatsplainblame
-rw-r--r--GNOME_Evolution_Notes.oaf.in1539logstatsplainblame
-rw-r--r--Makefile.am833logstatsplainblame
-rw-r--r--component-factory.c3751logstatsplainblame
-rw-r--r--component-factory.h179logstatsplainblame
-rw-r--r--e-bevel-button-util.c3401logstatsplainblame
-rw-r--r--e-bevel-button-util.h251logstatsplainblame
-rw-r--r--e-bevel-button.c4609logstatsplainblame
-rw-r--r--e-bevel-button.h1165logstatsplainblame
-rw-r--r--e-note.c9856logstatsplainblame
-rw-r--r--e-note.h995logstatsplainblame
-rw-r--r--main.c933logstatsplainblame
-rw-r--r--test-notes.c661logstatsplainblame
class='rem' style='width: 0.0%;'/> -rw-r--r--addressbook/addressbook.error.xml128
-rw-r--r--addressbook/backend/.cvsignore6
-rw-r--r--addressbook/backend/Makefile.am1
-rw-r--r--addressbook/backend/ebook/.cvsignore25
-rw-r--r--addressbook/backend/ebook/GNOME_Evolution_Addressbook_LDIF_Importer.oaf.in29
-rw-r--r--addressbook/backend/ebook/GNOME_Evolution_Addressbook_VCard_Importer.oaf.in29
-rw-r--r--addressbook/backend/ebook/Makefile.am178
-rw-r--r--addressbook/backend/ebook/TODO2
-rw-r--r--addressbook/backend/ebook/e-book-listener.c834
-rw-r--r--addressbook/backend/ebook/e-book-listener.h109
-rw-r--r--addressbook/backend/ebook/e-book-types.h53
-rw-r--r--addressbook/backend/ebook/e-book-util.c761
-rw-r--r--addressbook/backend/ebook/e-book-util.h93
-rw-r--r--addressbook/backend/ebook/e-book-view-listener.c516
-rw-r--r--addressbook/backend/ebook/e-book-view-listener.h82
-rw-r--r--addressbook/backend/ebook/e-book-view.c352
-rw-r--r--addressbook/backend/ebook/e-book-view.h62
-rw-r--r--addressbook/backend/ebook/e-book.c1569
-rw-r--r--addressbook/backend/ebook/e-book.h158
-rw-r--r--addressbook/backend/ebook/e-card-compare.c706
-rw-r--r--addressbook/backend/ebook/e-card-compare.h72
-rw-r--r--addressbook/backend/ebook/e-card-cursor.c235
-rw-r--r--addressbook/backend/ebook/e-card-cursor.h52
-rw-r--r--addressbook/backend/ebook/e-card-pairs.h118
-rw-r--r--addressbook/backend/ebook/e-card-simple.c1280
-rw-r--r--addressbook/backend/ebook/e-card-simple.h233
-rw-r--r--addressbook/backend/ebook/e-card-types.h101
-rw-r--r--addressbook/backend/ebook/e-card.c2865
-rw-r--r--addressbook/backend/ebook/e-card.h218
-rw-r--r--addressbook/backend/ebook/e-destination.c1693
-rw-r--r--addressbook/backend/ebook/e-destination.h138
-rw-r--r--addressbook/backend/ebook/evolution-ldif-importer.c629
-rw-r--r--addressbook/backend/ebook/evolution-vcard-importer.c266
-rw-r--r--addressbook/backend/ebook/load-gnomecard-addressbook.c91
-rw-r--r--addressbook/backend/ebook/load-pine-addressbook.c172
-rw-r--r--addressbook/backend/ebook/test-card.c191
-rw-r--r--addressbook/backend/ebook/test-client-list.c76
-rw-r--r--addressbook/backend/ebook/test-client.c193
-rw-r--r--addressbook/backend/idl/.cvsignore6
-rw-r--r--addressbook/backend/idl/Makefile.am6
-rw-r--r--addressbook/backend/idl/addressbook.idl185
-rw-r--r--addressbook/backend/pas/.cvsignore11
-rw-r--r--addressbook/backend/pas/Makefile.am81
-rw-r--r--addressbook/backend/pas/TODO2
-rw-r--r--addressbook/backend/pas/evolutionperson.schema216
-rw-r--r--addressbook/backend/pas/pas-backend-card-sexp.c467
-rw-r--r--addressbook/backend/pas/pas-backend-card-sexp.h51
-rw-r--r--addressbook/backend/pas/pas-backend-file.c1703
-rw-r--r--addressbook/backend/pas/pas-backend-file.h32
-rw-r--r--addressbook/backend/pas/pas-backend-ldap.c3521
-rw-r--r--addressbook/backend/pas/pas-backend-ldap.h32
-rw-r--r--addressbook/backend/pas/pas-backend-summary.c1087
-rw-r--r--addressbook/backend/pas/pas-backend-summary.h68
-rw-r--r--addressbook/backend/pas/pas-backend.c178
-rw-r--r--addressbook/backend/pas/pas-backend.h79
-rw-r--r--addressbook/backend/pas/pas-book-factory.c666
-rw-r--r--addressbook/backend/pas/pas-book-factory.h52
-rw-r--r--addressbook/backend/pas/pas-book-view.c316
-rw-r--r--addressbook/backend/pas/pas-book-view.h56
-rw-r--r--addressbook/backend/pas/pas-book.c1021
-rw-r--r--addressbook/backend/pas/pas-book.h182
-rw-r--r--addressbook/backend/pas/pas-card-cursor.c226
-rw-r--r--addressbook/backend/pas/pas-card-cursor.h58
-rw-r--r--addressbook/conduit/.cvsignore9
-rw-r--r--addressbook/conduit/Makefile.am43
-rw-r--r--addressbook/conduit/address-conduit.c1911
-rw-r--r--addressbook/conduit/e-address.conduit.in9
-rw-r--r--addressbook/gui/.cvsignore6
-rw-r--r--addressbook/gui/Makefile.am4
-rw-r--r--addressbook/gui/component/.cvsignore11
-rw-r--r--addressbook/gui/component/GNOME_Evolution_Addressbook.oaf.in177
-rw-r--r--addressbook/gui/component/Makefile.am96
-rw-r--r--addressbook/gui/component/addressbook-component.c648
-rw-r--r--addressbook/gui/component/addressbook-component.h32
-rw-r--r--addressbook/gui/component/addressbook-config.c1752
-rw-r--r--addressbook/gui/component/addressbook-config.etspec9
-rw-r--r--addressbook/gui/component/addressbook-config.h35
-rw-r--r--addressbook/gui/component/addressbook-factory.c108
-rw-r--r--addressbook/gui/component/addressbook-storage.c705
-rw-r--r--addressbook/gui/component/addressbook-storage.h81
-rw-r--r--addressbook/gui/component/addressbook.c1192
-rw-r--r--addressbook/gui/component/addressbook.h20
-rw-r--r--addressbook/gui/component/e-address-popup.c1279
-rw-r--r--addressbook/gui/component/e-address-popup.h89
-rw-r--r--addressbook/gui/component/e-address-widget.c576
-rw-r--r--addressbook/gui/component/e-address-widget.h102
-rw-r--r--addressbook/gui/component/e-cardlist-model.c229
-rw-r--r--addressbook/gui/component/e-cardlist-model.h42
-rw-r--r--addressbook/gui/component/ldap-config.glade5819
-rw-r--r--addressbook/gui/component/select-names/.cvsignore12
-rw-r--r--addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl113
-rw-r--r--addressbook/gui/component/select-names/GNOME_Evolution_Addressbook_SelectNames.oaf.in29
-rw-r--r--addressbook/gui/component/select-names/Makefile.am90
-rw-r--r--addressbook/gui/component/select-names/e-select-names-bonobo.c521
-rw-r--r--addressbook/gui/component/select-names/e-select-names-bonobo.h66
-rw-r--r--addressbook/gui/component/select-names/e-select-names-completion.c1312
-rw-r--r--addressbook/gui/component/select-names/e-select-names-completion.h68
-rw-r--r--addressbook/gui/component/select-names/e-select-names-factory.c58
-rw-r--r--addressbook/gui/component/select-names/e-select-names-factory.h30
-rw-r--r--addressbook/gui/component/select-names/e-select-names-manager.c740
-rw-r--r--addressbook/gui/component/select-names/e-select-names-manager.h67
-rw-r--r--addressbook/gui/component/select-names/e-select-names-model.c889
-rw-r--r--addressbook/gui/component/select-names/e-select-names-model.h91
-rw-r--r--addressbook/gui/component/select-names/e-select-names-popup.c564
-rw-r--r--addressbook/gui/component/select-names/e-select-names-popup.h35
-rw-r--r--addressbook/gui/component/select-names/e-select-names-table-model.c348
-rw-r--r--addressbook/gui/component/select-names/e-select-names-table-model.h51
-rw-r--r--addressbook/gui/component/select-names/e-select-names-text-model.c786
-rw-r--r--addressbook/gui/component/select-names/e-select-names-text-model.h53
-rw-r--r--addressbook/gui/component/select-names/e-select-names.c899
-rw-r--r--addressbook/gui/component/select-names/e-select-names.etspec7
-rw-r--r--addressbook/gui/component/select-names/e-select-names.h106
-rw-r--r--addressbook/gui/component/select-names/e-simple-card-bonobo.c269
-rw-r--r--addressbook/gui/component/select-names/e-simple-card-bonobo.h70
-rw-r--r--addressbook/gui/component/select-names/recipient.glade61
-rw-r--r--addressbook/gui/component/select-names/select-names.glade465
-rw-r--r--addressbook/gui/contact-editor/.cvsignore8
-rw-r--r--addressbook/gui/contact-editor/Makefile.am71
-rw-r--r--addressbook/gui/contact-editor/arrow.pngbin174 -> 0 bytes-rw-r--r--addressbook/gui/contact-editor/contact-editor.glade2537
-rw-r--r--addressbook/gui/contact-editor/contact-editor.ui2446
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor-address.c575
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor-address.h77
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor-confirm-delete.glade83
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor-fullname.c435
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor-fullname.h70
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor.c6003
-rw-r--r--addressbook/gui/contact-editor/e-contact-editor.h164
-rw-r--r--addressbook/gui/contact-editor/e-contact-quick-add.c731
-rw-r--r--addressbook/gui/contact-editor/e-contact-quick-add.h68
-rw-r--r--addressbook/gui/contact-editor/e-contact-save-as.c228
-rw-r--r--addressbook/gui/contact-editor/e-contact-save-as.h40
-rw-r--r--addressbook/gui/contact-editor/eab-editor.c403
-rw-r--r--addressbook/gui/contact-editor/eab-editor.h112
-rw-r--r--addressbook/gui/contact-editor/file-exists.glade95
-rw-r--r--addressbook/gui/contact-editor/fulladdr.glade473
-rw-r--r--addressbook/gui/contact-editor/fullname.glade389
-rw-r--r--addressbook/gui/contact-editor/fullname.ui363
-rw-r--r--addressbook/gui/contact-editor/test-editor.c154
-rw-r--r--addressbook/gui/contact-list-editor/.cvsignore4
-rw-r--r--addressbook/gui/contact-list-editor/Makefile.am53
-rw-r--r--addressbook/gui/contact-list-editor/contact-list-editor.glade272
-rw-r--r--addressbook/gui/contact-list-editor/contact-list-editor.ui412
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor.c2434
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor.etspec7
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-editor.h165
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-model.c424
-rw-r--r--addressbook/gui/contact-list-editor/e-contact-list-model.h94
-rw-r--r--addressbook/gui/merging/.cvsignore7
-rw-r--r--addressbook/gui/merging/Makefile.am38
-rw-r--r--addressbook/gui/merging/e-card-duplicate-detected.glade255
-rw-r--r--addressbook/gui/merging/e-card-merging-book-commit-duplicate-detected.glade255
-rw-r--r--addressbook/gui/merging/e-card-merging.c168
-rw-r--r--addressbook/gui/merging/e-card-merging.h31
-rw-r--r--addressbook/gui/merging/eab-contact-commit-duplicate-detected.ui185
-rw-r--r--addressbook/gui/merging/eab-contact-compare.c839
-rw-r--r--addressbook/gui/merging/eab-contact-compare.h101
-rw-r--r--addressbook/gui/merging/eab-contact-duplicate-detected.ui219
-rw-r--r--addressbook/gui/merging/eab-contact-merging.c795
-rw-r--r--addressbook/gui/merging/eab-contact-merging.h66
-rw-r--r--addressbook/gui/search/.cvsignore7
-rw-r--r--addressbook/gui/search/Makefile.am23
-rw-r--r--addressbook/gui/search/addresstypes.xml83
-rw-r--r--addressbook/gui/search/e-addressbook-search-dialog.c179
-rw-r--r--addressbook/gui/search/e-addressbook-search-dialog.h71
-rw-r--r--addressbook/gui/widgets/.cvsignore12
-rw-r--r--addressbook/gui/widgets/Makefile.am189
-rw-r--r--addressbook/gui/widgets/address_formats.dat214
-rw-r--r--addressbook/gui/widgets/addresstypes.xml104
-rw-r--r--addressbook/gui/widgets/countrytransl.map11370
-rw-r--r--addressbook/gui/widgets/e-addressbook-model.c1306
-rw-r--r--addressbook/gui/widgets/e-addressbook-model.h175
-rw-r--r--addressbook/gui/widgets/e-addressbook-reflow-adapter.c728
-rw-r--r--addressbook/gui/widgets/e-addressbook-reflow-adapter.h53
-rw-r--r--addressbook/gui/widgets/e-addressbook-selector.c443
-rw-r--r--addressbook/gui/widgets/e-addressbook-selector.h71
-rw-r--r--addressbook/gui/widgets/e-addressbook-table-adapter.c562
-rw-r--r--addressbook/gui/widgets/e-addressbook-table-adapter.h88
-rw-r--r--addressbook/gui/widgets/e-addressbook-util.c385
-rw-r--r--addressbook/gui/widgets/e-addressbook-util.h55
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.c2848
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.etspec100
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.h244
-rw-r--r--addressbook/gui/widgets/e-contact-map-window.c500
-rw-r--r--addressbook/gui/widgets/e-contact-map-window.h81
-rw-r--r--addressbook/gui/widgets/e-contact-map.c408
-rw-r--r--addressbook/gui/widgets/e-contact-map.h106
-rw-r--r--addressbook/gui/widgets/e-contact-marker.c624
-rw-r--r--addressbook/gui/widgets/e-contact-marker.h84
-rw-r--r--addressbook/gui/widgets/e-minicard-control.c373
-rw-r--r--addressbook/gui/widgets/e-minicard-control.h8
-rw-r--r--addressbook/gui/widgets/e-minicard-label.c754
-rw-r--r--addressbook/gui/widgets/e-minicard-label.h68
-rw-r--r--addressbook/gui/widgets/e-minicard-view-widget.c617
-rw-r--r--addressbook/gui/widgets/e-minicard-view-widget.h68
-rw-r--r--addressbook/gui/widgets/e-minicard-view.c695
-rw-r--r--addressbook/gui/widgets/e-minicard-view.h70
-rw-r--r--addressbook/gui/widgets/e-minicard-widget-test.c119
-rw-r--r--addressbook/gui/widgets/e-minicard-widget.c249
-rw-r--r--addressbook/gui/widgets/e-minicard-widget.h76
-rw-r--r--addressbook/gui/widgets/e-minicard.c1503
-rw-r--r--addressbook/gui/widgets/e-minicard.h129
-rw-r--r--addressbook/gui/widgets/ea-addressbook-view.c123
-rw-r--r--addressbook/gui/widgets/ea-addressbook-view.h55
-rw-r--r--addressbook/gui/widgets/ea-addressbook.c90
-rw-r--r--addressbook/gui/widgets/ea-addressbook.h33
-rw-r--r--addressbook/gui/widgets/ea-minicard-view.c446
-rw-r--r--addressbook/gui/widgets/ea-minicard-view.h56
-rw-r--r--addressbook/gui/widgets/ea-minicard.c303
-rw-r--r--addressbook/gui/widgets/ea-minicard.h56
-rw-r--r--addressbook/gui/widgets/eab-config.c160
-rw-r--r--addressbook/gui/widgets/eab-config.h82
-rw-r--r--addressbook/gui/widgets/eab-contact-display.c626
-rw-r--r--addressbook/gui/widgets/eab-contact-display.h103
-rw-r--r--addressbook/gui/widgets/eab-contact-formatter.c1207
-rw-r--r--addressbook/gui/widgets/eab-contact-formatter.h84
-rw-r--r--addressbook/gui/widgets/eab-gui-util.c1119
-rw-r--r--addressbook/gui/widgets/eab-gui-util.h63
-rw-r--r--addressbook/gui/widgets/gal-view-factory-minicard.c120
-rw-r--r--addressbook/gui/widgets/gal-view-factory-minicard.h35
-rw-r--r--addressbook/gui/widgets/gal-view-minicard.c261
-rw-r--r--addressbook/gui/widgets/gal-view-minicard.h91
-rw-r--r--addressbook/gui/widgets/test-minicard-label.c131
-rw-r--r--addressbook/gui/widgets/test-minicard-view.c208
-rw-r--r--addressbook/gui/widgets/test-minicard.c122
-rw-r--r--addressbook/gui/widgets/test-reflow.c201
-rw-r--r--addressbook/importers/Makefile.am32
-rw-r--r--addressbook/importers/evolution-addressbook-importers.h30
-rw-r--r--addressbook/importers/evolution-csv-importer.c1101
-rw-r--r--addressbook/importers/evolution-ldif-importer.c805
-rw-r--r--addressbook/importers/evolution-vcard-importer.c1016
-rw-r--r--addressbook/printing/.cvsignore9
-rw-r--r--addressbook/printing/Makefile.am79
-rw-r--r--addressbook/printing/e-contact-print-envelope.c245
-rw-r--r--addressbook/printing/e-contact-print-envelope.h32
-rw-r--r--addressbook/printing/e-contact-print-style-editor.c149
-rw-r--r--addressbook/printing/e-contact-print-style-editor.h73
-rw-r--r--addressbook/printing/e-contact-print-types.h39
-rw-r--r--addressbook/printing/e-contact-print.c1756
-rw-r--r--addressbook/printing/e-contact-print.glade2003
-rw-r--r--addressbook/printing/e-contact-print.h47
-rw-r--r--addressbook/printing/medbook.ecps6
-rw-r--r--addressbook/printing/test-contact-print-style-editor.c89
-rw-r--r--addressbook/printing/test-print.c101
-rw-r--r--addressbook/tools/Makefile.am35
-rwxr-xr-xaddressbook/tools/csv2vcard.in236
-rw-r--r--addressbook/tools/evolution-addressbook-export-list-cards.c750
-rw-r--r--addressbook/tools/evolution-addressbook-export-list-folders.c114
-rw-r--r--addressbook/tools/evolution-addressbook-export.c190
-rw-r--r--addressbook/tools/evolution-addressbook-export.h63
-rw-r--r--addressbook/util/Makefile.am35
-rw-r--r--addressbook/util/eab-book-util.c306
-rw-r--r--addressbook/util/eab-book-util.h56
-rw-r--r--art/.cvsignore2
-rw-r--r--art/16_copy.pngbin516 -> 0 bytes-rw-r--r--art/16_customize.pngbin266 -> 0 bytes-rw-r--r--art/16_cut.pngbin531 -> 0 bytes-rw-r--r--art/16_paste.pngbin626 -> 0 bytes-rw-r--r--art/ChangeLog636
-rw-r--r--art/Makefile.am262
-rw-r--r--art/README46
-rw-r--r--art/about-box.pngbin45047 -> 0 bytes-rw-r--r--art/add-attachment.pngbin715 -> 0 bytes-rw-r--r--art/add-nntp-folder-24.pngbin863 -> 0 bytes-rw-r--r--art/add-service.pngbin1186 -> 0 bytes-rw-r--r--art/alarm.pngbin4384 -> 0 bytes-rw-r--r--art/all_contacts.xpm158
-rw-r--r--art/apply-filters-16.xpm48
-rw-r--r--art/arrow-left-24.pngbin429 -> 0 bytes-rw-r--r--art/arrow-right-24.pngbin431 -> 0 bytes-rw-r--r--art/attachment.xpm22
-rw-r--r--art/bcg.pngbin526 -> 0 bytes-rw-r--r--art/bell.xpm83
-rw-r--r--art/briefcase.pngbin2358 -> 0 bytes-rw-r--r--art/butterfly.pngbin12117 -> 0 bytes-rw-r--r--art/calendar-and-tasks-settings.pngbin4134 -> 0 bytes-rw-r--r--art/cellphone.pngbin3440 -> 0 bytes-rw-r--r--art/compose-message.pngbin1062 -> 0 bytes-rw-r--r--art/composer-settings.pngbin3508 -> 0 bytes-rw-r--r--art/configure_16_addressbook.xpm77
-rw-r--r--art/configure_16_calendar.xpm76
-rw-r--r--art/configure_16_folder.xpm85
-rw-r--r--art/configure_16_mail.xpm61
-rw-r--r--art/connect_to_url-16.xpm123
-rw-r--r--art/contact-is-a-list.pngbin173 -> 0 bytes-rw-r--r--art/copy-message.pngbin863 -> 0 bytes-rw-r--r--art/copy.pngbin918 -> 0 bytes-rw-r--r--art/copy_16_message.xpm58
-rw-r--r--art/cut.pngbin1063 -> 0 bytes-rw-r--r--art/dayview.xpm34
-rw-r--r--art/delete-message.pngbin1210 -> 0 bytes-rw-r--r--art/drafts-16.pngbin539 -> 0 bytes-rw-r--r--art/edit.xpm84
-rw-r--r--art/empty.gifbin104 -> 0 bytes-rw-r--r--art/empty.xpm2
-rw-r--r--art/encrypt.xpm80
-rw-r--r--art/envelope.pngbin2393 -> 0 bytes-rw-r--r--art/es-appointments.pngbin433 -> 0 bytes-rw-r--r--art/es-weather.pngbin1002 -> 0 bytes-rw-r--r--art/evo-16-address-conduit.pngbin498 -> 0 bytes-rw-r--r--art/evo-16-calendar-conduit.pngbin505 -> 0 bytes-rw-r--r--art/evo-16-todo-conduit.pngbin702 -> 0 bytes-rw-r--r--art/evo-48-address-conduit.pngbin2919 -> 0 bytes-rw-r--r--art/evo-48-calendar-conduit.pngbin2889 -> 0 bytes-rw-r--r--art/evo-48-todo-conduit.pngbin3677 -> 0 bytes-rw-r--r--art/evolution-calendar-mini.pngbin502 -> 0 bytes-rw-r--r--art/evolution-calendar.pngbin2733 -> 0 bytes-rw-r--r--art/evolution-contacts-mini.pngbin452 -> 0 bytes-rw-r--r--art/evolution-contacts-plain.pngbin2341 -> 0 bytes-rw-r--r--art/evolution-contacts.pngbin2288 -> 0 bytes-rw-r--r--art/evolution-inbox-mini.pngbin478 -> 0 bytes-rw-r--r--art/evolution-inbox.pngbin2937 -> 0 bytes-rw-r--r--art/evolution-notes-mini.pngbin516 -> 0 bytes-rw-r--r--art/evolution-notes.pngbin3400 -> 0 bytes-rw-r--r--art/evolution-tasks-mini.pngbin708 -> 0 bytes-rw-r--r--art/evolution-tasks.pngbin3601 -> 0 bytes-rw-r--r--art/evolution-today-mini.pngbin664 -> 0 bytes-rw-r--r--art/evolution-today.pngbin3713 -> 0 bytes-rw-r--r--art/evolution-trash-mini.pngbin723 -> 0 bytes-rw-r--r--art/evolution-trash.pngbin2913 -> 0 bytes-rw-r--r--art/evolution.pngbin5182 -> 0 bytes-rw-r--r--art/executive-summary-bg.pngbin86508 -> 0 bytes-rw-r--r--art/executive-summary-curve.pngbin1786 -> 0 bytes-rw-r--r--art/faq-16.pngbin639 -> 0 bytes-rw-r--r--art/fetch-mail.pngbin1027 -> 0 bytes-rw-r--r--art/find_contact.xpm127
-rw-r--r--art/find_message.xpm130
-rw-r--r--art/flag-for-followup.xpm78
-rw-r--r--art/folder-copy-16.pngbin376 -> 0 bytes-rw-r--r--art/folder-mini.pngbin342 -> 0 bytes-rw-r--r--art/folder-move-16.pngbin273 -> 0 bytes-rw-r--r--art/folder-settings.pngbin2753 -> 0 bytes-rw-r--r--art/folder.pngbin2088 -> 0 bytes-rw-r--r--art/folder.xpm73
-rw-r--r--art/font.pngbin2403 -> 0 bytes-rw-r--r--art/forget_passwords.xpm125
-rw-r--r--art/forward.pngbin693 -> 0 bytes-rw-r--r--art/forward.xpm51
-rw-r--r--art/globe.pngbin3328 -> 0 bytes-rw-r--r--art/goto-16.pngbin470 -> 0 bytes-rw-r--r--art/goto-24.pngbin679 -> 0 bytes-rw-r--r--art/hand-16.xpm115
-rw-r--r--art/hide_deleted_messages.xpm39
-rw-r--r--art/hide_read_messages.xpm23
-rw-r--r--art/hide_selected_messages.xpm33
-rw-r--r--art/house.pngbin4135 -> 0 bytes-rw-r--r--art/ico-calendar.pngbin2677 -> 0 bytes-rw-r--r--art/ico-mail.pngbin2937 -> 0 bytes-rw-r--r--art/ico-rdf.pngbin3627 -> 0 bytes-rw-r--r--art/ico-weather.pngbin4343 -> 0 bytes-rw-r--r--art/imap-16.pngbin482 -> 0 bytes-rw-r--r--art/import.pngbin2309 -> 0 bytes-rw-r--r--art/import.xpm59
-rw-r--r--art/inbox-16.pngbin587 -> 0 bytes-rw-r--r--art/inbox-full-16.pngbin549 -> 0 bytes-rw-r--r--art/inbox-mini.pngbin587 -> 0 bytes-rw-r--r--art/inbox.pngbin3385 -> 0 bytes-rw-r--r--art/info-bulb.pngbin2661 -> 0 bytes-rw-r--r--art/insert-image-24.pngbin711 -> 0 bytes-rw-r--r--art/insert-link-24.pngbin782 -> 0 bytes-rw-r--r--art/jump.xpm18
-rw-r--r--art/ldap-mini.pngbin542 -> 0 bytes-rw-r--r--art/ldap-settings.pngbin2109 -> 0 bytes-rw-r--r--art/ldap.pngbin2614 -> 0 bytes-rw-r--r--art/mail-accounts-settings.pngbin2328 -> 0 bytes-rw-r--r--art/mail-config-druid-48.pngbin3529 -> 0 bytes-rw-r--r--art/mail-config-druid-account-name.pngbin3150 -> 0 bytes-rw-r--r--art/mail-config-druid-identity.pngbin2646 -> 0 bytes-rw-r--r--art/mail-config-druid-receive.pngbin3551 -> 0 bytes-rw-r--r--art/mail-config-druid-send.pngbin3379 -> 0 bytes-rw-r--r--art/mail-config-druid.pngbin3529 -> 0 bytes-rw-r--r--art/mail-need-reply.xpm101
-rw-r--r--art/mail-new.xpm67
-rw-r--r--art/mail-read.xpm70
-rw-r--r--art/mail-replied.xpm52
-rw-r--r--art/mail.pngbin2855 -> 0 bytes-rw-r--r--art/malehead.pngbin4220 -> 0 bytes-rw-r--r--art/mark-as-important-16.pngbin235 -> 0 bytes-rw-r--r--art/mark.xpm21
-rw-r--r--art/meeting-request-16.pngbin907 -> 0 bytes-rw-r--r--art/meeting-request.pngbin3520 -> 0 bytes-rw-r--r--art/minus.pngbin0 -> 344 bytes-rw-r--r--art/monkey-16.pngbin977 -> 0 bytes-rw-r--r--art/monthview.xpm34
-rw-r--r--art/move-message.pngbin777 -> 0 bytes-rw-r--r--art/move_message.xpm59
-rw-r--r--art/myevo-appointments.pngbin2857 -> 0 bytes-rw-r--r--art/myevo-mail-summary.pngbin3278 -> 0 bytes-rw-r--r--art/myevo-post-it.pngbin3715 -> 0 bytes-rw-r--r--art/myweather-clouds.pngbin414 -> 0 bytes-rw-r--r--art/myweather-fog.pngbin748 -> 0 bytes-rw-r--r--art/myweather-rain.pngbin186 -> 0 bytes-rw-r--r--art/myweather-snow.pngbin354 -> 0 bytes-rw-r--r--art/myweather-storm.pngbin429 -> 0 bytes-rw-r--r--art/myweather-sun.pngbin295 -> 0 bytes-rw-r--r--art/myweather-suncloud.pngbin469 -> 0 bytes-rw-r--r--art/new-message.xpm38
-rw-r--r--art/new_all_day_event.pngbin692 -> 0 bytes-rw-r--r--art/new_appointment.pngbin1542 -> 0 bytes-rw-r--r--art/new_appointment.xpm126
-rw-r--r--art/new_contact.xpm98
-rw-r--r--art/new_task-16.pngbin427 -> 0 bytes-rw-r--r--art/new_task.pngbin1032 -> 0 bytes-rw-r--r--art/next-message.pngbin1050 -> 0 bytes-rw-r--r--art/offline.pngbin640 -> 0 bytes-rw-r--r--art/online.pngbin547 -> 0 bytes-rw-r--r--art/open-in-new-window-16.pngbin504 -> 0 bytes-rw-r--r--art/outbox-16.pngbin575 -> 0 bytes-rw-r--r--art/outbox-full-16.pngbin551 -> 0 bytes-rw-r--r--art/outbox-mini.pngbin575 -> 0 bytes-rw-r--r--art/outbox.pngbin2861 -> 0 bytes-rw-r--r--art/paste.pngbin1053 -> 0 bytes-rw-r--r--art/pattern.pngbin271 -> 0 bytes-rw-r--r--art/pgp-signature-bad.pngbin4233 -> 0 bytes-rw-r--r--art/pgp-signature-nokey.pngbin2907 -> 0 bytes-rw-r--r--art/pgp-signature-ok.pngbin3140 -> 0 bytes-rw-r--r--art/pin.pngbin354 -> 0 bytes-rw-r--r--art/plus.pngbin0 -> 406 bytes-rw-r--r--art/post-message-16.pngbin574 -> 0 bytes-rw-r--r--art/post-reply-24.pngbin896 -> 0 bytes-rw-r--r--art/previous-message.pngbin1053 -> 0 bytes-rw-r--r--art/print-preview-24.pngbin1035 -> 0 bytes-rw-r--r--art/print-preview.xpm153
-rw-r--r--art/print.pngbin867 -> 0 bytes-rw-r--r--art/print.xpm107
-rw-r--r--art/priority-high.xpm22
-rw-r--r--art/priority-low.xpm21
-rw-r--r--art/properties-16.pngbin606 -> 0 bytes-rw-r--r--art/public-folder-mini.pngbin516 -> 0 bytes-rw-r--r--art/public-folder.pngbin3416 -> 0 bytes-rw-r--r--art/rdf.pngbin4372 -> 0 bytes-rw-r--r--art/receive-24.pngbin847 -> 0 bytes-rw-r--r--art/recur.xpm21
-rw-r--r--art/refresh-nntp-folders-24.pngbin575 -> 0 bytes-rw-r--r--art/remove-nntp-folder-24.pngbin878 -> 0 bytes-rw-r--r--art/reply-to-all.pngbin793 -> 0 bytes-rw-r--r--art/reply.pngbin721 -> 0 bytes-rw-r--r--art/reply.xpm46
-rw-r--r--art/reply_to_all.xpm52
-rw-r--r--art/save-16.pngbin540 -> 0 bytes-rw-r--r--art/save-24.pngbin634 -> 0 bytes-rw-r--r--art/save-as-16.pngbin667 -> 0 bytes-rw-r--r--art/save.xpm45
-rw-r--r--art/schedule-meeting-16.pngbin834 -> 0 bytes-rw-r--r--art/schedule-meeting-16.xpm178
-rw-r--r--art/schedule-meeting-24.pngbin1441 -> 0 bytes-rw-r--r--art/score-high.xpm26
-rw-r--r--art/score-higher.xpm26
-rw-r--r--art/score-highest.xpm26
-rw-r--r--art/score-low.xpm26
-rw-r--r--art/score-lower.xpm26
-rw-r--r--art/score-lowest.xpm26
-rw-r--r--art/score-normal.xpm24
-rw-r--r--art/search-16.pngbin526 -> 0 bytes-rw-r--r--art/search-and-replace-16.pngbin638 -> 0 bytes-rw-r--r--art/send-16.pngbin495 -> 0 bytes-rw-r--r--art/send-24-receive.pngbin900 -> 0 bytes-rw-r--r--art/send-24.pngbin803 -> 0 bytes-rw-r--r--art/send-48-receive.pngbin2788 -> 0 bytes-rw-r--r--art/send-later-16.pngbin509 -> 0 bytes-rw-r--r--art/send-receive.xpm58
-rw-r--r--art/send.pngbin1041 -> 0 bytes-rw-r--r--art/service-close.pngbin360 -> 0 bytes-rw-r--r--art/service-configure.pngbin341 -> 0 bytes-rw-r--r--art/service-down-disabled.pngbin331 -> 0 bytes-rw-r--r--art/service-down.pngbin249 -> 0 bytes-rw-r--r--art/service-left-disabled.pngbin319 -> 0 bytes-rw-r--r--art/service-left.pngbin268 -> 0 bytes-rw-r--r--art/service-right-disabled.pngbin318 -> 0 bytes-rw-r--r--art/service-right.pngbin270 -> 0 bytes-rw-r--r--art/service-up-disabled.pngbin347 -> 0 bytes-rw-r--r--art/service-up.pngbin267 -> 0 bytes-rw-r--r--art/show_all_messages.xpm27
-rw-r--r--art/splash-1-0.pngbin91906 -> 0 bytes-rw-r--r--art/splash.pngbin63156 -> 0 bytes-rw-r--r--art/summary-settings.pngbin4659 -> 0 bytes-rw-r--r--art/summary_preferences-16.pngbin584 -> 0 bytes-rw-r--r--art/talking-heads.pngbin3643 -> 0 bytes-rw-r--r--art/task-assigned-to.xpm30
-rw-r--r--art/task-assigned.xpm30
-rw-r--r--art/task-recurring.xpm59
-rw-r--r--art/task.pngbin172 -> 0 bytes-rw-r--r--art/task.xpm27
-rw-r--r--art/thankyou.pngbin4090 -> 0 bytes-rw-r--r--art/timezone-16.xpm162
-rw-r--r--art/timezone-48.pngbin3613 -> 0 bytes-rw-r--r--art/tree-expanded.xpm22
-rw-r--r--art/tree-unexpanded.xpm22
-rw-r--r--art/undelete_message-16.pngbin591 -> 0 bytes-rw-r--r--art/wax-seal-broken.pngbin27264 -> 0 bytes-rw-r--r--art/wax-seal.pngbin22433 -> 0 bytes-rw-r--r--art/weekview.xpm34
-rw-r--r--art/work_offline.xpm33
-rw-r--r--art/work_online-16.pngbin458 -> 0 bytes-rw-r--r--art/working-16.pngbin490 -> 0 bytes-rw-r--r--art/workweekview.xpm34
-rw-r--r--art/yearview.xpm44
-rwxr-xr-xautogen.sh20
-rw-r--r--calendar/.cvsignore6
-rw-r--r--calendar/ChangeLog18035
-rw-r--r--calendar/Makefile.am24
-rw-r--r--calendar/TODO88
-rw-r--r--calendar/alarm-notify/Makefile.am71
-rw-r--r--calendar/alarm-notify/alarm-notify-dialog.c538
-rw-r--r--calendar/alarm-notify/alarm-notify-dialog.h63
-rw-r--r--calendar/alarm-notify/alarm-notify.c334
-rw-r--r--calendar/alarm-notify/alarm-notify.h76
-rw-r--r--calendar/alarm-notify/alarm-notify.ui407
-rw-r--r--calendar/alarm-notify/alarm-queue.c2497
-rw-r--r--calendar/alarm-notify/alarm-queue.h37
-rw-r--r--calendar/alarm-notify/alarm.c337
-rw-r--r--calendar/alarm-notify/alarm.h43
-rw-r--r--calendar/alarm-notify/config-data.c316
-rw-r--r--calendar/alarm-notify/config-data.h61
-rw-r--r--calendar/alarm-notify/evolution-alarm-notify-icon.rc1
-rw-r--r--calendar/alarm-notify/evolution-alarm-notify.icobin0 -> 17542 bytes-rw-r--r--calendar/alarm-notify/notify-main.c124
-rw-r--r--calendar/alarm-notify/util.c91
-rw-r--r--calendar/alarm-notify/util.h33
-rw-r--r--calendar/cal-client/.cvsignore15
-rw-r--r--calendar/cal-client/Makefile.am91
-rw-r--r--calendar/cal-client/cal-client-multi.c706
-rw-r--r--calendar/cal-client/cal-client-multi.h104
-rw-r--r--calendar/cal-client/cal-client-types.c52
-rw-r--r--calendar/cal-client/cal-client-types.h50
-rw-r--r--calendar/cal-client/cal-client.c2752
-rw-r--r--calendar/cal-client/cal-client.h213
-rw-r--r--calendar/cal-client/cal-listener.c398
-rw-r--r--calendar/cal-client/cal-listener.h106
-rw-r--r--calendar/cal-client/cal-query.c411
-rw-r--r--calendar/cal-client/cal-query.h81
-rw-r--r--calendar/cal-client/client-test.c239
-rw-r--r--calendar/cal-client/query-listener.c321
-rw-r--r--calendar/cal-client/query-listener.h97
-rw-r--r--calendar/cal-client/test.ics318
-rw-r--r--calendar/cal-util/.cvsignore7
-rw-r--r--calendar/cal-util/Makefile.am50
-rw-r--r--calendar/cal-util/cal-component.c5254
-rw-r--r--calendar/cal-util/cal-component.h442
-rw-r--r--calendar/cal-util/cal-recur.c3980
-rw-r--r--calendar/cal-util/cal-recur.h69
-rw-r--r--calendar/cal-util/cal-util.c615
-rw-r--r--calendar/cal-util/cal-util.h94
-rw-r--r--calendar/cal-util/test-recur.c220
-rw-r--r--calendar/cal-util/timeutil.c577
-rw-r--r--calendar/cal-util/timeutil.h122
-rw-r--r--calendar/calendar.error.xml310
-rw-r--r--calendar/conduits/.cvsignore2
-rw-r--r--calendar/conduits/Makefile.am1
-rw-r--r--calendar/conduits/calendar/.cvsignore9
-rw-r--r--calendar/conduits/calendar/Makefile.am42
-rw-r--r--calendar/conduits/calendar/calendar-conduit.c1858
-rw-r--r--calendar/conduits/calendar/e-calendar.conduit.in9
-rw-r--r--calendar/conduits/todo/.cvsignore9
-rw-r--r--calendar/conduits/todo/Makefile.am42
-rw-r--r--calendar/conduits/todo/e-todo.conduit.in9
-rw-r--r--calendar/conduits/todo/todo-conduit.c1435
-rw-r--r--calendar/gui/.cvsignore24
-rw-r--r--calendar/gui/GNOME_Evolution_Calendar.oaf.in179
-rw-r--r--calendar/gui/Makefile.am322
-rw-r--r--calendar/gui/alarm-notify/.cvsignore11
-rw-r--r--calendar/gui/alarm-notify/GNOME_Evolution_Calendar_AlarmNotify.oaf.in24
-rw-r--r--calendar/gui/alarm-notify/Makefile.am83
-rw-r--r--calendar/gui/alarm-notify/alarm-notify-dialog.c412
-rw-r--r--calendar/gui/alarm-notify/alarm-notify-dialog.h44
-rw-r--r--calendar/gui/alarm-notify/alarm-notify.c478
-rw-r--r--calendar/gui/alarm-notify/alarm-notify.glade220
-rw-r--r--calendar/gui/alarm-notify/alarm-notify.h65
-rw-r--r--calendar/gui/alarm-notify/alarm-queue.c1038
-rw-r--r--calendar/gui/alarm-notify/alarm-queue.h34
-rw-r--r--calendar/gui/alarm-notify/alarm.c305
-rw-r--r--calendar/gui/alarm-notify/alarm.h42
-rw-r--r--calendar/gui/alarm-notify/config-data.c116
-rw-r--r--calendar/gui/alarm-notify/config-data.h33
-rw-r--r--calendar/gui/alarm-notify/notify-main.c203
-rw-r--r--calendar/gui/alarm-notify/save.c243
-rw-r--r--calendar/gui/alarm-notify/save.h39
-rw-r--r--calendar/gui/cal-search-bar.c544
-rw-r--r--calendar/gui/cal-search-bar.h71
-rw-r--r--calendar/gui/calendar-commands.c810
-rw-r--r--calendar/gui/calendar-commands.h51
-rw-r--r--calendar/gui/calendar-component.c773
-rw-r--r--calendar/gui/calendar-component.h31
-rw-r--r--calendar/gui/calendar-config-keys.h79
-rw-r--r--calendar/gui/calendar-config.c1073
-rw-r--r--calendar/gui/calendar-config.h190
-rw-r--r--calendar/gui/calendar-model.c2469
-rw-r--r--calendar/gui/calendar-model.h100
-rw-r--r--calendar/gui/calendar-offline-handler.c282
-rw-r--r--calendar/gui/calendar-offline-handler.h69
-rw-r--r--calendar/gui/calendar-view-factory.c252
-rw-r--r--calendar/gui/calendar-view-factory.h65
-rw-r--r--calendar/gui/calendar-view.c310
-rw-r--r--calendar/gui/calendar-view.h82
-rw-r--r--calendar/gui/caltypes.xml229
-rw-r--r--calendar/gui/comp-editor-factory.c653
-rw-r--r--calendar/gui/comp-editor-factory.h58
-rw-r--r--calendar/gui/comp-util.c741
-rw-r--r--calendar/gui/comp-util.h82
-rw-r--r--calendar/gui/component-factory.c773
-rw-r--r--calendar/gui/component-factory.h31
-rw-r--r--calendar/gui/config-control-factory.c61
-rw-r--r--calendar/gui/config-control-factory.h30
-rw-r--r--calendar/gui/control-factory.c267
-rw-r--r--calendar/gui/control-factory.h30
-rw-r--r--calendar/gui/dialogs/.cvsignore8
-rw-r--r--calendar/gui/dialogs/Makefile.am192
-rw-r--r--calendar/gui/dialogs/alarm-dialog.c1344
-rw-r--r--calendar/gui/dialogs/alarm-dialog.h46
-rw-r--r--calendar/gui/dialogs/alarm-dialog.ui1068
-rw-r--r--calendar/gui/dialogs/alarm-list-dialog.c352
-rw-r--r--calendar/gui/dialogs/alarm-list-dialog.h53
-rw-r--r--calendar/gui/dialogs/alarm-list-dialog.ui216
-rw-r--r--calendar/gui/dialogs/alarm-options.c621
-rw-r--r--calendar/gui/dialogs/alarm-options.glade398
-rw-r--r--calendar/gui/dialogs/alarm-options.h28
-rw-r--r--calendar/gui/dialogs/alarm-page.c902
-rw-r--r--calendar/gui/dialogs/alarm-page.glade381
-rw-r--r--calendar/gui/dialogs/alarm-page.h61
-rw-r--r--calendar/gui/dialogs/cal-prefs-dialog.c688
-rw-r--r--calendar/gui/dialogs/cal-prefs-dialog.glade1051
-rw-r--r--calendar/gui/dialogs/cal-prefs-dialog.h39
-rw-r--r--calendar/gui/dialogs/cancel-comp.c117
-rw-r--r--calendar/gui/dialogs/cancel-comp.h33
-rw-r--r--calendar/gui/dialogs/changed-comp.c99
-rw-r--r--calendar/gui/dialogs/changed-comp.h34
-rw-r--r--calendar/gui/dialogs/comp-editor-page.c517
-rw-r--r--calendar/gui/dialogs/comp-editor-page.h203
-rw-r--r--calendar/gui/dialogs/comp-editor-util.c659
-rw-r--r--calendar/gui/dialogs/comp-editor-util.h62
-rw-r--r--calendar/gui/dialogs/comp-editor.c4057
-rw-r--r--calendar/gui/dialogs/comp-editor.h268
-rw-r--r--calendar/gui/dialogs/copy-source-dialog.c259
-rw-r--r--calendar/gui/dialogs/copy-source-dialog.h37
-rw-r--r--calendar/gui/dialogs/delete-comp.c269
-rw-r--r--calendar/gui/dialogs/delete-comp.h36
-rw-r--r--calendar/gui/dialogs/delete-error.c126
-rw-r--r--calendar/gui/dialogs/delete-error.h33
-rw-r--r--calendar/gui/dialogs/e-delegate-dialog.c364
-rw-r--r--calendar/gui/dialogs/e-delegate-dialog.glade120
-rw-r--r--calendar/gui/dialogs/e-delegate-dialog.h123
-rw-r--r--calendar/gui/dialogs/e-delegate-dialog.ui103
-rw-r--r--calendar/gui/dialogs/e-send-options-utils.c246
-rw-r--r--calendar/gui/dialogs/e-send-options-utils.h41
-rw-r--r--calendar/gui/dialogs/event-editor.c1027
-rw-r--r--calendar/gui/dialogs/event-editor.h75
-rw-r--r--calendar/gui/dialogs/event-page.c4052
-rw-r--r--calendar/gui/dialogs/event-page.glade601
-rw-r--r--calendar/gui/dialogs/event-page.h124
-rw-r--r--calendar/gui/dialogs/event-page.ui1152
-rw-r--r--calendar/gui/dialogs/goto-dialog.c302
-rw-r--r--calendar/gui/dialogs/goto-dialog.h34
-rw-r--r--calendar/gui/dialogs/goto-dialog.ui180
-rw-r--r--calendar/gui/dialogs/meeting-page.c853
-rw-r--r--calendar/gui/dialogs/meeting-page.etspec21
-rw-r--r--calendar/gui/dialogs/meeting-page.glade234
-rw-r--r--calendar/gui/dialogs/meeting-page.h66
-rw-r--r--calendar/gui/dialogs/memo-editor.c179
-rw-r--r--calendar/gui/dialogs/memo-editor.h76
-rw-r--r--calendar/gui/dialogs/memo-page.c1319
-rw-r--r--calendar/gui/dialogs/memo-page.h78
-rw-r--r--calendar/gui/dialogs/memo-page.ui459
-rw-r--r--calendar/gui/dialogs/recur-comp.c129
-rw-r--r--calendar/gui/dialogs/recur-comp.h37
-rw-r--r--calendar/gui/dialogs/recurrence-page.c2511
-rw-r--r--calendar/gui/dialogs/recurrence-page.glade602
-rw-r--r--calendar/gui/dialogs/recurrence-page.h90
-rw-r--r--calendar/gui/dialogs/recurrence-page.ui621
-rw-r--r--calendar/gui/dialogs/save-comp.c79
-rw-r--r--calendar/gui/dialogs/save-comp.h33
-rw-r--r--calendar/gui/dialogs/schedule-page.c657
-rw-r--r--calendar/gui/dialogs/schedule-page.glade36
-rw-r--r--calendar/gui/dialogs/schedule-page.h91
-rw-r--r--calendar/gui/dialogs/schedule-page.ui20
-rw-r--r--calendar/gui/dialogs/select-source-dialog.c85
-rw-r--r--calendar/gui/dialogs/select-source-dialog.h37
-rw-r--r--calendar/gui/dialogs/send-comp.c307
-rw-r--r--calendar/gui/dialogs/send-comp.h35
-rw-r--r--calendar/gui/dialogs/task-details-page.c785
-rw-r--r--calendar/gui/dialogs/task-details-page.glade310
-rw-r--r--calendar/gui/dialogs/task-details-page.h61
-rw-r--r--calendar/gui/dialogs/task-editor.c674
-rw-r--r--calendar/gui/dialogs/task-editor.h77
-rw-r--r--calendar/gui/dialogs/task-page.c2951
-rw-r--r--calendar/gui/dialogs/task-page.glade493
-rw-r--r--calendar/gui/dialogs/task-page.h110
-rw-r--r--calendar/gui/dialogs/task-page.ui823
-rw-r--r--calendar/gui/e-alarm-list.c655
-rw-r--r--calendar/gui/e-alarm-list.h82
-rw-r--r--calendar/gui/e-cal-component-preview.c488
-rw-r--r--calendar/gui/e-cal-component-preview.h81
-rw-r--r--calendar/gui/e-cal-config.c161
-rw-r--r--calendar/gui/e-cal-config.h98
-rw-r--r--calendar/gui/e-cal-event.c87
-rw-r--r--calendar/gui/e-cal-event.h69
-rw-r--r--calendar/gui/e-cal-list-view.c602
-rw-r--r--calendar/gui/e-cal-list-view.etspec17
-rw-r--r--calendar/gui/e-cal-list-view.h96
-rw-r--r--calendar/gui/e-cal-model-calendar.c545
-rw-r--r--calendar/gui/e-cal-model-calendar.h79
-rw-r--r--calendar/gui/e-cal-model-memos.c268
-rw-r--r--calendar/gui/e-cal-model-memos.h78
-rw-r--r--calendar/gui/e-cal-model-tasks.c1453
-rw-r--r--calendar/gui/e-cal-model-tasks.h114
-rw-r--r--calendar/gui/e-cal-model.c4371
-rw-r--r--calendar/gui/e-cal-model.h332
-rw-r--r--calendar/gui/e-calendar-selector.c256
-rw-r--r--calendar/gui/e-calendar-selector.h65
-rw-r--r--calendar/gui/e-calendar-table.c1363
-rw-r--r--calendar/gui/e-calendar-table.etspec35
-rw-r--r--calendar/gui/e-calendar-table.h102
-rw-r--r--calendar/gui/e-calendar-view.c2422
-rw-r--r--calendar/gui/e-calendar-view.h291
-rw-r--r--calendar/gui/e-cell-date-edit-text.c332
-rw-r--r--calendar/gui/e-cell-date-edit-text.h109
-rw-r--r--calendar/gui/e-comp-editor-registry.c223
-rw-r--r--calendar/gui/e-comp-editor-registry.h79
-rw-r--r--calendar/gui/e-date-time-list.c586
-rw-r--r--calendar/gui/e-date-time-list.h100
-rw-r--r--calendar/gui/e-day-view-layout.c218
-rw-r--r--calendar/gui/e-day-view-layout.h49
-rw-r--r--calendar/gui/e-day-view-main-item.c1806
-rw-r--r--calendar/gui/e-day-view-main-item.h101
-rw-r--r--calendar/gui/e-day-view-time-item.c1226
-rw-r--r--calendar/gui/e-day-view-time-item.h125
-rw-r--r--calendar/gui/e-day-view-top-item.c1225
-rw-r--r--calendar/gui/e-day-view-top-item.h109
-rw-r--r--calendar/gui/e-day-view.c10019
-rw-r--r--calendar/gui/e-day-view.h593
-rw-r--r--calendar/gui/e-itip-control.c1966
-rw-r--r--calendar/gui/e-itip-control.glade478
-rw-r--r--calendar/gui/e-itip-control.h70
-rw-r--r--calendar/gui/e-meeting-attendee.c643
-rw-r--r--calendar/gui/e-meeting-attendee.h87
-rw-r--r--calendar/gui/e-meeting-list-view.c1110
-rw-r--r--calendar/gui/e-meeting-list-view.h75
-rw-r--r--calendar/gui/e-meeting-model.c1874
-rw-r--r--calendar/gui/e-meeting-model.h129
-rw-r--r--calendar/gui/e-meeting-store.c2124
-rw-r--r--calendar/gui/e-meeting-store.h157
-rw-r--r--calendar/gui/e-meeting-time-sel-item.c961
-rw-r--r--calendar/gui/e-meeting-time-sel-item.h57
-rw-r--r--calendar/gui/e-meeting-time-sel.c2556
-rw-r--r--calendar/gui/e-meeting-time-sel.etspec20
-rw-r--r--calendar/gui/e-meeting-time-sel.h418
-rw-r--r--calendar/gui/e-meeting-types.h78
-rw-r--r--calendar/gui/e-meeting-utils.c152
-rw-r--r--calendar/gui/e-meeting-utils.h52
-rw-r--r--calendar/gui/e-memo-list-selector.c372
-rw-r--r--calendar/gui/e-memo-list-selector.h70
-rw-r--r--calendar/gui/e-memo-table.c1299
-rw-r--r--calendar/gui/e-memo-table.etspec14
-rw-r--r--calendar/gui/e-memo-table.h111
-rw-r--r--calendar/gui/e-month-view.c188
-rw-r--r--calendar/gui/e-month-view.h66
-rw-r--r--calendar/gui/e-select-names-editable.c245
-rw-r--r--calendar/gui/e-select-names-editable.h81
-rw-r--r--calendar/gui/e-select-names-renderer.c397
-rw-r--r--calendar/gui/e-select-names-renderer.h87
-rw-r--r--calendar/gui/e-task-list-selector.c374
-rw-r--r--calendar/gui/e-task-list-selector.h70
-rw-r--r--calendar/gui/e-task-table.c1913
-rw-r--r--calendar/gui/e-task-table.h111
-rw-r--r--calendar/gui/e-tasks.c829
-rw-r--r--calendar/gui/e-tasks.h86
-rw-r--r--calendar/gui/e-timezone-entry.c554
-rw-r--r--calendar/gui/e-timezone-entry.h110
-rw-r--r--calendar/gui/e-week-view-event-item.c1620
-rw-r--r--calendar/gui/e-week-view-event-item.h121
-rw-r--r--calendar/gui/e-week-view-layout.c396
-rw-r--r--calendar/gui/e-week-view-layout.h97
-rw-r--r--calendar/gui/e-week-view-main-item.c680
-rw-r--r--calendar/gui/e-week-view-main-item.h102
-rw-r--r--calendar/gui/e-week-view-titles-item.c451
-rw-r--r--calendar/gui/e-week-view-titles-item.h101
-rw-r--r--calendar/gui/e-week-view.c6022
-rw-r--r--calendar/gui/e-week-view.h471
-rw-r--r--calendar/gui/e-weekday-chooser.c665
-rw-r--r--calendar/gui/e-weekday-chooser.h81
-rw-r--r--calendar/gui/ea-cal-view-event.c614
-rw-r--r--calendar/gui/ea-cal-view-event.h57
-rw-r--r--calendar/gui/ea-cal-view.c457
-rw-r--r--calendar/gui/ea-cal-view.h58
-rw-r--r--calendar/gui/ea-calendar-helpers.c163
-rw-r--r--calendar/gui/ea-calendar-helpers.h41
-rw-r--r--calendar/gui/ea-calendar.c216
-rw-r--r--calendar/gui/ea-calendar.h37
-rw-r--r--calendar/gui/ea-day-view-cell.c416
-rw-r--r--calendar/gui/ea-day-view-cell.h85
-rw-r--r--calendar/gui/ea-day-view-main-item.c1359
-rw-r--r--calendar/gui/ea-day-view-main-item.h58
-rw-r--r--calendar/gui/ea-day-view.c301
-rw-r--r--calendar/gui/ea-day-view.h57
-rw-r--r--calendar/gui/ea-gnome-calendar.c342
-rw-r--r--calendar/gui/ea-gnome-calendar.h59
-rw-r--r--calendar/gui/ea-jump-button.c228
-rw-r--r--calendar/gui/ea-jump-button.h57
-rw-r--r--calendar/gui/ea-week-view-cell.c501
-rw-r--r--calendar/gui/ea-week-view-cell.h85
-rw-r--r--calendar/gui/ea-week-view-main-item.c1346
-rw-r--r--calendar/gui/ea-week-view-main-item.h59
-rw-r--r--calendar/gui/ea-week-view.c350
-rw-r--r--calendar/gui/ea-week-view.h58
-rw-r--r--calendar/gui/gnome-cal.c4188
-rw-r--r--calendar/gui/gnome-cal.h279
-rw-r--r--calendar/gui/gnome-calendar-conduit.pngbin3000 -> 0 bytes-rw-r--r--calendar/gui/goto-dialog.glade154
-rw-r--r--calendar/gui/goto.c257
-rw-r--r--calendar/gui/goto.h31
-rw-r--r--calendar/gui/itip-bonobo-control.c252
-rw-r--r--calendar/gui/itip-bonobo-control.h29
-rw-r--r--calendar/gui/itip-control-factory.c252
-rw-r--r--calendar/gui/itip-control-factory.h29
-rw-r--r--calendar/gui/itip-utils.c2502
-rw-r--r--calendar/gui/itip-utils.h128
-rw-r--r--calendar/gui/main.c193
-rw-r--r--calendar/gui/memotypes.xml165
-rw-r--r--calendar/gui/misc.c95
-rw-r--r--calendar/gui/misc.h32
-rw-r--r--calendar/gui/print.c4238
-rw-r--r--calendar/gui/print.h54
-rw-r--r--calendar/gui/tag-calendar.c248
-rw-r--r--calendar/gui/tag-calendar.h42
-rw-r--r--calendar/gui/tasks-control-factory.c79
-rw-r--r--calendar/gui/tasks-control-factory.h30
-rw-r--r--calendar/gui/tasks-control.c690
-rw-r--r--calendar/gui/tasks-control.h31
-rw-r--r--calendar/gui/tasks-migrate.c307
-rw-r--r--calendar/gui/tasks-migrate.h28
-rw-r--r--calendar/gui/tasktypes.xml242
-rw-r--r--calendar/gui/weekday-picker.c574
-rw-r--r--calendar/gui/weekday-picker.h72
-rw-r--r--calendar/idl/.cvsignore2
-rw-r--r--calendar/idl/Makefile.am7
-rw-r--r--calendar/idl/evolution-calendar.idl369
-rw-r--r--calendar/importers/.cvsignore6
-rw-r--r--calendar/importers/GNOME_Evolution_Calendar_Importer.oaf.in51
-rw-r--r--calendar/importers/Makefile.am52
-rw-r--r--calendar/importers/evolution-calendar-importer.h39
-rw-r--r--calendar/importers/icalendar-importer.c1817
-rw-r--r--calendar/importers/main.c91
-rw-r--r--calendar/pcs/.cvsignore11
-rw-r--r--calendar/pcs/Makefile.am67
-rw-r--r--calendar/pcs/cal-backend-file.c2038
-rw-r--r--calendar/pcs/cal-backend-file.h62
-rw-r--r--calendar/pcs/cal-backend-util.c116
-rw-r--r--calendar/pcs/cal-backend-util.h51
-rw-r--r--calendar/pcs/cal-backend.c905
-rw-r--r--calendar/pcs/cal-backend.h221
-rw-r--r--calendar/pcs/cal-common.h41
-rw-r--r--calendar/pcs/cal-factory.c838
-rw-r--r--calendar/pcs/cal-factory.h73
-rw-r--r--calendar/pcs/cal.c1015
-rw-r--r--calendar/pcs/cal.h80
-rw-r--r--calendar/pcs/job.c98
-rw-r--r--calendar/pcs/job.h35
-rw-r--r--calendar/pcs/query-backend.c368
-rw-r--r--calendar/pcs/query-backend.h55
-rw-r--r--calendar/pcs/query.c1729
-rw-r--r--calendar/pcs/query.h69
-rw-r--r--calendar/zones.h19
-rw-r--r--camel/.cvsignore13
-rw-r--r--camel/CODING.STYLE19
-rw-r--r--camel/ChangeLog20314
-rw-r--r--camel/Makefile.am284
-rw-r--r--camel/README54
-rw-r--r--camel/README.COPYRIGHT46
-rw-r--r--camel/README.HACKING14
-rw-r--r--camel/README.mt171
-rw-r--r--camel/broken-date-parser.c515
-rw-r--r--camel/broken-date-parser.h33
-rw-r--r--camel/camel-address.c240
-rw-r--r--camel/camel-address.h79
-rw-r--r--camel/camel-arg.c126
-rw-r--r--camel/camel-arg.h109
-rw-r--r--camel/camel-block-file.c1146
-rw-r--r--camel/camel-block-file.h142
-rw-r--r--camel/camel-certdb.c667
-rw-r--r--camel/camel-certdb.h153
-rw-r--r--camel/camel-charset-map-private.h621
-rw-r--r--camel/camel-charset-map.c354
-rw-r--r--camel/camel-charset-map.h51
-rw-r--r--camel/camel-cipher-context.c438
-rw-r--r--camel/camel-cipher-context.h130
-rw-r--r--camel/camel-cms-context.c324
-rw-r--r--camel/camel-cms-context.h128
-rw-r--r--camel/camel-data-cache.c496
-rw-r--r--camel/camel-data-cache.h98
-rw-r--r--camel/camel-data-wrapper.c319
-rw-r--r--camel/camel-data-wrapper.h98
-rw-r--r--camel/camel-digest-folder.c407
-rw-r--r--camel/camel-digest-folder.h52
-rw-r--r--camel/camel-digest-store.c186
-rw-r--r--camel/camel-digest-store.h59
-rw-r--r--camel/camel-digest-summary.c90
-rw-r--r--camel/camel-digest-summary.h62
-rw-r--r--camel/camel-disco-diary.c436
-rw-r--r--camel/camel-disco-diary.h98
-rw-r--r--camel/camel-disco-folder.c326
-rw-r--r--camel/camel-disco-folder.h121
-rw-r--r--camel/camel-disco-store.c373
-rw-r--r--camel/camel-disco-store.h125
-rw-r--r--camel/camel-exception-list.def37
-rw-r--r--camel/camel-exception.c313
-rw-r--r--camel/camel-exception.h87
-rw-r--r--camel/camel-file-utils.c332
-rw-r--r--camel/camel-file-utils.h57
-rw-r--r--camel/camel-filter-driver.c1320
-rw-r--r--camel/camel-filter-driver.h119
-rw-r--r--camel/camel-filter-search.c689
-rw-r--r--camel/camel-filter-search.h54
-rw-r--r--camel/camel-folder-search.c1159
-rw-r--r--camel/camel-folder-search.h131
-rw-r--r--camel/camel-folder-summary.c2792
-rw-r--r--camel/camel-folder-summary.h348
-rw-r--r--camel/camel-folder-thread.c857
-rw-r--r--camel/camel-folder-thread.h75
-rw-r--r--camel/camel-folder.c2121
-rw-r--r--camel/camel-folder.h342
-rw-r--r--camel/camel-gpg-context.c1503
-rw-r--r--camel/camel-gpg-context.h67
-rw-r--r--camel/camel-html-parser.c807
-rw-r--r--camel/camel-html-parser.h78
-rw-r--r--camel/camel-http-stream.c548
-rw-r--r--camel/camel-http-stream.h105
-rw-r--r--camel/camel-index-control.c211
-rw-r--r--camel/camel-index.c396
-rw-r--r--camel/camel-index.h165
-rw-r--r--camel/camel-internet-address.c510
-rw-r--r--camel/camel-internet-address.h65
-rw-r--r--camel/camel-lock-client.c332
-rw-r--r--camel/camel-lock-client.h41
-rw-r--r--camel/camel-lock-helper.c390
-rw-r--r--camel/camel-lock-helper.h69
-rw-r--r--camel/camel-lock.c420
-rw-r--r--camel/camel-lock.h63
-rw-r--r--camel/camel-medium.c335
-rw-r--r--camel/camel-medium.h100
-rw-r--r--camel/camel-mime-filter-basic.c291
-rw-r--r--camel/camel-mime-filter-basic.h71
-rw-r--r--camel/camel-mime-filter-bestenc.c294
-rw-r--r--camel/camel-mime-filter-bestenc.h98
-rw-r--r--camel/camel-mime-filter-canon.c230
-rw-r--r--camel/camel-mime-filter-canon.h65
-rw-r--r--camel/camel-mime-filter-charset.c271
-rw-r--r--camel/camel-mime-filter-charset.h62
-rw-r--r--camel/camel-mime-filter-chomp.c154
-rw-r--r--camel/camel-mime-filter-chomp.h57
-rw-r--r--camel/camel-mime-filter-crlf.c172
-rw-r--r--camel/camel-mime-filter-crlf.h73
-rw-r--r--camel/camel-mime-filter-from.c220
-rw-r--r--camel/camel-mime-filter-from.h59
-rw-r--r--camel/camel-mime-filter-html.c200
-rw-r--r--camel/camel-mime-filter-html.h57
-rw-r--r--camel/camel-mime-filter-index.c157
-rw-r--r--camel/camel-mime-filter-index.h65
-rw-r--r--camel/camel-mime-filter-linewrap.c147
-rw-r--r--camel/camel-mime-filter-linewrap.h60
-rw-r--r--camel/camel-mime-filter-save.c115
-rw-r--r--camel/camel-mime-filter-save.h61
-rw-r--r--camel/camel-mime-filter-tohtml.c533
-rw-r--r--camel/camel-mime-filter-tohtml.h75
-rw-r--r--camel/camel-mime-filter.c256
-rw-r--r--camel/camel-mime-filter.h94
-rw-r--r--camel/camel-mime-message.c904
-rw-r--r--camel/camel-mime-message.h138
-rw-r--r--camel/camel-mime-parser.c1968
-rw-r--r--camel/camel-mime-parser.h147
-rw-r--r--camel/camel-mime-part-utils.c388
-rw-r--r--camel/camel-mime-part-utils.h44
-rw-r--r--camel/camel-mime-part.c950
-rw-r--r--camel/camel-mime-part.h134
-rw-r--r--camel/camel-mime-utils.c4230
-rw-r--r--camel/camel-mime-utils.h230
-rw-r--r--camel/camel-movemail.c543
-rw-r--r--camel/camel-movemail.h44
-rw-r--r--camel/camel-multipart-encrypted.c331
-rw-r--r--camel/camel-multipart-encrypted.h83
-rw-r--r--camel/camel-multipart-signed.c720
-rw-r--r--camel/camel-multipart-signed.h106
-rw-r--r--camel/camel-multipart.c588
-rw-r--r--camel/camel-multipart.h104
-rw-r--r--camel/camel-news-address.c65
-rw-r--r--camel/camel-news-address.h56
-rw-r--r--camel/camel-object.c1042
-rw-r--r--camel/camel-object.h222
-rw-r--r--camel/camel-operation.c676
-rw-r--r--camel/camel-operation.h68
-rw-r--r--camel/camel-partition-table.c1017
-rw-r--r--camel/camel-partition-table.h152
-rw-r--r--camel/camel-pgp-mime.c154
-rw-r--r--camel/camel-pgp-mime.h44
-rw-r--r--camel/camel-pkcs7-context.c691
-rw-r--r--camel/camel-pkcs7-context.h73
-rw-r--r--camel/camel-private.h244
-rw-r--r--camel/camel-provider.c191
-rw-r--r--camel/camel-provider.h195
-rw-r--r--camel/camel-sasl-anonymous.c150
-rw-r--r--camel/camel-sasl-anonymous.h70
-rw-r--r--camel/camel-sasl-cram-md5.c142
-rw-r--r--camel/camel-sasl-cram-md5.h59
-rw-r--r--camel/camel-sasl-digest-md5.c895
-rw-r--r--camel/camel-sasl-digest-md5.h62
-rw-r--r--camel/camel-sasl-kerberos4.c223
-rw-r--r--camel/camel-sasl-kerberos4.h62
-rw-r--r--camel/camel-sasl-login.c134
-rw-r--r--camel/camel-sasl-login.h61
-rw-r--r--camel/camel-sasl-ntlm.c706
-rw-r--r--camel/camel-sasl-ntlm.h57
-rw-r--r--camel/camel-sasl-plain.c104
-rw-r--r--camel/camel-sasl-plain.h59
-rw-r--r--camel/camel-sasl-popb4smtp.c155
-rw-r--r--camel/camel-sasl-popb4smtp.h59
-rw-r--r--camel/camel-sasl.c271
-rw-r--r--camel/camel-sasl.h78
-rw-r--r--camel/camel-search-private.c683
-rw-r--r--camel/camel-search-private.h82
-rw-r--r--camel/camel-seekable-stream.c202
-rw-r--r--camel/camel-seekable-stream.h87
-rw-r--r--camel/camel-seekable-substream.c302
-rw-r--r--camel/camel-seekable-substream.h68
-rw-r--r--camel/camel-service.c939
-rw-r--r--camel/camel-service.h155
-rw-r--r--camel/camel-session.c870
-rw-r--r--camel/camel-session.h200
-rw-r--r--camel/camel-smime-context.c1001
-rw-r--r--camel/camel-smime-context.h62
-rw-r--r--camel/camel-smime-utils.c126
-rw-r--r--camel/camel-smime-utils.h43
-rw-r--r--camel/camel-store-summary.c932
-rw-r--r--camel/camel-store-summary.h176
-rw-r--r--camel/camel-store.c1170
-rw-r--r--camel/camel-store.h237
-rw-r--r--camel/camel-stream-buffer.c471
-rw-r--r--camel/camel-stream-buffer.h106
-rw-r--r--camel/camel-stream-filter.c396
-rw-r--r--camel/camel-stream-filter.h63
-rw-r--r--camel/camel-stream-fs.c413
-rw-r--r--camel/camel-stream-fs.h74
-rw-r--r--camel/camel-stream-mem.c250
-rw-r--r--camel/camel-stream-mem.h74
-rw-r--r--camel/camel-stream-null.c91
-rw-r--r--camel/camel-stream-null.h57
-rw-r--r--camel/camel-stream.c281
-rw-r--r--camel/camel-stream.h90
-rw-r--r--camel/camel-tcp-stream-openssl.c952
-rw-r--r--camel/camel-tcp-stream-raw.c674
-rw-r--r--camel/camel-tcp-stream-raw.h64
-rw-r--r--camel/camel-tcp-stream-ssl.c783
-rw-r--r--camel/camel-tcp-stream-ssl.h68
-rw-r--r--camel/camel-tcp-stream.c249
-rw-r--r--camel/camel-tcp-stream.h140
-rw-r--r--camel/camel-text-index.c1947
-rw-r--r--camel/camel-text-index.h114
-rw-r--r--camel/camel-transport.c145
-rw-r--r--camel/camel-transport.h82
-rw-r--r--camel/camel-types.h84
-rw-r--r--camel/camel-uid-cache.c268
-rw-r--r--camel/camel-uid-cache.h54
-rw-r--r--camel/camel-url.c553
-rw-r--r--camel/camel-url.h89
-rw-r--r--camel/camel-utf8.c257
-rw-r--r--camel/camel-utf8.h16
-rw-r--r--camel/camel-vee-folder.c1666
-rw-r--r--camel/camel-vee-folder.h84
-rw-r--r--camel/camel-vee-store.c344
-rw-r--r--camel/camel-vee-store.h61
-rw-r--r--camel/camel-vtrash-folder.c209
-rw-r--r--camel/camel-vtrash-folder.h62
-rw-r--r--camel/camel.c121
-rw-r--r--camel/camel.h94
-rw-r--r--camel/devel-docs/camel-index.txt407
-rw-r--r--camel/devel-docs/camel_data_wrapper.diabin3062 -> 0 bytes-rw-r--r--camel/devel-docs/camel_parser_states.diabin2505 -> 0 bytes-rw-r--r--camel/devel-docs/camel_stream.diabin2669 -> 0 bytes-rw-r--r--camel/gstring-util.c216
-rw-r--r--camel/gstring-util.h65
-rw-r--r--camel/hash-table-utils.c78
-rw-r--r--camel/hash-table-utils.h47
-rw-r--r--camel/providers/.cvsignore2
-rw-r--r--camel/providers/Makefile.am7
-rw-r--r--camel/providers/imap/.cvsignore11
-rw-r--r--camel/providers/imap/Makefile.am49
-rw-r--r--camel/providers/imap/camel-imap-command.c822
-rw-r--r--camel/providers/imap/camel-imap-command.h80
-rw-r--r--camel/providers/imap/camel-imap-folder.c2714
-rw-r--r--camel/providers/imap/camel-imap-folder.h90
-rw-r--r--camel/providers/imap/camel-imap-message-cache.c527
-rw-r--r--camel/providers/imap/camel-imap-message-cache.h111
-rw-r--r--camel/providers/imap/camel-imap-private.h76
-rw-r--r--camel/providers/imap/camel-imap-provider.c149
-rw-r--r--camel/providers/imap/camel-imap-search.c499
-rw-r--r--camel/providers/imap/camel-imap-search.h62
-rw-r--r--camel/providers/imap/camel-imap-store-summary.c519
-rw-r--r--camel/providers/imap/camel-imap-store-summary.h100
-rw-r--r--camel/providers/imap/camel-imap-store.c2670
-rw-r--r--camel/providers/imap/camel-imap-store.h146
-rw-r--r--camel/providers/imap/camel-imap-summary.c255
-rw-r--r--camel/providers/imap/camel-imap-summary.h79
-rw-r--r--camel/providers/imap/camel-imap-types.h39
-rw-r--r--camel/providers/imap/camel-imap-utils.c1156
-rw-r--r--camel/providers/imap/camel-imap-utils.h95
-rw-r--r--camel/providers/imap/camel-imap-wrapper.c226
-rw-r--r--camel/providers/imap/camel-imap-wrapper.h70
-rw-r--r--camel/providers/imap/libcamelimap.urls1
-rw-r--r--camel/providers/local/.cvsignore11
-rw-r--r--camel/providers/local/Makefile.am62
-rw-r--r--camel/providers/local/camel-local-folder.c545
-rw-r--r--camel/providers/local/camel-local-folder.h95
-rw-r--r--camel/providers/local/camel-local-private.h59
-rw-r--r--camel/providers/local/camel-local-provider.c222
-rw-r--r--camel/providers/local/camel-local-store.c414
-rw-r--r--camel/providers/local/camel-local-store.h68
-rw-r--r--camel/providers/local/camel-local-summary.c610
-rw-r--r--camel/providers/local/camel-local-summary.h88
-rw-r--r--camel/providers/local/camel-maildir-folder.c245
-rw-r--r--camel/providers/local/camel-maildir-folder.h58
-rw-r--r--camel/providers/local/camel-maildir-store.c416
-rw-r--r--camel/providers/local/camel-maildir-store.h55
-rw-r--r--camel/providers/local/camel-maildir-summary.c803
-rw-r--r--camel/providers/local/camel-maildir-summary.h84
-rw-r--r--camel/providers/local/camel-mbox-folder.c479
-rw-r--r--camel/providers/local/camel-mbox-folder.h62
-rw-r--r--camel/providers/local/camel-mbox-store.c171
-rw-r--r--camel/providers/local/camel-mbox-store.h58
-rw-r--r--camel/providers/local/camel-mbox-summary.c1096
-rw-r--r--camel/providers/local/camel-mbox-summary.h80
-rw-r--r--camel/providers/local/camel-mh-folder.c230
-rw-r--r--camel/providers/local/camel-mh-folder.h58
-rw-r--r--camel/providers/local/camel-mh-store.c534
-rw-r--r--camel/providers/local/camel-mh-store.h60
-rw-r--r--camel/providers/local/camel-mh-summary.c418
-rw-r--r--camel/providers/local/camel-mh-summary.h53
-rw-r--r--camel/providers/local/camel-spool-folder.c185
-rw-r--r--camel/providers/local/camel-spool-folder.h64
-rw-r--r--camel/providers/local/camel-spool-store.c480
-rw-r--r--camel/providers/local/camel-spool-store.h69
-rw-r--r--camel/providers/local/camel-spool-summary.c341
-rw-r--r--camel/providers/local/camel-spool-summary.h72
-rw-r--r--camel/providers/local/libcamellocal.urls5
-rw-r--r--camel/providers/nntp/.cvsignore12
-rw-r--r--camel/providers/nntp/Makefile.am37
-rw-r--r--camel/providers/nntp/camel-nntp-auth.c92
-rw-r--r--camel/providers/nntp/camel-nntp-auth.h42
-rw-r--r--camel/providers/nntp/camel-nntp-folder.c406
-rw-r--r--camel/providers/nntp/camel-nntp-folder.h72
-rw-r--r--camel/providers/nntp/camel-nntp-grouplist.c219
-rw-r--r--camel/providers/nntp/camel-nntp-grouplist.h48
-rw-r--r--camel/providers/nntp/camel-nntp-newsrc.c655
-rw-r--r--camel/providers/nntp/camel-nntp-newsrc.h34
-rw-r--r--camel/providers/nntp/camel-nntp-private.h74
-rw-r--r--camel/providers/nntp/camel-nntp-provider.c113
-rw-r--r--camel/providers/nntp/camel-nntp-resp-codes.h55
-rw-r--r--camel/providers/nntp/camel-nntp-store.c580
-rw-r--r--camel/providers/nntp/camel-nntp-store.h92
-rw-r--r--camel/providers/nntp/camel-nntp-stream.c462
-rw-r--r--camel/providers/nntp/camel-nntp-stream.h66
-rw-r--r--camel/providers/nntp/camel-nntp-summary.c581
-rw-r--r--camel/providers/nntp/camel-nntp-summary.h67
-rw-r--r--camel/providers/nntp/camel-nntp-types.h33
-rw-r--r--camel/providers/nntp/camel-nntp-utils.c300
-rw-r--r--camel/providers/nntp/camel-nntp-utils.h41
-rw-r--r--camel/providers/nntp/libcamelnntp.urls2
-rw-r--r--camel/providers/nntp/test-newsrc.c10
-rw-r--r--camel/providers/pop3/.cvsignore10
-rw-r--r--camel/providers/pop3/Makefile.am39
-rw-r--r--camel/providers/pop3/camel-pop3-engine.c366
-rw-r--r--camel/providers/pop3/camel-pop3-engine.h127
-rw-r--r--camel/providers/pop3/camel-pop3-folder.c550
-rw-r--r--camel/providers/pop3/camel-pop3-folder.h77
-rw-r--r--camel/providers/pop3/camel-pop3-provider.c106
-rw-r--r--camel/providers/pop3/camel-pop3-store.c627
-rw-r--r--camel/providers/pop3/camel-pop3-store.h79
-rw-r--r--camel/providers/pop3/camel-pop3-stream.c468
-rw-r--r--camel/providers/pop3/camel-pop3-stream.h69
-rw-r--r--camel/providers/pop3/libcamelpop3.urls1
-rw-r--r--camel/providers/sendmail/.cvsignore11
-rw-r--r--camel/providers/sendmail/Makefile.am29
-rw-r--r--camel/providers/sendmail/camel-sendmail-provider.c63
-rw-r--r--camel/providers/sendmail/camel-sendmail-transport.c215
-rw-r--r--camel/providers/sendmail/camel-sendmail-transport.h63
-rw-r--r--camel/providers/sendmail/libcamelsendmail.urls1
-rw-r--r--camel/providers/smtp/.cvsignore10
-rw-r--r--camel/providers/smtp/Makefile.am36
-rw-r--r--camel/providers/smtp/camel-smtp-provider.c65
-rw-r--r--camel/providers/smtp/camel-smtp-transport.c1450
-rw-r--r--camel/providers/smtp/camel-smtp-transport.h89
-rw-r--r--camel/providers/smtp/libcamelsmtp.urls1
-rw-r--r--camel/string-utils.c232
-rw-r--r--camel/string-utils.h69
-rw-r--r--camel/tests/.cvsignore7
-rw-r--r--camel/tests/Makefile.am3
-rw-r--r--camel/tests/README44
-rwxr-xr-xcamel/tests/data/gendoc.pl65
-rwxr-xr-xcamel/tests/data/genline.pl72
-rwxr-xr-xcamel/tests/data/getaddr.pl32
-rw-r--r--camel/tests/folder/.cvsignore21
-rw-r--r--camel/tests/folder/Makefile.am28
-rw-r--r--camel/tests/folder/README11
-rw-r--r--camel/tests/folder/test1.c50
-rw-r--r--camel/tests/folder/test2.c58
-rw-r--r--camel/tests/folder/test3.c339
-rw-r--r--camel/tests/folder/test4.c53
-rw-r--r--camel/tests/folder/test5.c53
-rw-r--r--camel/tests/folder/test6.c56
-rw-r--r--camel/tests/folder/test7.c55
-rw-r--r--camel/tests/folder/test8.c217
-rw-r--r--camel/tests/folder/test9.c229
-rw-r--r--camel/tests/lib/.cvsignore12
-rw-r--r--camel/tests/lib/Makefile.am22
-rw-r--r--camel/tests/lib/address-data.h93
-rw-r--r--camel/tests/lib/addresses.c54
-rw-r--r--camel/tests/lib/addresses.h5
-rw-r--r--camel/tests/lib/camel-test.c367
-rw-r--r--camel/tests/lib/camel-test.h68
-rw-r--r--camel/tests/lib/folders.c568
-rw-r--r--camel/tests/lib/folders.h20
-rw-r--r--camel/tests/lib/messages.c154
-rw-r--r--camel/tests/lib/messages.h12
-rw-r--r--camel/tests/lib/session.c44
-rw-r--r--camel/tests/lib/session.h19
-rw-r--r--camel/tests/lib/streams.c244
-rw-r--r--camel/tests/lib/streams.h12
-rw-r--r--camel/tests/message/.cvsignore15
-rw-r--r--camel/tests/message/Makefile.am26
-rw-r--r--camel/tests/message/README5
-rw-r--r--camel/tests/message/test1.c201
-rw-r--r--camel/tests/message/test2.c326
-rw-r--r--camel/tests/message/test3.c199
-rw-r--r--camel/tests/mime-filter/.cvsignore8
-rw-r--r--camel/tests/mime-filter/Makefile.am37
-rw-r--r--camel/tests/mime-filter/charset-gb2312.0.in448
-rw-r--r--camel/tests/mime-filter/charset-gb2312.0.out448
-rw-r--r--camel/tests/mime-filter/charset-iso-2022-jp.0.in5
-rw-r--r--camel/tests/mime-filter/charset-iso-2022-jp.0.out5
-rw-r--r--camel/tests/mime-filter/crlf-1.in19
-rw-r--r--camel/tests/mime-filter/crlf-1.out19
-rw-r--r--camel/tests/mime-filter/test-charset.c140
-rw-r--r--camel/tests/mime-filter/test-crlf.c160
-rw-r--r--camel/tests/misc/.cvsignore12
-rw-r--r--camel/tests/misc/Makefile.am29
-rw-r--r--camel/tests/misc/README4
-rw-r--r--camel/tests/misc/split.c113
-rw-r--r--camel/tests/misc/url.c108
-rw-r--r--camel/tests/misc/utf7.c106
-rw-r--r--camel/tests/smime/.cvsignore5
-rw-r--r--camel/tests/smime/Makefile.am26
-rw-r--r--camel/tests/smime/README2
-rw-r--r--camel/tests/smime/pgp-mime.c175
-rw-r--r--camel/tests/smime/pgp.c179
-rw-r--r--camel/tests/smime/pkcs7.c178
-rw-r--r--camel/tests/stream/.cvsignore14
-rw-r--r--camel/tests/stream/Makefile.am27
-rw-r--r--camel/tests/stream/README4
-rw-r--r--camel/tests/stream/test1.c119
-rw-r--r--camel/tests/stream/test2.c53
-rw-r--r--camel/tests/stream/test3.c104
-rw-r--r--camelConf.sh.in10
-rw-r--r--composer/.cvsignore21
-rw-r--r--composer/ChangeLog3319
-rw-r--r--composer/Composer.idl4
-rw-r--r--composer/Evolution-Composer.idl141
-rw-r--r--composer/Makefile.am145
-rw-r--r--composer/bad-icon.xpm53
-rw-r--r--composer/e-composer-actions.c524
-rw-r--r--composer/e-composer-actions.h65
-rw-r--r--composer/e-composer-activity.c188
-rw-r--r--composer/e-composer-activity.h65
-rw-r--r--composer/e-composer-common.h27
-rw-r--r--composer/e-composer-from-header.c148
-rw-r--r--composer/e-composer-from-header.h70
-rw-r--r--composer/e-composer-header-table.c1501
-rw-r--r--composer/e-composer-header-table.h147
-rw-r--r--composer/e-composer-header.c428
-rw-r--r--composer/e-composer-header.h83
-rw-r--r--composer/e-composer-name-header.c380
-rw-r--r--composer/e-composer-name-header.h77
-rw-r--r--composer/e-composer-post-header.c378
-rw-r--r--composer/e-composer-post-header.h83
-rw-r--r--composer/e-composer-private.c1046
-rw-r--r--composer/e-composer-private.h130
-rw-r--r--composer/e-composer-spell-header.c79
-rw-r--r--composer/e-composer-spell-header.h76
-rw-r--r--composer/e-composer-text-header.c158
-rw-r--r--composer/e-composer-text-header.h75
-rw-r--r--composer/e-icon-list.c2674
-rw-r--r--composer/e-icon-list.h178
-rw-r--r--composer/e-msg-composer-attachment-bar.c852
-rw-r--r--composer/e-msg-composer-attachment-bar.h76
-rw-r--r--composer/e-msg-composer-attachment.c494
-rw-r--r--composer/e-msg-composer-attachment.glade280
-rw-r--r--composer/e-msg-composer-attachment.h77
-rw-r--r--composer/e-msg-composer-hdrs.c1224
-rw-r--r--composer/e-msg-composer-hdrs.h152
-rw-r--r--composer/e-msg-composer-select-file.c276
-rw-r--r--composer/e-msg-composer-select-file.h35
-rw-r--r--composer/e-msg-composer.c7943
-rw-r--r--composer/e-msg-composer.h391
-rw-r--r--composer/evolution-composer.c414
-rw-r--r--composer/evolution-composer.h70
-rw-r--r--composer/evolution-composer.ui68
-rw-r--r--composer/listener.c346
-rw-r--r--composer/listener.h55
-rw-r--r--composer/mail-composer.error.xml90
-rw-r--r--configure.ac1595
-rw-r--r--configure.in1395
-rw-r--r--data/.cvsignore4
-rw-r--r--data/Makefile.am92
-rw-r--r--data/cde_app_root/.cvsignore2
-rw-r--r--data/cde_app_root/Makefile.am1
-rw-r--r--data/cde_app_root/dt/.cvsignore2
-rw-r--r--data/cde_app_root/dt/Makefile.am1
-rw-r--r--data/cde_app_root/dt/appconfig/.cvsignore2
-rw-r--r--data/cde_app_root/dt/appconfig/Makefile.am1
-rw-r--r--data/cde_app_root/dt/appconfig/appmanager/.cvsignore2
-rw-r--r--data/cde_app_root/dt/appconfig/appmanager/C/.cvsignore2
-rw-r--r--data/cde_app_root/dt/appconfig/appmanager/C/Makefile.am1
-rw-r--r--data/cde_app_root/dt/appconfig/appmanager/C/Ximian/.cvsignore2
-rwxr-xr-xdata/cde_app_root/dt/appconfig/appmanager/C/Ximian/Evolution17
-rw-r--r--data/cde_app_root/dt/appconfig/appmanager/C/Ximian/Makefile.am6
-rw-r--r--data/cde_app_root/dt/appconfig/appmanager/Makefile.am1
-rw-r--r--data/cde_app_root/dt/appconfig/icons/.cvsignore2
-rw-r--r--data/cde_app_root/dt/appconfig/icons/C/.cvsignore2
-rw-r--r--data/cde_app_root/dt/appconfig/icons/C/Evolution.l.pm307
-rw-r--r--data/cde_app_root/dt/appconfig/icons/C/Evolution.m.pm291
-rw-r--r--data/cde_app_root/dt/appconfig/icons/C/Evolution.t.pm103
-rw-r--r--data/cde_app_root/dt/appconfig/icons/C/Makefile.am15
-rw-r--r--data/cde_app_root/dt/appconfig/icons/C/Ximian.l.pm147
-rw-r--r--data/cde_app_root/dt/appconfig/icons/C/Ximian.m.pm272
-rw-r--r--data/cde_app_root/dt/appconfig/icons/C/Ximian.t.pm289
-rw-r--r--data/cde_app_root/dt/appconfig/icons/Makefile.am1
-rw-r--r--data/cde_app_root/dt/appconfig/types/.cvsignore2
-rw-r--r--data/cde_app_root/dt/appconfig/types/C/.cvsignore3
-rw-r--r--data/cde_app_root/dt/appconfig/types/C/Makefile.am6
-rw-r--r--data/cde_app_root/dt/appconfig/types/C/Ximian.dt.in30
-rw-r--r--data/cde_app_root/dt/appconfig/types/Makefile.am1
-rw-r--r--data/evolution-alarm-notify.desktop.in.in15
-rw-r--r--data/evolution.convert277
-rw-r--r--data/evolution.desktop.in8
-rw-r--r--data/evolution.desktop.in.in19
-rw-r--r--data/evolution.keys.in24
-rw-r--r--data/evolution.mime5
-rw-r--r--data/icons/Makefile.am308
-rw-r--r--data/icons/hicolor_actions_16x16_folder-copy.pngbin0 -> 443 bytes-rw-r--r--data/icons/hicolor_actions_16x16_folder-move.pngbin0 -> 547 bytes-rw-r--r--data/icons/hicolor_actions_16x16_go-today.pngbin0 -> 652 bytes-rw-r--r--data/icons/hicolor_actions_16x16_go-today.svg306
-rw-r--r--data/icons/hicolor_actions_16x16_mail-copy.pngbin0 -> 394 bytes-rw-r--r--data/icons/hicolor_actions_16x16_mail-move.pngbin0 -> 352 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_bell.pngbin0 -> 491 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_contact-list.png (renamed from art/contact-list-16.png)bin450 -> 450 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_insert-note.pngbin0 -> 265 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_insert-rule.pngbin0 -> 174 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_insert-table.pngbin0 -> 311 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_mail-filters-apply.pngbin0 -> 475 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_mail-flag-for-followup-done.png (renamed from art/flag-for-followup-16.png)bin515 -> 515 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_mail-flag-for-followup.pngbin0 -> 562 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_mail-open-multiple.pngbin0 -> 661 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_mail-unread-multiple.pngbin0 -> 553 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_new-24h-appointment.pngbin0 -> 780 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_new-meeting.pngbin0 -> 827 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_notes.pngbin0 -> 534 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_people.pngbin0 -> 764 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_select-column.pngbin0 -> 240 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_select-row.pngbin0 -> 238 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_shared-by-me.pngbin0 -> 777 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_shared-to-me.pngbin0 -> 825 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_show-all.pngbin0 -> 186 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_task-assigned-to.pngbin0 -> 467 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_task-assigned.pngbin0 -> 482 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_task-recurring.pngbin0 -> 475 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_task.pngbin0 -> 292 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_text-monospaced.pngbin0 -> 344 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_timezone.pngbin0 -> 922 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_todo.pngbin0 -> 560 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_video-conferencing.pngbin0 -> 1090 bytes-rw-r--r--data/icons/hicolor_actions_16x16_stock_view-details.pngbin0 -> 467 bytes-rw-r--r--data/icons/hicolor_actions_16x16_view-calendar-day.pngbin0 -> 540 bytes-rw-r--r--data/icons/hicolor_actions_16x16_view-calendar-day.svg240
-rw-r--r--data/icons/hicolor_actions_16x16_view-calendar-list.pngbin0 -> 511 bytes-rw-r--r--data/icons/hicolor_actions_16x16_view-calendar-list.svg229
-rw-r--r--data/icons/hicolor_actions_16x16_view-calendar-month.pngbin0 -> 627 bytes-rw-r--r--data/icons/hicolor_actions_16x16_view-calendar-month.svg281
-rw-r--r--data/icons/hicolor_actions_16x16_view-calendar-week.pngbin0 -> 591 bytes-rw-r--r--data/icons/hicolor_actions_16x16_view-calendar-week.svg207
-rw-r--r--data/icons/hicolor_actions_16x16_view-calendar-workweek.pngbin0 -> 491 bytes-rw-r--r--data/icons/hicolor_actions_16x16_view-calendar-workweek.svg207
-rw-r--r--data/icons/hicolor_actions_22x22_go-today.pngbin0 -> 1008 bytes-rw-r--r--data/icons/hicolor_actions_22x22_go-today.svg354
-rw-r--r--data/icons/hicolor_actions_22x22_view-calendar-day.pngbin0 -> 717 bytes-rw-r--r--data/icons/hicolor_actions_22x22_view-calendar-day.svg327
-rw-r--r--data/icons/hicolor_actions_22x22_view-calendar-list.pngbin0 -> 713 bytes-rw-r--r--data/icons/hicolor_actions_22x22_view-calendar-list.svg316
-rw-r--r--data/icons/hicolor_actions_22x22_view-calendar-month.pngbin0 -> 968 bytes-rw-r--r--data/icons/hicolor_actions_22x22_view-calendar-month.svg329
-rw-r--r--data/icons/hicolor_actions_22x22_view-calendar-week.pngbin0 -> 774 bytes-rw-r--r--data/icons/hicolor_actions_22x22_view-calendar-week.svg275
-rw-r--r--data/icons/hicolor_actions_22x22_view-calendar-workweek.pngbin0 -> 699 bytes-rw-r--r--data/icons/hicolor_actions_22x22_view-calendar-workweek.svg294
-rw-r--r--data/icons/hicolor_actions_24x24_go-today.pngbin0 -> 1031 bytes-rw-r--r--data/icons/hicolor_actions_24x24_query-free-busy.pngbin0 -> 1127 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_contact-list.pngbin0 -> 899 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_insert-note.pngbin0 -> 1284 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_insert-rule.pngbin0 -> 199 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_insert-table.png (renamed from art/insert-table-24.png)bin430 -> 430 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_mail-filters-apply.pngbin0 -> 849 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_mail-open-multiple.pngbin0 -> 1033 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_mail-unread-multiple.pngbin0 -> 813 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_new-24h-appointment.pngbin0 -> 1246 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_new-meeting.pngbin0 -> 1801 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_notes.pngbin0 -> 913 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_people.pngbin0 -> 1499 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_select-column.pngbin0 -> 379 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_select-row.pngbin0 -> 388 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_shared-by-me.pngbin0 -> 1078 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_shared-to-me.pngbin0 -> 959 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_show-all.pngbin0 -> 543 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_task-assigned-to.pngbin0 -> 899 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_task-assigned.pngbin0 -> 907 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_task-recurring.pngbin0 -> 814 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_task.pngbin0 -> 608 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_text-monospaced.pngbin0 -> 500 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_timezone.pngbin0 -> 1124 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_todo.pngbin0 -> 853 bytes-rw-r--r--data/icons/hicolor_actions_24x24_stock_video-conferencing.pngbin0 -> 1724 bytes-rw-r--r--data/icons/hicolor_actions_24x24_view-calendar-day.pngbin0 -> 736 bytes-rw-r--r--data/icons/hicolor_actions_24x24_view-calendar-list.pngbin0 -> 727 bytes-rw-r--r--data/icons/hicolor_actions_24x24_view-calendar-month.pngbin0 -> 988 bytes-rw-r--r--data/icons/hicolor_actions_24x24_view-calendar-week.pngbin0 -> 788 bytes-rw-r--r--data/icons/hicolor_actions_24x24_view-calendar-workweek.pngbin0 -> 711 bytes-rw-r--r--data/icons/hicolor_actions_32x32_view-calendar-day.pngbin0 -> 1041 bytes-rw-r--r--data/icons/hicolor_actions_32x32_view-calendar-day.svg328
-rw-r--r--data/icons/hicolor_actions_32x32_view-calendar-list.pngbin0 -> 991 bytes-rw-r--r--data/icons/hicolor_actions_32x32_view-calendar-list.svg317
-rw-r--r--data/icons/hicolor_actions_32x32_view-calendar-month.pngbin0 -> 1412 bytes-rw-r--r--data/icons/hicolor_actions_32x32_view-calendar-month.svg357
-rw-r--r--data/icons/hicolor_actions_32x32_view-calendar-week.pngbin0 -> 1086 bytes-rw-r--r--data/icons/hicolor_actions_32x32_view-calendar-week.svg307
-rw-r--r--data/icons/hicolor_actions_32x32_view-calendar-workweek.pngbin0 -> 903 bytes-rw-r--r--data/icons/hicolor_actions_32x32_view-calendar-workweek.svg308
-rw-r--r--data/icons/hicolor_actions_48x48_stock_alarm.pngbin0 -> 5022 bytes-rw-r--r--data/icons/hicolor_actions_48x48_stock_mail-flag-for-followup-done.png (renamed from art/flag-for-followup-48.png)bin3273 -> 3273 bytes-rw-r--r--data/icons/hicolor_actions_48x48_stock_mail-flag-for-followup.pngbin0 -> 3397 bytes-rw-r--r--data/icons/hicolor_actions_48x48_stock_new-24h-appointment.pngbin0 -> 3550 bytes-rw-r--r--data/icons/hicolor_actions_48x48_stock_new-meeting.pngbin0 -> 3766 bytes-rw-r--r--data/icons/hicolor_actions_48x48_stock_notes.pngbin0 -> 2454 bytes-rw-r--r--data/icons/hicolor_actions_48x48_stock_people.pngbin0 -> 3667 bytes-rw-r--r--data/icons/hicolor_actions_48x48_stock_timezone.pngbin0 -> 2870 bytes-rw-r--r--data/icons/hicolor_actions_48x48_stock_todo.pngbin0 -> 2936 bytes-rw-r--r--data/icons/hicolor_actions_scalable_view-calendar-day.svg327
-rw-r--r--data/icons/hicolor_actions_scalable_view-calendar-list.svg317
-rw-r--r--data/icons/hicolor_actions_scalable_view-calendar-month.svg352
-rw-r--r--data/icons/hicolor_actions_scalable_view-calendar-week.svg448
-rw-r--r--data/icons/hicolor_actions_scalable_view-calendar-workweek.svg455
-rw-r--r--data/icons/hicolor_apps_16x16_contact-editor.pngbin0 -> 442 bytes-rw-r--r--data/icons/hicolor_apps_16x16_evolution-mail.pngbin0 -> 617 bytes-rw-r--r--data/icons/hicolor_apps_16x16_evolution-memos.pngbin0 -> 617 bytes-rw-r--r--data/icons/hicolor_apps_16x16_evolution-tasks.pngbin0 -> 818 bytes-rw-r--r--data/icons/hicolor_apps_16x16_evolution.pngbin0 -> 919 bytes-rw-r--r--data/icons/hicolor_apps_16x16_im-aim.pngbin0 -> 635 bytes-rw-r--r--data/icons/hicolor_apps_16x16_im-icq.pngbin0 -> 586 bytes-rw-r--r--data/icons/hicolor_apps_16x16_im-jabber.pngbin0 -> 558 bytes-rw-r--r--data/icons/hicolor_apps_16x16_im-msn.pngbin0 -> 538 bytes-rw-r--r--data/icons/hicolor_apps_16x16_im-nov.pngbin0 -> 769 bytes-rw-r--r--data/icons/hicolor_apps_16x16_im-yahoo.pngbin0 -> 843 bytes-rw-r--r--data/icons/hicolor_apps_22x22_contact-editor.pngbin0 -> 719 bytes-rw-r--r--data/icons/hicolor_apps_22x22_evolution-mail.pngbin0 -> 900 bytes-rw-r--r--data/icons/hicolor_apps_22x22_evolution-memos.pngbin0 -> 930 bytes-rw-r--r--data/icons/hicolor_apps_22x22_evolution-tasks.pngbin0 -> 1147 bytes-rw-r--r--data/icons/hicolor_apps_22x22_evolution.pngbin0 -> 1279 bytes-rw-r--r--data/icons/hicolor_apps_22x22_im-aim.pngbin0 -> 904 bytes-rw-r--r--data/icons/hicolor_apps_22x22_im-icq.pngbin0 -> 1304 bytes-rw-r--r--data/icons/hicolor_apps_22x22_im-jabber.pngbin0 -> 1050 bytes-rw-r--r--data/icons/hicolor_apps_22x22_im-msn.pngbin0 -> 992 bytes-rw-r--r--data/icons/hicolor_apps_22x22_im-nov.pngbin0 -> 1087 bytes-rw-r--r--data/icons/hicolor_apps_22x22_im-yahoo.pngbin0 -> 1217 bytes-rw-r--r--data/icons/hicolor_apps_24x24_contact-editor.pngbin0 -> 743 bytes-rw-r--r--data/icons/hicolor_apps_24x24_evolution-mail.pngbin0 -> 902 bytes-rw-r--r--data/icons/hicolor_apps_24x24_evolution-memos.pngbin0 -> 964 bytes-rw-r--r--data/icons/hicolor_apps_24x24_evolution-tasks.pngbin0 -> 1132 bytes-rw-r--r--data/icons/hicolor_apps_24x24_evolution.pngbin0 -> 1343 bytes-rw-r--r--data/icons/hicolor_apps_24x24_im-aim.pngbin0 -> 908 bytes-rw-r--r--data/icons/hicolor_apps_24x24_im-icq.pngbin0 -> 1316 bytes-rw-r--r--data/icons/hicolor_apps_24x24_im-jabber.pngbin0 -> 1052 bytes-rw-r--r--data/icons/hicolor_apps_24x24_im-msn.pngbin0 -> 1003 bytes-rw-r--r--data/icons/hicolor_apps_24x24_im-nov.pngbin0 -> 1101 bytes-rw-r--r--data/icons/hicolor_apps_24x24_im-yahoo.pngbin0 -> 1225 bytes-rw-r--r--data/icons/hicolor_apps_256x256_evolution.pngbin0 -> 40876 bytes-rw-r--r--data/icons/hicolor_apps_32x32_contact-editor.pngbin0 -> 4218 bytes-rw-r--r--data/icons/hicolor_apps_32x32_evolution-mail.pngbin0 -> 1168 bytes-rw-r--r--data/icons/hicolor_apps_32x32_evolution-memos.pngbin0 -> 1611 bytes-rw-r--r--data/icons/hicolor_apps_32x32_evolution-tasks.pngbin0 -> 1718 bytes-rw-r--r--data/icons/hicolor_apps_32x32_evolution.pngbin0 -> 2295 bytes-rw-r--r--data/icons/hicolor_apps_48x48_contact-editor.pngbin0 -> 4977 bytes-rw-r--r--data/icons/hicolor_apps_48x48_evolution-mail.pngbin0 -> 1609 bytes-rw-r--r--data/icons/hicolor_apps_48x48_evolution-memos.pngbin0 -> 2644 bytes-rw-r--r--data/icons/hicolor_apps_48x48_evolution-tasks.pngbin0 -> 2496 bytes-rw-r--r--data/icons/hicolor_apps_48x48_evolution.pngbin0 -> 3875 bytes-rw-r--r--data/icons/hicolor_apps_scalable_evolution.svg3516
-rw-r--r--data/icons/hicolor_apps_scalable_im-aim.svg183
-rw-r--r--data/icons/hicolor_apps_scalable_im-icq.svg200
-rw-r--r--data/icons/hicolor_apps_scalable_im-jabber.svg360
-rw-r--r--data/icons/hicolor_apps_scalable_im-msn.svg225
-rw-r--r--data/icons/hicolor_apps_scalable_im-nov.svg167
-rw-r--r--data/icons/hicolor_apps_scalable_im-yahoo.svg266
-rw-r--r--data/icons/hicolor_categories_48x48_preferences-autocompletion.pngbin0 -> 3291 bytes-rw-r--r--data/icons/hicolor_categories_48x48_preferences-calendar-and-tasks.pngbin0 -> 2731 bytes-rw-r--r--data/icons/hicolor_categories_48x48_preferences-certificates.pngbin0 -> 1947 bytes-rw-r--r--data/icons/hicolor_categories_48x48_preferences-composer.pngbin0 -> 1971 bytes-rw-r--r--data/icons/hicolor_categories_48x48_preferences-mail-accounts.pngbin0 -> 3261 bytes-rw-r--r--data/icons/hicolor_categories_48x48_preferences-mail.pngbin0 -> 1532 bytes-rw-r--r--data/icons/hicolor_categories_48x48_preferences-system-network-proxy.pngbin0 -> 3191 bytes-rw-r--r--data/icons/hicolor_places_16x16_mail-inbox.pngbin0 -> 674 bytes-rw-r--r--data/icons/hicolor_places_16x16_mail-inbox.svg433
-rw-r--r--data/icons/hicolor_places_16x16_mail-outbox.pngbin0 -> 661 bytes-rw-r--r--data/icons/hicolor_places_16x16_mail-outbox.svg1492
-rw-r--r--data/icons/hicolor_places_16x16_mail-sent.pngbin0 -> 723 bytes-rw-r--r--data/icons/hicolor_places_16x16_mail-sent.svg217
-rw-r--r--data/icons/hicolor_places_22x22_mail-inbox.pngbin0 -> 1035 bytes-rw-r--r--data/icons/hicolor_places_22x22_mail-inbox.svg558
-rw-r--r--data/icons/hicolor_places_22x22_mail-outbox.pngbin0 -> 990 bytes-rw-r--r--data/icons/hicolor_places_22x22_mail-outbox.svg563
-rw-r--r--data/icons/hicolor_places_22x22_mail-sent.pngbin0 -> 1103 bytes-rw-r--r--data/icons/hicolor_places_22x22_mail-sent.svg319
-rw-r--r--data/icons/hicolor_places_24x24_mail-inbox.pngbin0 -> 1075 bytes-rw-r--r--data/icons/hicolor_places_24x24_mail-outbox.pngbin0 -> 1017 bytes-rw-r--r--data/icons/hicolor_places_24x24_mail-sent.pngbin0 -> 1136 bytes-rw-r--r--data/icons/hicolor_status_16x16_stock_check-filled.pngbin0 -> 270 bytes-rw-r--r--data/icons/hicolor_status_16x16_stock_score-high.pngbin0 -> 383 bytes-rw-r--r--data/icons/hicolor_status_16x16_stock_score-higher.pngbin0 -> 381 bytes-rw-r--r--data/icons/hicolor_status_16x16_stock_score-highest.pngbin0 -> 376 bytes-rw-r--r--data/icons/hicolor_status_16x16_stock_score-low.pngbin0 -> 387 bytes-rw-r--r--data/icons/hicolor_status_16x16_stock_score-lower.pngbin0 -> 382 bytes-rw-r--r--data/icons/hicolor_status_16x16_stock_score-lowest.pngbin0 -> 378 bytes-rw-r--r--data/icons/hicolor_status_16x16_stock_score-normal.pngbin0 -> 343 bytes-rw-r--r--data/icons/hicolor_status_16x16_stock_signature-bad.pngbin0 -> 839 bytes-rw-r--r--data/icons/hicolor_status_16x16_stock_signature-ok.pngbin0 -> 1110 bytes-rw-r--r--data/icons/hicolor_status_16x16_stock_signature.pngbin0 -> 1108 bytes-rw-r--r--data/icons/hicolor_status_16x16_wrapped.pngbin0 -> 680 bytes-rw-r--r--data/icons/hicolor_status_24x24_stock_signature-bad.pngbin0 -> 1618 bytes-rw-r--r--data/icons/hicolor_status_24x24_stock_signature-ok.pngbin0 -> 1659 bytes-rw-r--r--data/icons/hicolor_status_24x24_stock_signature.pngbin0 -> 1548 bytes-rw-r--r--data/icons/hicolor_status_32x32_offline.pngbin0 -> 1001 bytes-rw-r--r--data/icons/hicolor_status_32x32_offline.svg969
-rw-r--r--data/icons/hicolor_status_32x32_online.pngbin0 -> 870 bytes-rw-r--r--data/icons/hicolor_status_32x32_online.svg359
-rw-r--r--data/icons/hicolor_status_48x48_stock_signature-bad.pngbin0 -> 4764 bytes-rw-r--r--data/icons/hicolor_status_48x48_stock_signature-ok.pngbin0 -> 4273 bytes-rw-r--r--data/icons/hicolor_status_48x48_stock_signature.pngbin0 -> 3730 bytes-rw-r--r--data/org.gnome.evolution.addressbook.gschema.xml.in54
-rw-r--r--data/org.gnome.evolution.bogofilter.gschema.xml.in9
-rw-r--r--data/org.gnome.evolution.calendar.gschema.xml.in380
-rw-r--r--data/org.gnome.evolution.gschema.xml.in38
-rw-r--r--data/org.gnome.evolution.importer.gschema.xml.in14
-rw-r--r--data/org.gnome.evolution.mail.gschema.xml.in587
-rw-r--r--data/org.gnome.evolution.plugin.attachment-reminder.gschema.xml.in12
-rw-r--r--data/org.gnome.evolution.plugin.autocontacts.gschema.xml.in39
-rw-r--r--data/org.gnome.evolution.plugin.email-custom-header.gschema.xml.in9
-rw-r--r--data/org.gnome.evolution.plugin.external-editor.gschema.xml.in14
-rw-r--r--data/org.gnome.evolution.plugin.face-picture.gschema.xml.in9
-rw-r--r--data/org.gnome.evolution.plugin.itip.gschema.xml.in9
-rw-r--r--data/org.gnome.evolution.plugin.mail-notification.gschema.xml.in49
-rw-r--r--data/org.gnome.evolution.plugin.prefer-plain.gschema.xml.in14
-rw-r--r--data/org.gnome.evolution.plugin.publish-calendar.gschema.xml.in9
-rw-r--r--data/org.gnome.evolution.plugin.templates.gschema.xml.in9
-rw-r--r--data/org.gnome.evolution.shell.gschema.xml.in70
-rw-r--r--data/org.gnome.evolution.spamassassin.gschema.xml.in9
-rw-r--r--data/webview-print.css63
-rw-r--r--data/webview.css181
-rw-r--r--default_user/.cvsignore2
-rw-r--r--default_user/ChangeLog291
-rw-r--r--default_user/Makefile.am13
-rw-r--r--default_user/addressbook-sources.xml10
-rw-r--r--default_user/local/.cvsignore2
-rw-r--r--default_user/local/Calendar/.cvsignore2
-rw-r--r--default_user/local/Calendar/Makefile.am3
-rw-r--r--default_user/local/Calendar/folder-metadata.xml5
-rw-r--r--default_user/local/Contacts/.cvsignore2
-rw-r--r--default_user/local/Contacts/Makefile.am5
-rw-r--r--default_user/local/Contacts/folder-metadata.xml5
-rw-r--r--default_user/local/Drafts/.cvsignore2
-rw-r--r--default_user/local/Drafts/Makefile.am4
-rw-r--r--default_user/local/Drafts/folder-metadata.xml5
-rw-r--r--default_user/local/Inbox/.cvsignore2
-rw-r--r--default_user/local/Inbox/Makefile.am7
-rw-r--r--default_user/local/Inbox/folder-metadata.xml5
-rw-r--r--default_user/local/Inbox/mbox432
-rw-r--r--default_user/local/Makefile.am9
-rw-r--r--default_user/local/Outbox/.cvsignore2
-rw-r--r--default_user/local/Outbox/Makefile.am4
-rw-r--r--default_user/local/Outbox/folder-metadata.xml5
-rw-r--r--default_user/local/Sent/.cvsignore2
-rw-r--r--default_user/local/Sent/Makefile.am4
-rw-r--r--default_user/local/Sent/folder-metadata.xml5
-rw-r--r--default_user/local/Tasks/.cvsignore2
-rw-r--r--default_user/local/Tasks/Makefile.am3
-rw-r--r--default_user/local/Tasks/folder-metadata.xml5
-rw-r--r--default_user/local/Trash/.cvsignore2
-rw-r--r--default_user/local/Trash/Makefile.am4
-rw-r--r--default_user/local/Trash/folder-metadata.xml5
-rw-r--r--default_user/searches.xml110
-rw-r--r--default_user/vfolders.xml25
-rw-r--r--designs/OOA/Comments3
-rw-r--r--designs/OOA/ooa.ui450
-rw-r--r--designs/OOA/oooa_question.pngbin0 -> 16230 bytes-rw-r--r--designs/OOA/oooa_screenshot.pngbin0 -> 14630 bytes-rw-r--r--designs/OOA/outlook_question.pngbin0 -> 9421 bytes-rw-r--r--designs/OOA/outlook_screenshot.pngbin0 -> 54458 bytes-rw-r--r--designs/OOA/spec.txt29
-rw-r--r--designs/read_receipts/Comments3
-rw-r--r--designs/read_receipts/notification-of-rr-request.jpgbin0 -> 26853 bytes-rw-r--r--designs/read_receipts/proposal.pngbin0 -> 26147 bytes-rw-r--r--designs/read_receipts/read.gladep7
-rw-r--r--designs/read_receipts/read.ui314
-rw-r--r--designs/read_receipts/read_receipt_options.jpgbin0 -> 40847 bytes-rw-r--r--designs/read_receipts/receipt.jpgbin0 -> 103530 bytes-rw-r--r--designs/read_receipts/secure_options.jpgbin0 -> 18181 bytes-rw-r--r--designs/read_receipts/spec.txt67
-rw-r--r--devel-docs/.cvsignore3
-rw-r--r--devel-docs/Makefile.am3
-rw-r--r--devel-docs/camel/.cvsignore12
-rw-r--r--devel-docs/camel/Makefile.am101
-rw-r--r--devel-docs/camel/README_AND_TODO.txt43
-rw-r--r--devel-docs/camel/camel-docs.sgml28
-rw-r--r--devel-docs/camel/camel-sections.txt154
-rw-r--r--devel-docs/camel/camel.types9
-rw-r--r--devel-docs/camel/tmpl/.cvsignore2
-rw-r--r--devel-docs/camel/tmpl/camel-data-wrapper.sgml26
-rw-r--r--devel-docs/camel/tmpl/camel-folder.sgml96
-rw-r--r--devel-docs/camel/tmpl/camel-mime-message.sgml171
-rw-r--r--devel-docs/camel/tmpl/camel-mime-part.sgml151
-rw-r--r--devel-docs/camel/tmpl/camel-recipient.sgml88
-rw-r--r--devel-docs/camel/tmpl/camel-service.sgml72
-rw-r--r--devel-docs/camel/tmpl/camel-store.sgml45
-rw-r--r--devel-docs/camel/tmpl/camel-stream.sgml101
-rw-r--r--devel-docs/misc/errors.txt168
-rw-r--r--devel-docs/misc/ref_and_id_proposition.txt4
-rw-r--r--doc/.cvsignore2
-rw-r--r--doc/COPYING-DOCS355
-rw-r--r--doc/COPYING-DOCS.CCBYSA58
-rw-r--r--doc/COPYING-DOCS.GFDL142
-rw-r--r--doc/Camel-Classes65
-rw-r--r--doc/ChangeLog1146
-rw-r--r--doc/Design201
-rw-r--r--doc/Keybindings13
-rw-r--r--doc/Makefile.am4
-rw-r--r--doc/NAMESPACE65
-rw-r--r--doc/devel/.cvsignore5
-rw-r--r--doc/devel/ChangeLog282
-rw-r--r--doc/devel/Makefile.am7
-rwxr-xr-xdoc/devel/build-eplugin-manual.pl272
-rw-r--r--doc/devel/calendar/.cvsignore2
-rw-r--r--doc/devel/calendar/Makefile.am7
-rw-r--r--doc/devel/calendar/alarm-generation.sgml155
-rw-r--r--doc/devel/calendar/architecture.sgml162
-rw-r--r--doc/devel/calendar/cal-client/.cvsignore13
-rw-r--r--doc/devel/calendar/cal-client/Makefile.am196
-rw-r--r--doc/devel/calendar/cal-client/evolution-cal-client-decl.txt526
-rw-r--r--doc/devel/calendar/cal-client/evolution-cal-client-docs.sgml15
-rw-r--r--doc/devel/calendar/cal-client/evolution-cal-client-sections.txt69
-rw-r--r--doc/devel/calendar/cal-client/evolution-cal-client.args0
-rw-r--r--doc/devel/calendar/cal-client/evolution-cal-client.hierarchy2
-rw-r--r--doc/devel/calendar/cal-client/evolution-cal-client.types4
-rw-r--r--doc/devel/calendar/cal-client/tmpl/cal-client.sgml346
-rw-r--r--doc/devel/calendar/cal-client/tmpl/evolution-cal-client-unused.sgml84
-rw-r--r--doc/devel/calendar/cal-util/.cvsignore13
-rw-r--r--doc/devel/calendar/cal-util/Makefile.am196
-rw-r--r--doc/devel/calendar/cal-util/evolution-cal-util-decl.txt1034
-rw-r--r--doc/devel/calendar/cal-util/evolution-cal-util-docs.sgml19
-rw-r--r--doc/devel/calendar/cal-util/evolution-cal-util-sections.txt161
-rw-r--r--doc/devel/calendar/cal-util/evolution-cal-util.args0
-rw-r--r--doc/devel/calendar/cal-util/evolution-cal-util.hierarchy2
-rw-r--r--doc/devel/calendar/cal-util/evolution-cal-util.signals0
-rw-r--r--doc/devel/calendar/cal-util/evolution-cal-util.types4
-rw-r--r--doc/devel/calendar/cal-util/tmpl/cal-component.sgml992
-rw-r--r--doc/devel/calendar/cal-util/tmpl/cal-recur.sgml45
-rw-r--r--doc/devel/calendar/cal-util/tmpl/cal-util.sgml48
-rw-r--r--doc/devel/calendar/cal-util/tmpl/evolution-cal-util-unused.sgml322
-rw-r--r--doc/devel/calendar/cal-util/tmpl/timeutil.sgml73
-rw-r--r--doc/devel/calendar/evolution-calendar.sgml52
-rw-r--r--doc/devel/calendar/public-reference.sgml24
-rw-r--r--doc/devel/evolution-devel-guide.sgml2
-rw-r--r--doc/devel/evolution-plugin-manual.xml3033
-rw-r--r--doc/devel/executive-summary/.cvsignore12
-rw-r--r--doc/devel/executive-summary/Makefile.am191
-rw-r--r--doc/devel/executive-summary/evolution-services-decl.txt536
-rw-r--r--doc/devel/executive-summary/evolution-services-sections.txt95
-rw-r--r--doc/devel/executive-summary/evolution-services.args0
-rw-r--r--doc/devel/executive-summary/evolution-services.types10
-rw-r--r--doc/devel/executive-summary/private-reference.sgml20
-rw-r--r--doc/devel/executive-summary/public-reference.sgml22
-rw-r--r--doc/devel/executive-summary/tmpl/evolution-services-unused.sgml8
-rw-r--r--doc/devel/executive-summary/tmpl/executive-summary-component-factory-client.sgml53
-rw-r--r--doc/devel/executive-summary/tmpl/executive-summary-component-factory.sgml46
-rw-r--r--doc/devel/executive-summary/tmpl/executive-summary-component.sgml37
-rw-r--r--doc/devel/executive-summary/tmpl/executive-summary-html-view.sgml75
-rw-r--r--doc/devel/fdl.sgml6
-rw-r--r--doc/devel/images/Makefile21
-rw-r--r--doc/devel/images/e-config-build-1.pngbin0 -> 16402 bytes-rw-r--r--doc/devel/images/e-config-build-2.pngbin0 -> 19889 bytes-rw-r--r--doc/devel/images/e-config-build-3.pngbin0 -> 7281 bytes-rw-r--r--doc/devel/images/e-config-flow.pic36
-rw-r--r--doc/devel/images/e-popup-merge-1.pic61
-rw-r--r--doc/devel/images/e-popup-merge-2.pic67
-rw-r--r--doc/devel/importer/.cvsignore10
-rw-r--r--doc/devel/importer/Makefile.am195
-rw-r--r--doc/devel/importer/evolution-shell-importer-sections.txt79
-rw-r--r--doc/devel/importer/evolution-shell-importer.args0
-rw-r--r--doc/devel/importer/evolution-shell-importer.hierarchy7
-rw-r--r--doc/devel/importer/evolution-shell-importer.types9
-rw-r--r--doc/devel/importer/private-reference.sgml21
-rw-r--r--doc/devel/importer/public-reference.sgml20
-rw-r--r--doc/devel/importer/tmpl/evolution-importer-client.sgml84
-rw-r--r--doc/devel/importer/tmpl/evolution-importer.sgml96
-rw-r--r--doc/devel/importer/tmpl/evolution-shell-importer-unused.sgml10
-rw-r--r--doc/reference/Makefile.am10
-rw-r--r--doc/reference/evolution-mail-composer/Makefile.am40
-rw-r--r--doc/reference/evolution-mail-composer/evolution-mail-composer-docs.sgml40
-rw-r--r--doc/reference/evolution-mail-composer/evolution-mail-composer-overrides.txt (renamed from default_user/local/Contacts/create-initial)0
-rw-r--r--doc/reference/evolution-mail-composer/evolution-mail-composer-sections.txt246
-rw-r--r--doc/reference/evolution-mail-composer/evolution-mail-composer.types19
-rw-r--r--doc/reference/evolution-mail-formatter/Makefile.am39
-rw-r--r--doc/reference/evolution-mail-formatter/evolution-mail-formatter-docs.sgml53
-rw-r--r--doc/reference/evolution-mail-formatter/evolution-mail-formatter-overrides.txt (renamed from default_user/local/Drafts/mbox)0
-rw-r--r--doc/reference/evolution-mail-formatter/evolution-mail-formatter-sections.txt395
-rw-r--r--doc/reference/evolution-mail-formatter/evolution-mail-formatter.types33
-rw-r--r--doc/reference/evolution-shell/Makefile.am42
-rw-r--r--doc/reference/evolution-shell/evolution-shell-docs.sgml46
-rw-r--r--doc/reference/evolution-shell/evolution-shell-overrides.txt (renamed from default_user/local/Outbox/mbox)0
-rw-r--r--doc/reference/evolution-shell/evolution-shell-sections.txt372
-rw-r--r--doc/reference/evolution-shell/evolution-shell.types19
-rw-r--r--doc/reference/evolution-shell/tmpl/e-mail-account-manager.sgml72
-rw-r--r--doc/reference/evolution-shell/tmpl/e-mail-account-tree-view.sgml90
-rw-r--r--doc/reference/evolution-shell/tmpl/e-mail-identity-combo-box.sgml56
-rw-r--r--doc/reference/evolution-util/Makefile.am73
-rw-r--r--doc/reference/evolution-util/evolution-util-docs.sgml277
-rw-r--r--doc/reference/evolution-util/evolution-util-overrides.txt (renamed from default_user/local/Sent/mbox)0
-rw-r--r--doc/reference/evolution-util/evolution-util-sections.txt4674
-rw-r--r--doc/reference/evolution-util/evolution-util.types167
-rw-r--r--e-util/.cvsignore6
-rw-r--r--e-util/ChangeLog2030
-rw-r--r--e-util/Makefile.am763
-rw-r--r--e-util/arrow-down.xpm (renamed from widgets/table/arrow-down.xpm)0
-rw-r--r--e-util/arrow-up.xpm (renamed from widgets/table/arrow-up.xpm)0
-rw-r--r--e-util/check-empty.xpm (renamed from my-evolution/check-empty.xpm)0
-rw-r--r--e-util/check-filled.xpm (renamed from art/check-filled.xpm)0
-rw-r--r--e-util/e-action-combo-box.c583
-rw-r--r--e-util/e-action-combo-box.h89
-rw-r--r--e-util/e-activity-bar.c364
-rw-r--r--e-util/e-activity-bar.h71
-rw-r--r--e-util/e-activity-proxy.c379
-rw-r--r--e-util/e-activity-proxy.h74
-rw-r--r--e-util/e-activity.c796
-rw-r--r--e-util/e-activity.h99
-rw-r--r--e-util/e-alarm-selector.c94
-rw-r--r--e-util/e-alarm-selector.h67
-rw-r--r--e-util/e-alert-bar.c390
-rw-r--r--e-util/e-alert-bar.h72
-rw-r--r--e-util/e-alert-dialog.c421
-rw-r--r--e-util/e-alert-dialog.h85
-rw-r--r--e-util/e-alert-sink.c93
-rw-r--r--e-util/e-alert-sink.h67
-rw-r--r--e-util/e-alert.c1001
-rw-r--r--e-util/e-alert.h123
-rw-r--r--e-util/e-attachment-bar.c778
-rw-r--r--e-util/e-attachment-bar.h83
-rw-r--r--e-util/e-attachment-button.c869
-rw-r--r--e-util/e-attachment-button.h91
-rw-r--r--e-util/e-attachment-dialog.c432
-rw-r--r--e-util/e-attachment-dialog.h77
-rw-r--r--e-util/e-attachment-handler-image.c240
-rw-r--r--e-util/e-attachment-handler-image.h69
-rw-r--r--e-util/e-attachment-handler.c133
-rw-r--r--e-util/e-attachment-handler.h84
-rw-r--r--e-util/e-attachment-icon-view.c570
-rw-r--r--e-util/e-attachment-icon-view.h71
-rw-r--r--e-util/e-attachment-paned.c904
-rw-r--r--e-util/e-attachment-paned.h99
-rw-r--r--e-util/e-attachment-store.c1481
-rw-r--r--e-util/e-attachment-store.h137
-rw-r--r--e-util/e-attachment-tree-view.c623
-rw-r--r--e-util/e-attachment-tree-view.h70
-rw-r--r--e-util/e-attachment-view.c1908
-rw-r--r--e-util/e-attachment-view.h244
-rw-r--r--e-util/e-attachment.c3512
-rw-r--r--e-util/e-attachment.h166
-rw-r--r--e-util/e-auth-combo-box.c266
-rw-r--r--e-util/e-auth-combo-box.h75
-rw-r--r--e-util/e-autocomplete-selector.c96
-rw-r--r--e-util/e-autocomplete-selector.h68
-rw-r--r--e-util/e-bit-array.c430
-rw-r--r--e-util/e-bit-array.h190
-rw-r--r--e-util/e-bonobo-factory-util.c53
-rw-r--r--e-util/e-bonobo-factory-util.h32
-rw-r--r--e-util/e-book-source-config.c287
-rw-r--r--e-util/e-book-source-config.h71
-rw-r--r--e-util/e-buffer-tagger.c692
-rw-r--r--e-util/e-buffer-tagger.h39
-rw-r--r--e-util/e-cal-source-config.c431
-rw-r--r--e-util/e-cal-source-config.h76
-rw-r--r--e-util/e-calendar-item.c3781
-rw-r--r--e-util/e-calendar-item.h392
-rw-r--r--e-util/e-calendar.c848
-rw-r--r--e-util/e-calendar.h112
-rw-r--r--e-util/e-canvas-background.c279
-rw-r--r--e-util/e-canvas-background.h75
-rw-r--r--e-util/e-canvas-utils.c222
-rw-r--r--e-util/e-canvas-utils.h59
-rw-r--r--e-util/e-canvas-vbox.c410
-rw-r--r--e-util/e-canvas-vbox.h92
-rw-r--r--e-util/e-canvas.c880
-rw-r--r--e-util/e-canvas.h141
-rw-r--r--e-util/e-categories-config.c235
-rw-r--r--e-util/e-categories-config.h49
-rw-r--r--e-util/e-categories-dialog.c155
-rw-r--r--e-util/e-categories-dialog.h73
-rw-r--r--e-util/e-categories-editor.c437
-rw-r--r--e-util/e-categories-editor.h88
-rw-r--r--e-util/e-categories-master-list-wombat.c207
-rw-r--r--e-util/e-categories-master-list-wombat.h35
-rw-r--r--e-util/e-categories-selector.c587
-rw-r--r--e-util/e-categories-selector.h97
-rw-r--r--e-util/e-category-completion.c505
-rw-r--r--e-util/e-category-completion.h72
-rw-r--r--e-util/e-category-editor.c343
-rw-r--r--e-util/e-category-editor.h81
-rw-r--r--e-util/e-cell-checkbox.c102
-rw-r--r--e-util/e-cell-checkbox.h71
-rw-r--r--e-util/e-cell-combo.c838
-rw-r--r--e-util/e-cell-combo.h89
-rw-r--r--e-util/e-cell-date-edit.c1039
-rw-r--r--e-util/e-cell-date-edit.h124
-rw-r--r--e-util/e-cell-date.c130
-rw-r--r--e-util/e-cell-date.h74
-rw-r--r--e-util/e-cell-hbox.c353
-rw-r--r--e-util/e-cell-hbox.h91
-rw-r--r--e-util/e-cell-number.c95
-rw-r--r--e-util/e-cell-number.h71
-rw-r--r--e-util/e-cell-percent.c160
-rw-r--r--e-util/e-cell-percent.h76
-rw-r--r--e-util/e-cell-pixbuf.c389
-rw-r--r--e-util/e-cell-pixbuf.h75
-rw-r--r--e-util/e-cell-popup.c550
-rw-r--r--e-util/e-cell-popup.h118
-rw-r--r--e-util/e-cell-renderer-color.c243
-rw-r--r--e-util/e-cell-renderer-color.h79
-rw-r--r--e-util/e-cell-size.c112
-rw-r--r--e-util/e-cell-size.h72
-rw-r--r--e-util/e-cell-text.c2810
-rw-r--r--e-util/e-cell-text.h195
-rw-r--r--e-util/e-cell-toggle.c469
-rw-r--r--e-util/e-cell-toggle.h83
-rw-r--r--e-util/e-cell-tree.c847
-rw-r--r--e-util/e-cell-tree.h90
-rw-r--r--e-util/e-cell-vbox.c341
-rw-r--r--e-util/e-cell-vbox.h93
-rw-r--r--e-util/e-cell.c675
-rw-r--r--e-util/e-cell.h297
-rw-r--r--e-util/e-charset-combo-box.c407
-rw-r--r--e-util/e-charset-combo-box.h73
-rw-r--r--e-util/e-charset.c267
-rw-r--r--e-util/e-charset.h40
-rw-r--r--e-util/e-client-cache.c1349
-rw-r--r--e-util/e-client-cache.h112
-rw-r--r--e-util/e-client-combo-box.c461
-rw-r--r--e-util/e-client-combo-box.h92
-rw-r--r--e-util/e-client-selector.c715
-rw-r--r--e-util/e-client-selector.h95
-rw-r--r--e-util/e-component-listener.c232
-rw-r--r--e-util/e-component-listener.h50
-rw-r--r--e-util/e-config-listener.c545
-rw-r--r--e-util/e-config-listener.h75
-rw-r--r--e-util/e-config.c1369
-rw-r--r--e-util/e-config.h445
-rw-r--r--e-util/e-contact-store.c1384
-rw-r--r--e-util/e-contact-store.h96
-rw-r--r--e-util/e-corba-utils.c42
-rw-r--r--e-util/e-corba-utils.h30
-rw-r--r--e-util/e-data-capture.c359
-rw-r--r--e-util/e-data-capture.h79
-rw-r--r--e-util/e-dateedit.c2499
-rw-r--r--e-util/e-dateedit.h219
-rw-r--r--e-util/e-datetime-format.c693
-rw-r--r--e-util/e-datetime-format.h64
-rw-r--r--e-util/e-db3-utils.c185
-rw-r--r--e-util/e-db3-utils.h29
-rw-r--r--e-util/e-dbhash.c227
-rw-r--r--e-util/e-dbhash.h45
-rw-r--r--e-util/e-destination-store.c751
-rw-r--r--e-util/e-destination-store.h106
-rw-r--r--e-util/e-dialog-utils.c295
-rw-r--r--e-util/e-dialog-utils.h57
-rw-r--r--e-util/e-dialog-widgets.c813
-rw-r--r--e-util/e-dialog-widgets.h67
-rw-r--r--e-util/e-event.c528
-rw-r--r--e-util/e-event.h280
-rw-r--r--e-util/e-file-request.c184
-rw-r--r--e-util/e-file-request.h69
-rw-r--r--e-util/e-file-utils.c205
-rw-r--r--e-util/e-file-utils.h50
-rw-r--r--e-util/e-filter-code.c102
-rw-r--r--e-util/e-filter-code.h72
-rw-r--r--e-util/e-filter-color.c163
-rw-r--r--e-util/e-filter-color.h74
-rw-r--r--e-util/e-filter-datespec.c513
-rw-r--r--e-util/e-filter-datespec.h91
-rw-r--r--e-util/e-filter-element.c448
-rw-r--r--e-util/e-filter-element.h123
-rw-r--r--e-util/e-filter-file.c261
-rw-r--r--e-util/e-filter-file.h78
-rw-r--r--e-util/e-filter-input.c304
-rw-r--r--e-util/e-filter-input.h78
-rw-r--r--e-util/e-filter-int.c230
-rw-r--r--e-util/e-filter-int.h81
-rw-r--r--e-util/e-filter-option.c566
-rw-r--r--e-util/e-filter-option.h101
-rw-r--r--e-util/e-filter-part.c513
-rw-r--r--e-util/e-filter-part.h112
-rw-r--r--e-util/e-filter-rule.c1241
-rw-r--r--e-util/e-filter-rule.h163
-rw-r--r--e-util/e-focus-tracker.c886
-rw-r--r--e-util/e-focus-tracker.h104
-rw-r--r--e-util/e-gtk-utils.c152
-rw-r--r--e-util/e-gtk-utils.h41
-rw-r--r--e-util/e-gui-utils.c66
-rw-r--r--e-util/e-gui-utils.h8
-rw-r--r--e-util/e-host-utils.c386
-rw-r--r--e-util/e-host-utils.h38
-rw-r--r--e-util/e-html-utils.c343
-rw-r--r--e-util/e-html-utils.h37
-rw-r--r--e-util/e-i18n.h94
-rw-r--r--e-util/e-icon-factory.c215
-rw-r--r--e-util/e-icon-factory.h43
-rw-r--r--e-util/e-iconv.c496
-rw-r--r--e-util/e-iconv.h44
-rw-r--r--e-util/e-image-chooser.c562
-rw-r--r--e-util/e-image-chooser.h80
-rw-r--r--e-util/e-import-assistant.c1436
-rw-r--r--e-util/e-import-assistant.h72
-rw-r--r--e-util/e-import.c622
-rw-r--r--e-util/e-import.h333
-rw-r--r--e-util/e-interval-chooser.c214
-rw-r--r--e-util/e-interval-chooser.h72
-rw-r--r--e-util/e-iterator.c186
-rw-r--r--e-util/e-iterator.h69
-rw-r--r--e-util/e-lang-utils.c58
-rw-r--r--e-util/e-lang-utils.h31
-rw-r--r--e-util/e-list-iterator.c249
-rw-r--r--e-util/e-list-iterator.h45
-rw-r--r--e-util/e-list.c180
-rw-r--r--e-util/e-list.h63
-rw-r--r--e-util/e-mail-identity-combo-box.c382
-rw-r--r--e-util/e-mail-identity-combo-box.h75
-rw-r--r--e-util/e-mail-signature-combo-box.c668
-rw-r--r--e-util/e-mail-signature-combo-box.h95
-rw-r--r--e-util/e-mail-signature-editor.c925
-rw-r--r--e-util/e-mail-signature-editor.h87
-rw-r--r--e-util/e-mail-signature-manager.c708
-rw-r--r--e-util/e-mail-signature-manager.h93
-rw-r--r--e-util/e-mail-signature-preview.c418
-rw-r--r--e-util/e-mail-signature-preview.h84
-rw-r--r--e-util/e-mail-signature-script-dialog.c731
-rw-r--r--e-util/e-mail-signature-script-dialog.h94
-rw-r--r--e-util/e-mail-signature-tree-view.c395
-rw-r--r--e-util/e-mail-signature-tree-view.h80
-rw-r--r--e-util/e-map.c1429
-rw-r--r--e-util/e-map.h155
-rw-r--r--e-util/e-marshal.list53
-rw-r--r--e-util/e-memory.c1306
-rw-r--r--e-util/e-memory.h74
-rw-r--r--e-util/e-menu-tool-action.c59
-rw-r--r--e-util/e-menu-tool-action.h75
-rw-r--r--e-util/e-menu-tool-button.c278
-rw-r--r--e-util/e-menu-tool-button.h79
-rw-r--r--e-util/e-misc-utils.c2091
-rw-r--r--e-util/e-misc-utils.h190
-rw-r--r--e-util/e-mktemp.c329
-rw-r--r--e-util/e-mktemp.h34
-rw-r--r--e-util/e-msgport.c917
-rw-r--r--e-util/e-msgport.h83
-rw-r--r--e-util/e-name-selector-dialog.c1887
-rw-r--r--e-util/e-name-selector-dialog.h99
-rw-r--r--e-util/e-name-selector-entry.c3590
-rw-r--r--e-util/e-name-selector-entry.h123
-rw-r--r--e-util/e-name-selector-list.c791
-rw-r--r--e-util/e-name-selector-list.h82
-rw-r--r--e-util/e-name-selector-model.c663
-rw-r--r--e-util/e-name-selector-model.h108
-rw-r--r--e-util/e-name-selector.c692
-rw-r--r--e-util/e-name-selector.h93
-rw-r--r--e-util/e-online-button.c210
-rw-r--r--e-util/e-online-button.h69
-rw-r--r--e-util/e-paned.c503
-rw-r--r--e-util/e-paned.h82
-rw-r--r--e-util/e-passwords.c1145
-rw-r--r--e-util/e-passwords.h84
-rw-r--r--e-util/e-path.c255
-rw-r--r--e-util/e-path.h36
-rw-r--r--e-util/e-photo-cache.c1228
-rw-r--r--e-util/e-photo-cache.h103
-rw-r--r--e-util/e-photo-source.c123
-rw-r--r--e-util/e-photo-source.h76
-rw-r--r--e-util/e-picture-gallery.c437
-rw-r--r--e-util/e-picture-gallery.h71
-rw-r--r--e-util/e-pilot-map.c450
-rw-r--r--e-util/e-pilot-map.h58
-rw-r--r--e-util/e-pilot-settings.c149
-rw-r--r--e-util/e-pilot-settings.h73
-rw-r--r--e-util/e-pilot-util.c62
-rw-r--r--e-util/e-pilot-util.h29
-rw-r--r--e-util/e-plugin-ui.c635
-rw-r--r--e-util/e-plugin-ui.h80
-rw-r--r--e-util/e-plugin.c992
-rw-r--r--e-util/e-plugin.h287
-rw-r--r--e-util/e-poolv.c154
-rw-r--r--e-util/e-poolv.h45
-rw-r--r--e-util/e-popup-action.c408
-rw-r--r--e-util/e-popup-action.h96
-rw-r--r--e-util/e-popup-menu.c112
-rw-r--r--e-util/e-popup-menu.h59
-rw-r--r--e-util/e-port-entry.c549
-rw-r--r--e-util/e-port-entry.h91
-rw-r--r--e-util/e-preferences-window.c611
-rw-r--r--e-util/e-preferences-window.h85
-rw-r--r--e-util/e-preview-pane.c330
-rw-r--r--e-util/e-preview-pane.h77
-rw-r--r--e-util/e-print.c255
-rw-r--r--e-util/e-print.h42
-rw-r--r--e-util/e-printable.c221
-rw-r--r--e-util/e-printable.h113
-rw-r--r--e-util/e-proxy.c96
-rw-r--r--e-util/e-proxy.h38
-rw-r--r--e-util/e-reflow-model.c406
-rw-r--r--e-util/e-reflow-model.h135
-rw-r--r--e-util/e-reflow.c1732
-rw-r--r--e-util/e-reflow.h145
-rw-r--r--e-util/e-request.c104
-rw-r--r--e-util/e-request.h33
-rw-r--r--e-util/e-rule-context.c1026
-rw-r--r--e-util/e-rule-context.h218
-rw-r--r--e-util/e-rule-editor.c780
-rw-r--r--e-util/e-rule-editor.h104
-rw-r--r--e-util/e-search-bar.c801
-rw-r--r--e-util/e-search-bar.h86
-rw-r--r--e-util/e-selectable.c168
-rw-r--r--e-util/e-selectable.h85
-rw-r--r--e-util/e-selection-model-array.c580
-rw-r--r--e-util/e-selection-model-array.h114
-rw-r--r--e-util/e-selection-model-simple.c117
-rw-r--r--e-util/e-selection-model-simple.h91
-rw-r--r--e-util/e-selection-model.c798
-rw-r--r--e-util/e-selection-model.h201
-rw-r--r--e-util/e-selection.c904
-rw-r--r--e-util/e-selection.h134
-rw-r--r--e-util/e-send-options.c767
-rw-r--r--e-util/e-send-options.h154
-rw-r--r--e-util/e-send-options.ui949
-rw-r--r--e-util/e-sexp.c1367
-rw-r--r--e-util/e-sexp.h162
-rw-r--r--e-util/e-sorter-array.c360
-rw-r--r--e-util/e-sorter-array.h140
-rw-r--r--e-util/e-sorter.c172
-rw-r--r--e-util/e-sorter.h128
-rw-r--r--e-util/e-source-combo-box.c701
-rw-r--r--e-util/e-source-combo-box.h90
-rw-r--r--e-util/e-source-config-backend.c140
-rw-r--r--e-util/e-source-config-backend.h98
-rw-r--r--e-util/e-source-config-dialog.c394
-rw-r--r--e-util/e-source-config-dialog.h69
-rw-r--r--e-util/e-source-config.c1473
-rw-r--r--e-util/e-source-config.h120
-rw-r--r--e-util/e-source-selector-dialog.c455
-rw-r--r--e-util/e-source-selector-dialog.h85
-rw-r--r--e-util/e-source-selector.c2165
-rw-r--r--e-util/e-source-selector.h148
-rw-r--r--e-util/e-source-util.c280
-rw-r--r--e-util/e-source-util.h48
-rw-r--r--e-util/e-spell-entry.c953
-rw-r--r--e-util/e-spell-entry.h74
-rw-r--r--e-util/e-stock-request.c279
-rw-r--r--e-util/e-stock-request.h69
-rw-r--r--e-util/e-system.error.xml88
-rw-r--r--e-util/e-table-click-to-add.c711
-rw-r--r--e-util/e-table-click-to-add.h100
-rw-r--r--e-util/e-table-col-dnd.h43
-rw-r--r--e-util/e-table-col.c153
-rw-r--r--e-util/e-table-col.h105
-rw-r--r--e-util/e-table-column-selector.c463
-rw-r--r--e-util/e-table-column-selector.h81
-rw-r--r--e-util/e-table-column-specification.c123
-rw-r--r--e-util/e-table-column-specification.h89
-rw-r--r--e-util/e-table-config.c1141
-rw-r--r--e-util/e-table-config.h123
-rw-r--r--e-util/e-table-config.ui1402
-rw-r--r--e-util/e-table-defines.h44
-rw-r--r--e-util/e-table-extras.c411
-rw-r--r--e-util/e-table-extras.h95
-rw-r--r--e-util/e-table-field-chooser-dialog.c235
-rw-r--r--e-util/e-table-field-chooser-dialog.h77
-rw-r--r--e-util/e-table-field-chooser-item.c755
-rw-r--r--e-util/e-table-field-chooser-item.h99
-rw-r--r--e-util/e-table-field-chooser.c338
-rw-r--r--e-util/e-table-field-chooser.h84
-rw-r--r--e-util/e-table-group-container.c1708
-rw-r--r--e-util/e-table-group-container.h140
-rw-r--r--e-util/e-table-group-leaf.c874
-rw-r--r--e-util/e-table-group-leaf.h111
-rw-r--r--e-util/e-table-group.c812
-rw-r--r--e-util/e-table-group.h244
-rw-r--r--e-util/e-table-header-item.c2230
-rw-r--r--e-util/e-table-header-item.h148
-rw-r--r--e-util/e-table-header-utils.c282
-rw-r--r--e-util/e-table-header-utils.h53
-rw-r--r--e-util/e-table-header.c1045
-rw-r--r--e-util/e-table-header.h147
-rw-r--r--e-util/e-table-item.c4094
-rw-r--r--e-util/e-table-item.h265
-rw-r--r--e-util/e-table-model.c645
-rw-r--r--e-util/e-table-model.h199
-rw-r--r--e-util/e-table-one.c258
-rw-r--r--e-util/e-table-one.h75
-rw-r--r--e-util/e-table-search.c235
-rw-r--r--e-util/e-table-search.h86
-rw-r--r--e-util/e-table-selection-model.c387
-rw-r--r--e-util/e-table-selection-model.h91
-rw-r--r--e-util/e-table-sort-info.c900
-rw-r--r--e-util/e-table-sort-info.h135
-rw-r--r--e-util/e-table-sorted-variable.c244
-rw-r--r--e-util/e-table-sorted-variable.h85
-rw-r--r--e-util/e-table-sorted.c335
-rw-r--r--e-util/e-table-sorted.h84
-rw-r--r--e-util/e-table-sorter.c527
-rw-r--r--e-util/e-table-sorter.h90
-rw-r--r--e-util/e-table-sorting-utils.c538
-rw-r--r--e-util/e-table-sorting-utils.h95
-rw-r--r--e-util/e-table-specification.c686
-rw-r--r--e-util/e-table-specification.h98
-rw-r--r--e-util/e-table-state.c704
-rw-r--r--e-util/e-table-state.h97
-rw-r--r--e-util/e-table-subset-variable.c271
-rw-r--r--e-util/e-table-subset-variable.h105
-rw-r--r--e-util/e-table-subset.c680
-rw-r--r--e-util/e-table-subset.h119
-rw-r--r--e-util/e-table-utils.c206
-rw-r--r--e-util/e-table-utils.h54
-rw-r--r--e-util/e-table.c3506
-rw-r--r--e-util/e-table.h386
-rw-r--r--e-util/e-text-event-processor-emacs-like.c353
-rw-r--r--e-util/e-text-event-processor-emacs-like.h98
-rw-r--r--e-util/e-text-event-processor-types.h66
-rw-r--r--e-util/e-text-event-processor.c177
-rw-r--r--e-util/e-text-event-processor.h120
-rw-r--r--e-util/e-text-model-repos.c74
-rw-r--r--e-util/e-text-model-repos.h58
-rw-r--r--e-util/e-text-model.c642
-rw-r--r--e-util/e-text-model.h155
-rw-r--r--e-util/e-text.c3405
-rw-r--r--e-util/e-text.h254
-rw-r--r--e-util/e-time-utils.c479
-rw-r--r--e-util/e-time-utils.h58
-rw-r--r--e-util/e-timezone-dialog.c870
-rw-r--r--e-util/e-timezone-dialog.h77
-rw-r--r--e-util/e-timezone-dialog.ui312
-rw-r--r--e-util/e-tree-model-generator.c1345
-rw-r--r--e-util/e-tree-model-generator.h104
-rw-r--r--e-util/e-tree-model.c814
-rw-r--r--e-util/e-tree-model.h217
-rw-r--r--e-util/e-tree-selection-model.c842
-rw-r--r--e-util/e-tree-selection-model.h95
-rw-r--r--e-util/e-tree-table-adapter.c1569
-rw-r--r--e-util/e-tree-table-adapter.h135
-rw-r--r--e-util/e-tree-view-frame.c1179
-rw-r--r--e-util/e-tree-view-frame.h119
-rw-r--r--e-util/e-tree.c3253
-rw-r--r--e-util/e-tree.h260
-rw-r--r--e-util/e-unicode.c352
-rw-r--r--e-util/e-unicode.h70
-rw-r--r--e-util/e-url-entry.c133
-rw-r--r--e-util/e-url-entry.h67
-rw-r--r--e-util/e-url.c339
-rw-r--r--e-util/e-url.h56
-rw-r--r--e-util/e-util-enums.h130
-rw-r--r--e-util/e-util-private.h127
-rw-r--r--e-util/e-util.c1667
-rw-r--r--e-util/e-util.h546
-rw-r--r--e-util/e-web-view-gtkhtml.c2315
-rw-r--r--e-util/e-web-view-gtkhtml.h210
-rw-r--r--e-util/e-web-view-preview.c470
-rw-r--r--e-util/e-web-view-preview.h115
-rw-r--r--e-util/e-web-view.c3234
-rw-r--r--e-util/e-web-view.h205
-rw-r--r--e-util/e-win32-defaults.c523
-rw-r--r--e-util/e-win32-defaults.h40
-rw-r--r--e-util/e-win32-reloc.c181
-rw-r--r--e-util/e-xml-utils.c562
-rw-r--r--e-util/e-xml-utils.h58
-rw-r--r--e-util/ea-calendar-cell.c404
-rw-r--r--e-util/ea-calendar-cell.h90
-rw-r--r--e-util/ea-calendar-item.c1373
-rw-r--r--e-util/ea-calendar-item.h71
-rw-r--r--e-util/ea-cell-table.c215
-rw-r--r--e-util/ea-cell-table.h63
-rw-r--r--e-util/ea-factory.h118
-rw-r--r--e-util/ea-widgets.c36
-rw-r--r--e-util/ea-widgets.h36
-rw-r--r--e-util/ename/.cvsignore8
-rw-r--r--e-util/ename/Makefile.am51
-rw-r--r--e-util/ename/TODO2
-rw-r--r--e-util/ename/e-address-western.c446
-rw-r--r--e-util/ename/e-address-western.h21
-rw-r--r--e-util/ename/e-name-western-tables.h74
-rw-r--r--e-util/ename/e-name-western.c958
-rw-r--r--e-util/ename/e-name-western.h21
-rw-r--r--e-util/ename/test-ename-western-gtk.c157
-rw-r--r--e-util/ename/test-ename-western.c71
-rw-r--r--e-util/evolution-source-viewer.c1176
-rw-r--r--e-util/filter.error.xml34
-rw-r--r--e-util/filter.ui591
-rw-r--r--e-util/gal-a11y-e-cell-popup.c153
-rw-r--r--e-util/gal-a11y-e-cell-popup.h65
-rw-r--r--e-util/gal-a11y-e-cell-registry.c151
-rw-r--r--e-util/gal-a11y-e-cell-registry.h75
-rw-r--r--e-util/gal-a11y-e-cell-toggle.c198
-rw-r--r--e-util/gal-a11y-e-cell-toggle.h67
-rw-r--r--e-util/gal-a11y-e-cell-tree.c266
-rw-r--r--e-util/gal-a11y-e-cell-tree.h66
-rw-r--r--e-util/gal-a11y-e-cell-vbox.c235
-rw-r--r--e-util/gal-a11y-e-cell-vbox.h67
-rw-r--r--e-util/gal-a11y-e-cell.c648
-rw-r--r--e-util/gal-a11y-e-cell.h112
-rw-r--r--e-util/gal-a11y-e-table-click-to-add-factory.c108
-rw-r--r--e-util/gal-a11y-e-table-click-to-add-factory.h52
-rw-r--r--e-util/gal-a11y-e-table-click-to-add.c358
-rw-r--r--e-util/gal-a11y-e-table-click-to-add.h58
-rw-r--r--e-util/gal-a11y-e-table-column-header.c243
-rw-r--r--e-util/gal-a11y-e-table-column-header.h59
-rw-r--r--e-util/gal-a11y-e-table-factory.c101
-rw-r--r--e-util/gal-a11y-e-table-factory.h53
-rw-r--r--e-util/gal-a11y-e-table-item-factory.c107
-rw-r--r--e-util/gal-a11y-e-table-item-factory.h52
-rw-r--r--e-util/gal-a11y-e-table-item.c1438
-rw-r--r--e-util/gal-a11y-e-table-item.h62
-rw-r--r--e-util/gal-a11y-e-table.c315
-rw-r--r--e-util/gal-a11y-e-table.h62
-rw-r--r--e-util/gal-a11y-e-text-factory.c103
-rw-r--r--e-util/gal-a11y-e-text-factory.h52
-rw-r--r--e-util/gal-a11y-e-text.c1141
-rw-r--r--e-util/gal-a11y-e-text.h59
-rw-r--r--e-util/gal-a11y-e-tree-factory.c99
-rw-r--r--e-util/gal-a11y-e-tree-factory.h52
-rw-r--r--e-util/gal-a11y-e-tree.c196
-rw-r--r--e-util/gal-a11y-e-tree.h61
-rw-r--r--e-util/gal-a11y-factory.h89
-rw-r--r--e-util/gal-a11y-util.c49
-rw-r--r--e-util/gal-a11y-util.h40
-rw-r--r--e-util/gal-view-collection.c819
-rw-r--r--e-util/gal-view-collection.h129
-rw-r--r--e-util/gal-view-etable.c267
-rw-r--r--e-util/gal-view-etable.h76
-rw-r--r--e-util/gal-view-instance-save-as-dialog.c366
-rw-r--r--e-util/gal-view-instance-save-as-dialog.h92
-rw-r--r--e-util/gal-view-instance-save-as-dialog.ui133
-rw-r--r--e-util/gal-view-instance.c509
-rw-r--r--e-util/gal-view-instance.h135
-rw-r--r--e-util/gal-view.c261
-rw-r--r--e-util/gal-view.h87
-rw-r--r--e-util/md5-utils.c363
-rw-r--r--e-util/md5-utils.h52
-rw-r--r--e-util/test-calendar.c145
-rw-r--r--e-util/test-category-completion.c68
-rw-r--r--e-util/test-contact-store.c146
-rw-r--r--e-util/test-dateedit.c299
-rw-r--r--e-util/test-mail-signatures.c195
-rw-r--r--e-util/test-name-selector.c113
-rw-r--r--e-util/test-preferences-window.c108
-rw-r--r--e-util/test-source-combo-box.c107
-rw-r--r--e-util/test-source-config.c57
-rw-r--r--e-util/test-source-selector.c158
-rw-r--r--e-util/test-tree-view-frame.c375
-rw-r--r--e-util/widgets.error.xml38
-rw-r--r--em-format/Makefile.am147
-rw-r--r--em-format/e-mail-extension-registry.c335
-rw-r--r--em-format/e-mail-extension-registry.h156
-rw-r--r--em-format/e-mail-formatter-attachment-bar.c104
-rw-r--r--em-format/e-mail-formatter-attachment.c408
-rw-r--r--em-format/e-mail-formatter-enums.h90
-rw-r--r--em-format/e-mail-formatter-error.c121
-rw-r--r--em-format/e-mail-formatter-extension.c141
-rw-r--r--em-format/e-mail-formatter-extension.h112
-rw-r--r--em-format/e-mail-formatter-headers.c595
-rw-r--r--em-format/e-mail-formatter-image.c162
-rw-r--r--em-format/e-mail-formatter-message-rfc822.c262
-rw-r--r--em-format/e-mail-formatter-print-headers.c235
-rw-r--r--em-format/e-mail-formatter-print.c295
-rw-r--r--em-format/e-mail-formatter-print.h93
-rw-r--r--em-format/e-mail-formatter-quote-attachment.c126
-rw-r--r--em-format/e-mail-formatter-quote-headers.c279
-rw-r--r--em-format/e-mail-formatter-quote-message-rfc822.c154
-rw-r--r--em-format/e-mail-formatter-quote-text-enriched.c101
-rw-r--r--em-format/e-mail-formatter-quote-text-html.c100
-rw-r--r--em-format/e-mail-formatter-quote-text-plain.c125
-rw-r--r--em-format/e-mail-formatter-quote.c250
-rw-r--r--em-format/e-mail-formatter-quote.h103
-rw-r--r--em-format/e-mail-formatter-secure-button.c479
-rw-r--r--em-format/e-mail-formatter-source.c140
-rw-r--r--em-format/e-mail-formatter-text-enriched.c114
-rw-r--r--em-format/e-mail-formatter-text-html.c363
-rw-r--r--em-format/e-mail-formatter-text-plain.c204
-rw-r--r--em-format/e-mail-formatter-utils.c541
-rw-r--r--em-format/e-mail-formatter-utils.h60
-rw-r--r--em-format/e-mail-formatter.c1435
-rw-r--r--em-format/e-mail-formatter.h192
-rw-r--r--em-format/e-mail-inline-filter.c496
-rw-r--r--em-format/e-mail-inline-filter.h83
-rw-r--r--em-format/e-mail-parser-application-mbox.c173
-rw-r--r--em-format/e-mail-parser-application-smime.c161
-rw-r--r--em-format/e-mail-parser-attachment-bar.c79
-rw-r--r--em-format/e-mail-parser-extension.c93
-rw-r--r--em-format/e-mail-parser-extension.h96
-rw-r--r--em-format/e-mail-parser-headers.c80
-rw-r--r--em-format/e-mail-parser-image.c102
-rw-r--r--em-format/e-mail-parser-inlinepgp-encrypted.c188
-rw-r--r--em-format/e-mail-parser-inlinepgp-signed.c201
-rw-r--r--em-format/e-mail-parser-message-deliverystatus.c87
-rw-r--r--em-format/e-mail-parser-message-external.c182
-rw-r--r--em-format/e-mail-parser-message-rfc822.c136
-rw-r--r--em-format/e-mail-parser-message.c130
-rw-r--r--em-format/e-mail-parser-multipart-alternative.c158
-rw-r--r--em-format/e-mail-parser-multipart-appledouble.c95
-rw-r--r--em-format/e-mail-parser-multipart-digest.c135
-rw-r--r--em-format/e-mail-parser-multipart-encrypted.c183
-rw-r--r--em-format/e-mail-parser-multipart-mixed.c133
-rw-r--r--em-format/e-mail-parser-multipart-related.c155
-rw-r--r--em-format/e-mail-parser-multipart-signed.c217
-rw-r--r--em-format/e-mail-parser-secure-button.c77
-rw-r--r--em-format/e-mail-parser-source.c78
-rw-r--r--em-format/e-mail-parser-text-enriched.c109
-rw-r--r--em-format/e-mail-parser-text-html.c110
-rw-r--r--em-format/e-mail-parser-text-plain.c241
-rw-r--r--em-format/e-mail-parser.c776
-rw-r--r--em-format/e-mail-parser.h115
-rw-r--r--em-format/e-mail-part-attachment-bar.c89
-rw-r--r--em-format/e-mail-part-attachment-bar.h71
-rw-r--r--em-format/e-mail-part-attachment.c170
-rw-r--r--em-format/e-mail-part-attachment.h75
-rw-r--r--em-format/e-mail-part-headers.c382
-rw-r--r--em-format/e-mail-part-headers.h84
-rw-r--r--em-format/e-mail-part-image.c100
-rw-r--r--em-format/e-mail-part-image.h65
-rw-r--r--em-format/e-mail-part-list.c417
-rw-r--r--em-format/e-mail-part-list.h81
-rw-r--r--em-format/e-mail-part-utils.c582
-rw-r--r--em-format/e-mail-part-utils.h60
-rw-r--r--em-format/e-mail-part.c613
-rw-r--r--em-format/e-mail-part.h132
-rw-r--r--em-format/e-mail-stripsig-filter.c165
-rw-r--r--em-format/e-mail-stripsig-filter.h69
-rw-r--r--enumtypes.c.template37
-rw-r--r--enumtypes.h.template24
-rw-r--r--evolution-calendar.pc.in17
-rw-r--r--evolution-mail.pc.in17
-rw-r--r--evolution-plugin.pc.in20
-rw-r--r--evolution-shell.pc.in23
-rwxr-xr-xevolution-zip.in82
-rw-r--r--evolution.doap52
-rw-r--r--evolution_addressbookConf.sh.in10
-rw-r--r--evolution_calendarConf.sh.in10
-rw-r--r--evolution_shellConf.sh.in10
-rw-r--r--executive-summary/.cvsignore4
-rw-r--r--executive-summary/ChangeLog908
-rw-r--r--executive-summary/GNOME_Evolution_Summary.oaf.in29
-rw-r--r--executive-summary/Makefile.am12
-rw-r--r--executive-summary/component/.cvsignore10
-rw-r--r--executive-summary/component/Makefile.am88
-rw-r--r--executive-summary/component/component-factory.c154
-rw-r--r--executive-summary/component/component-factory.h30
-rw-r--r--executive-summary/component/e-summary-callbacks.c320
-rw-r--r--executive-summary/component/e-summary-callbacks.h12
-rw-r--r--executive-summary/component/e-summary-factory.c185
-rw-r--r--executive-summary/component/e-summary-factory.h34
-rw-r--r--executive-summary/component/e-summary-prefs.c122
-rw-r--r--executive-summary/component/e-summary-prefs.h45
-rw-r--r--executive-summary/component/e-summary-url.c851
-rw-r--r--executive-summary/component/e-summary-url.h36
-rw-r--r--executive-summary/component/e-summary-util.c131
-rw-r--r--executive-summary/component/e-summary-util.h29
-rw-r--r--executive-summary/component/e-summary.c1340
-rw-r--r--executive-summary/component/e-summary.h115
-rw-r--r--executive-summary/component/executive-summary-config.glade223
-rw-r--r--executive-summary/component/executive-summary.pngbin25562 -> 0 bytes-rw-r--r--executive-summary/component/main.c79
-rw-r--r--executive-summary/default-header.html14
-rw-r--r--executive-summary/evolution-services/.cvsignore11
-rw-r--r--executive-summary/evolution-services/Makefile.am55
-rw-r--r--executive-summary/evolution-services/executive-summary-client.c171
-rw-r--r--executive-summary/evolution-services/executive-summary-client.h64
-rw-r--r--executive-summary/evolution-services/executive-summary-component-client.c177
-rw-r--r--executive-summary/evolution-services/executive-summary-component-client.h67
-rw-r--r--executive-summary/evolution-services/executive-summary-component-factory-client.c177
-rw-r--r--executive-summary/evolution-services/executive-summary-component-factory-client.h56
-rw-r--r--executive-summary/evolution-services/executive-summary-component-view.c400
-rw-r--r--executive-summary/evolution-services/executive-summary-component-view.h92
-rw-r--r--executive-summary/evolution-services/executive-summary-component.c353
-rw-r--r--executive-summary/evolution-services/executive-summary-component.h83
-rw-r--r--executive-summary/evolution-services/executive-summary-html-view.c340
-rw-r--r--executive-summary/evolution-services/executive-summary-html-view.h64
-rw-r--r--executive-summary/evolution-services/executive-summary.c266
-rw-r--r--executive-summary/evolution-services/executive-summary.h67
-rw-r--r--executive-summary/idl/.cvsignore2
-rw-r--r--executive-summary/idl/Executive-Summary.idl4
-rw-r--r--executive-summary/idl/HtmlView.idl25
-rw-r--r--executive-summary/idl/Makefile.am7
-rw-r--r--executive-summary/idl/Summary.idl20
-rw-r--r--executive-summary/idl/SummaryComponent.idl36
-rw-r--r--executive-summary/summary.html45
-rw-r--r--executive-summary/test-service/.cvsignore9
-rw-r--r--executive-summary/test-service/GNOME_Evolution_Summary_rdf.oaf.in27
-rw-r--r--executive-summary/test-service/GNOME_Evolution_Summary_test.oaf.in53
-rw-r--r--executive-summary/test-service/Makefile.am43
-rw-r--r--executive-summary/test-service/main.c296
-rw-r--r--executive-summary/test-service/rdf-summary.c984
-rw-r--r--executive-summary/widgets/.cvsignore5
-rw-r--r--executive-summary/widgets/Makefile.am32
-rw-r--r--executive-summary/widgets/e-summary-subwindow.c300
-rw-r--r--executive-summary/widgets/e-summary-subwindow.h67
-rw-r--r--executive-summary/widgets/e-summary-title-button.c402
-rw-r--r--executive-summary/widgets/e-summary-title-button.h54
-rw-r--r--executive-summary/widgets/e-summary-titlebar.c411
-rw-r--r--executive-summary/widgets/e-summary-titlebar.h55
-rw-r--r--executive-summary/widgets/edit.xpm19
-rw-r--r--executive-summary/widgets/esummary-window-test.c45
-rw-r--r--executive-summary/widgets/shade.xpm19
-rw-r--r--executive-summary/widgets/x.xpm19
-rw-r--r--filter/.cvsignore10
-rw-r--r--filter/ChangeLog2576
-rw-r--r--filter/Makefile.am83
-rw-r--r--filter/filter-code.c122
-rw-r--r--filter/filter-code.h51
-rw-r--r--filter/filter-colour.c238
-rw-r--r--filter/filter-colour.h54
-rw-r--r--filter/filter-context.c285
-rw-r--r--filter/filter-context.h58
-rw-r--r--filter/filter-datespec.c476
-rw-r--r--filter/filter-datespec.h69
-rw-r--r--filter/filter-editor.c187
-rw-r--r--filter/filter-editor.h54
-rw-r--r--filter/filter-element.c391
-rw-r--r--filter/filter-element.h88
-rw-r--r--filter/filter-file.c331
-rw-r--r--filter/filter-file.h70
-rw-r--r--filter/filter-filter.c560
-rw-r--r--filter/filter-filter.h59
-rw-r--r--filter/filter-folder.c258
-rw-r--r--filter/filter-folder.h55
-rw-r--r--filter/filter-input.c373
-rw-r--r--filter/filter-input.h58
-rw-r--r--filter/filter-int.c257
-rw-r--r--filter/filter-int.h60
-rw-r--r--filter/filter-label.c199
-rw-r--r--filter/filter-label.h66
-rw-r--r--filter/filter-option.c377
-rw-r--r--filter/filter-option.h65
-rw-r--r--filter/filter-part.c558
-rw-r--r--filter/filter-part.h79
-rw-r--r--filter/filter-rule.c910
-rw-r--r--filter/filter-rule.h114
-rw-r--r--filter/filter-source.c411
-rw-r--r--filter/filter-source.h52
-rw-r--r--filter/filter.glade1032
-rw-r--r--filter/filtertypes.xml714
-rw-r--r--filter/libfilter-i18n.h61
-rw-r--r--filter/rule-context.c835
-rw-r--r--filter/rule-context.h128
-rw-r--r--filter/rule-editor.c684
-rw-r--r--filter/rule-editor.h96
-rw-r--r--filter/score-context.c104
-rw-r--r--filter/score-context.h51
-rw-r--r--filter/score-editor.c149
-rw-r--r--filter/score-editor.h53
-rw-r--r--filter/score-rule.c221
-rw-r--r--filter/score-rule.h54
-rw-r--r--filter/vfolder-context.c119
-rw-r--r--filter/vfolder-context.h53
-rw-r--r--filter/vfolder-editor.c149
-rw-r--r--filter/vfolder-editor.h54
-rw-r--r--filter/vfolder-rule.c530
-rw-r--r--filter/vfolder-rule.h60
-rw-r--r--filter/vfoldertypes.xml421
-rw-r--r--git.mk224
-rw-r--r--help/.cvsignore2
-rw-r--r--help/C/.cvsignore2
-rw-r--r--help/C/Makefile.am54
-rw-r--r--help/C/POTFILES.in16
-rw-r--r--help/C/apx-authors.sgml72
-rw-r--r--help/C/apx-bugs.sgml30
-rw-r--r--help/C/apx-gloss.sgml480
-rw-r--r--help/C/backup-restore.page45
-rw-r--r--help/C/calendar-alarms-and-reminders.page45
-rw-r--r--help/C/calendar-caldav.page40
-rw-r--r--help/C/calendar-classifications.page29
-rw-r--r--help/C/calendar-free-busy.page53
-rw-r--r--help/C/calendar-google.page40
-rw-r--r--help/C/calendar-layout-appointment-display.page53
-rw-r--r--help/C/calendar-layout-general-formatting.page57
-rw-r--r--help/C/calendar-layout-views.page42
-rw-r--r--help/C/calendar-layout.page22
-rw-r--r--help/C/calendar-local.page33
-rw-r--r--help/C/calendar-marcus-bains-line.page23
-rw-r--r--help/C/calendar-meetings-delegating.page40
-rw-r--r--help/C/calendar-meetings-replying-to-invitation.page33
-rw-r--r--help/C/calendar-meetings-sending-invitation.page52
-rw-r--r--help/C/calendar-meetings.page22
-rw-r--r--help/C/calendar-organizing.page23
-rw-r--r--help/C/calendar-publishing.page32
-rw-r--r--help/C/calendar-recurrence.page27
-rw-r--r--help/C/calendar-searching.page57
-rw-r--r--help/C/calendar-sharing-information.page22
-rw-r--r--help/C/calendar-timezones.page41
-rw-r--r--help/C/calendar-usage-add-appointment.page36
-rw-r--r--help/C/calendar-usage-delete-appointment.page24
-rw-r--r--help/C/calendar-usage-edit-appointment.page30
-rw-r--r--help/C/calendar-usage.page23
-rw-r--r--help/C/calendar-using-several-calendars.page33
-rw-r--r--help/C/calendar-weather.page39
-rw-r--r--help/C/calendar-webdav.page39
-rw-r--r--help/C/change-switcher-appearance.page40
-rw-r--r--help/C/config-prefs.sgml908
-rw-r--r--help/C/config-sync.sgml138
-rw-r--r--help/C/contacts-add-automatically.page30
-rw-r--r--help/C/contacts-autocompletion.page36
-rw-r--r--help/C/contacts-google.page36
-rw-r--r--help/C/contacts-ldap.page76
-rw-r--r--help/C/contacts-libreoffice.page35
-rw-r--r--help/C/contacts-local.page32
-rw-r--r--help/C/contacts-organizing.page25
-rw-r--r--help/C/contacts-searching.page63
-rw-r--r--help/C/contacts-usage-add-contact.page41
-rw-r--r--help/C/contacts-usage-delete-contact.page24
-rw-r--r--help/C/contacts-usage-edit-contact.page30
-rw-r--r--help/C/contacts-usage.page22
-rw-r--r--help/C/contacts-using-contact-lists.page48
-rw-r--r--help/C/contacts-using-several-addressbooks.page26
-rw-r--r--help/C/credits.page101
-rw-r--r--help/C/data-storage.page51
-rw-r--r--help/C/default-browser.page92
-rw-r--r--help/C/deleting-appointments.page25
-rw-r--r--help/C/deleting-emails.page40
-rw-r--r--help/C/deleting-to-free-disk-space.page23
-rw-r--r--help/C/evolution-C.omf16
-rw-r--r--help/C/evolution.sgml126
-rw-r--r--help/C/exchange-connectors-overview.page52
-rw-r--r--help/C/exchange-placeholder.page23
-rw-r--r--help/C/exporting-data-calendar.page24
-rw-r--r--help/C/exporting-data-contacts.page29
-rw-r--r--help/C/exporting-data-mail.page27
-rw-r--r--help/C/exporting-data.page22
-rw-r--r--help/C/figures/calendar.pngbin49112 -> 0 bytes-rw-r--r--help/C/figures/color-000000.pngbin0 -> 205 bytes-rw-r--r--help/C/figures/color-204a87.pngbin0 -> 208 bytes-rw-r--r--help/C/figures/color-2e3436.pngbin0 -> 208 bytes-rw-r--r--help/C/figures/color-4e9a06.pngbin0 -> 208 bytes-rw-r--r--help/C/figures/color-5c3566.pngbin0 -> 208 bytes-rw-r--r--help/C/figures/color-8f5902.pngbin0 -> 207 bytes-rw-r--r--help/C/figures/color-a40000.pngbin0 -> 207 bytes-rw-r--r--help/C/figures/color-c4a000.pngbin0 -> 208 bytes-rw-r--r--help/C/figures/color-ce5c00.pngbin0 -> 208 bytes-rw-r--r--help/C/figures/config-cal.pngbin9151 -> 0 bytes-rw-r--r--help/C/figures/config-mail.pngbin25374 -> 0 bytes-rw-r--r--help/C/figures/contact-editor.pngbin29672 -> 0 bytes-rw-r--r--help/C/figures/contact.pngbin39318 -> 0 bytes-rw-r--r--help/C/figures/evolutionlogo.pngbin0 -> 3660 bytes-rw-r--r--help/C/figures/exchange-identity.pngbin12600 -> 0 bytes-rw-r--r--help/C/figures/exchange-receive-options.pngbin14033 -> 0 bytes-rw-r--r--help/C/figures/exchange-receive.pngbin14455 -> 0 bytes-rw-r--r--help/C/figures/filter-assist-fig.pngbin12495 -> 0 bytes-rw-r--r--help/C/figures/filter-new-fig.pngbin8802 -> 0 bytes-rw-r--r--help/C/figures/full-1.pngbin1218 -> 0 bytes-rw-r--r--help/C/figures/full-2.pngbin1260 -> 0 bytes-rw-r--r--help/C/figures/full-3.pngbin1290 -> 0 bytes-rw-r--r--help/C/figures/full-4.pngbin1251 -> 0 bytes-rw-r--r--help/C/figures/full-5.pngbin1293 -> 0 bytes-rw-r--r--help/C/figures/full-6.pngbin1284 -> 0 bytes-rw-r--r--help/C/figures/full-7.pngbin818 -> 0 bytes-rw-r--r--help/C/figures/html-composer-insert-image.pngbin0 -> 1041 bytes-rw-r--r--help/C/figures/html-composer-insert-link.pngbin0 -> 1180 bytes-rw-r--r--help/C/figures/html-composer-insert-rule.pngbin0 -> 199 bytes-rw-r--r--help/C/figures/html-composer-insert-table.pngbin0 -> 430 bytes-rw-r--r--help/C/figures/mail-composer.pngbin16405 -> 0 bytes-rw-r--r--help/C/figures/mail-druid-pic.pngbin8457 -> 0 bytes-rw-r--r--help/C/figures/mail-inbox.pngbin61955 -> 0 bytes-rw-r--r--help/C/figures/mail-threaded.pngbin45997 -> 0 bytes-rw-r--r--help/C/figures/mainwindow-pic.pngbin65810 -> 0 bytes-rw-r--r--help/C/figures/minus-icon.pngbin0 -> 344 bytes-rw-r--r--help/C/figures/new-mail-notification.pngbin0 -> 431131 bytes-rw-r--r--help/C/figures/new-mail-switcher.pngbin0 -> 8613 bytes-rw-r--r--help/C/figures/newmsg.pngbin25303 -> 0 bytes-rw-r--r--help/C/figures/outline.pngbin5171 -> 0 bytes-rw-r--r--help/C/figures/plus-icon.pngbin0 -> 406 bytes-rw-r--r--help/C/figures/print-dest.pngbin7358 -> 0 bytes-rw-r--r--help/C/figures/print-preview.pngbin41550 -> 0 bytes-rw-r--r--help/C/figures/replymsg.pngbin23506 -> 0 bytes-rw-r--r--help/C/figures/schedule.pngbin84480 -> 0 bytes-rw-r--r--help/C/figures/search-icon.pngbin0 -> 1014 bytes-rw-r--r--help/C/figures/small_desktop.pngbin62588 -> 0 bytes-rw-r--r--help/C/figures/summary.pngbin94768 -> 0 bytes-rw-r--r--help/C/figures/vfolder-createrule-fig.pngbin11228 -> 0 bytes-rw-r--r--help/C/figures/window-overview-layers.pngbin0 -> 130866 bytes-rw-r--r--help/C/google-services.page20
-rw-r--r--help/C/import-apps-mozilla.page37
-rw-r--r--help/C/import-apps-outlook.page71
-rw-r--r--help/C/import-data.page26
-rw-r--r--help/C/import-single-files.page32
-rw-r--r--help/C/import-supported-file-formats.page87
-rw-r--r--help/C/index.page96
-rw-r--r--help/C/intro-application.page31
-rw-r--r--help/C/intro-first-run.page273
-rw-r--r--help/C/intro-main-window.page161
-rw-r--r--help/C/legal.xml8
-rw-r--r--help/C/mail-access-gmail-imap-account.page30
-rw-r--r--help/C/mail-access-gmail-pop-account.page43
-rw-r--r--help/C/mail-account-manage-imap-plus.page74
-rw-r--r--help/C/mail-account-manage-local-delivery.page72
-rw-r--r--help/C/mail-account-manage-maildir-format-directories.page72
-rw-r--r--help/C/mail-account-manage-mh-format-directories.page72
-rw-r--r--help/C/mail-account-manage-microsoft-exchange-evo-ews.page65
-rw-r--r--help/C/mail-account-manage-microsoft-exchange-evo-mapi.page70
-rw-r--r--help/C/mail-account-manage-microsoft-exchange.page25
-rw-r--r--help/C/mail-account-manage-pop.page72
-rw-r--r--help/C/mail-account-manage-unix-mbox-spool-directory.page72
-rw-r--r--help/C/mail-account-manage-unix-mbox-spool-file.page72
-rw-r--r--help/C/mail-account-manage-usenet-news.page72
-rw-r--r--help/C/mail-account-management.page34
-rw-r--r--help/C/mail-attachments-received.page35
-rw-r--r--help/C/mail-attachments-sending.page55
-rw-r--r--help/C/mail-attachments.page20
-rw-r--r--help/C/mail-calendar-sending-invitations.page44
-rw-r--r--help/C/mail-cannot-see.page45
-rw-r--r--help/C/mail-change-columns-in-message-list.page26
-rw-r--r--help/C/mail-change-time-format.page23
-rw-r--r--help/C/mail-composer-change-quotation-string.page44
-rw-r--r--help/C/mail-composer-custom-header-lines.page49
-rw-r--r--help/C/mail-composer-enable-html-format.page29
-rw-r--r--help/C/mail-composer-forward-as-attachment.page29
-rw-r--r--help/C/mail-composer-forward.page45
-rw-r--r--help/C/mail-composer-html-image.page33
-rw-r--r--help/C/mail-composer-html-link.page36
-rw-r--r--help/C/mail-composer-html-rule.page34
-rw-r--r--help/C/mail-composer-html-table.page35
-rw-r--r--help/C/mail-composer-html-text.page70
-rw-r--r--help/C/mail-composer-html.page41
-rw-r--r--help/C/mail-composer-mail-signatures-manage.page25
-rw-r--r--help/C/mail-composer-mail-signatures-per-account.page35
-rw-r--r--help/C/mail-composer-mail-signatures.page26
-rw-r--r--help/C/mail-composer-message-templates-reply.page39
-rw-r--r--help/C/mail-composer-message-templates-save.page52
-rw-r--r--help/C/mail-composer-message-templates-variables.page62
-rw-r--r--help/C/mail-composer-message-templates.page31
-rw-r--r--help/C/mail-composer-plain-text.page43
-rw-r--r--help/C/mail-composer-priority.page29
-rw-r--r--help/C/mail-composer-reply.page58
-rw-r--r--help/C/mail-composer-search.page42
-rw-r--r--help/C/mail-composer-several-recipients.page51
-rw-r--r--help/C/mail-composer-spellcheck.page54
-rw-r--r--help/C/mail-composer-write-new-message.page31
-rw-r--r--help/C/mail-default-CC-and-BCC.page34
-rw-r--r--help/C/mail-default-folder-locations.page34
-rw-r--r--help/C/mail-delete-and-undelete.page45
-rw-r--r--help/C/mail-display-message-source.page26
-rw-r--r--help/C/mail-displaying-character-encodings.page39
-rw-r--r--help/C/mail-displaying-collapsible-headers.page31
-rw-r--r--help/C/mail-displaying-images-in-html.page54
-rw-r--r--help/C/mail-displaying-message.page26
-rw-r--r--help/C/mail-displaying-sender-photograph.page39
-rw-r--r--help/C/mail-duplicates.page43
-rw-r--r--help/C/mail-encryption-gpg-create-key.page53
-rw-r--r--help/C/mail-encryption-gpg-decrypting.page36
-rw-r--r--help/C/mail-encryption-gpg-getting-keys.page31
-rw-r--r--help/C/mail-encryption-gpg-set-up.page40
-rw-r--r--help/C/mail-encryption-gpg-signing-encrypting.page44
-rw-r--r--help/C/mail-encryption-s-mime-manage.page33
-rw-r--r--help/C/mail-encryption-s-mime-signing-encrypting.page37
-rw-r--r--help/C/mail-encryption.page42
-rw-r--r--help/C/mail-filters-actions.page72
-rw-r--r--help/C/mail-filters-conditions.page46
-rw-r--r--help/C/mail-filters-not-working.page58
-rw-r--r--help/C/mail-filters.page79
-rw-r--r--help/C/mail-folders.page68
-rw-r--r--help/C/mail-follow-up-flag.page45
-rw-r--r--help/C/mail-imap-subscriptions.page37
-rw-r--r--help/C/mail-labels.page39
-rw-r--r--help/C/mail-layout-changing.page22
-rw-r--r--help/C/mail-localized-re-subjects.page32
-rw-r--r--help/C/mail-moving-emails.page30
-rw-r--r--help/C/mail-not-sent.page30
-rw-r--r--help/C/mail-organizing.page28
-rw-r--r--help/C/mail-read-receipts.page40
-rw-r--r--help/C/mail-reading-keyboard-shortcuts.page62
-rw-r--r--help/C/mail-received-notification.page38
-rw-r--r--help/C/mail-receiving-options-exchange-ews.page50
-rw-r--r--help/C/mail-receiving-options-exchange-mapi.page50
-rw-r--r--help/C/mail-receiving-options-imap-plus.page56
-rw-r--r--help/C/mail-receiving-options-local-delivery.page44
-rw-r--r--help/C/mail-receiving-options-maildir-format-directories.page45
-rw-r--r--help/C/mail-receiving-options-mh-format-directories.page44
-rw-r--r--help/C/mail-receiving-options-pop.page57
-rw-r--r--help/C/mail-receiving-options-unix-mbox-spool-directory.page44
-rw-r--r--help/C/mail-receiving-options-unix-mbox-spool-file.page45
-rw-r--r--help/C/mail-receiving-options-usenet-news.page55
-rw-r--r--help/C/mail-receiving-options.page31
-rw-r--r--help/C/mail-recognized-thread-related-headers.page31
-rw-r--r--help/C/mail-refresh-folders.page26
-rw-r--r--help/C/mail-save-as-pdf.page34
-rw-r--r--help/C/mail-search-folders-add.page51
-rw-r--r--help/C/mail-search-folders-conditions.page39
-rw-r--r--help/C/mail-search-folders-enable.page27
-rw-r--r--help/C/mail-search-folders-refresh.page33
-rw-r--r--help/C/mail-search-folders.page34
-rw-r--r--help/C/mail-searching-attachment-type.page25
-rw-r--r--help/C/mail-searching.page62
-rw-r--r--help/C/mail-send-and-receive-automatically.page24
-rw-r--r--help/C/mail-send-and-receive-manual.page26
-rw-r--r--help/C/mail-send-and-receive.page24
-rw-r--r--help/C/mail-sending-options-smtp.page41
-rw-r--r--help/C/mail-several-pop-accounts.page29
-rw-r--r--help/C/mail-sorting-folder-list.page43
-rw-r--r--help/C/mail-sorting-message-list.page121
-rw-r--r--help/C/mail-spam-marking.page40
-rw-r--r--help/C/mail-spam-settings.page83
-rw-r--r--help/C/mail-spam.page22
-rw-r--r--help/C/mail-two-trash-folders.page34
-rw-r--r--help/C/mail-usenet-subscriptions.page35
-rw-r--r--help/C/mail-vertical-view.page32
-rw-r--r--help/C/mail-word-wrap.page25
-rw-r--r--help/C/mail-working-offline.page51
-rw-r--r--help/C/memos-searching.page64
-rw-r--r--help/C/memos-usage-add-memo.page53
-rw-r--r--help/C/memos-usage-delete-memo.page24
-rw-r--r--help/C/memos-usage-edit-memo.page29
-rw-r--r--help/C/memos-usage.page25
-rw-r--r--help/C/menuref.sgml421
-rw-r--r--help/C/minimize-to-system-tray.page31
-rw-r--r--help/C/offline.page32
-rw-r--r--help/C/organizing.page20
-rw-r--r--help/C/preface.sgml362
-rw-r--r--help/C/problems-debug-how-to.page31
-rw-r--r--help/C/problems-getting-help.page25
-rw-r--r--help/C/problems-reporting-bugs.page27
-rw-r--r--help/C/searching-items.page20
-rw-r--r--help/C/sync-with-other-devices.page66
-rw-r--r--help/C/tasks-caldav.page37
-rw-r--r--help/C/tasks-display-settings.page39
-rw-r--r--help/C/tasks-local.page33
-rw-r--r--help/C/tasks-organizing.page23
-rw-r--r--help/C/tasks-searching.page64
-rw-r--r--help/C/tasks-usage-add-task.page45
-rw-r--r--help/C/tasks-usage-delete-task.page24
-rw-r--r--help/C/tasks-usage-edit-task.page30
-rw-r--r--help/C/tasks-usage.page22
-rw-r--r--help/C/tasks-using-several-tasklists.page28
-rw-r--r--help/C/tasks-webdav.page39
-rw-r--r--help/C/topic.dat11
-rw-r--r--help/C/usage-calendar.sgml757
-rw-r--r--help/C/usage-contact.sgml571
-rw-r--r--help/C/usage-exchange.sgml748
-rw-r--r--help/C/usage-exec-summary.sgml323
-rw-r--r--help/C/usage-mail-org.sgml1129
-rw-r--r--help/C/usage-mail.sgml2209
-rw-r--r--help/C/usage-mainwindow.sgml1512
-rw-r--r--help/C/usage-print.sgml115
-rw-r--r--help/C/usage-sync.sgml39
-rw-r--r--help/C/using-categories.page59
-rw-r--r--help/C/xinclude-filter-vfolder-conditions.xml64
-rw-r--r--help/C/xinclude-mail-account-identity.xml9
-rw-r--r--help/C/xinclude-searching.xml34
-rw-r--r--help/COPYING-DOCS355
-rw-r--r--help/COPYING-DOCS.CCBYSA58
-rw-r--r--help/COPYING-DOCS.GFDL142
-rw-r--r--help/ChangeLog1909
-rw-r--r--help/Makefile.am244
-rw-r--r--help/README_Translations46
-rw-r--r--help/cs/cs.po24010
-rw-r--r--help/cs/figures/new-mail-switcher.pngbin0 -> 7520 bytes-rw-r--r--help/de/de.po12931
-rw-r--r--help/de/figures/new-mail-notification.pngbin0 -> 754482 bytes-rw-r--r--help/de/figures/new-mail-switcher.pngbin0 -> 11754 bytes-rw-r--r--help/de/figures/window-overview-layers.pngbin0 -> 156941 bytes-rw-r--r--help/devel/executive-summary/evolution-services.hierarchy7
-rw-r--r--help/devel/importer/evolution-shell-importer.hierarchy7
-rw-r--r--help/el/el.po25674
-rw-r--r--help/el/figures/new-mail-switcher.pngbin0 -> 7738 bytes-rw-r--r--help/en_GB/en_GB.po24339
-rw-r--r--help/es.po/apx-authors.sgml.po178
-rw-r--r--help/es.po/apx-bugs.sgml.po56
-rw-r--r--help/es.po/apx-gloss.sgml.po745
-rw-r--r--help/es.po/config-prefs.sgml.po1364
-rw-r--r--help/es.po/config-setupassist.sgml.po446
-rw-r--r--help/es.po/config-sync.sgml.po264
-rw-r--r--help/es.po/evolution.sgml.po165
-rw-r--r--help/es.po/menuref.sgml.po3062
-rw-r--r--help/es.po/preface.sgml.po932
-rw-r--r--help/es.po/usage-calendar.sgml.po816
-rw-r--r--help/es.po/usage-contact.sgml.po1225
-rw-r--r--help/es.po/usage-mail.sgml.po2322
-rw-r--r--help/es.po/usage-mainwindow.sgml.po788
-rw-r--r--help/es.po/usage-notes.sgml.po111
-rw-r--r--help/es.po/usage-print.sgml.po196
-rw-r--r--help/es.po/usage-sync.sgml.po60
-rw-r--r--help/es/Makefile.in321
-rw-r--r--help/es/apx-authors.sgml75
-rw-r--r--help/es/apx-bugs.sgml23
-rw-r--r--help/es/apx-gloss.sgml462
-rw-r--r--help/es/config-prefs.sgml646
-rw-r--r--help/es/config-setupassist.sgml211
-rw-r--r--help/es/config-sync.sgml122
-rw-r--r--help/es/es.po15553
-rw-r--r--help/es/evolution-es.omf16
-rw-r--r--help/es/evolution.sgml147
-rw-r--r--help/es/figures/new-mail-notification.pngbin0 -> 327823 bytes-rw-r--r--help/es/figures/new-mail-switcher.pngbin0 -> 10414 bytes-rw-r--r--help/es/figures/window-overview-layers.pngbin0 -> 124597 bytes-rw-r--r--help/es/menuref.sgml1477
-rw-r--r--help/es/preface.sgml444
-rw-r--r--help/es/usage-calendar.sgml373
-rw-r--r--help/es/usage-contact.sgml619
-rw-r--r--help/es/usage-mail.sgml1526
-rw-r--r--help/es/usage-mainwindow.sgml453
-rw-r--r--help/es/usage-notes.sgml49
-rw-r--r--help/es/usage-print.sgml104
-rw-r--r--help/es/usage-sync.sgml20
-rw-r--r--help/eu/eu.po23546
-rw-r--r--help/eu/figures/new-mail-switcher.pngbin0 -> 6436 bytes-rw-r--r--help/evolution.omf.in9
-rwxr-xr-xhelp/fr/figures/new-mail-switcher.pngbin0 -> 16179 bytes-rwxr-xr-xhelp/fr/figures/window-overview.pngbin0 -> 197966 bytes-rw-r--r--help/fr/fr.po13347
-rw-r--r--help/gl/gl.po12245
-rw-r--r--help/hu/hu.po13060
-rw-r--r--help/mk/mk.po15201
-rw-r--r--help/no/.cvsignore9
-rw-r--r--help/no/ChangeLog13
-rw-r--r--help/no/Makefile.am49
-rw-r--r--help/no/apx-authors.sgml98
-rw-r--r--help/no/apx-bugs.sgml38
-rw-r--r--help/no/apx-gloss.sgml419
-rw-r--r--help/no/config-encryption.sgml147
-rw-r--r--help/no/config-prefs.sgml744
-rw-r--r--help/no/config-sync.sgml126
-rw-r--r--help/no/evolution-faq.sgml973
-rw-r--r--help/no/evolution-no.omf16
-rw-r--r--help/no/evolution.sgml128
-rw-r--r--help/no/figures/calendar.pngbin42615 -> 0 bytes-rw-r--r--help/no/figures/config-cal.pngbin7338 -> 0 bytes-rw-r--r--help/no/figures/config-mail.pngbin9210 -> 0 bytes-rw-r--r--help/no/figures/contact-editor.pngbin37707 -> 0 bytes-rw-r--r--help/no/figures/contact.pngbin39742 -> 0 bytes-rw-r--r--help/no/figures/filter-assist-fig.pngbin5575 -> 0 bytes-rw-r--r--help/no/figures/filter-new-fig.pngbin8802 -> 0 bytes-rw-r--r--help/no/figures/full-1.pngbin1218 -> 0 bytes-rw-r--r--help/no/figures/full-2.pngbin1260 -> 0 bytes-rw-r--r--help/no/figures/full-3.pngbin1290 -> 0 bytes-rw-r--r--help/no/figures/full-4.pngbin1251 -> 0 bytes-rw-r--r--help/no/figures/full-5.pngbin1293 -> 0 bytes-rw-r--r--help/no/figures/full-6.pngbin1284 -> 0 bytes-rw-r--r--help/no/figures/full-7.pngbin818 -> 0 bytes-rw-r--r--help/no/figures/mail-composer.pngbin14971 -> 0 bytes-rw-r--r--help/no/figures/mail-druid-pic.pngbin8457 -> 0 bytes-rw-r--r--help/no/figures/mail-inbox.pngbin127593 -> 0 bytes-rw-r--r--help/no/figures/mainwindow-pic.pngbin130739 -> 0 bytes-rw-r--r--help/no/figures/newmsg.pngbin14798 -> 0 bytes-rw-r--r--help/no/figures/print-dest.pngbin7358 -> 0 bytes-rw-r--r--help/no/figures/print-preview.pngbin51801 -> 0 bytes-rw-r--r--help/no/figures/replymsg.pngbin19338 -> 0 bytes-rw-r--r--help/no/figures/vfolder-createrule-fig.pngbin8321 -> 0 bytes-rw-r--r--help/no/menuref.sgml421
-rw-r--r--help/no/preface.sgml83
-rw-r--r--help/no/topic.dat10
-rw-r--r--help/no/usage-calendar.sgml561
-rw-r--r--help/no/usage-contact.sgml609
-rw-r--r--help/no/usage-encryption.sgml147
-rw-r--r--help/no/usage-exec-summary.sgml315
-rw-r--r--help/no/usage-mail-org.sgml1021
-rw-r--r--help/no/usage-mail.sgml2005
-rw-r--r--help/no/usage-mainwindow.sgml1174
-rw-r--r--help/no/usage-notes.sgml49
-rw-r--r--help/no/usage-print.sgml115
-rw-r--r--help/no/usage-sync.sgml39
-rw-r--r--help/oc/oc.po13457
-rw-r--r--help/quickref/C/Makefile.am10
-rw-r--r--help/quickref/C/quickref.pdfbin0 -> 34236 bytes-rw-r--r--help/quickref/C/quickref.tex116
-rw-r--r--help/quickref/Makefile.am5
-rw-r--r--help/quickref/ca/Makefile.am10
-rw-r--r--help/quickref/ca/quickref.pdfbin0 -> 34908 bytes-rw-r--r--help/quickref/ca/quickref.tex116
-rw-r--r--help/quickref/cs/Makefile.am10
-rw-r--r--help/quickref/cs/quickref.pdfbin0 -> 35383 bytes-rw-r--r--help/quickref/cs/quickref.tex117
-rw-r--r--help/quickref/de/Makefile.am10
-rw-r--r--help/quickref/de/quickref.pdfbin0 -> 34875 bytes-rw-r--r--help/quickref/de/quickref.tex119
-rw-r--r--help/quickref/es/Makefile.am10
-rw-r--r--help/quickref/es/quickref.pdfbin0 -> 34255 bytes-rw-r--r--help/quickref/es/quickref.tex116
-rw-r--r--help/quickref/evolution-logo.eps300
-rw-r--r--help/quickref/fr/Makefile.am10
-rw-r--r--help/quickref/fr/quickref.pdfbin0 -> 35535 bytes-rw-r--r--help/quickref/fr/quickref.tex119
-rw-r--r--help/quickref/hu/Makefile.am10
-rw-r--r--help/quickref/hu/quickref.pdfbin0 -> 36307 bytes-rw-r--r--help/quickref/hu/quickref.tex116
-rw-r--r--help/quickref/it/Makefile.am10
-rw-r--r--help/quickref/it/quickref.pdfbin0 -> 33539 bytes-rw-r--r--help/quickref/it/quickref.tex116
-rw-r--r--help/quickref/oc/Makefile.am10
-rw-r--r--help/quickref/oc/quickref.pdfbin0 -> 35370 bytes-rw-r--r--help/quickref/oc/quickref.tex119
-rw-r--r--help/quickref/pl/Makefile.am10
-rw-r--r--help/quickref/pl/quickref.pdfbin0 -> 38047 bytes-rw-r--r--help/quickref/pl/quickref.tex118
-rw-r--r--help/quickref/pt/Makefile.am10
-rw-r--r--help/quickref/pt/quickref.pdfbin0 -> 34909 bytes-rw-r--r--help/quickref/pt/quickref.tex116
-rw-r--r--help/quickref/sq/Makefile.am10
-rw-r--r--help/quickref/sq/quickref.pdfbin0 -> 34872 bytes-rw-r--r--help/quickref/sq/quickref.tex116
-rw-r--r--help/quickref/sv/Makefile.am10
-rw-r--r--help/quickref/sv/quickref.pdfbin0 -> 34885 bytes-rw-r--r--help/quickref/sv/quickref.tex116
-rw-r--r--help/ru/ru.po23218
-rw-r--r--help/sgmldocs.make144
-rw-r--r--help/sl/sl.po8778
-rw-r--r--help/sv/sv.po17709
-rw-r--r--help/te/te.po10384
-rwxr-xr-xhelp/update_po.pl212
-rwxr-xr-xhelp/update_translation.pl240
-rw-r--r--help/zh_CN/zh_CN.po21957
-rw-r--r--iconv-detect.c186
-rw-r--r--importers/.cvsignore20
-rw-r--r--importers/ChangeLog345
-rw-r--r--importers/GNOME_Evolution_Elm_Intelligent_Importer.oaf.in21
-rw-r--r--importers/GNOME_Evolution_GnomeCard_Intelligent_Importer.oaf.in21
-rw-r--r--importers/GNOME_Evolution_Netscape_Intelligent_Importer.oaf.in21
-rw-r--r--importers/GNOME_Evolution_Pine_Intelligent_Importer.oaf.in21
-rw-r--r--importers/Makefile.am83
-rw-r--r--importers/elm-importer.c623
-rw-r--r--importers/evolution-gnomecard-importer.c328
-rw-r--r--importers/netscape-importer.c2236
-rw-r--r--importers/pine-importer.c739
-rw-r--r--libemail-engine/Makefile.am97
-rw-r--r--libemail-engine/camel-null-store.c81
-rw-r--r--libemail-engine/camel-null-store.h64
-rw-r--r--libemail-engine/camel-sasl-xoauth2.c132
-rw-r--r--libemail-engine/camel-sasl-xoauth2.h63
-rw-r--r--libemail-engine/e-mail-authenticator.c267
-rw-r--r--libemail-engine/e-mail-authenticator.h76
-rw-r--r--libemail-engine/e-mail-enums.h74
-rw-r--r--libemail-engine/e-mail-folder-utils.c2070
-rw-r--r--libemail-engine/e-mail-folder-utils.h176
-rw-r--r--libemail-engine/e-mail-junk-filter.c69
-rw-r--r--libemail-engine/e-mail-junk-filter.h72
-rw-r--r--libemail-engine/e-mail-session-utils.c1601
-rw-r--r--libemail-engine/e-mail-session-utils.h126
-rw-r--r--libemail-engine/e-mail-session.c2528
-rw-r--r--libemail-engine/e-mail-session.h167
-rw-r--r--libemail-engine/e-mail-store-utils.c429
-rw-r--r--libemail-engine/e-mail-store-utils.h80
-rw-r--r--libemail-engine/e-mail-utils.c731
-rw-r--r--libemail-engine/e-mail-utils.h78
-rw-r--r--libemail-engine/em-filter-folder-element.c226
-rw-r--r--libemail-engine/em-filter-folder-element.h74
-rw-r--r--libemail-engine/em-vfolder-context.c110
-rw-r--r--libemail-engine/em-vfolder-context.h70
-rw-r--r--libemail-engine/em-vfolder-rule.c505
-rw-r--r--libemail-engine/em-vfolder-rule.h102
-rw-r--r--libemail-engine/libemail-engine.pc.in16
-rw-r--r--libemail-engine/mail-config.c281
-rw-r--r--libemail-engine/mail-config.h48
-rw-r--r--libemail-engine/mail-folder-cache.c2271
-rw-r--r--libemail-engine/mail-folder-cache.h144
-rw-r--r--libemail-engine/mail-mt.c660
-rw-r--r--libemail-engine/mail-mt.h123
-rw-r--r--libemail-engine/mail-ops.c1506
-rw-r--r--libemail-engine/mail-ops.h103
-rw-r--r--libemail-engine/mail-tools.c249
-rw-r--r--libemail-engine/mail-tools.h41
-rw-r--r--libemail-engine/mail-vfolder.c1245
-rw-r--r--libemail-engine/mail-vfolder.h36
-rw-r--r--libgnomecanvas/Makefile.am62
-rw-r--r--libgnomecanvas/gailcanvas.c263
-rw-r--r--libgnomecanvas/gailcanvas.h73
-rw-r--r--libgnomecanvas/gailcanvasgroup.c105
-rw-r--r--libgnomecanvas/gailcanvasgroup.h55
-rw-r--r--libgnomecanvas/gailcanvasgroupfactory.c81
-rw-r--r--libgnomecanvas/gailcanvasgroupfactory.h52
-rw-r--r--libgnomecanvas/gailcanvasitem.c411
-rw-r--r--libgnomecanvas/gailcanvasitem.h54
-rw-r--r--libgnomecanvas/gailcanvasitemfactory.c61
-rw-r--r--libgnomecanvas/gailcanvasitemfactory.h52
-rw-r--r--libgnomecanvas/gailcanvastext.c519
-rw-r--r--libgnomecanvas/gailcanvastext.h52
-rw-r--r--libgnomecanvas/gailcanvastextfactory.c61
-rw-r--r--libgnomecanvas/gailcanvastextfactory.h52
-rw-r--r--libgnomecanvas/gailcanvaswidget.c119
-rw-r--r--libgnomecanvas/gailcanvaswidget.h55
-rw-r--r--libgnomecanvas/gailcanvaswidgetfactory.c60
-rw-r--r--libgnomecanvas/gailcanvaswidgetfactory.h52
-rw-r--r--libgnomecanvas/gnome-canvas-i18n.h68
-rw-r--r--libgnomecanvas/gnome-canvas-pixbuf.c350
-rw-r--r--libgnomecanvas/gnome-canvas-pixbuf.h56
-rw-r--r--libgnomecanvas/gnome-canvas-rect.c731
-rw-r--r--libgnomecanvas/gnome-canvas-rect.h68
-rw-r--r--libgnomecanvas/gnome-canvas-text.c1429
-rw-r--r--libgnomecanvas/gnome-canvas-text.h153
-rw-r--r--libgnomecanvas/gnome-canvas-util.c172
-rw-r--r--libgnomecanvas/gnome-canvas-util.h56
-rw-r--r--libgnomecanvas/gnome-canvas-widget.c442
-rw-r--r--libgnomecanvas/gnome-canvas-widget.h92
-rw-r--r--libgnomecanvas/gnome-canvas.c3419
-rw-r--r--libgnomecanvas/gnome-canvas.h492
-rw-r--r--libgnomecanvas/libgnomecanvas.h36
-rw-r--r--libibex/.cvsignore9
-rw-r--r--libibex/COPYING.LIB481
-rw-r--r--libibex/ChangeLog544
-rw-r--r--libibex/Makefile.am33
-rw-r--r--libibex/TODO61
-rw-r--r--libibex/block.c620
-rw-r--r--libibex/block.h125
-rw-r--r--libibex/diskarray.c254
-rw-r--r--libibex/disktail.c819
-rw-r--r--libibex/dumpindex.c66
-rw-r--r--libibex/hash.c856
-rw-r--r--libibex/ibex.h108
-rw-r--r--libibex/ibex_block.c649
-rw-r--r--libibex/ibex_internal.h65
-rw-r--r--libibex/index.h102
-rw-r--r--libibex/testindex.c320
-rw-r--r--libibex/wordindex.c645
-rw-r--r--libibex/wordindex.h75
-rw-r--r--libibex/wordindexmem.c901
-rw-r--r--libical/.cvsignore19
-rw-r--r--libical/AUTHORS1
-rw-r--r--libical/COPYING0
-rw-r--r--libical/ChangeLog1254
-rw-r--r--libical/INSTALL24
-rw-r--r--libical/Makefile.am12
-rw-r--r--libical/NEWS447
-rw-r--r--libical/README100
-rw-r--r--libical/TEST4
-rw-r--r--libical/THANKS54
-rw-r--r--libical/TODO39
-rw-r--r--libical/acconfig.h20
-rwxr-xr-xlibical/autogen.sh80
-rw-r--r--libical/configure.in101
-rw-r--r--libical/design-data/.cvsignore2
-rw-r--r--libical/design-data/Makefile.am6
-rw-r--r--libical/design-data/components.txt22
-rw-r--r--libical/design-data/param-c-types.txt23
-rw-r--r--libical/design-data/parameters.csv24
-rw-r--r--libical/design-data/params-in-prop.txt55
-rw-r--r--libical/design-data/prop-to-value.txt57
-rw-r--r--libical/design-data/properties.csv66
-rw-r--r--libical/design-data/property-tokens.txt65
-rw-r--r--libical/design-data/restrictions.csv1348
-rw-r--r--libical/design-data/status.txt56
-rw-r--r--libical/design-data/value-c-types.txt23
-rw-r--r--libical/design-data/value-mem-semantics.txt19
-rw-r--r--libical/design-data/value-types.csv31
-rw-r--r--libical/doc/.cvsignore2
-rw-r--r--libical/doc/Makefile.am1
-rw-r--r--libical/doc/UsingLibical.lyx2578
-rw-r--r--libical/doc/UsingLibical.ps2327
-rw-r--r--libical/doc/UsingLibical.txt1384
-rw-r--r--libical/examples/.cvsignore5
-rw-r--r--libical/examples/Makefile.am15
-rw-r--r--libical/examples/access_components.c319
-rw-r--r--libical/examples/access_properties_and_parameters.c144
-rw-r--r--libical/examples/errors.c70
-rw-r--r--libical/examples/main.c12
-rw-r--r--libical/examples/parse_text.c68
-rw-r--r--libical/scripts/.cvsignore2
-rw-r--r--libical/scripts/Makefile.am9
-rwxr-xr-xlibical/scripts/mkderivedcomponents.pl170
-rwxr-xr-xlibical/scripts/mkderivedparameters.pl321
-rwxr-xr-xlibical/scripts/mkderivedproperties.pl240
-rwxr-xr-xlibical/scripts/mkderivedvalues.pl225
-rwxr-xr-xlibical/scripts/mkparameterrestrictions.pl85
-rwxr-xr-xlibical/scripts/mkrestrictionrecords.pl109
-rwxr-xr-xlibical/scripts/mkrestrictiontable.pl98
-rw-r--r--libical/scripts/readvaluesfile.pl130
-rw-r--r--libical/src/.cvsignore2
-rw-r--r--libical/src/Makefile.am9
-rw-r--r--libical/src/libical/.cvsignore22
-rw-r--r--libical/src/libical/Makefile.am238
-rw-r--r--libical/src/libical/icalarray.c147
-rw-r--r--libical/src/libical/icalarray.h61
-rw-r--r--libical/src/libical/icalattendee.c30
-rw-r--r--libical/src/libical/icalattendee.h68
-rw-r--r--libical/src/libical/icalcomponent.c1932
-rw-r--r--libical/src/libical/icalcomponent.h264
-rw-r--r--libical/src/libical/icalderivedparameter.c.in211
-rw-r--r--libical/src/libical/icalderivedparameter.h.in37
-rw-r--r--libical/src/libical/icalderivedproperty.c.in250
-rw-r--r--libical/src/libical/icalderivedproperty.h.in23
-rw-r--r--libical/src/libical/icalderivedvalue.c.in341
-rw-r--r--libical/src/libical/icalderivedvalue.h.in61
-rw-r--r--libical/src/libical/icalduration.c320
-rw-r--r--libical/src/libical/icalduration.h60
-rw-r--r--libical/src/libical/icalenums.c135
-rw-r--r--libical/src/libical/icalenums.h157
-rw-r--r--libical/src/libical/icalerror.c194
-rw-r--r--libical/src/libical/icalerror.h153
-rw-r--r--libical/src/libical/icallangbind.c272
-rw-r--r--libical/src/libical/icallangbind.h49
-rw-r--r--libical/src/libical/icallexer.l161
-rw-r--r--libical/src/libical/icalmemory.c287
-rw-r--r--libical/src/libical/icalmemory.h80
-rw-r--r--libical/src/libical/icalmime.c386
-rw-r--r--libical/src/libical/icalmime.h43
-rw-r--r--libical/src/libical/icalparameter.c392
-rw-r--r--libical/src/libical/icalparameter.h69
-rw-r--r--libical/src/libical/icalparameterimpl.h52
-rw-r--r--libical/src/libical/icalparser.c1121
-rw-r--r--libical/src/libical/icalparser.h93
-rw-r--r--libical/src/libical/icalperiod.c174
-rw-r--r--libical/src/libical/icalperiod.h55
-rw-r--r--libical/src/libical/icalproperty.c908
-rw-r--r--libical/src/libical/icalproperty.h116
-rw-r--r--libical/src/libical/icalrecur.c2370
-rw-r--r--libical/src/libical/icalrecur.h189
-rw-r--r--libical/src/libical/icalrestriction.c.in447
-rw-r--r--libical/src/libical/icalrestriction.h64
-rw-r--r--libical/src/libical/icaltime.c737
-rw-r--r--libical/src/libical/icaltime.h156
-rw-r--r--libical/src/libical/icaltimezone.c1677
-rw-r--r--libical/src/libical/icaltimezone.h149
-rw-r--r--libical/src/libical/icaltypes.c255
-rw-r--r--libical/src/libical/icaltypes.h135
-rw-r--r--libical/src/libical/icalvalue.c1256
-rw-r--r--libical/src/libical/icalvalue.h85
-rw-r--r--libical/src/libical/icalvalueimpl.h117
-rw-r--r--libical/src/libical/icalversion.h.in7
-rw-r--r--libical/src/libical/icalyacc.y400
-rw-r--r--libical/src/libical/pvl.c761
-rw-r--r--libical/src/libical/pvl.h94
-rw-r--r--libical/src/libical/sspm.c1613
-rw-r--r--libical/src/libical/sspm.h143
-rw-r--r--libical/src/libical/vsnprintf.c167
-rw-r--r--libical/src/libicalss/.cvsignore10
-rw-r--r--libical/src/libicalss/Makefile.am69
-rw-r--r--libical/src/libicalss/icalcalendar.c265
-rw-r--r--libical/src/libicalss/icalcalendar.h67
-rw-r--r--libical/src/libicalss/icalclassify.c696
-rw-r--r--libical/src/libicalss/icalclassify.h73
-rw-r--r--libical/src/libicalss/icalcomponent.h115
-rw-r--r--libical/src/libicalss/icalcsdb.h67
-rw-r--r--libical/src/libicalss/icalcstp.c116
-rw-r--r--libical/src/libicalss/icalcstp.h79
-rw-r--r--libical/src/libicalss/icalcstpclient.c343
-rw-r--r--libical/src/libicalss/icalcstpclient.h100
-rw-r--r--libical/src/libicalss/icalcstpserver.c278
-rw-r--r--libical/src/libicalss/icalcstpserver.h101
-rw-r--r--libical/src/libicalss/icaldirset.c753
-rw-r--r--libical/src/libicalss/icaldirset.h82
-rw-r--r--libical/src/libicalss/icaldirsetimpl.h47
-rw-r--r--libical/src/libicalss/icalfileset.c637
-rw-r--r--libical/src/libicalss/icalfileset.h105
-rw-r--r--libical/src/libicalss/icalfilesetimpl.h49
-rw-r--r--libical/src/libicalss/icalgauge.c447
-rw-r--r--libical/src/libicalss/icalgauge.h51
-rw-r--r--libical/src/libicalss/icalgaugeimpl.h63
-rw-r--r--libical/src/libicalss/icalmessage.c376
-rw-r--r--libical/src/libicalss/icalmessage.h71
-rw-r--r--libical/src/libicalss/icalset.c367
-rw-r--r--libical/src/libicalss/icalset.h111
-rw-r--r--libical/src/libicalss/icalspanlist.c309
-rw-r--r--libical/src/libicalss/icalspanlist.h54
-rw-r--r--libical/src/libicalss/icalsslexer.l113
-rw-r--r--libical/src/libicalss/icalssutil.c29
-rw-r--r--libical/src/libicalss/icalssutil.h27
-rw-r--r--libical/src/libicalss/icalssyacc.h22
-rw-r--r--libical/src/libicalss/icalssyacc.y245
-rw-r--r--libical/src/libicalvcal/.cvsignore12
-rw-r--r--libical/src/libicalvcal/Makefile.am34
-rw-r--r--libical/src/libicalvcal/README.TXT951
-rw-r--r--libical/src/libicalvcal/icalvcal.c1636
-rw-r--r--libical/src/libicalvcal/icalvcal.h54
-rw-r--r--libical/src/libicalvcal/port.h88
-rw-r--r--libical/src/libicalvcal/vcaltest.c118
-rw-r--r--libical/src/libicalvcal/vcaltmp.c337
-rw-r--r--libical/src/libicalvcal/vcaltmp.h128
-rw-r--r--libical/src/libicalvcal/vcc.h80
-rw-r--r--libical/src/libicalvcal/vcc.y1195
-rw-r--r--libical/src/libicalvcal/vctest.c95
-rw-r--r--libical/src/libicalvcal/vobject.c1449
-rw-r--r--libical/src/libicalvcal/vobject.h366
-rw-r--r--libical/src/python/.cvsignore2
-rw-r--r--libical/src/python/ChangeLog109
-rw-r--r--libical/src/python/Collection.py124
-rw-r--r--libical/src/python/Component.py670
-rw-r--r--libical/src/python/DerivedProperties.py59
-rw-r--r--libical/src/python/Libical.py39
-rw-r--r--libical/src/python/LibicalWrap.i352
-rw-r--r--libical/src/python/Makefile.am42
-rw-r--r--libical/src/python/Property.py839
-rw-r--r--libical/src/python/Store.py176
-rw-r--r--libical/src/python/python-binding.txt434
-rw-r--r--libical/src/python/test.py373
-rw-r--r--libical/src/test/.cvsignore18
-rw-r--r--libical/src/test/Makefile.am25
-rw-r--r--libical/src/test/copycluster.c130
-rw-r--r--libical/src/test/findobj.c72
-rw-r--r--libical/src/test/icaltestparser.c122
-rw-r--r--libical/src/test/process.c446
-rw-r--r--libical/src/test/recur.c120
-rw-r--r--libical/src/test/regression.c3605
-rw-r--r--libical/src/test/storage.c459
-rw-r--r--libical/src/test/stow.c866
-rw-r--r--libical/src/test/testclassify.c156
-rw-r--r--libical/src/test/testmime.c340
-rw-r--r--libical/src/test/testvcal.c64
-rw-r--r--libical/test-data/.cvsignore2
-rw-r--r--libical/test-data/07
-rw-r--r--libical/test-data/138
-rw-r--r--libical/test-data/1.113
-rw-r--r--libical/test-data/222
-rw-r--r--libical/test-data/2445.ics331
-rw-r--r--libical/test-data/2446.ics1006
-rw-r--r--libical/test-data/321
-rw-r--r--libical/test-data/423
-rw-r--r--libical/test-data/516
-rw-r--r--libical/test-data/612
-rw-r--r--libical/test-data/714
-rw-r--r--libical/test-data/Makefile.am26
-rw-r--r--libical/test-data/calendar.ics47
-rw-r--r--libical/test-data/classify.ics43
-rw-r--r--libical/test-data/complex-mime.txt81
-rw-r--r--libical/test-data/incoming.ics168
-rw-r--r--libical/test-data/overlaps.ics32
-rw-r--r--libical/test-data/process-incoming.ics107
-rw-r--r--libical/test-data/recur.txt404
-rw-r--r--libical/test-data/restriction.ics49
-rw-r--r--libical/test-data/simple-mime.txt26
-rw-r--r--libical/test-data/smallcluster.ics13
-rw-r--r--libical/test-data/stresstest.ics178
-rw-r--r--libical/test-data/user-cal.vcf76
-rw-r--r--libical/zoneinfo/.cvsignore2
-rw-r--r--libical/zoneinfo/Africa/Abidjan.ics14
-rw-r--r--libical/zoneinfo/Africa/Accra.ics14
-rw-r--r--libical/zoneinfo/Africa/Addis_Ababa.ics14
-rw-r--r--libical/zoneinfo/Africa/Algiers.ics14
-rw-r--r--libical/zoneinfo/Africa/Asmera.ics14
-rw-r--r--libical/zoneinfo/Africa/Bamako.ics14
-rw-r--r--libical/zoneinfo/Africa/Bangui.ics14
-rw-r--r--libical/zoneinfo/Africa/Banjul.ics14
-rw-r--r--libical/zoneinfo/Africa/Bissau.ics14
-rw-r--r--libical/zoneinfo/Africa/Blantyre.ics14
-rw-r--r--libical/zoneinfo/Africa/Brazzaville.ics14
-rw-r--r--libical/zoneinfo/Africa/Bujumbura.ics14
-rw-r--r--libical/zoneinfo/Africa/Cairo.ics22
-rw-r--r--libical/zoneinfo/Africa/Casablanca.ics14
-rw-r--r--libical/zoneinfo/Africa/Ceuta.ics22
-rw-r--r--libical/zoneinfo/Africa/Conakry.ics14
-rw-r--r--libical/zoneinfo/Africa/Dakar.ics14
-rw-r--r--libical/zoneinfo/Africa/Dar_es_Salaam.ics14
-rw-r--r--libical/zoneinfo/Africa/Djibouti.ics14
-rw-r--r--libical/zoneinfo/Africa/Douala.ics14
-rw-r--r--libical/zoneinfo/Africa/El_Aaiun.ics14
-rw-r--r--libical/zoneinfo/Africa/Freetown.ics14
-rw-r--r--libical/zoneinfo/Africa/Gaborone.ics14
-rw-r--r--libical/zoneinfo/Africa/Harare.ics14
-rw-r--r--libical/zoneinfo/Africa/Johannesburg.ics14
-rw-r--r--libical/zoneinfo/Africa/Kampala.ics14
-rw-r--r--libical/zoneinfo/Africa/Khartoum.ics14
-rw-r--r--libical/zoneinfo/Africa/Kigali.ics14
-rw-r--r--libical/zoneinfo/Africa/Kinshasa.ics14
-rw-r--r--libical/zoneinfo/Africa/Lagos.ics14
-rw-r--r--libical/zoneinfo/Africa/Libreville.ics14
-rw-r--r--libical/zoneinfo/Africa/Lome.ics14
-rw-r--r--libical/zoneinfo/Africa/Luanda.ics14
-rw-r--r--libical/zoneinfo/Africa/Lubumbashi.ics14
-rw-r--r--libical/zoneinfo/Africa/Lusaka.ics14
-rw-r--r--libical/zoneinfo/Africa/Malabo.ics14
-rw-r--r--libical/zoneinfo/Africa/Maputo.ics14
-rw-r--r--libical/zoneinfo/Africa/Maseru.ics14
-rw-r--r--libical/zoneinfo/Africa/Mbabane.ics14
-rw-r--r--libical/zoneinfo/Africa/Mogadishu.ics14
-rw-r--r--libical/zoneinfo/Africa/Monrovia.ics14
-rw-r--r--libical/zoneinfo/Africa/Nairobi.ics14
-rw-r--r--libical/zoneinfo/Africa/Ndjamena.ics14
-rw-r--r--libical/zoneinfo/Africa/Niamey.ics14
-rw-r--r--libical/zoneinfo/Africa/Nouakchott.ics14
-rw-r--r--libical/zoneinfo/Africa/Ouagadougou.ics14
-rw-r--r--libical/zoneinfo/Africa/Porto-Novo.ics14
-rw-r--r--libical/zoneinfo/Africa/Sao_Tome.ics14
-rw-r--r--libical/zoneinfo/Africa/Timbuktu.ics14
-rw-r--r--libical/zoneinfo/Africa/Tripoli.ics14
-rw-r--r--libical/zoneinfo/Africa/Tunis.ics14
-rw-r--r--libical/zoneinfo/Africa/Windhoek.ics22
-rw-r--r--libical/zoneinfo/America/Adak.ics22
-rw-r--r--libical/zoneinfo/America/Anchorage.ics22
-rw-r--r--libical/zoneinfo/America/Anguilla.ics14
-rw-r--r--libical/zoneinfo/America/Antigua.ics14
-rw-r--r--libical/zoneinfo/America/Araguaina.ics22
-rw-r--r--libical/zoneinfo/America/Aruba.ics14
-rw-r--r--libical/zoneinfo/America/Asuncion.ics22
-rw-r--r--libical/zoneinfo/America/Barbados.ics14
-rw-r--r--libical/zoneinfo/America/Belem.ics14
-rw-r--r--libical/zoneinfo/America/Belize.ics14
-rw-r--r--libical/zoneinfo/America/Boa_Vista.ics14
-rw-r--r--libical/zoneinfo/America/Bogota.ics14
-rw-r--r--libical/zoneinfo/America/Boise.ics22
-rw-r--r--libical/zoneinfo/America/Buenos_Aires.ics14
-rw-r--r--libical/zoneinfo/America/Cambridge_Bay.ics22
-rw-r--r--libical/zoneinfo/America/Cancun.ics22
-rw-r--r--libical/zoneinfo/America/Caracas.ics14
-rw-r--r--libical/zoneinfo/America/Catamarca.ics14
-rw-r--r--libical/zoneinfo/America/Cayenne.ics14
-rw-r--r--libical/zoneinfo/America/Cayman.ics14
-rw-r--r--libical/zoneinfo/America/Chicago.ics22
-rw-r--r--libical/zoneinfo/America/Chihuahua.ics22
-rw-r--r--libical/zoneinfo/America/Cordoba.ics14
-rw-r--r--libical/zoneinfo/America/Costa_Rica.ics14
-rw-r--r--libical/zoneinfo/America/Cuiaba.ics22
-rw-r--r--libical/zoneinfo/America/Curacao.ics14
-rw-r--r--libical/zoneinfo/America/Danmarkshavn.ics14
-rw-r--r--libical/zoneinfo/America/Dawson.ics22
-rw-r--r--libical/zoneinfo/America/Dawson_Creek.ics14
-rw-r--r--libical/zoneinfo/America/Denver.ics22
-rw-r--r--libical/zoneinfo/America/Detroit.ics22
-rw-r--r--libical/zoneinfo/America/Dominica.ics14
-rw-r--r--libical/zoneinfo/America/Edmonton.ics22
-rw-r--r--libical/zoneinfo/America/Eirunepe.ics14
-rw-r--r--libical/zoneinfo/America/El_Salvador.ics14
-rw-r--r--libical/zoneinfo/America/Fortaleza.ics22
-rw-r--r--libical/zoneinfo/America/Glace_Bay.ics22
-rw-r--r--libical/zoneinfo/America/Godthab.ics22
-rw-r--r--libical/zoneinfo/America/Goose_Bay.ics22
-rw-r--r--libical/zoneinfo/America/Grand_Turk.ics22
-rw-r--r--libical/zoneinfo/America/Grenada.ics14
-rw-r--r--libical/zoneinfo/America/Guadeloupe.ics14
-rw-r--r--libical/zoneinfo/America/Guatemala.ics14
-rw-r--r--libical/zoneinfo/America/Guayaquil.ics14
-rw-r--r--libical/zoneinfo/America/Guyana.ics14
-rw-r--r--libical/zoneinfo/America/Halifax.ics22
-rw-r--r--libical/zoneinfo/America/Havana.ics22
-rw-r--r--libical/zoneinfo/America/Hermosillo.ics14
-rw-r--r--libical/zoneinfo/America/Indiana/Indianapolis.ics14
-rw-r--r--libical/zoneinfo/America/Indiana/Knox.ics14
-rw-r--r--libical/zoneinfo/America/Indiana/Marengo.ics14
-rw-r--r--libical/zoneinfo/America/Indiana/Vevay.ics14
-rw-r--r--libical/zoneinfo/America/Indianapolis.ics14
-rw-r--r--libical/zoneinfo/America/Inuvik.ics22
-rw-r--r--libical/zoneinfo/America/Iqaluit.ics22
-rw-r--r--libical/zoneinfo/America/Jamaica.ics14
-rw-r--r--libical/zoneinfo/America/Jujuy.ics14
-rw-r--r--libical/zoneinfo/America/Juneau.ics22
-rw-r--r--libical/zoneinfo/America/Kentucky/Louisville.ics22
-rw-r--r--libical/zoneinfo/America/Kentucky/Monticello.ics22
-rw-r--r--libical/zoneinfo/America/La_Paz.ics14
-rw-r--r--libical/zoneinfo/America/Lima.ics14
-rw-r--r--libical/zoneinfo/America/Los_Angeles.ics22
-rw-r--r--libical/zoneinfo/America/Louisville.ics22
-rw-r--r--libical/zoneinfo/America/Maceio.ics22
-rw-r--r--libical/zoneinfo/America/Managua.ics14
-rw-r--r--libical/zoneinfo/America/Manaus.ics14
-rw-r--r--libical/zoneinfo/America/Martinique.ics14
-rw-r--r--libical/zoneinfo/America/Mazatlan.ics22
-rw-r--r--libical/zoneinfo/America/Mendoza.ics14
-rw-r--r--libical/zoneinfo/America/Menominee.ics22
-rw-r--r--libical/zoneinfo/America/Merida.ics22
-rw-r--r--libical/zoneinfo/America/Mexico_City.ics22
-rw-r--r--libical/zoneinfo/America/Miquelon.ics22
-rw-r--r--libical/zoneinfo/America/Monterrey.ics22
-rw-r--r--libical/zoneinfo/America/Montevideo.ics14
-rw-r--r--libical/zoneinfo/America/Montreal.ics22
-rw-r--r--libical/zoneinfo/America/Montserrat.ics14
-rw-r--r--libical/zoneinfo/America/Nassau.ics22
-rw-r--r--libical/zoneinfo/America/New_York.ics22
-rw-r--r--libical/zoneinfo/America/Nipigon.ics22
-rw-r--r--libical/zoneinfo/America/Nome.ics22
-rw-r--r--libical/zoneinfo/America/Noronha.ics14
-rw-r--r--libical/zoneinfo/America/North_Dakota/Center.ics22
-rw-r--r--libical/zoneinfo/America/Panama.ics14
-rw-r--r--libical/zoneinfo/America/Pangnirtung.ics22
-rw-r--r--libical/zoneinfo/America/Paramaribo.ics14
-rw-r--r--libical/zoneinfo/America/Phoenix.ics14
-rw-r--r--libical/zoneinfo/America/Port-au-Prince.ics14
-rw-r--r--libical/zoneinfo/America/Port_of_Spain.ics14
-rw-r--r--libical/zoneinfo/America/Porto_Velho.ics14
-rw-r--r--libical/zoneinfo/America/Puerto_Rico.ics14
-rw-r--r--libical/zoneinfo/America/Rainy_River.ics22
-rw-r--r--libical/zoneinfo/America/Rankin_Inlet.ics22
-rw-r--r--libical/zoneinfo/America/Recife.ics22
-rw-r--r--libical/zoneinfo/America/Regina.ics14
-rw-r--r--libical/zoneinfo/America/Rio_Branco.ics14
-rw-r--r--libical/zoneinfo/America/Rosario.ics14
-rw-r--r--libical/zoneinfo/America/Santiago.ics22
-rw-r--r--libical/zoneinfo/America/Santo_Domingo.ics14
-rw-r--r--libical/zoneinfo/America/Sao_Paulo.ics22
-rw-r--r--libical/zoneinfo/America/Scoresbysund.ics22
-rw-r--r--libical/zoneinfo/America/Shiprock.ics22
-rw-r--r--libical/zoneinfo/America/St_Johns.ics22
-rw-r--r--libical/zoneinfo/America/St_Kitts.ics14
-rw-r--r--libical/zoneinfo/America/St_Lucia.ics14
-rw-r--r--libical/zoneinfo/America/St_Thomas.ics14
-rw-r--r--libical/zoneinfo/America/St_Vincent.ics14
-rw-r--r--libical/zoneinfo/America/Swift_Current.ics14
-rw-r--r--libical/zoneinfo/America/Tegucigalpa.ics14
-rw-r--r--libical/zoneinfo/America/Thule.ics22
-rw-r--r--libical/zoneinfo/America/Thunder_Bay.ics22
-rw-r--r--libical/zoneinfo/America/Tijuana.ics22
-rw-r--r--libical/zoneinfo/America/Tortola.ics14
-rw-r--r--libical/zoneinfo/America/Vancouver.ics22
-rw-r--r--libical/zoneinfo/America/Whitehorse.ics22
-rw-r--r--libical/zoneinfo/America/Winnipeg.ics22
-rw-r--r--libical/zoneinfo/America/Yakutat.ics22
-rw-r--r--libical/zoneinfo/America/Yellowknife.ics22
-rw-r--r--libical/zoneinfo/Antarctica/Casey.ics14
-rw-r--r--libical/zoneinfo/Antarctica/Davis.ics14
-rw-r--r--libical/zoneinfo/Antarctica/DumontDUrville.ics14
-rw-r--r--libical/zoneinfo/Antarctica/Mawson.ics14
-rw-r--r--libical/zoneinfo/Antarctica/McMurdo.ics22
-rw-r--r--libical/zoneinfo/Antarctica/Palmer.ics22
-rw-r--r--libical/zoneinfo/Antarctica/South_Pole.ics22
-rw-r--r--libical/zoneinfo/Antarctica/Syowa.ics14
-rw-r--r--libical/zoneinfo/Antarctica/Vostok.ics14
-rw-r--r--libical/zoneinfo/Arctic/Longyearbyen.ics22
-rw-r--r--libical/zoneinfo/Asia/Aden.ics14
-rw-r--r--libical/zoneinfo/Asia/Almaty.ics22
-rw-r--r--libical/zoneinfo/Asia/Amman.ics22
-rw-r--r--libical/zoneinfo/Asia/Anadyr.ics22
-rw-r--r--libical/zoneinfo/Asia/Aqtau.ics22
-rw-r--r--libical/zoneinfo/Asia/Aqtobe.ics22
-rw-r--r--libical/zoneinfo/Asia/Ashgabat.ics14
-rw-r--r--libical/zoneinfo/Asia/Baghdad.ics22
-rw-r--r--libical/zoneinfo/Asia/Bahrain.ics14
-rw-r--r--libical/zoneinfo/Asia/Baku.ics22
-rw-r--r--libical/zoneinfo/Asia/Bangkok.ics14
-rw-r--r--libical/zoneinfo/Asia/Beirut.ics22
-rw-r--r--libical/zoneinfo/Asia/Bishkek.ics22
-rw-r--r--libical/zoneinfo/Asia/Brunei.ics14
-rw-r--r--libical/zoneinfo/Asia/Calcutta.ics14
-rw-r--r--libical/zoneinfo/Asia/Choibalsan.ics14
-rw-r--r--libical/zoneinfo/Asia/Chongqing.ics14
-rw-r--r--libical/zoneinfo/Asia/Chungking.ics46
-rw-r--r--libical/zoneinfo/Asia/Colombo.ics14
-rw-r--r--libical/zoneinfo/Asia/Damascus.ics22
-rw-r--r--libical/zoneinfo/Asia/Dhaka.ics14
-rw-r--r--libical/zoneinfo/Asia/Dili.ics14
-rw-r--r--libical/zoneinfo/Asia/Dubai.ics14
-rw-r--r--libical/zoneinfo/Asia/Dushanbe.ics14
-rw-r--r--libical/zoneinfo/Asia/Gaza.ics22
-rw-r--r--libical/zoneinfo/Asia/Harbin.ics14
-rw-r--r--libical/zoneinfo/Asia/Hong_Kong.ics14
-rw-r--r--libical/zoneinfo/Asia/Hovd.ics14
-rw-r--r--libical/zoneinfo/Asia/Irkutsk.ics22
-rw-r--r--libical/zoneinfo/Asia/Istanbul.ics22
-rw-r--r--libical/zoneinfo/Asia/Jakarta.ics14
-rw-r--r--libical/zoneinfo/Asia/Jayapura.ics14
-rw-r--r--libical/zoneinfo/Asia/Jerusalem.ics22
-rw-r--r--libical/zoneinfo/Asia/Kabul.ics14
-rw-r--r--libical/zoneinfo/Asia/Kamchatka.ics22
-rw-r--r--libical/zoneinfo/Asia/Karachi.ics22
-rw-r--r--libical/zoneinfo/Asia/Kashgar.ics14
-rw-r--r--libical/zoneinfo/Asia/Katmandu.ics14
-rw-r--r--libical/zoneinfo/Asia/Krasnoyarsk.ics22
-rw-r--r--libical/zoneinfo/Asia/Kuala_Lumpur.ics14
-rw-r--r--libical/zoneinfo/Asia/Kuching.ics14
-rw-r--r--libical/zoneinfo/Asia/Kuwait.ics14
-rw-r--r--libical/zoneinfo/Asia/Macao.ics14
-rw-r--r--libical/zoneinfo/Asia/Magadan.ics22
-rw-r--r--libical/zoneinfo/Asia/Manila.ics14
-rw-r--r--libical/zoneinfo/Asia/Muscat.ics14
-rw-r--r--libical/zoneinfo/Asia/Nicosia.ics22
-rw-r--r--libical/zoneinfo/Asia/Novosibirsk.ics22
-rw-r--r--libical/zoneinfo/Asia/Omsk.ics22
-rw-r--r--libical/zoneinfo/Asia/Phnom_Penh.ics14
-rw-r--r--libical/zoneinfo/Asia/Pontianak.ics14
-rw-r--r--libical/zoneinfo/Asia/Pyongyang.ics14
-rw-r--r--libical/zoneinfo/Asia/Qatar.ics14
-rw-r--r--libical/zoneinfo/Asia/Rangoon.ics14
-rw-r--r--libical/zoneinfo/Asia/Riyadh.ics14
-rw-r--r--libical/zoneinfo/Asia/Saigon.ics14
-rw-r--r--libical/zoneinfo/Asia/Sakhalin.ics22
-rw-r--r--libical/zoneinfo/Asia/Samarkand.ics14
-rw-r--r--libical/zoneinfo/Asia/Seoul.ics14
-rw-r--r--libical/zoneinfo/Asia/Shanghai.ics14
-rw-r--r--libical/zoneinfo/Asia/Singapore.ics14
-rw-r--r--libical/zoneinfo/Asia/Taipei.ics14
-rw-r--r--libical/zoneinfo/Asia/Tashkent.ics14
-rw-r--r--libical/zoneinfo/Asia/Tbilisi.ics22
-rw-r--r--libical/zoneinfo/Asia/Tehran.ics14
-rw-r--r--libical/zoneinfo/Asia/Thimphu.ics14
-rw-r--r--libical/zoneinfo/Asia/Tokyo.ics14
-rw-r--r--libical/zoneinfo/Asia/Ujung_Pandang.ics14
-rw-r--r--libical/zoneinfo/Asia/Ulaanbaatar.ics14
-rw-r--r--libical/zoneinfo/Asia/Urumqi.ics14
-rw-r--r--libical/zoneinfo/Asia/Vientiane.ics14
-rw-r--r--libical/zoneinfo/Asia/Vladivostok.ics22
-rw-r--r--libical/zoneinfo/Asia/Yakutsk.ics22
-rw-r--r--libical/zoneinfo/Asia/Yekaterinburg.ics22
-rw-r--r--libical/zoneinfo/Asia/Yerevan.ics22
-rw-r--r--libical/zoneinfo/Atlantic/Azores.ics22
-rw-r--r--libical/zoneinfo/Atlantic/Bermuda.ics22
-rw-r--r--libical/zoneinfo/Atlantic/Canary.ics22
-rw-r--r--libical/zoneinfo/Atlantic/Cape_Verde.ics14
-rw-r--r--libical/zoneinfo/Atlantic/Faeroe.ics22
-rw-r--r--libical/zoneinfo/Atlantic/Jan_Mayen.ics22
-rw-r--r--libical/zoneinfo/Atlantic/Madeira.ics22
-rw-r--r--libical/zoneinfo/Atlantic/Reykjavik.ics14
-rw-r--r--libical/zoneinfo/Atlantic/South_Georgia.ics14
-rw-r--r--libical/zoneinfo/Atlantic/St_Helena.ics14
-rw-r--r--libical/zoneinfo/Atlantic/Stanley.ics22
-rw-r--r--libical/zoneinfo/Australia/Adelaide.ics22
-rw-r--r--libical/zoneinfo/Australia/Brisbane.ics14
-rw-r--r--libical/zoneinfo/Australia/Broken_Hill.ics22
-rw-r--r--libical/zoneinfo/Australia/Darwin.ics14
-rw-r--r--libical/zoneinfo/Australia/Hobart.ics22
-rw-r--r--libical/zoneinfo/Australia/Lindeman.ics14
-rw-r--r--libical/zoneinfo/Australia/Lord_Howe.ics22
-rw-r--r--libical/zoneinfo/Australia/Melbourne.ics22
-rw-r--r--libical/zoneinfo/Australia/Perth.ics14
-rw-r--r--libical/zoneinfo/Australia/Sydney.ics22
-rw-r--r--libical/zoneinfo/Europe/Amsterdam.ics22
-rw-r--r--libical/zoneinfo/Europe/Andorra.ics22
-rw-r--r--libical/zoneinfo/Europe/Athens.ics22
-rw-r--r--libical/zoneinfo/Europe/Belfast.ics22
-rw-r--r--libical/zoneinfo/Europe/Belgrade.ics22
-rw-r--r--libical/zoneinfo/Europe/Berlin.ics22
-rw-r--r--libical/zoneinfo/Europe/Bratislava.ics22
-rw-r--r--libical/zoneinfo/Europe/Brussels.ics22
-rw-r--r--libical/zoneinfo/Europe/Bucharest.ics22
-rw-r--r--libical/zoneinfo/Europe/Budapest.ics22
-rw-r--r--libical/zoneinfo/Europe/Chisinau.ics22
-rw-r--r--libical/zoneinfo/Europe/Copenhagen.ics22
-rw-r--r--libical/zoneinfo/Europe/Dublin.ics22
-rw-r--r--libical/zoneinfo/Europe/Gibraltar.ics22
-rw-r--r--libical/zoneinfo/Europe/Helsinki.ics22
-rw-r--r--libical/zoneinfo/Europe/Istanbul.ics22
-rw-r--r--libical/zoneinfo/Europe/Kaliningrad.ics22
-rw-r--r--libical/zoneinfo/Europe/Kiev.ics22
-rw-r--r--libical/zoneinfo/Europe/Lisbon.ics22
-rw-r--r--libical/zoneinfo/Europe/Ljubljana.ics22
-rw-r--r--libical/zoneinfo/Europe/London.ics22
-rw-r--r--libical/zoneinfo/Europe/Luxembourg.ics22
-rw-r--r--libical/zoneinfo/Europe/Madrid.ics22
-rw-r--r--libical/zoneinfo/Europe/Malta.ics22
-rw-r--r--libical/zoneinfo/Europe/Minsk.ics22
-rw-r--r--libical/zoneinfo/Europe/Monaco.ics22
-rw-r--r--libical/zoneinfo/Europe/Moscow.ics22
-rw-r--r--libical/zoneinfo/Europe/Nicosia.ics22
-rw-r--r--libical/zoneinfo/Europe/Oslo.ics22
-rw-r--r--libical/zoneinfo/Europe/Paris.ics22
-rw-r--r--libical/zoneinfo/Europe/Prague.ics22
-rw-r--r--libical/zoneinfo/Europe/Riga.ics22
-rw-r--r--libical/zoneinfo/Europe/Rome.ics22
-rw-r--r--libical/zoneinfo/Europe/Samara.ics22
-rw-r--r--libical/zoneinfo/Europe/San_Marino.ics22
-rw-r--r--libical/zoneinfo/Europe/Sarajevo.ics22
-rw-r--r--libical/zoneinfo/Europe/Simferopol.ics22
-rw-r--r--libical/zoneinfo/Europe/Skopje.ics22
-rw-r--r--libical/zoneinfo/Europe/Sofia.ics22
-rw-r--r--libical/zoneinfo/Europe/Stockholm.ics22
-rw-r--r--libical/zoneinfo/Europe/Tallinn.ics22
-rw-r--r--libical/zoneinfo/Europe/Tirane.ics22
-rw-r--r--libical/zoneinfo/Europe/Uzhgorod.ics22
-rw-r--r--libical/zoneinfo/Europe/Vaduz.ics22
-rw-r--r--libical/zoneinfo/Europe/Vatican.ics22
-rw-r--r--libical/zoneinfo/Europe/Vienna.ics22
-rw-r--r--libical/zoneinfo/Europe/Vilnius.ics14
-rw-r--r--libical/zoneinfo/Europe/Warsaw.ics22
-rw-r--r--libical/zoneinfo/Europe/Zagreb.ics22
-rw-r--r--libical/zoneinfo/Europe/Zaporozhye.ics22
-rw-r--r--libical/zoneinfo/Europe/Zurich.ics22
-rw-r--r--libical/zoneinfo/Indian/Antananarivo.ics14
-rw-r--r--libical/zoneinfo/Indian/Chagos.ics14
-rw-r--r--libical/zoneinfo/Indian/Christmas.ics14
-rw-r--r--libical/zoneinfo/Indian/Cocos.ics14
-rw-r--r--libical/zoneinfo/Indian/Comoro.ics14
-rw-r--r--libical/zoneinfo/Indian/Kerguelen.ics14
-rw-r--r--libical/zoneinfo/Indian/Mahe.ics14
-rw-r--r--libical/zoneinfo/Indian/Maldives.ics14
-rw-r--r--libical/zoneinfo/Indian/Mauritius.ics14
-rw-r--r--libical/zoneinfo/Indian/Mayotte.ics14
-rw-r--r--libical/zoneinfo/Indian/Reunion.ics14
-rw-r--r--libical/zoneinfo/Makefile.am39
-rw-r--r--libical/zoneinfo/Pacific/Apia.ics14
-rw-r--r--libical/zoneinfo/Pacific/Auckland.ics22
-rw-r--r--libical/zoneinfo/Pacific/Chatham.ics22
-rw-r--r--libical/zoneinfo/Pacific/Easter.ics22
-rw-r--r--libical/zoneinfo/Pacific/Efate.ics14
-rw-r--r--libical/zoneinfo/Pacific/Enderbury.ics14
-rw-r--r--libical/zoneinfo/Pacific/Fakaofo.ics14
-rw-r--r--libical/zoneinfo/Pacific/Fiji.ics14
-rw-r--r--libical/zoneinfo/Pacific/Funafuti.ics14
-rw-r--r--libical/zoneinfo/Pacific/Galapagos.ics14
-rw-r--r--libical/zoneinfo/Pacific/Gambier.ics14
-rw-r--r--libical/zoneinfo/Pacific/Guadalcanal.ics14
-rw-r--r--libical/zoneinfo/Pacific/Guam.ics14
-rw-r--r--libical/zoneinfo/Pacific/Honolulu.ics14
-rw-r--r--libical/zoneinfo/Pacific/Johnston.ics14
-rw-r--r--libical/zoneinfo/Pacific/Kiritimati.ics14
-rw-r--r--libical/zoneinfo/Pacific/Kosrae.ics14
-rw-r--r--libical/zoneinfo/Pacific/Kwajalein.ics14
-rw-r--r--libical/zoneinfo/Pacific/Majuro.ics14
-rw-r--r--libical/zoneinfo/Pacific/Marquesas.ics14
-rw-r--r--libical/zoneinfo/Pacific/Midway.ics14
-rw-r--r--libical/zoneinfo/Pacific/Nauru.ics14
-rw-r--r--libical/zoneinfo/Pacific/Niue.ics14
-rw-r--r--libical/zoneinfo/Pacific/Norfolk.ics14
-rw-r--r--libical/zoneinfo/Pacific/Noumea.ics14
-rw-r--r--libical/zoneinfo/Pacific/Pago_Pago.ics14
-rw-r--r--libical/zoneinfo/Pacific/Palau.ics14
-rw-r--r--libical/zoneinfo/Pacific/Pitcairn.ics14
-rw-r--r--libical/zoneinfo/Pacific/Ponape.ics14
-rw-r--r--libical/zoneinfo/Pacific/Port_Moresby.ics14
-rw-r--r--libical/zoneinfo/Pacific/Rarotonga.ics14
-rw-r--r--libical/zoneinfo/Pacific/Saipan.ics14
-rw-r--r--libical/zoneinfo/Pacific/Tahiti.ics14
-rw-r--r--libical/zoneinfo/Pacific/Tarawa.ics14
-rw-r--r--libical/zoneinfo/Pacific/Tongatapu.ics22
-rw-r--r--libical/zoneinfo/Pacific/Truk.ics14
-rw-r--r--libical/zoneinfo/Pacific/Wake.ics14
-rw-r--r--libical/zoneinfo/Pacific/Wallis.ics14
-rw-r--r--libical/zoneinfo/Pacific/Yap.ics14
-rw-r--r--libical/zoneinfo/zones.tab378
-rw-r--r--libversit/.cvsignore3
-rw-r--r--libversit/Makefile.am20
-rw-r--r--libversit/README.TXT951
-rw-r--r--libversit/port.h88
-rw-r--r--libversit/vcaltest.c118
-rw-r--r--libversit/vcaltmp.c337
-rw-r--r--libversit/vcaltmp.h128
-rw-r--r--libversit/vcc.h80
-rw-r--r--libversit/vcc.y1280
-rw-r--r--libversit/vctest.c95
-rw-r--r--libversit/vobject.c1469
-rw-r--r--libversit/vobject.h367
-rw-r--r--libwombat/.cvsignore15
-rw-r--r--libwombat/ChangeLog35
-rw-r--r--libwombat/Makefile.am35
-rw-r--r--libwombat/wombat-client.c173
-rw-r--r--libwombat/wombat-client.h73
-rw-r--r--m4/Makefile.am1
-rw-r--r--m4/as-ac-expand.m450
-rw-r--r--m4/as-compiler-flag.m461
-rw-r--r--m4/evo_krb5_support.m4136
-rw-r--r--m4/evo_ldap_check.m492
-rw-r--r--m4/evo_purify_support.m423
-rw-r--r--m4/evo_sunldap_check.m494
-rw-r--r--macros/.cvsignore2
-rw-r--r--macros/ChangeLog1228
-rw-r--r--macros/Makefile.am43
-rw-r--r--macros/README.cvs-commits13
-rw-r--r--macros/aclocal-include.m416
-rw-r--r--macros/autogen.sh207
-rw-r--r--macros/compiler-flags.m4109
-rw-r--r--macros/curses.m4318
-rw-r--r--macros/gnome-bonobo-check.m4166
-rw-r--r--macros/gnome-common.m414
-rw-r--r--macros/gnome-cxx-check.m410
-rw-r--r--macros/gnome-fileutils.m4414
-rw-r--r--macros/gnome-gettext.m4338
-rw-r--r--macros/gnome-ghttp-check.m414
-rw-r--r--macros/gnome-gnorba-check.m435
-rw-r--r--macros/gnome-guile-checks.m4134
-rw-r--r--macros/gnome-libgtop-check.m4217
-rw-r--r--macros/gnome-objc-checks.m483
-rw-r--r--macros/gnome-orbit-check.m433
-rw-r--r--macros/gnome-pilot.m4213
-rw-r--r--macros/gnome-print-check.m463
-rw-r--r--macros/gnome-pthread-check.m418
-rw-r--r--macros/gnome-support.m468
-rw-r--r--macros/gnome-undelfs.m422
-rw-r--r--macros/gnome-vfs.m4126
-rw-r--r--macros/gnome-x-checks.m480
-rw-r--r--macros/gnome-xml-check.m432
-rw-r--r--macros/gnome.m4130
-rw-r--r--macros/gperf-check.m479
-rw-r--r--macros/linger.m428
-rw-r--r--macros/need-declaration.m442
-rw-r--r--macros/psiconv.m453
-rw-r--r--mail/.cvsignore24
-rw-r--r--mail/ChangeLog21491
-rw-r--r--mail/GNOME_Evolution_Mail.oaf.in309
-rw-r--r--mail/Mailer.idl67
-rw-r--r--mail/Makefile.am431
-rw-r--r--mail/Spell.idl71
-rw-r--r--mail/component-factory.c1587
-rw-r--r--mail/component-factory.h31
-rw-r--r--mail/default/C/Inbox311
-rw-r--r--mail/default/C/Makefile.am9
-rw-r--r--mail/default/Makefile.am6
-rw-r--r--mail/default/ca/Inbox317
-rw-r--r--mail/default/ca/Makefile.am9
-rw-r--r--mail/default/cs/Inbox315
-rw-r--r--mail/default/cs/Makefile.am9
-rw-r--r--mail/default/de/Inbox337
-rw-r--r--mail/default/de/Makefile.am9
-rw-r--r--mail/default/es/Inbox317
-rw-r--r--mail/default/es/Makefile.am9
-rw-r--r--mail/default/fi/Inbox331
-rw-r--r--mail/default/fi/Makefile.am9
-rw-r--r--mail/default/fr/Inbox283
-rw-r--r--mail/default/fr/Makefile.am9
-rw-r--r--mail/default/hu/Inbox314
-rw-r--r--mail/default/hu/Makefile.am9
-rw-r--r--mail/default/id/Inbox316
-rw-r--r--mail/default/id/Makefile.am9
-rw-r--r--mail/default/it/Inbox325
-rw-r--r--mail/default/it/Makefile.am9
-rw-r--r--mail/default/ja/Inbox353
-rw-r--r--mail/default/ja/Makefile.am9
-rw-r--r--mail/default/ko/Inbox310
-rw-r--r--mail/default/ko/Makefile.am9
-rw-r--r--mail/default/lt/Inbox348
-rw-r--r--mail/default/lt/Makefile.am9
-rw-r--r--mail/default/mk/Inbox369
-rw-r--r--mail/default/mk/Makefile.am9
-rw-r--r--mail/default/nl/Inbox318
-rw-r--r--mail/default/nl/Makefile.am9
-rw-r--r--mail/default/pl/Inbox317
-rw-r--r--mail/default/pl/Makefile.am9
-rw-r--r--mail/default/pt/Inbox353
-rw-r--r--mail/default/pt/Makefile.am9
-rw-r--r--mail/default/ro/Inbox311
-rw-r--r--mail/default/ro/Makefile.am9
-rw-r--r--mail/default/sr/Inbox318
-rw-r--r--mail/default/sr/Makefile.am9
-rw-r--r--mail/default/sr@latin/Inbox315
-rw-r--r--mail/default/sr@latin/Makefile.am9
-rw-r--r--mail/default/sv/Inbox311
-rw-r--r--mail/default/sv/Makefile.am9
-rw-r--r--mail/default/zh_CN/Inbox316
-rw-r--r--mail/default/zh_CN/Makefile.am9
-rw-r--r--mail/e-attchmt.pngbin169 -> 0 bytes-rw-r--r--mail/e-http-request.c580
-rw-r--r--mail/e-http-request.h65
-rw-r--r--mail/e-mail-account-manager.c853
-rw-r--r--mail/e-mail-account-manager.h78
-rw-r--r--mail/e-mail-account-store.c1632
-rw-r--r--mail/e-mail-account-store.h152
-rw-r--r--mail/e-mail-account-tree-view.c303
-rw-r--r--mail/e-mail-account-tree-view.h75
-rw-r--r--mail/e-mail-autoconfig.c835
-rw-r--r--mail/e-mail-autoconfig.h87
-rw-r--r--mail/e-mail-backend.c1231
-rw-r--r--mail/e-mail-backend.h82
-rw-r--r--mail/e-mail-browser.c1166
-rw-r--r--mail/e-mail-browser.h88
-rw-r--r--mail/e-mail-config-activity-page.c173
-rw-r--r--mail/e-mail-config-activity-page.h72
-rw-r--r--mail/e-mail-config-assistant.c1250
-rw-r--r--mail/e-mail-config-assistant.h96
-rw-r--r--mail/e-mail-config-auth-check.c455
-rw-r--r--mail/e-mail-config-auth-check.h73
-rw-r--r--mail/e-mail-config-confirm-page.c208
-rw-r--r--mail/e-mail-config-confirm-page.h75
-rw-r--r--mail/e-mail-config-defaults-page.c908
-rw-r--r--mail/e-mail-config-defaults-page.h79
-rw-r--r--mail/e-mail-config-identity-page.c805
-rw-r--r--mail/e-mail-config-identity-page.h96
-rw-r--r--mail/e-mail-config-lookup-page.c109
-rw-r--r--mail/e-mail-config-lookup-page.h73
-rw-r--r--mail/e-mail-config-notebook.c884
-rw-r--r--mail/e-mail-config-notebook.h98
-rw-r--r--mail/e-mail-config-page.c287
-rw-r--r--mail/e-mail-config-page.h96
-rw-r--r--mail/e-mail-config-provider-page.c735
-rw-r--r--mail/e-mail-config-provider-page.h82
-rw-r--r--mail/e-mail-config-receiving-page.c68
-rw-r--r--mail/e-mail-config-receiving-page.h69
-rw-r--r--mail/e-mail-config-security-page.c669
-rw-r--r--mail/e-mail-config-security-page.h73
-rw-r--r--mail/e-mail-config-sending-page.c68
-rw-r--r--mail/e-mail-config-sending-page.h68
-rw-r--r--mail/e-mail-config-service-backend.c521
-rw-r--r--mail/e-mail-config-service-backend.h120
-rw-r--r--mail/e-mail-config-service-notebook.c368
-rw-r--r--mail/e-mail-config-service-notebook.h77
-rw-r--r--mail/e-mail-config-service-page.c943
-rw-r--r--mail/e-mail-config-service-page.h102
-rw-r--r--mail/e-mail-config-sidebar.c416
-rw-r--r--mail/e-mail-config-sidebar.h72
-rw-r--r--mail/e-mail-config-summary-page.c988
-rw-r--r--mail/e-mail-config-summary-page.h95
-rw-r--r--mail/e-mail-config-welcome-page.c206
-rw-r--r--mail/e-mail-config-welcome-page.h75
-rw-r--r--mail/e-mail-config-window.c535
-rw-r--r--mail/e-mail-config-window.h74
-rw-r--r--mail/e-mail-display-popup-extension.c54
-rw-r--r--mail/e-mail-display-popup-extension.h64
-rw-r--r--mail/e-mail-display.c2114
-rw-r--r--mail/e-mail-display.h101
-rw-r--r--mail/e-mail-folder-pane.c194
-rw-r--r--mail/e-mail-folder-pane.h66
-rw-r--r--mail/e-mail-junk-options.c375
-rw-r--r--mail/e-mail-junk-options.h67
-rw-r--r--mail/e-mail-label-action.c127
-rw-r--r--mail/e-mail-label-action.h73
-rw-r--r--mail/e-mail-label-dialog.c305
-rw-r--r--mail/e-mail-label-dialog.h77
-rw-r--r--mail/e-mail-label-list-store.c621
-rw-r--r--mail/e-mail-label-list-store.h85
-rw-r--r--mail/e-mail-label-manager.c457
-rw-r--r--mail/e-mail-label-manager.h81
-rw-r--r--mail/e-mail-label-tree-view.c112
-rw-r--r--mail/e-mail-label-tree-view.h66
-rw-r--r--mail/e-mail-message-pane.c96
-rw-r--r--mail/e-mail-message-pane.h67
-rw-r--r--mail/e-mail-migrate.c326
-rw-r--r--mail/e-mail-migrate.h37
-rw-r--r--mail/e-mail-paned-view.c1099
-rw-r--r--mail/e-mail-paned-view.h76
-rw-r--r--mail/e-mail-print-config-headers.c290
-rw-r--r--mail/e-mail-print-config-headers.h70
-rw-r--r--mail/e-mail-printer.c632
-rw-r--r--mail/e-mail-printer.h81
-rw-r--r--mail/e-mail-reader-utils.c2469
-rw-r--r--mail/e-mail-reader-utils.h99
-rw-r--r--mail/e-mail-reader.c4550
-rw-r--r--mail/e-mail-reader.h186
-rw-r--r--mail/e-mail-request.c453
-rw-r--r--mail/e-mail-request.h65
-rw-r--r--mail/e-mail-sidebar.c657
-rw-r--r--mail/e-mail-sidebar.h93
-rw-r--r--mail/e-mail-tag-editor.c376
-rw-r--r--mail/e-mail-tag-editor.h83
-rw-r--r--mail/e-mail-ui-session.c991
-rw-r--r--mail/e-mail-ui-session.h110
-rw-r--r--mail/e-mail-view.c495
-rw-r--r--mail/e-mail-view.h107
-rw-r--r--mail/e-mail.h40
-rw-r--r--mail/e-searching-tokenizer.c1252
-rw-r--r--mail/e-searching-tokenizer.h75
-rw-r--r--mail/em-composer-utils.c3056
-rw-r--r--mail/em-composer-utils.h91
-rw-r--r--mail/em-config.c242
-rw-r--r--mail/em-config.h124
-rw-r--r--mail/em-event.c220
-rw-r--r--mail/em-event.h189
-rw-r--r--mail/em-filter-context.c356
-rw-r--r--mail/em-filter-context.h80
-rw-r--r--mail/em-filter-editor-folder-element.c219
-rw-r--r--mail/em-filter-editor-folder-element.h73
-rw-r--r--mail/em-filter-editor.c171
-rw-r--r--mail/em-filter-editor.h79
-rw-r--r--mail/em-filter-i18n.h80
-rw-r--r--mail/em-filter-rule.c668
-rw-r--r--mail/em-filter-rule.h61
-rw-r--r--mail/em-filter-source-element.c467
-rw-r--r--mail/em-filter-source-element.h72
-rw-r--r--mail/em-folder-properties.c546
-rw-r--r--mail/em-folder-properties.h39
-rw-r--r--mail/em-folder-selection-button.c561
-rw-r--r--mail/em-folder-selection-button.h101
-rw-r--r--mail/em-folder-selector.c465
-rw-r--r--mail/em-folder-selector.h101
-rw-r--r--mail/em-folder-tree-model.c1443
-rw-r--r--mail/em-folder-tree-model.h167
-rw-r--r--mail/em-folder-tree.c3608
-rw-r--r--mail/em-folder-tree.h152
-rw-r--r--mail/em-folder-utils.c717
-rw-r--r--mail/em-folder-utils.h57
-rw-r--r--mail/em-search-context.c75
-rw-r--r--mail/em-search-context.h67
-rw-r--r--mail/em-subscription-editor.c1955
-rw-r--r--mail/em-subscription-editor.h71
-rw-r--r--mail/em-utils.c1494
-rw-r--r--mail/em-utils.h85
-rw-r--r--mail/em-vfolder-editor-context.c216
-rw-r--r--mail/em-vfolder-editor-context.h73
-rw-r--r--mail/em-vfolder-editor-rule.c686
-rw-r--r--mail/em-vfolder-editor-rule.h81
-rw-r--r--mail/em-vfolder-editor.c111
-rw-r--r--mail/em-vfolder-editor.h68
-rw-r--r--mail/filtertypes.xml1046
-rw-r--r--mail/folder-browser-factory.c253
-rw-r--r--mail/folder-browser-factory.h25
-rw-r--r--mail/folder-browser-ui.c784
-rw-r--r--mail/folder-browser-ui.h36
-rw-r--r--mail/folder-browser.c2601
-rw-r--r--mail/folder-browser.h183
-rw-r--r--mail/folder-info.c294
-rw-r--r--mail/folder-info.h44
-rw-r--r--mail/importers/.cvsignore12
-rw-r--r--mail/importers/GNOME_Evolution_Mail_Mbox_Importer.oaf.in29
-rw-r--r--mail/importers/GNOME_Evolution_Mail_Outlook_Importer.oaf.in29
-rw-r--r--mail/importers/Makefile.am54
-rw-r--r--mail/importers/elm-importer.c382
-rw-r--r--mail/importers/evolution-mbox-importer.c728
-rw-r--r--mail/importers/evolution-outlook-importer.c318
-rw-r--r--mail/importers/mail-importer.c415
-rw-r--r--mail/importers/mail-importer.h77
-rw-r--r--mail/importers/mozilla-status-headers.h29
-rw-r--r--mail/importers/pine-importer.c478
-rw-r--r--mail/local-config.glade314
-rw-r--r--mail/mail-account-editor.c195
-rw-r--r--mail/mail-account-editor.h67
-rw-r--r--mail/mail-account-gui.c1993
-rw-r--r--mail/mail-account-gui.h136
-rw-r--r--mail/mail-accounts.c637
-rw-r--r--mail/mail-accounts.etspec12
-rw-r--r--mail/mail-accounts.h107
-rw-r--r--mail/mail-autofilter.c613
-rw-r--r--mail/mail-autofilter.h73
-rw-r--r--mail/mail-callbacks.c3487
-rw-r--r--mail/mail-callbacks.h144
-rw-r--r--mail/mail-composer-prefs.c971
-rw-r--r--mail/mail-composer-prefs.h136
-rw-r--r--mail/mail-config-druid.c1064
-rw-r--r--mail/mail-config-druid.h91
-rw-r--r--mail/mail-config-factory.c135
-rw-r--r--mail/mail-config-factory.h42
-rw-r--r--mail/mail-config.c3245
-rw-r--r--mail/mail-config.glade4915
-rw-r--r--mail/mail-config.h333
-rw-r--r--mail/mail-config.ui3022
-rw-r--r--mail/mail-crypto.c214
-rw-r--r--mail/mail-crypto.h63
-rw-r--r--mail/mail-dialogs.ui470
-rw-r--r--mail/mail-display.c2745
-rw-r--r--mail/mail-display.h117
-rw-r--r--mail/mail-folder-cache.c900
-rw-r--r--mail/mail-folder-cache.h50
-rw-r--r--mail/mail-font-prefs.c127
-rw-r--r--mail/mail-font-prefs.h66
-rw-r--r--mail/mail-format.c2429
-rw-r--r--mail/mail-identify.c135
-rw-r--r--mail/mail-importer.c262
-rw-r--r--mail/mail-importer.h49
-rw-r--r--mail/mail-local.c1521
-rw-r--r--mail/mail-local.h36
-rw-r--r--mail/mail-mt.c1014
-rw-r--r--mail/mail-mt.h126
-rw-r--r--mail/mail-offline-handler.c353
-rw-r--r--mail/mail-offline-handler.h65
-rw-r--r--mail/mail-ops.c2302
-rw-r--r--mail/mail-ops.h165
-rw-r--r--mail/mail-preferences.c440
-rw-r--r--mail/mail-preferences.h128
-rw-r--r--mail/mail-search-dialogue.c176
-rw-r--r--mail/mail-search-dialogue.h61
-rw-r--r--mail/mail-search.c421
-rw-r--r--mail/mail-search.h79
-rw-r--r--mail/mail-send-recv.c1735
-rw-r--r--mail/mail-send-recv.h57
-rw-r--r--mail/mail-session.c1060
-rw-r--r--mail/mail-session.h58
-rw-r--r--mail/mail-signature-editor.c397
-rw-r--r--mail/mail-signature-editor.h41
-rw-r--r--mail/mail-stream-gtkhtml.c98
-rw-r--r--mail/mail-stream-gtkhtml.h62
-rw-r--r--mail/mail-summary.c522
-rw-r--r--mail/mail-summary.h31
-rw-r--r--mail/mail-tools.c478
-rw-r--r--mail/mail-tools.h80
-rw-r--r--mail/mail-types.h40
-rw-r--r--mail/mail-vfolder-ui.c337
-rw-r--r--mail/mail-vfolder-ui.h49
-rw-r--r--mail/mail-vfolder.c984
-rw-r--r--mail/mail-vfolder.h35
-rw-r--r--mail/mail.error.xml525
-rw-r--r--mail/mail.h87
-rw-r--r--mail/main.c173
-rw-r--r--mail/message-browser.c356
-rw-r--r--mail/message-browser.h61
-rw-r--r--mail/message-list.c6952
-rw-r--r--mail/message-list.etspec24
-rw-r--r--mail/message-list.h258
-rw-r--r--mail/message-tag-editor.c131
-rw-r--r--mail/message-tag-editor.h71
-rw-r--r--mail/message-tag-followup.c312
-rw-r--r--mail/message-tag-followup.h81
-rw-r--r--mail/message-tags.glade355
-rw-r--r--mail/searchtypes.xml1016
-rw-r--r--mail/subscribe-dialog.c1687
-rw-r--r--mail/subscribe-dialog.etspec9
-rw-r--r--mail/subscribe-dialog.glade336
-rw-r--r--mail/subscribe-dialog.h63
-rw-r--r--mail/test-mail-autoconfig.c53
-rw-r--r--mail/upgrade-mailer.c1134
-rw-r--r--mail/vfoldertypes.xml945
-rw-r--r--maint/Makefile.am24
-rw-r--r--maint/evolution.xml56
-rw-r--r--marshal.mk7
-rw-r--r--modules/Makefile.am65
-rw-r--r--modules/addressbook/Makefile.am91
-rw-r--r--modules/addressbook/autocompletion-config.c225
-rw-r--r--modules/addressbook/autocompletion-config.h36
-rw-r--r--modules/addressbook/e-book-config-hook.c75
-rw-r--r--modules/addressbook/e-book-config-hook.h33
-rw-r--r--modules/addressbook/e-book-shell-backend.c524
-rw-r--r--modules/addressbook/e-book-shell-backend.h67
-rw-r--r--modules/addressbook/e-book-shell-content.c749
-rw-r--r--modules/addressbook/e-book-shell-content.h117
-rw-r--r--modules/addressbook/e-book-shell-migrate.c41
-rw-r--r--modules/addressbook/e-book-shell-migrate.h40
-rw-r--r--modules/addressbook/e-book-shell-sidebar.c319
-rw-r--r--modules/addressbook/e-book-shell-sidebar.h83
-rw-r--r--modules/addressbook/e-book-shell-view-actions.c1422
-rw-r--r--modules/addressbook/e-book-shell-view-actions.h101
-rw-r--r--modules/addressbook/e-book-shell-view-private.c609
-rw-r--r--modules/addressbook/e-book-shell-view-private.h120
-rw-r--r--modules/addressbook/e-book-shell-view.c430
-rw-r--r--modules/addressbook/e-book-shell-view.h69
-rw-r--r--modules/addressbook/eab-composer-util.c206
-rw-r--r--modules/addressbook/eab-composer-util.h33
-rw-r--r--modules/addressbook/evolution-module-addressbook.c53
-rw-r--r--modules/addressbook/openldap-extract.h1449
-rw-r--r--modules/audio-inline/Makefile.am34
-rw-r--r--modules/audio-inline/e-mail-formatter-audio.c336
-rw-r--r--modules/audio-inline/e-mail-formatter-audio.h30
-rw-r--r--modules/audio-inline/e-mail-parser-audio.c132
-rw-r--r--modules/audio-inline/e-mail-parser-audio.h30
-rw-r--r--modules/audio-inline/e-mail-part-audio.c142
-rw-r--r--modules/audio-inline/e-mail-part-audio.h75
-rw-r--r--modules/audio-inline/evolution-module-audio-inline.c54
-rw-r--r--modules/backup-restore/Makefile.am85
-rw-r--r--modules/backup-restore/e-mail-config-restore-page.c380
-rw-r--r--modules/backup-restore/e-mail-config-restore-page.h81
-rw-r--r--modules/backup-restore/e-mail-config-restore-ready-page.c80
-rw-r--r--modules/backup-restore/e-mail-config-restore-ready-page.h76
-rw-r--r--modules/backup-restore/evolution-backup-restore.c494
-rw-r--r--modules/backup-restore/evolution-backup-tool.c1089
-rw-r--r--modules/backup-restore/org-gnome-backup-restore.error.xml24
-rw-r--r--modules/bogofilter/Makefile.am24
-rw-r--r--modules/bogofilter/evolution-bogofilter.c523
-rw-r--r--modules/book-config-google/Makefile.am23
-rw-r--r--modules/book-config-google/evolution-book-config-google.c150
-rw-r--r--modules/book-config-ldap/Makefile.am27
-rw-r--r--modules/book-config-ldap/e-source-ldap.c686
-rw-r--r--modules/book-config-ldap/e-source-ldap.h123
-rw-r--r--modules/book-config-ldap/evolution-book-config-ldap.c1012
-rw-r--r--modules/book-config-local/Makefile.am23
-rw-r--r--modules/book-config-local/evolution-book-config-local.c72
-rw-r--r--modules/book-config-webdav/Makefile.am23
-rw-r--r--modules/book-config-webdav/evolution-book-config-webdav.c231
-rw-r--r--modules/cal-config-caldav/Makefile.am29
-rw-r--r--modules/cal-config-caldav/e-caldav-chooser-dialog.c477
-rw-r--r--modules/cal-config-caldav/e-caldav-chooser-dialog.h68
-rw-r--r--modules/cal-config-caldav/e-caldav-chooser.c1754
-rw-r--r--modules/cal-config-caldav/e-caldav-chooser.h80
-rw-r--r--modules/cal-config-caldav/evolution-cal-config-caldav.c359
-rw-r--r--modules/cal-config-contacts/Makefile.am27
-rw-r--r--modules/cal-config-contacts/e-contacts-selector.c113
-rw-r--r--modules/cal-config-contacts/e-contacts-selector.h65
-rw-r--r--modules/cal-config-contacts/e-source-contacts.c172
-rw-r--r--modules/cal-config-contacts/e-source-contacts.h70
-rw-r--r--modules/cal-config-contacts/evolution-cal-config-contacts.c254
-rw-r--r--modules/cal-config-google/Makefile.am31
-rw-r--r--modules/cal-config-google/e-google-chooser-button.c242
-rw-r--r--modules/cal-config-google/e-google-chooser-button.h67
-rw-r--r--modules/cal-config-google/e-google-chooser-dialog.c387
-rw-r--r--modules/cal-config-google/e-google-chooser-dialog.h68
-rw-r--r--modules/cal-config-google/e-google-chooser.c645
-rw-r--r--modules/cal-config-google/e-google-chooser.h80
-rw-r--r--modules/cal-config-google/evolution-cal-config-google.c199
-rw-r--r--modules/cal-config-local/Makefile.am25
-rw-r--r--modules/cal-config-local/e-source-local.c203
-rw-r--r--modules/cal-config-local/e-source-local.h69
-rw-r--r--modules/cal-config-local/evolution-cal-config-local.c305
-rw-r--r--modules/cal-config-weather/Makefile.am27
-rw-r--r--modules/cal-config-weather/e-source-weather.c258
-rw-r--r--modules/cal-config-weather/e-source-weather.h83
-rw-r--r--modules/cal-config-weather/evolution-cal-config-weather.c265
-rw-r--r--modules/cal-config-webcal/Makefile.am23
-rw-r--r--modules/cal-config-webcal/evolution-cal-config-webcal.c221
-rw-r--r--modules/calendar/Makefile.am89
-rw-r--r--modules/calendar/e-cal-attachment-handler.c577
-rw-r--r--modules/calendar/e-cal-attachment-handler.h67
-rw-r--r--modules/calendar/e-cal-config-hook.c75
-rw-r--r--modules/calendar/e-cal-config-hook.h33
-rw-r--r--modules/calendar/e-cal-event-hook.c75
-rw-r--r--modules/calendar/e-cal-event-hook.h33
-rw-r--r--modules/calendar/e-cal-shell-backend.c858
-rw-r--r--modules/calendar/e-cal-shell-backend.h71
-rw-r--r--modules/calendar/e-cal-shell-content.c945
-rw-r--r--modules/calendar/e-cal-shell-content.h98
-rw-r--r--modules/calendar/e-cal-shell-migrate.c37
-rw-r--r--modules/calendar/e-cal-shell-migrate.h37
-rw-r--r--modules/calendar/e-cal-shell-sidebar.c889
-rw-r--r--modules/calendar/e-cal-shell-sidebar.h104
-rw-r--r--modules/calendar/e-cal-shell-view-actions.c2021
-rw-r--r--modules/calendar/e-cal-shell-view-actions.h163
-rw-r--r--modules/calendar/e-cal-shell-view-memopad.c482
-rw-r--r--modules/calendar/e-cal-shell-view-private.c1787
-rw-r--r--modules/calendar/e-cal-shell-view-private.h223
-rw-r--r--modules/calendar/e-cal-shell-view-taskpad.c609
-rw-r--r--modules/calendar/e-cal-shell-view.c632
-rw-r--r--modules/calendar/e-cal-shell-view.h66
-rw-r--r--modules/calendar/e-calendar-preferences.c972
-rw-r--r--modules/calendar/e-calendar-preferences.h83
-rw-r--r--modules/calendar/e-calendar-preferences.ui1508
-rw-r--r--modules/calendar/e-memo-shell-backend.c488
-rw-r--r--modules/calendar/e-memo-shell-backend.h67
-rw-r--r--modules/calendar/e-memo-shell-content.c766
-rw-r--r--modules/calendar/e-memo-shell-content.h94
-rw-r--r--modules/calendar/e-memo-shell-migrate.c38
-rw-r--r--modules/calendar/e-memo-shell-migrate.h37
-rw-r--r--modules/calendar/e-memo-shell-sidebar.c816
-rw-r--r--modules/calendar/e-memo-shell-sidebar.h103
-rw-r--r--modules/calendar/e-memo-shell-view-actions.c1049
-rw-r--r--modules/calendar/e-memo-shell-view-actions.h91
-rw-r--r--modules/calendar/e-memo-shell-view-private.c551
-rw-r--r--modules/calendar/e-memo-shell-view-private.h135
-rw-r--r--modules/calendar/e-memo-shell-view.c344
-rw-r--r--modules/calendar/e-memo-shell-view.h66
-rw-r--r--modules/calendar/e-task-shell-backend.c488
-rw-r--r--modules/calendar/e-task-shell-backend.h67
-rw-r--r--modules/calendar/e-task-shell-content.c790
-rw-r--r--modules/calendar/e-task-shell-content.h98
-rw-r--r--modules/calendar/e-task-shell-migrate.c38
-rw-r--r--modules/calendar/e-task-shell-migrate.h37
-rw-r--r--modules/calendar/e-task-shell-sidebar.c816
-rw-r--r--modules/calendar/e-task-shell-sidebar.h103
-rw-r--r--modules/calendar/e-task-shell-view-actions.c1251
-rw-r--r--modules/calendar/e-task-shell-view-actions.h109
-rw-r--r--modules/calendar/e-task-shell-view-private.c755
-rw-r--r--modules/calendar/e-task-shell-view-private.h155
-rw-r--r--modules/calendar/e-task-shell-view.c530
-rw-r--r--modules/calendar/e-task-shell-view.h71
-rw-r--r--modules/calendar/evolution-module-calendar.c83
-rw-r--r--modules/composer-autosave/Makefile.am29
-rw-r--r--modules/composer-autosave/e-autosave-utils.c520
-rw-r--r--modules/composer-autosave/e-autosave-utils.h48
-rw-r--r--modules/composer-autosave/e-composer-autosave.c231
-rw-r--r--modules/composer-autosave/e-composer-registry.c240
-rw-r--r--modules/composer-autosave/evolution-composer-autosave.c44
-rw-r--r--modules/contact-photos/Makefile.am30
-rw-r--r--modules/contact-photos/e-contact-photo-source.c469
-rw-r--r--modules/contact-photos/e-contact-photo-source.h73
-rw-r--r--modules/contact-photos/e-photo-cache-contact-loader.c252
-rw-r--r--modules/contact-photos/e-photo-cache-contact-loader.h66
-rw-r--r--modules/contact-photos/evolution-contact-photos.c40
-rw-r--r--modules/gravatar/Makefile.am30
-rw-r--r--modules/gravatar/e-gravatar-photo-source.c267
-rw-r--r--modules/gravatar/e-gravatar-photo-source.h68
-rw-r--r--modules/gravatar/e-photo-cache-gravatar-loader.c88
-rw-r--r--modules/gravatar/e-photo-cache-gravatar-loader.h66
-rw-r--r--modules/gravatar/evolution-module-gravatar.c40
-rw-r--r--modules/itip-formatter/Makefile.am55
-rw-r--r--modules/itip-formatter/e-conflict-search-selector.c103
-rw-r--r--modules/itip-formatter/e-conflict-search-selector.h64
-rw-r--r--modules/itip-formatter/e-mail-formatter-itip.c169
-rw-r--r--modules/itip-formatter/e-mail-formatter-itip.h30
-rw-r--r--modules/itip-formatter/e-mail-parser-itip.c157
-rw-r--r--modules/itip-formatter/e-mail-parser-itip.h30
-rw-r--r--modules/itip-formatter/e-mail-part-itip.c171
-rw-r--r--modules/itip-formatter/e-mail-part-itip.h145
-rw-r--r--modules/itip-formatter/e-source-conflict-search.c154
-rw-r--r--modules/itip-formatter/e-source-conflict-search.h86
-rw-r--r--modules/itip-formatter/evolution-module-itip-formatter.c77
-rw-r--r--modules/itip-formatter/itip-view.c6190
-rw-r--r--modules/itip-formatter/itip-view.h254
-rw-r--r--modules/itip-formatter/org-gnome-itip-formatter.error.xml17
-rw-r--r--modules/itip-formatter/plugin/Makefile.am41
-rw-r--r--modules/itip-formatter/plugin/config-ui.c159
-rw-r--r--modules/itip-formatter/plugin/org-gnome-itip-formatter.eplug.xml15
-rw-r--r--modules/mail-config/Makefile.am40
-rw-r--r--modules/mail-config/e-mail-config-google-summary.c369
-rw-r--r--modules/mail-config/e-mail-config-google-summary.h68
-rw-r--r--modules/mail-config/e-mail-config-local-accounts.c385
-rw-r--r--modules/mail-config/e-mail-config-remote-accounts.c462
-rw-r--r--modules/mail-config/e-mail-config-sendmail-backend.c231
-rw-r--r--modules/mail-config/e-mail-config-sendmail-backend.h66
-rw-r--r--modules/mail-config/e-mail-config-smtp-backend.c427
-rw-r--r--modules/mail-config/e-mail-config-smtp-backend.h66
-rw-r--r--modules/mail-config/e-mail-config-yahoo-summary.c348
-rw-r--r--modules/mail-config/e-mail-config-yahoo-summary.h68
-rw-r--r--modules/mail-config/evolution-mail-config.c51
-rw-r--r--modules/mail/Makefile.am59
-rw-r--r--modules/mail/e-mail-attachment-handler.c638
-rw-r--r--modules/mail/e-mail-attachment-handler.h67
-rw-r--r--modules/mail/e-mail-config-hook.c76
-rw-r--r--modules/mail/e-mail-config-hook.h33
-rw-r--r--modules/mail/e-mail-event-hook.c100
-rw-r--r--modules/mail/e-mail-event-hook.h33
-rw-r--r--modules/mail/e-mail-shell-backend.c1117
-rw-r--r--modules/mail/e-mail-shell-backend.h85
-rw-r--r--modules/mail/e-mail-shell-content.c504
-rw-r--r--modules/mail/e-mail-shell-content.h77
-rw-r--r--modules/mail/e-mail-shell-sidebar.c384
-rw-r--r--modules/mail/e-mail-shell-sidebar.h73
-rw-r--r--modules/mail/e-mail-shell-view-actions.c2469
-rw-r--r--modules/mail/e-mail-shell-view-actions.h271
-rw-r--r--modules/mail/e-mail-shell-view-private.c1548
-rw-r--r--modules/mail/e-mail-shell-view-private.h177
-rw-r--r--modules/mail/e-mail-shell-view.c1114
-rw-r--r--modules/mail/e-mail-shell-view.h66
-rw-r--r--modules/mail/em-account-prefs.c275
-rw-r--r--modules/mail/em-account-prefs.h70
-rw-r--r--modules/mail/em-composer-prefs.c521
-rw-r--r--modules/mail/em-composer-prefs.h83
-rw-r--r--modules/mail/em-mailer-prefs.c1311
-rw-r--r--modules/mail/em-mailer-prefs.h108
-rw-r--r--modules/mail/em-network-prefs.c539
-rw-r--r--modules/mail/em-network-prefs.h104
-rw-r--r--modules/mail/evolution-module-mail.c64
-rw-r--r--modules/mailto-handler/Makefile.am24
-rw-r--r--modules/mailto-handler/evolution-mailto-handler.c286
-rw-r--r--modules/mdn/Makefile.am36
-rw-r--r--modules/mdn/evolution-mdn.c706
-rw-r--r--modules/mdn/evolution-mdn.error.xml9
-rw-r--r--modules/offline-alert/Makefile.am34
-rw-r--r--modules/offline-alert/evolution-offline-alert.c219
-rw-r--r--modules/offline-alert/evolution-offline-alert.error.xml11
-rw-r--r--modules/plugin-lib/Makefile.am26
-rw-r--r--modules/plugin-lib/e-plugin-lib.c276
-rw-r--r--modules/plugin-lib/e-plugin-lib.h92
-rw-r--r--modules/plugin-lib/evolution-module-plugin-lib.c43
-rw-r--r--modules/plugin-manager/Makefile.am24
-rw-r--r--modules/plugin-manager/evolution-plugin-manager.c543
-rw-r--r--modules/prefer-plain/Makefile.am33
-rw-r--r--modules/prefer-plain/e-mail-display-popup-prefer-plain.c433
-rw-r--r--modules/prefer-plain/e-mail-display-popup-prefer-plain.h30
-rw-r--r--modules/prefer-plain/e-mail-parser-prefer-plain.c522
-rw-r--r--modules/prefer-plain/e-mail-parser-prefer-plain.h30
-rw-r--r--modules/prefer-plain/evolution-module-prefer-plain.c75
-rw-r--r--modules/prefer-plain/plugin/Makefile.am31
-rw-r--r--modules/prefer-plain/plugin/config-ui.c190
-rw-r--r--modules/prefer-plain/plugin/org-gnome-prefer-plain.eplug.xml25
-rw-r--r--modules/settings/Makefile.am70
-rw-r--r--modules/settings/e-settings-cal-model.c248
-rw-r--r--modules/settings/e-settings-cal-model.h65
-rw-r--r--modules/settings/e-settings-calendar-item.c104
-rw-r--r--modules/settings/e-settings-calendar-item.h66
-rw-r--r--modules/settings/e-settings-calendar-view.c139
-rw-r--r--modules/settings/e-settings-calendar-view.h66
-rw-r--r--modules/settings/e-settings-client-cache.c137
-rw-r--r--modules/settings/e-settings-client-cache.h66
-rw-r--r--modules/settings/e-settings-comp-editor.c160
-rw-r--r--modules/settings/e-settings-comp-editor.h64
-rw-r--r--modules/settings/e-settings-date-edit.c108
-rw-r--r--modules/settings/e-settings-date-edit.h65
-rw-r--r--modules/settings/e-settings-deprecated.c640
-rw-r--r--modules/settings/e-settings-deprecated.h65
-rw-r--r--modules/settings/e-settings-mail-browser.c93
-rw-r--r--modules/settings/e-settings-mail-browser.h66
-rw-r--r--modules/settings/e-settings-mail-formatter.c145
-rw-r--r--modules/settings/e-settings-mail-formatter.h66
-rw-r--r--modules/settings/e-settings-mail-part-headers.c126
-rw-r--r--modules/settings/e-settings-mail-part-headers.h66
-rw-r--r--modules/settings/e-settings-mail-reader.c137
-rw-r--r--modules/settings/e-settings-mail-reader.h65
-rw-r--r--modules/settings/e-settings-meeting-store.c146
-rw-r--r--modules/settings/e-settings-meeting-store.h65
-rw-r--r--modules/settings/e-settings-meeting-time-selector.c100
-rw-r--r--modules/settings/e-settings-meeting-time-selector.h66
-rw-r--r--modules/settings/e-settings-message-list.c109
-rw-r--r--modules/settings/e-settings-message-list.h66
-rw-r--r--modules/settings/e-settings-name-selector-entry.c122
-rw-r--r--modules/settings/e-settings-name-selector-entry.h66
-rw-r--r--modules/settings/e-settings-spell-entry.c94
-rw-r--r--modules/settings/e-settings-spell-entry.h65
-rw-r--r--modules/settings/e-settings-web-view-gtkhtml.c303
-rw-r--r--modules/settings/e-settings-web-view-gtkhtml.h65
-rw-r--r--modules/settings/e-settings-web-view.c109
-rw-r--r--modules/settings/e-settings-web-view.h64
-rw-r--r--modules/settings/e-settings-weekday-chooser.c95
-rw-r--r--modules/settings/e-settings-weekday-chooser.h66
-rw-r--r--modules/settings/evolution-module-settings.c71
-rw-r--r--modules/spamassassin/Makefile.am26
-rw-r--r--modules/spamassassin/evolution-spamassassin.c611
-rw-r--r--modules/startup-wizard/Makefile.am39
-rw-r--r--modules/startup-wizard/e-mail-config-import-page.c378
-rw-r--r--modules/startup-wizard/e-mail-config-import-page.h87
-rw-r--r--modules/startup-wizard/e-mail-config-import-progress-page.c381
-rw-r--r--modules/startup-wizard/e-mail-config-import-progress-page.h80
-rw-r--r--modules/startup-wizard/e-startup-assistant.c244
-rw-r--r--modules/startup-wizard/e-startup-assistant.h64
-rw-r--r--modules/startup-wizard/evolution-startup-wizard.c330
-rw-r--r--modules/text-highlight/Makefile.am35
-rw-r--r--modules/text-highlight/e-mail-display-popup-text-highlight.c374
-rw-r--r--modules/text-highlight/e-mail-display-popup-text-highlight.h30
-rw-r--r--modules/text-highlight/e-mail-formatter-text-highlight.c388
-rw-r--r--modules/text-highlight/e-mail-formatter-text-highlight.h30
-rw-r--r--modules/text-highlight/e-mail-parser-text-highlight.c112
-rw-r--r--modules/text-highlight/e-mail-parser-text-highlight.h30
-rw-r--r--modules/text-highlight/evolution-module-text-highlight.c54
-rw-r--r--modules/text-highlight/languages.c528
-rw-r--r--modules/text-highlight/languages.h39
-rw-r--r--modules/tnef-attachment/Makefile.am35
-rw-r--r--modules/tnef-attachment/e-mail-parser-tnef-attachment.c1418
-rw-r--r--modules/tnef-attachment/e-mail-parser-tnef-attachment.h30
-rw-r--r--modules/tnef-attachment/evolution-module-tnef-attachment.c51
-rw-r--r--modules/vcard-inline/Makefile.am35
-rw-r--r--modules/vcard-inline/e-mail-formatter-vcard.c230
-rw-r--r--modules/vcard-inline/e-mail-formatter-vcard.h30
-rw-r--r--modules/vcard-inline/e-mail-parser-vcard.c158
-rw-r--r--modules/vcard-inline/e-mail-parser-vcard.h30
-rw-r--r--modules/vcard-inline/e-mail-part-vcard.c353
-rw-r--r--modules/vcard-inline/e-mail-part-vcard.h82
-rw-r--r--modules/vcard-inline/evolution-module-vcard-inline.c53
-rw-r--r--modules/web-inspector/Makefile.am23
-rw-r--r--modules/web-inspector/evolution-web-inspector.c165
-rw-r--r--my-evolution/.cvsignore13
-rw-r--r--my-evolution/ChangeLog1845
-rw-r--r--my-evolution/GNOME_Evolution_Summary.oaf.in.in73
-rwxr-xr-xmy-evolution/Location-translation-script8
-rw-r--r--my-evolution/Locations3024
-rw-r--r--my-evolution/Locations.h2536
-rw-r--r--my-evolution/Makefile.am130
-rw-r--r--my-evolution/check-filled.xpm21
-rw-r--r--my-evolution/check-none.xpm20
-rw-r--r--my-evolution/component-factory.c178
-rw-r--r--my-evolution/component-factory.h28
-rw-r--r--my-evolution/e-cell-tri.c121
-rw-r--r--my-evolution/e-cell-tri.h44
-rw-r--r--my-evolution/e-summary-calendar.c582
-rw-r--r--my-evolution/e-summary-calendar.h46
-rw-r--r--my-evolution/e-summary-factory.c159
-rw-r--r--my-evolution/e-summary-factory.h34
-rw-r--r--my-evolution/e-summary-mail.c922
-rw-r--r--my-evolution/e-summary-mail.h54
-rw-r--r--my-evolution/e-summary-offline-handler.c292
-rw-r--r--my-evolution/e-summary-offline-handler.h74
-rw-r--r--my-evolution/e-summary-preferences.c1586
-rw-r--r--my-evolution/e-summary-preferences.h39
-rw-r--r--my-evolution/e-summary-rdf.c637
-rw-r--r--my-evolution/e-summary-rdf.h36
-rw-r--r--my-evolution/e-summary-shown.c709
-rw-r--r--my-evolution/e-summary-shown.h80
-rw-r--r--my-evolution/e-summary-table.c441
-rw-r--r--my-evolution/e-summary-table.h74
-rw-r--r--my-evolution/e-summary-tasks.c529
-rw-r--r--my-evolution/e-summary-tasks.h35
-rw-r--r--my-evolution/e-summary-type.h28
-rw-r--r--my-evolution/e-summary-weather.c816
-rw-r--r--my-evolution/e-summary-weather.h153
-rw-r--r--my-evolution/e-summary.c939
-rw-r--r--my-evolution/e-summary.h178
-rw-r--r--my-evolution/main.c85
-rw-r--r--my-evolution/metar.c1016
-rw-r--r--my-evolution/metar.h48
-rw-r--r--my-evolution/my-evolution-html.h68
-rw-r--r--my-evolution/my-evolution.glade648
-rw-r--r--my-evolution/weather.h54
-rw-r--r--notes/.cvsignore4
-rw-r--r--notes/GNOME_Evolution_Notes.oaf.in54
-rw-r--r--notes/Makefile.am34
-rw-r--r--notes/component-factory.c155
-rw-r--r--notes/component-factory.h7
-rw-r--r--notes/e-bevel-button-util.c189
-rw-r--r--notes/e-bevel-button-util.h12
-rw-r--r--notes/e-bevel-button.c175
-rw-r--r--notes/e-bevel-button.h37
-rw-r--r--notes/e-note.c382
-rw-r--r--notes/e-note.h37
-rw-r--r--notes/main.c52
-rw-r--r--notes/test-notes.c34
-rw-r--r--omf-install/.cvsignore3
-rw-r--r--omf-install/Makefile.am17
-rw-r--r--plugin.mk11
-rw-r--r--plugins/Makefile.am4
-rw-r--r--plugins/attachment-reminder/Makefile.am44
-rw-r--r--plugins/attachment-reminder/attachment-reminder.c653
-rw-r--r--plugins/attachment-reminder/org-gnome-attachment-reminder.error.xml11
-rw-r--r--plugins/attachment-reminder/org-gnome-evolution-attachment-reminder.eplug.xml27
-rw-r--r--plugins/bbdb/Makefile.am41
-rw-r--r--plugins/bbdb/bbdb.c735
-rw-r--r--plugins/bbdb/bbdb.h52
-rw-r--r--plugins/bbdb/gaimbuddies.c616
-rw-r--r--plugins/bbdb/org-gnome-evolution-bbdb.eplug.xml28
-rw-r--r--plugins/bbdb/test-evobuddy.c35
-rw-r--r--plugins/dbx-import/Makefile.am41
-rw-r--r--plugins/dbx-import/dbx-importer.c840
-rw-r--r--plugins/dbx-import/org-gnome-dbx-import.eplug.xml22
-rw-r--r--plugins/email-custom-header/Makefile.am44
-rw-r--r--plugins/email-custom-header/email-custom-header.c959
-rw-r--r--plugins/email-custom-header/email-custom-header.h90
-rw-r--r--plugins/email-custom-header/org-gnome-email-custom-header.eplug.xml29
-rw-r--r--plugins/email-custom-header/org-gnome-email-custom-header.ui95
-rw-r--r--plugins/external-editor/Makefile.am58
-rw-r--r--plugins/external-editor/external-editor.c502
-rw-r--r--plugins/external-editor/org-gnome-external-editor.eplug.xml25
-rw-r--r--plugins/external-editor/org-gnome-external-editor.error.xml19
-rw-r--r--plugins/face/Makefile.am43
-rw-r--r--plugins/face/face.c484
-rw-r--r--plugins/face/org-gnome-face.eplug.xml24
-rw-r--r--plugins/face/org-gnome-face.error.xml20
-rw-r--r--plugins/image-inline/Makefile.am29
-rw-r--r--plugins/image-inline/image-inline.c476
-rw-r--r--plugins/image-inline/org-gnome-image-inline.eplug.xml126
-rw-r--r--plugins/mail-notification/Makefile.am45
-rw-r--r--plugins/mail-notification/mail-notification.c900
-rw-r--r--plugins/mail-notification/org-gnome-mail-notification.eplug.xml25
-rw-r--r--plugins/mail-to-task/Makefile.am35
-rw-r--r--plugins/mail-to-task/mail-to-task.c1391
-rw-r--r--plugins/mail-to-task/org-gnome-mail-to-task.eplug.xml71
-rw-r--r--plugins/mailing-list-actions/Makefile.am41
-rw-r--r--plugins/mailing-list-actions/mailing-list-actions.c475
-rw-r--r--plugins/mailing-list-actions/org-gnome-mailing-list-actions.eplug.xml54
-rw-r--r--plugins/mailing-list-actions/org-gnome-mailing-list-actions.error.xml38
-rw-r--r--plugins/pst-import/Makefile.am43
-rw-r--r--plugins/pst-import/org-gnome-pst-import.eplug.xml23
-rw-r--r--plugins/pst-import/pst-importer.c2293
-rw-r--r--plugins/publish-calendar/Makefile.am50
-rw-r--r--plugins/publish-calendar/org-gnome-publish-calendar.eplug.xml31
-rw-r--r--plugins/publish-calendar/publish-calendar.c1156
-rw-r--r--plugins/publish-calendar/publish-calendar.ui852
-rw-r--r--plugins/publish-calendar/publish-format-fb.c169
-rw-r--r--plugins/publish-calendar/publish-format-fb.h33
-rw-r--r--plugins/publish-calendar/publish-format-ical.c152
-rw-r--r--plugins/publish-calendar/publish-format-ical.h33
-rw-r--r--plugins/publish-calendar/publish-location.c275
-rw-r--r--plugins/publish-calendar/publish-location.h84
-rw-r--r--plugins/publish-calendar/url-editor-dialog.c623
-rw-r--r--plugins/publish-calendar/url-editor-dialog.h112
-rw-r--r--plugins/save-calendar/Makefile.am34
-rw-r--r--plugins/save-calendar/csv-format.c638
-rw-r--r--plugins/save-calendar/format-handler.h49
-rw-r--r--plugins/save-calendar/ical-format.c178
-rw-r--r--plugins/save-calendar/org-gnome-save-calendar.eplug.xml37
-rw-r--r--plugins/save-calendar/rdf-format.c392
-rw-r--r--plugins/save-calendar/save-calendar.c420
-rw-r--r--plugins/templates/Makefile.am36
-rw-r--r--plugins/templates/org-gnome-templates.eplug.xml33
-rw-r--r--plugins/templates/templates.c1473
-rw-r--r--po/.cvsignore11
-rw-r--r--po/ChangeLog3998
-rw-r--r--po/LINGUAS92
-rw-r--r--po/POTFILES.in806
-rw-r--r--po/POTFILES.skip48
-rw-r--r--po/af.po23350
-rw-r--r--po/am.po20342
-rw-r--r--po/an.po21403
-rw-r--r--po/ar.po23558
-rw-r--r--po/as.po28648
-rw-r--r--po/ast.po20893
-rw-r--r--po/az.po37475
-rw-r--r--po/be.po21182
-rw-r--r--po/be@latin.po24459
-rw-r--r--po/bg.po40424
-rw-r--r--po/bn.po26442
-rw-r--r--po/bn_IN.po24851
-rw-r--r--po/br.po22232
-rw-r--r--po/bs.po25078
-rw-r--r--po/ca.po48915
-rw-r--r--po/ca@valencia.po31189
-rw-r--r--po/cs.po42190
-rw-r--r--po/cy.po23927
-rw-r--r--po/da.po45018
-rw-r--r--po/de.po40834
-rw-r--r--po/dz.po23429
-rw-r--r--po/el.po45420
-rw-r--r--po/en@shaw.po21375
-rw-r--r--po/en_AU.po30255
-rw-r--r--po/en_CA.po21070
-rw-r--r--po/en_GB.po43983
-rw-r--r--po/eo.po21963
-rw-r--r--po/es.po45515
-rw-r--r--po/et.po34597
-rw-r--r--po/eu.po40986
-rw-r--r--po/fa.po29875
-rw-r--r--po/fi.po40855
-rw-r--r--po/flu-danish114
-rw-r--r--po/fr.po39940
-rw-r--r--[-rwxr-xr-x]po/ga.po38007
-rw-r--r--po/gl.po44114
-rw-r--r--po/gu.po23035
-rw-r--r--po/he.po26520
-rw-r--r--po/hi.po28119
-rw-r--r--po/hr.po23954
-rw-r--r--po/hu.po42287
-rw-r--r--po/id.po21017
-rw-r--r--po/is.po19750
-rw-r--r--po/it.po42652
-rw-r--r--po/ja.po40878
-rw-r--r--po/ka.po25168
-rw-r--r--po/kn.po27407
-rw-r--r--po/ko.po40338
-rw-r--r--po/ku.po19840
-rw-r--r--po/lt.po41954
-rw-r--r--po/lv.po42477
-rw-r--r--po/mai.po23114
-rw-r--r--po/mk.po22727
-rw-r--r--po/ml.po23492
-rw-r--r--po/mn.po20276
-rw-r--r--po/mr.po24132
-rw-r--r--po/ms.po20718
-rw-r--r--po/nb.po20911
-rw-r--r--po/nds.po21314
-rw-r--r--po/ne.po25203
-rw-r--r--po/nl.po45900
-rw-r--r--po/nn.po38881
-rw-r--r--po/no.po31906
-rw-r--r--po/oc.po23135
-rw-r--r--po/or.po24646
-rw-r--r--po/pa.po29062
-rw-r--r--po/pl.po39758
-rw-r--r--po/ps.po22868
-rw-r--r--po/pt.po46797
-rw-r--r--po/pt_BR.po38875
-rw-r--r--po/ro.po44129
-rw-r--r--po/ru.po40614
-rw-r--r--po/rw.po22995
-rw-r--r--po/si.po21658
-rw-r--r--po/sk.po39533
-rw-r--r--po/sl.po42853
-rw-r--r--po/sq.po24241
-rw-r--r--po/sr.po21429
-rw-r--r--po/sr@latin.po21429
-rw-r--r--po/sv.po47156
-rw-r--r--po/ta.po24159
-rw-r--r--po/te.po27143
-rw-r--r--po/th.po27168
-rw-r--r--po/tr.po43818
-rw-r--r--po/ug.po22430
-rw-r--r--po/uk.po41453
-rw-r--r--po/vi.po42252
-rw-r--r--po/wa.po20298
-rw-r--r--po/xh.po20597
-rw-r--r--po/zh_CN.po63170
-rw-r--r--po/zh_HK.po20639
-rw-r--r--po/zh_TW.po46714
-rw-r--r--shell/.cvsignore21
-rw-r--r--shell/ChangeLog12225
-rw-r--r--shell/Evolution-Activity.idl106
-rw-r--r--shell/Evolution-ConfigControl.idl34
-rw-r--r--shell/Evolution-Offline.idl78
-rw-r--r--shell/Evolution-Session.idl41
-rw-r--r--shell/Evolution-Shell.idl138
-rw-r--r--shell/Evolution-ShellComponent.idl182
-rw-r--r--shell/Evolution-ShellComponentDnd.idl98
-rw-r--r--shell/Evolution-ShellView.idl25
-rw-r--r--shell/Evolution-Shortcuts.idl55
-rw-r--r--shell/Evolution-Storage.idl175
-rw-r--r--shell/Evolution-StorageSetView.idl37
-rw-r--r--shell/Evolution-Wizard.idl37
-rw-r--r--shell/Evolution-common.idl36
-rw-r--r--shell/Evolution.idl26
-rw-r--r--shell/GNOME_Evolution_Shell.oaf.in51
-rw-r--r--shell/GNOME_Evolution_TestComponent.oaf41
-rw-r--r--shell/Makefile.am414
-rw-r--r--shell/README14
-rw-r--r--shell/check-empty.xpm21
-rw-r--r--shell/check-filled.xpm21
-rw-r--r--shell/check-missing.xpm20
-rw-r--r--shell/e-activity-handler.c581
-rw-r--r--shell/e-activity-handler.h72
-rw-r--r--shell/e-component-info.c295
-rw-r--r--shell/e-component-info.h66
-rw-r--r--shell/e-component-registry.c505
-rw-r--r--shell/e-component-registry.h80
-rw-r--r--shell/e-convert-local-mail.c324
-rw-r--r--shell/e-corba-config-page.c249
-rw-r--r--shell/e-corba-config-page.h68
-rw-r--r--shell/e-corba-shortcuts.c333
-rw-r--r--shell/e-corba-shortcuts.h66
-rw-r--r--shell/e-corba-storage-registry.c531
-rw-r--r--shell/e-corba-storage-registry.h68
-rw-r--r--shell/e-corba-storage.c839
-rw-r--r--shell/e-corba-storage.h89
-rw-r--r--shell/e-folder-dnd-bridge.c478
-rw-r--r--shell/e-folder-dnd-bridge.h55
-rw-r--r--shell/e-folder-list.c668
-rw-r--r--shell/e-folder-list.h112
-rw-r--r--shell/e-folder-tree.c460
-rw-r--r--shell/e-folder-tree.h60
-rw-r--r--shell/e-folder-type-registry.c561
-rw-r--r--shell/e-folder-type-registry.h107
-rw-r--r--shell/e-folder.c530
-rw-r--r--shell/e-folder.h106
-rw-r--r--shell/e-gray-bar.c107
-rw-r--r--shell/e-gray-bar.h60
-rw-r--r--shell/e-history.c261
-rw-r--r--shell/e-history.h83
-rw-r--r--shell/e-icon-factory.c162
-rw-r--r--shell/e-icon-factory.h33
-rw-r--r--shell/e-local-folder.c557
-rw-r--r--shell/e-local-folder.h84
-rw-r--r--shell/e-local-storage.c1184
-rw-r--r--shell/e-local-storage.h67
-rw-r--r--shell/e-migrate-base-dirs.c653
-rw-r--r--shell/e-setup.c458
-rw-r--r--shell/e-setup.h34
-rw-r--r--shell/e-shell-about-box.c421
-rw-r--r--shell/e-shell-about-box.h63
-rw-r--r--shell/e-shell-backend.c704
-rw-r--r--shell/e-shell-backend.h145
-rw-r--r--shell/e-shell-common.h29
-rw-r--r--shell/e-shell-config-autocompletion.c125
-rw-r--r--shell/e-shell-config-autocompletion.h34
-rw-r--r--shell/e-shell-config-default-folders.c189
-rw-r--r--shell/e-shell-config-default-folders.h34
-rw-r--r--shell/e-shell-config-folder-settings.c83
-rw-r--r--shell/e-shell-config-folder-settings.h32
-rw-r--r--shell/e-shell-config-offline.c209
-rw-r--r--shell/e-shell-config-offline.h33
-rw-r--r--shell/e-shell-config.c69
-rw-r--r--shell/e-shell-config.h30
-rw-r--r--shell/e-shell-constants.h50
-rw-r--r--shell/e-shell-content.c805
-rw-r--r--shell/e-shell-content.h93
-rw-r--r--shell/e-shell-corba-icon-utils.c208
-rw-r--r--shell/e-shell-corba-icon-utils.h40
-rw-r--r--shell/e-shell-folder-commands.c652
-rw-r--r--shell/e-shell-folder-commands.h42
-rw-r--r--shell/e-shell-folder-creation-dialog.c542
-rw-r--r--shell/e-shell-folder-creation-dialog.h49
-rw-r--r--shell/e-shell-folder-selection-dialog.c571
-rw-r--r--shell/e-shell-folder-selection-dialog.h84
-rw-r--r--shell/e-shell-folder-title-bar.c792
-rw-r--r--shell/e-shell-folder-title-bar.h84
-rw-r--r--shell/e-shell-importer.c1289
-rw-r--r--shell/e-shell-importer.h32
-rw-r--r--shell/e-shell-migrate.c255
-rw-r--r--shell/e-shell-migrate.h37
-rw-r--r--shell/e-shell-offline-handler.c847
-rw-r--r--shell/e-shell-offline-handler.h81
-rw-r--r--shell/e-shell-offline-sync.c452
-rw-r--r--shell/e-shell-offline-sync.h33
-rw-r--r--shell/e-shell-searchbar.c1584
-rw-r--r--shell/e-shell-searchbar.h112
-rw-r--r--shell/e-shell-settings-dialog.c372
-rw-r--r--shell/e-shell-settings-dialog.h65
-rw-r--r--shell/e-shell-shared-folder-picker-dialog.c510
-rw-r--r--shell/e-shell-shared-folder-picker-dialog.h33
-rw-r--r--shell/e-shell-sidebar.c702
-rw-r--r--shell/e-shell-sidebar.h93
-rw-r--r--shell/e-shell-startup-wizard.c919
-rw-r--r--shell/e-shell-startup-wizard.h30
-rw-r--r--shell/e-shell-switcher.c794
-rw-r--r--shell/e-shell-switcher.h87
-rw-r--r--shell/e-shell-taskbar.c513
-rw-r--r--shell/e-shell-taskbar.h83
-rw-r--r--shell/e-shell-user-creatable-items-handler.c775
-rw-r--r--shell/e-shell-user-creatable-items-handler.h74
-rw-r--r--shell/e-shell-utils.c326
-rw-r--r--shell/e-shell-utils.h48
-rw-r--r--shell/e-shell-view-menu.c886
-rw-r--r--shell/e-shell-view-menu.h32
-rw-r--r--shell/e-shell-view.c3993
-rw-r--r--shell/e-shell-view.h329
-rw-r--r--shell/e-shell-window-actions.c1849
-rw-r--r--shell/e-shell-window-actions.h129
-rw-r--r--shell/e-shell-window-private.c583
-rw-r--r--shell/e-shell-window-private.h123
-rw-r--r--shell/e-shell-window.c1681
-rw-r--r--shell/e-shell-window.h154
-rw-r--r--shell/e-shell.c3241
-rw-r--r--shell/e-shell.h288
-rw-r--r--shell/e-shortcuts-view-model.c354
-rw-r--r--shell/e-shortcuts-view-model.h66
-rw-r--r--shell/e-shortcuts-view.c773
-rw-r--r--shell/e-shortcuts-view.h74
-rw-r--r--shell/e-shortcuts.c1275
-rw-r--r--shell/e-shortcuts.h167
-rw-r--r--shell/e-splash.c429
-rw-r--r--shell/e-splash.h71
-rw-r--r--shell/e-storage-set-view-checkboxes.etstate5
-rw-r--r--shell/e-storage-set-view-no-checkboxes.etstate4
-rw-r--r--shell/e-storage-set-view.c2454
-rw-r--r--shell/e-storage-set-view.etspec8
-rw-r--r--shell/e-storage-set-view.h122
-rw-r--r--shell/e-storage-set.c866
-rw-r--r--shell/e-storage-set.h123
-rw-r--r--shell/e-storage.c794
-rw-r--r--shell/e-storage.h196
-rw-r--r--shell/e-task-bar.c204
-rw-r--r--shell/e-task-bar.h71
-rw-r--r--shell/e-task-widget.c231
-rw-r--r--shell/e-task-widget.h78
-rw-r--r--shell/e-uri-schema-registry.c181
-rw-r--r--shell/e-uri-schema-registry.h70
-rw-r--r--shell/evo-version.h.in30
-rw-r--r--shell/evolution-activity-client.c426
-rw-r--r--shell/evolution-activity-client.h91
-rw-r--r--shell/evolution-config-control.c222
-rw-r--r--shell/evolution-config-control.h70
-rw-r--r--shell/evolution-folder-selector-button.c421
-rw-r--r--shell/evolution-folder-selector-button.h81
-rw-r--r--shell/evolution-icon.rc4
-rw-r--r--shell/evolution-mail.icobin0 -> 19622 bytes-rw-r--r--shell/evolution-memos.icobin0 -> 19622 bytes-rw-r--r--shell/evolution-nognome.in9
-rw-r--r--shell/evolution-session.c213
-rw-r--r--shell/evolution-session.h67
-rw-r--r--shell/evolution-shell-client.c649
-rw-r--r--shell/evolution-shell-client.h94
-rw-r--r--shell/evolution-shell-component-client.c919
-rw-r--r--shell/evolution-shell-component-client.h139
-rw-r--r--shell/evolution-shell-component-dnd.c446
-rw-r--r--shell/evolution-shell-component-dnd.h130
-rw-r--r--shell/evolution-shell-component-utils.c166
-rw-r--r--shell/evolution-shell-component-utils.h54
-rw-r--r--shell/evolution-shell-component.c1188
-rw-r--r--shell/evolution-shell-component.h214
-rw-r--r--shell/evolution-shell-view.c315
-rw-r--r--shell/evolution-shell-view.h75
-rw-r--r--shell/evolution-storage-listener.c379
-rw-r--r--shell/evolution-storage-listener.h94
-rw-r--r--shell/evolution-storage-set-view-factory.c74
-rw-r--r--shell/evolution-storage-set-view-factory.h30
-rw-r--r--shell/evolution-storage-set-view-listener.c284
-rw-r--r--shell/evolution-storage-set-view-listener.h81
-rw-r--r--shell/evolution-storage-set-view.c521
-rw-r--r--shell/evolution-storage-set-view.h69
-rw-r--r--shell/evolution-storage.c1403
-rw-r--r--shell/evolution-storage.h179
-rw-r--r--shell/evolution-tasks.icobin0 -> 19622 bytes-rw-r--r--shell/evolution-test-component.c659
-rw-r--r--shell/evolution-wizard.c394
-rw-r--r--shell/evolution-wizard.h86
-rw-r--r--shell/evolution.icobin0 -> 19622 bytes-rw-r--r--shell/glade/.cvsignore4
-rw-r--r--shell/glade/Makefile.am11
-rw-r--r--shell/glade/e-active-connection-dialog.glade179
-rw-r--r--shell/glade/e-folder-list.glade120
-rw-r--r--shell/glade/e-shell-config-default-folders.glade235
-rw-r--r--shell/glade/e-shell-folder-creation-dialog.glade169
-rw-r--r--shell/glade/e-shell-shared-folder-picker-dialog.glade256
-rw-r--r--shell/glade/evolution-startup-wizard.glade255
-rw-r--r--shell/importer/.cvsignore10
-rw-r--r--shell/importer/GNOME_Evolution_Importer.idl95
-rw-r--r--shell/importer/Makefile.am59
-rw-r--r--shell/importer/evolution-importer-client.c248
-rw-r--r--shell/importer/evolution-importer-client.h74
-rw-r--r--shell/importer/evolution-importer-listener.c224
-rw-r--r--shell/importer/evolution-importer-listener.h71
-rw-r--r--shell/importer/evolution-importer.c229
-rw-r--r--shell/importer/evolution-importer.h95
-rw-r--r--shell/importer/evolution-intelligent-importer.c197
-rw-r--r--shell/importer/evolution-intelligent-importer.h74
-rw-r--r--shell/importer/import.glade145
-rw-r--r--shell/importer/intelligent.c486
-rw-r--r--shell/importer/intelligent.h28
-rw-r--r--shell/killev.c174
-rw-r--r--shell/main.c1007
-rw-r--r--shell/shell.error.xml29
-rw-r--r--smime/Makefile.am3
-rw-r--r--smime/gui/Makefile.am54
-rw-r--r--smime/gui/ca-trust-dialog.c154
-rw-r--r--smime/gui/ca-trust-dialog.h35
-rw-r--r--smime/gui/cert-trust-dialog.c162
-rw-r--r--smime/gui/cert-trust-dialog.h35
-rw-r--r--smime/gui/certificate-manager.c1139
-rw-r--r--smime/gui/certificate-manager.h73
-rw-r--r--smime/gui/certificate-viewer.c688
-rw-r--r--smime/gui/certificate-viewer.h32
-rw-r--r--smime/gui/component.c141
-rw-r--r--smime/gui/component.h28
-rw-r--r--smime/gui/e-cert-selector.c277
-rw-r--r--smime/gui/e-cert-selector.h76
-rw-r--r--smime/gui/smime-ui.ui799
-rw-r--r--smime/lib/Makefile.am41
-rw-r--r--smime/lib/e-asn1-object.c964
-rw-r--r--smime/lib/e-asn1-object.h109
-rw-r--r--smime/lib/e-cert-db.c1521
-rw-r--r--smime/lib/e-cert-db.h148
-rw-r--r--smime/lib/e-cert-trust.c471
-rw-r--r--smime/lib/e-cert-trust.h87
-rw-r--r--smime/lib/e-cert.c542
-rw-r--r--smime/lib/e-cert.h106
-rw-r--r--smime/lib/e-pkcs12.c371
-rw-r--r--smime/lib/e-pkcs12.h68
-rw-r--r--smime/tests/Makefile.am20
-rw-r--r--smime/tests/import-cert.c57
-rw-r--r--sounds/.cvsignore2
-rw-r--r--sounds/Makefile.am4
-rw-r--r--tests/.cvsignore24
-rw-r--r--tests/Makefile.am70
-rw-r--r--tests/test-movemail.c164
-rw-r--r--tests/test-url.c37
-rw-r--r--tests/test1.c136
-rw-r--r--tests/test10.c127
-rw-r--r--tests/test11.c136
-rw-r--r--tests/test12.c56
-rw-r--r--tests/test13.c123
-rw-r--r--tests/test14.c177
-rw-r--r--tests/test2.c48
-rw-r--r--tests/test3.c29
-rw-r--r--tests/test4.c65
-rw-r--r--tests/test5.c59
-rw-r--r--tests/test6.c49
-rw-r--r--tests/test8.c75
-rw-r--r--tests/test9.c80
-rw-r--r--tests/ui-tests/.cvsignore8
-rw-r--r--tests/ui-tests/Makefile.am39
-rw-r--r--tests/ui-tests/filter.c30
-rw-r--r--tests/ui-tests/filterdescription.xml99
-rw-r--r--tests/ui-tests/mail-atchmt-image.msg67
-rw-r--r--tests/ui-tests/mail-atchmt-postscript.msg8069
-rw-r--r--tests/ui-tests/mail-atchmt-svg.msg418
-rw-r--r--tests/ui-tests/message-browser.c819
-rw-r--r--tests/ui-tests/saveoptions.xml37
-rw-r--r--tests/ui-tests/store_listing.c424
-rw-r--r--tests/ui-tests/store_listing.glade489
-rw-r--r--tests/ui-tests/test-multipart-alt.msg17738
-rw-r--r--tests/ui-tests/test-multipart-mixed.msg377
-rw-r--r--tools/.cvsignore8
-rw-r--r--tools/Makefile.am49
-rwxr-xr-xtools/csv2vcard236
-rw-r--r--tools/evolution-addressbook-abuse.c139
-rw-r--r--tools/evolution-addressbook-clean.in24
-rw-r--r--tools/evolution-addressbook-export.c67
-rw-r--r--tools/evolution-addressbook-import.c93
-rwxr-xr-xtools/evolution-move-tasks135
-rwxr-xr-xtools/killev142
-rwxr-xr-xtools/verify-evolution-install.sh640
-rw-r--r--ui/.cvsignore8
-rw-r--r--ui/ChangeLog1793
-rw-r--r--ui/Makefile.am32
-rw-r--r--ui/evolution-addressbook.h25
-rw-r--r--ui/evolution-addressbook.xml150
-rw-r--r--ui/evolution-calendar.xml91
-rw-r--r--ui/evolution-calendars.ui162
-rw-r--r--ui/evolution-comp-editor.xml85
-rw-r--r--ui/evolution-contact-editor.xml99
-rw-r--r--ui/evolution-contact-list-editor.xml65
-rw-r--r--ui/evolution-contacts.ui100
-rw-r--r--ui/evolution-event-editor.xml53
-rw-r--r--ui/evolution-executive-summary.xml12
-rw-r--r--ui/evolution-mail-global.xml121
-rw-r--r--ui/evolution-mail-list.xml122
-rw-r--r--ui/evolution-mail-message.xml400
-rw-r--r--ui/evolution-mail-messagedisplay.xml56
-rw-r--r--ui/evolution-mail-reader.ui168
-rw-r--r--ui/evolution-mail.ui149
-rw-r--r--ui/evolution-memos.ui79
-rw-r--r--ui/evolution-message-composer.h53
-rw-r--r--ui/evolution-message-composer.xml153
-rw-r--r--ui/evolution-shell.ui88
-rw-r--r--ui/evolution-signature-editor.xml77
-rw-r--r--ui/evolution-subscribe.xml57
-rw-r--r--ui/evolution-task-editor.xml41
-rw-r--r--ui/evolution-tasks.ui92
-rw-r--r--ui/evolution-tasks.xml66
-rw-r--r--ui/evolution.xml297
-rw-r--r--ui/my-evolution.xml29
-rw-r--r--views/.cvsignore2
-rw-r--r--views/ChangeLog96
-rw-r--r--views/Makefile.am4
-rw-r--r--views/addressbook/.cvsignore2
-rw-r--r--views/addressbook/Address_Cards.galview2
-rw-r--r--views/addressbook/By_Company.galview14
-rw-r--r--views/addressbook/Makefile.am8
-rw-r--r--views/addressbook/Phone_List.galview14
-rw-r--r--views/addressbook/galview.xml2
-rw-r--r--views/calendar/.cvsignore2
-rw-r--r--views/calendar/List_View.galview7
-rw-r--r--views/calendar/Makefile.am8
-rw-r--r--views/calendar/galview.xml2
-rw-r--r--views/mail/.cvsignore2
-rw-r--r--views/mail/Makefile.am8
-rw-r--r--views/mail/Wide_View_Normal.galview7
-rw-r--r--views/mail/Wide_View_Sent.galview7
-rw-r--r--views/mail/galview.xml14
-rw-r--r--views/memos/Makefile.am5
-rw-r--r--views/memos/Memos.galview7
-rw-r--r--views/memos/galview.xml4
-rw-r--r--views/tasks/.cvsignore2
-rw-r--r--views/tasks/Makefile.am8
-rw-r--r--views/tasks/Tasks.galview6
-rw-r--r--views/tasks/With_Category.galview8
-rw-r--r--views/tasks/With_DueDate.galview8
-rw-r--r--views/tasks/With_Status.galview8
-rw-r--r--views/tasks/galview.xml3
-rw-r--r--widgets/.cvsignore9
-rw-r--r--widgets/ChangeLog360
-rw-r--r--widgets/LICENSE1
-rw-r--r--widgets/Makefile.am5
-rw-r--r--widgets/e-timezone-dialog/.cvsignore7
-rw-r--r--widgets/e-timezone-dialog/Makefile.am20
-rw-r--r--widgets/e-timezone-dialog/e-timezone-dialog.c719
-rw-r--r--widgets/e-timezone-dialog/e-timezone-dialog.glade264
-rw-r--r--widgets/e-timezone-dialog/e-timezone-dialog.h90
-rw-r--r--widgets/menus/.cvsignore8
-rw-r--r--widgets/menus/Makefile.am11
-rw-r--r--widgets/menus/gal-define-views-dialog.c354
-rw-r--r--widgets/menus/gal-define-views-dialog.h78
-rw-r--r--widgets/menus/gal-define-views-model.c335
-rw-r--r--widgets/menus/gal-define-views-model.h72
-rw-r--r--widgets/menus/gal-define-views.glade311
-rw-r--r--widgets/menus/gal-view-collection.c838
-rw-r--r--widgets/menus/gal-view-collection.h152
-rw-r--r--widgets/menus/gal-view-etable.c321
-rw-r--r--widgets/menus/gal-view-etable.h78
-rw-r--r--widgets/menus/gal-view-factory-etable.c143
-rw-r--r--widgets/menus/gal-view-factory-etable.h61
-rw-r--r--widgets/menus/gal-view-factory.c126
-rw-r--r--widgets/menus/gal-view-factory.h78
-rw-r--r--widgets/menus/gal-view-instance-save-as-dialog.c312
-rw-r--r--widgets/menus/gal-view-instance-save-as-dialog.glade269
-rw-r--r--widgets/menus/gal-view-instance-save-as-dialog.h89
-rw-r--r--widgets/menus/gal-view-instance.c620
-rw-r--r--widgets/menus/gal-view-instance.h119
-rw-r--r--widgets/menus/gal-view-menus.c532
-rw-r--r--widgets/menus/gal-view-menus.h43
-rw-r--r--widgets/menus/gal-view-new-dialog.c224
-rw-r--r--widgets/menus/gal-view-new-dialog.glade220
-rw-r--r--widgets/menus/gal-view-new-dialog.h79
-rw-r--r--widgets/menus/gal-view.c225
-rw-r--r--widgets/menus/gal-view.h96
-rw-r--r--widgets/misc/.cvsignore12
-rw-r--r--widgets/misc/ChangeLog1357
-rw-r--r--widgets/misc/Makefile.am118
-rw-r--r--widgets/misc/e-bonobo-widget.c194
-rw-r--r--widgets/misc/e-bonobo-widget.h74
-rw-r--r--widgets/misc/e-calendar-item.c2961
-rw-r--r--widgets/misc/e-calendar-item.h338
-rw-r--r--widgets/misc/e-calendar.c603
-rw-r--r--widgets/misc/e-calendar.h101
-rw-r--r--widgets/misc/e-canvas-background.c467
-rw-r--r--widgets/misc/e-canvas-background.h82
-rw-r--r--widgets/misc/e-canvas-utils.c172
-rw-r--r--widgets/misc/e-canvas-utils.h57
-rw-r--r--widgets/misc/e-canvas-vbox.c376
-rw-r--r--widgets/misc/e-canvas-vbox.h93
-rw-r--r--widgets/misc/e-canvas.c1160
-rw-r--r--widgets/misc/e-canvas.h157
-rw-r--r--widgets/misc/e-cell-date-edit.c969
-rw-r--r--widgets/misc/e-cell-date-edit.h106
-rw-r--r--widgets/misc/e-cell-percent.c158
-rw-r--r--widgets/misc/e-cell-percent.h55
-rw-r--r--widgets/misc/e-charset-picker.c470
-rw-r--r--widgets/misc/e-charset-picker.h48
-rw-r--r--widgets/misc/e-clipped-label.c386
-rw-r--r--widgets/misc/e-clipped-label.h89
-rw-r--r--widgets/misc/e-colors.c99
-rw-r--r--widgets/misc/e-colors.h44
-rw-r--r--widgets/misc/e-combo-button.c574
-rw-r--r--widgets/misc/e-combo-button.h80
-rw-r--r--widgets/misc/e-config-page.c154
-rw-r--r--widgets/misc/e-config-page.h76
-rw-r--r--widgets/misc/e-cursors.c153
-rw-r--r--widgets/misc/e-cursors.h68
-rw-r--r--widgets/misc/e-dateedit.c1937
-rw-r--r--widgets/misc/e-dateedit.h184
-rw-r--r--widgets/misc/e-dropdown-button.c250
-rw-r--r--widgets/misc/e-dropdown-button.h71
-rw-r--r--widgets/misc/e-filter-bar.c704
-rw-r--r--widgets/misc/e-filter-bar.h117
-rw-r--r--widgets/misc/e-gui-utils.c262
-rw-r--r--widgets/misc/e-gui-utils.h62
-rw-r--r--widgets/misc/e-hsv-utils.c178
-rw-r--r--widgets/misc/e-hsv-utils.h53
-rw-r--r--widgets/misc/e-map.c1803
-rw-r--r--widgets/misc/e-map.h139
-rw-r--r--widgets/misc/e-messagebox.c356
-rw-r--r--widgets/misc/e-messagebox.h85
-rw-r--r--widgets/misc/e-multi-config-dialog.c515
-rw-r--r--widgets/misc/e-multi-config-dialog.h78
-rw-r--r--widgets/misc/e-popup-menu.c248
-rw-r--r--widgets/misc/e-popup-menu.h120
-rw-r--r--widgets/misc/e-printable.c221
-rw-r--r--widgets/misc/e-printable.h91
-rw-r--r--widgets/misc/e-reflow-model.c303
-rw-r--r--widgets/misc/e-reflow-model.h105
-rw-r--r--widgets/misc/e-reflow.c1395
-rw-r--r--widgets/misc/e-reflow.h142
-rw-r--r--widgets/misc/e-search-bar.c1208
-rw-r--r--widgets/misc/e-search-bar.h156
-rw-r--r--widgets/misc/e-selection-model-array.c549
-rw-r--r--widgets/misc/e-selection-model-array.h95
-rw-r--r--widgets/misc/e-selection-model-simple.c117
-rw-r--r--widgets/misc/e-selection-model-simple.h70
-rw-r--r--widgets/misc/e-selection-model.c661
-rw-r--r--widgets/misc/e-selection-model.h169
-rw-r--r--widgets/misc/e-title-bar.c406
-rw-r--r--widgets/misc/e-title-bar.h86
-rw-r--r--widgets/misc/e-unicode.c3161
-rw-r--r--widgets/misc/e-unicode.h135
-rw-r--r--widgets/misc/e-url-entry.c165
-rw-r--r--widgets/misc/e-url-entry.h69
-rw-r--r--widgets/misc/gal-categories.glade197
-rw-r--r--widgets/misc/pixmaps/.cvsignore2
-rw-r--r--widgets/misc/pixmaps/cursor_cross.xpm38
-rw-r--r--widgets/misc/pixmaps/cursor_hand_closed.xpm38
-rw-r--r--widgets/misc/pixmaps/cursor_hand_open.xpm38
-rw-r--r--widgets/misc/pixmaps/cursor_zoom_in.xpm37
-rw-r--r--widgets/misc/pixmaps/cursor_zoom_out.xpm37
-rw-r--r--widgets/misc/test-calendar.c219
-rw-r--r--widgets/misc/test-charset-picker.c18
-rw-r--r--widgets/misc/test-color.c69
-rw-r--r--widgets/misc/test-dateedit.c283
-rw-r--r--widgets/misc/test-dropdown-button.c100
-rw-r--r--widgets/misc/test-multi-config-dialog.c94
-rw-r--r--widgets/misc/test-title-bar.c76
-rw-r--r--widgets/table/.cvsignore13
-rw-r--r--widgets/table/add-col.xpm22
-rw-r--r--widgets/table/check-empty.xpm21
-rw-r--r--widgets/table/check-filled.xpm21
-rw-r--r--widgets/table/clip.pngbin192 -> 0 bytes-rw-r--r--widgets/table/e-cell-checkbox.c67
-rw-r--r--widgets/table/e-cell-checkbox.h51
-rw-r--r--widgets/table/e-cell-combo.c656
-rw-r--r--widgets/table/e-cell-combo.h63
-rw-r--r--widgets/table/e-cell-date.c182
-rw-r--r--widgets/table/e-cell-date.h50
-rw-r--r--widgets/table/e-cell-float.c93
-rw-r--r--widgets/table/e-cell-float.h54
-rw-r--r--widgets/table/e-cell-number.c85
-rw-r--r--widgets/table/e-cell-number.h50
-rw-r--r--widgets/table/e-cell-pixbuf.c394
-rw-r--r--widgets/table/e-cell-pixbuf.h53
-rw-r--r--widgets/table/e-cell-popup.c529
-rw-r--r--widgets/table/e-cell-popup.h97
-rw-r--r--widgets/table/e-cell-progress.c456
-rw-r--r--widgets/table/e-cell-progress.h74
-rw-r--r--widgets/table/e-cell-size.c108
-rw-r--r--widgets/table/e-cell-size.h50
-rw-r--r--widgets/table/e-cell-spin-button.c674
-rw-r--r--widgets/table/e-cell-spin-button.h103
-rw-r--r--widgets/table/e-cell-text.c2696
-rw-r--r--widgets/table/e-cell-text.h108
-rw-r--r--widgets/table/e-cell-toggle.c484
-rw-r--r--widgets/table/e-cell-toggle.h63
-rw-r--r--widgets/table/e-cell-tree.c767
-rw-r--r--widgets/table/e-cell-tree.h76
-rw-r--r--widgets/table/e-cell-vbox.c489
-rw-r--r--widgets/table/e-cell-vbox.h68
-rw-r--r--widgets/table/e-cell.c499
-rw-r--r--widgets/table/e-cell.h222
-rw-r--r--widgets/table/e-table-click-to-add.c552
-rw-r--r--widgets/table/e-table-click-to-add.h78
-rw-r--r--widgets/table/e-table-col-dnd.h39
-rw-r--r--widgets/table/e-table-col.c238
-rw-r--r--widgets/table/e-table-col.h107
-rw-r--r--widgets/table/e-table-column-specification.c148
-rw-r--r--widgets/table/e-table-column-specification.h77
-rw-r--r--widgets/table/e-table-column.c308
-rw-r--r--widgets/table/e-table-config-field.c292
-rw-r--r--widgets/table/e-table-config-field.h70
-rw-r--r--widgets/table/e-table-config-no-group.glade1761
-rw-r--r--widgets/table/e-table-config.c1149
-rw-r--r--widgets/table/e-table-config.glade1841
-rw-r--r--widgets/table/e-table-config.h112
-rw-r--r--widgets/table/e-table-defines.h45
-rw-r--r--widgets/table/e-table-example-1.c308
-rw-r--r--widgets/table/e-table-example-2.c350
-rw-r--r--widgets/table/e-table-extras.c249
-rw-r--r--widgets/table/e-table-extras.h82
-rw-r--r--widgets/table/e-table-field-chooser-dialog.c219
-rw-r--r--widgets/table/e-table-field-chooser-dialog.h79
-rw-r--r--widgets/table/e-table-field-chooser-item.c694
-rw-r--r--widgets/table/e-table-field-chooser-item.h76
-rw-r--r--widgets/table/e-table-field-chooser.c275
-rw-r--r--widgets/table/e-table-field-chooser.glade129
-rw-r--r--widgets/table/e-table-field-chooser.h84
-rw-r--r--widgets/table/e-table-group-container.c1449
-rw-r--r--widgets/table/e-table-group-container.h99
-rw-r--r--widgets/table/e-table-group-leaf.c633
-rw-r--r--widgets/table/e-table-group-leaf.h91
-rw-r--r--widgets/table/e-table-group.c702
-rw-r--r--widgets/table/e-table-group.glade206
-rw-r--r--widgets/table/e-table-group.h179
-rw-r--r--widgets/table/e-table-header-item.c1809
-rw-r--r--widgets/table/e-table-header-item.h115
-rw-r--r--widgets/table/e-table-header-utils.c473
-rw-r--r--widgets/table/e-table-header-utils.h66
-rw-r--r--widgets/table/e-table-header.c954
-rw-r--r--widgets/table/e-table-header.h121
-rw-r--r--widgets/table/e-table-item.c3558
-rw-r--r--widgets/table/e-table-item.h226
-rw-r--r--widgets/table/e-table-memory-callbacks.c265
-rw-r--r--widgets/table/e-table-memory-callbacks.h94
-rw-r--r--widgets/table/e-table-memory-store.c436
-rw-r--r--widgets/table/e-table-memory-store.h122
-rw-r--r--widgets/table/e-table-memory.c295
-rw-r--r--widgets/table/e-table-memory.h80
-rw-r--r--widgets/table/e-table-model.c599
-rw-r--r--widgets/table/e-table-model.h173
-rw-r--r--widgets/table/e-table-one.c254
-rw-r--r--widgets/table/e-table-one.h61
-rw-r--r--widgets/table/e-table-scrolled.c224
-rw-r--r--widgets/table/e-table-scrolled.h77
-rw-r--r--widgets/table/e-table-search.c250
-rw-r--r--widgets/table/e-table-search.h72
-rw-r--r--widgets/table/e-table-selection-model.c338
-rw-r--r--widgets/table/e-table-selection-model.h76
-rw-r--r--widgets/table/e-table-simple.c313
-rw-r--r--widgets/table/e-table-simple.h123
-rw-r--r--widgets/table/e-table-size-test.c308
-rw-r--r--widgets/table/e-table-sort-info.c488
-rw-r--r--widgets/table/e-table-sort-info.h110
-rw-r--r--widgets/table/e-table-sorted-variable.c224
-rw-r--r--widgets/table/e-table-sorted-variable.h68
-rw-r--r--widgets/table/e-table-sorted.c310
-rw-r--r--widgets/table/e-table-sorted.h68
-rw-r--r--widgets/table/e-table-sorter.c445
-rw-r--r--widgets/table/e-table-sorter.h75
-rw-r--r--widgets/table/e-table-sorting-utils.c349
-rw-r--r--widgets/table/e-table-sorting-utils.h83
-rw-r--r--widgets/table/e-table-specification.c426
-rw-r--r--widgets/table/e-table-specification.h92
-rw-r--r--widgets/table/e-table-state.c275
-rw-r--r--widgets/table/e-table-state.h76
-rw-r--r--widgets/table/e-table-subset-variable.c256
-rw-r--r--widgets/table/e-table-subset-variable.h86
-rw-r--r--widgets/table/e-table-subset.c461
-rw-r--r--widgets/table/e-table-subset.h92
-rw-r--r--widgets/table/e-table-tooltip.h45
-rw-r--r--widgets/table/e-table-tree.h49
-rw-r--r--widgets/table/e-table-utils.c188
-rw-r--r--widgets/table/e-table-utils.h50
-rw-r--r--widgets/table/e-table-without.c395
-rw-r--r--widgets/table/e-table-without.h90
-rw-r--r--widgets/table/e-table.c3214
-rw-r--r--widgets/table/e-table.diabin4514 -> 0 bytes-rw-r--r--widgets/table/e-table.h356
-rw-r--r--widgets/table/e-tree-memory-callbacks.c275
-rw-r--r--widgets/table/e-tree-memory-callbacks.h119
-rw-r--r--widgets/table/e-tree-memory.c725
-rw-r--r--widgets/table/e-tree-memory.h105
-rw-r--r--widgets/table/e-tree-model.c1113
-rw-r--r--widgets/table/e-tree-model.h225
-rw-r--r--widgets/table/e-tree-scrolled.c223
-rw-r--r--widgets/table/e-tree-scrolled.h77
-rw-r--r--widgets/table/e-tree-selection-model.c1397
-rw-r--r--widgets/table/e-tree-selection-model.h77
-rw-r--r--widgets/table/e-tree-simple.c213
-rw-r--r--widgets/table/e-tree-simple.h88
-rw-r--r--widgets/table/e-tree-sorted-variable.c472
-rw-r--r--widgets/table/e-tree-sorted-variable.h85
-rw-r--r--widgets/table/e-tree-sorted.c1424
-rw-r--r--widgets/table/e-tree-sorted.h87
-rw-r--r--widgets/table/e-tree-table-adapter.c1179
-rw-r--r--widgets/table/e-tree-table-adapter.h87
-rw-r--r--widgets/table/e-tree.c3277
-rw-r--r--widgets/table/e-tree.h311
-rw-r--r--widgets/table/image1.pngbin1858 -> 0 bytes-rw-r--r--widgets/table/image2.pngbin1987 -> 0 bytes-rw-r--r--widgets/table/image3.pngbin2051 -> 0 bytes-rw-r--r--widgets/table/remove-col.xpm22
-rw-r--r--widgets/table/sample.table45
-rw-r--r--widgets/table/spec.xml21
-rw-r--r--widgets/table/table-test.c62
-rw-r--r--widgets/table/table-test.h27
-rw-r--r--widgets/table/test-check.c222
-rw-r--r--widgets/table/test-cols.c266
-rw-r--r--widgets/table/test-table.c478
-rw-r--r--widgets/table/tree-expanded.xpm23
-rw-r--r--widgets/table/tree-unexpanded.xpm23
-rw-r--r--widgets/text/.cvsignore11
-rw-r--r--widgets/text/e-completion-match.c186
-rw-r--r--widgets/text/e-completion-match.h69
-rw-r--r--widgets/text/e-completion-test.c220
-rw-r--r--widgets/text/e-completion-view.c935
-rw-r--r--widgets/text/e-completion-view.h103
-rw-r--r--widgets/text/e-completion.c644
-rw-r--r--widgets/text/e-completion.h103
-rw-r--r--widgets/text/e-entry-test.c83
-rw-r--r--widgets/text/e-entry.c1355
-rw-r--r--widgets/text/e-entry.h89
-rw-r--r--widgets/text/e-table-text-model.c246
-rw-r--r--widgets/text/e-table-text-model.h66
-rw-r--r--widgets/text/e-text-model-repos.c87
-rw-r--r--widgets/text/e-text-model-repos.h69
-rw-r--r--widgets/text/e-text-model-test.c93
-rw-r--r--widgets/text/e-text-model-uri.c359
-rw-r--r--widgets/text/e-text-model-uri.h57
-rw-r--r--widgets/text/e-text-model.c645
-rw-r--r--widgets/text/e-text-model.h119
-rw-r--r--widgets/text/e-text-test.c171
-rw-r--r--widgets/text/e-text.c4233
-rw-r--r--widgets/text/e-text.h274
-rw-r--r--wombat/.cvsignore15
-rw-r--r--wombat/ChangeLog350
-rw-r--r--wombat/Evolution-Wombat.idl19
-rw-r--r--wombat/GNOME_Evolution_WombatLDAP.oaf.in76
-rw-r--r--wombat/GNOME_Evolution_WombatNOLDAP.oaf.in75
-rw-r--r--wombat/Makefile.am82
-rw-r--r--wombat/wombat-moniker.c159
-rw-r--r--wombat/wombat-moniker.h11
-rw-r--r--wombat/wombat-private-moniker.c171
-rw-r--r--wombat/wombat-private-moniker.h11
-rw-r--r--wombat/wombat.c305
5193 files changed, 2819173 insertions, 1755927 deletions
diff --git a/.cvsignore b/.cvsignore
deleted file mode 100644
index fdd9a79f6d..0000000000
--- a/.cvsignore
+++ /dev/null
@@ -1,27 +0,0 @@
-ABOUT-NLS
-Makefile
-Makefile.in
-aclocal.m4
-config.cache
-config.guess
-config.h
-config.h.in
-config.log
-config.status
-config.sub
-configure
-install-sh
-intl
-libtool
-ltconfig
-ltmain.sh
-missing
-mkinstalldirs
-stamp-h
-stamp-h.in
-stamp.h
-xlibtool
-xltmain.sh
-evolution.spec
-xml-i18n-*
-*Conf.sh
diff --git a/AUTHORS b/AUTHORS
index 027a8de4ae..80633a8c61 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -42,9 +42,6 @@ Mailer
Notes
Anders Carlsson <andersca@gnu.org>
-Pilot
- JP Rosevear <jpr@ximian.com>
-
Shell
Miguel de Icaza <miguel@ximian.com>
Jason Leach <jleach@ximian.com>
@@ -69,6 +66,7 @@ Translations
Sung-Hyun Nam <namsh@kldp.org>
Szabolcs BAN <shooby@gnome.hu>
Tiago Antão <tiagoantao@bigfoot.com>
+ Duarte Loreto <happyguy_pt@hotmail.com>
Valek Filippov <frob@df.ru>
Vincent Renardias <vincent@redhat.com>
Yuri Syrota <rasta@renome.rovno.ua>
diff --git a/COPYING b/COPYING
index d60c31a97a..e1c15eb47c 100644
--- a/COPYING
+++ b/COPYING
@@ -1,340 +1,22 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- 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 Place, Suite 330, Boston, MA 02111-1307 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
+Code in Evolution is available under a variety of licenses. Each file should
+have a license header stating the license. In the absence of that code is
+available under the LGPLv2 or (at your choice) LGPLv3. See COPYING.LGPL2 and
+COPYING.LGPL3 for the full license texts.
+
+There are a few exceptions to this rule that have an impact on overall
+licensing. At the present, the code seems GPLv2+ clean.
+
+OpenLDAP license
+ addressbook/gui/component/openldap-extract.h
+
+LGPLv2+
+ widgets/text/e-text.[ch]
+ widgets/table/e-cell-tree.[ch]
+ widgets/misc/e-dateedit.[ch]
+
+MPL/GPL/LGPLv2+
+ smime/lib/e-asn1-object.c
+ smime/lib/e-cert.c
+ smime/lib/e-cert-db.c
+ smime/lib/e-cert-trust.c
+ smime/lib/e-pkcs12.c
diff --git a/COPYING-DOCS b/COPYING-DOCS
index b42936beb3..fa28abb989 100644
--- a/COPYING-DOCS
+++ b/COPYING-DOCS
@@ -1,355 +1 @@
- GNU Free Documentation License
- Version 1.1, March 2000
-
- Copyright (C) 2000 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
-0. PREAMBLE
-
-The purpose of this License is to make a manual, textbook, or other
-written document "free" in the sense of freedom: to assure everyone
-the effective freedom to copy and redistribute it, with or without
-modifying it, either commercially or noncommercially. Secondarily,
-this License preserves for the author and publisher a way to get
-credit for their work, while not being considered responsible for
-modifications made by others.
-
-This License is a kind of "copyleft", which means that derivative
-works of the document must themselves be free in the same sense. It
-complements the GNU General Public License, which is a copyleft
-license designed for free software.
-
-We have designed this License in order to use it for manuals for free
-software, because free software needs free documentation: a free
-program should come with manuals providing the same freedoms that the
-software does. But this License is not limited to software manuals;
-it can be used for any textual work, regardless of subject matter or
-whether it is published as a printed book. We recommend this License
-principally for works whose purpose is instruction or reference.
-
-
-1. APPLICABILITY AND DEFINITIONS
-
-This License applies to any manual or other work that contains a
-notice placed by the copyright holder saying it can be distributed
-under the terms of this License. The "Document", below, refers to any
-such manual or work. Any member of the public is a licensee, and is
-addressed as "you".
-
-A "Modified Version" of the Document means any work containing the
-Document or a portion of it, either copied verbatim, or with
-modifications and/or translated into another language.
-
-A "Secondary Section" is a named appendix or a front-matter section of
-the Document that deals exclusively with the relationship of the
-publishers or authors of the Document to the Document's overall subject
-(or to related matters) and contains nothing that could fall directly
-within that overall subject. (For example, if the Document is in part a
-textbook of mathematics, a Secondary Section may not explain any
-mathematics.) The relationship could be a matter of historical
-connection with the subject or with related matters, or of legal,
-commercial, philosophical, ethical or political position regarding
-them.
-
-The "Invariant Sections" are certain Secondary Sections whose titles
-are designated, as being those of Invariant Sections, in the notice
-that says that the Document is released under this License.
-
-The "Cover Texts" are certain short passages of text that are listed,
-as Front-Cover Texts or Back-Cover Texts, in the notice that says that
-the Document is released under this License.
-
-A "Transparent" copy of the Document means a machine-readable copy,
-represented in a format whose specification is available to the
-general public, whose contents can be viewed and edited directly and
-straightforwardly with generic text editors or (for images composed of
-pixels) generic paint programs or (for drawings) some widely available
-drawing editor, and that is suitable for input to text formatters or
-for automatic translation to a variety of formats suitable for input
-to text formatters. A copy made in an otherwise Transparent file
-format whose markup has been designed to thwart or discourage
-subsequent modification by readers is not Transparent. A copy that is
-not "Transparent" is called "Opaque".
-
-Examples of suitable formats for Transparent copies include plain
-ASCII without markup, Texinfo input format, LaTeX input format, SGML
-or XML using a publicly available DTD, and standard-conforming simple
-HTML designed for human modification. Opaque formats include
-PostScript, PDF, proprietary formats that can be read and edited only
-by proprietary word processors, SGML or XML for which the DTD and/or
-processing tools are not generally available, and the
-machine-generated HTML produced by some word processors for output
-purposes only.
-
-The "Title Page" means, for a printed book, the title page itself,
-plus such following pages as are needed to hold, legibly, the material
-this License requires to appear in the title page. For works in
-formats which do not have any title page as such, "Title Page" means
-the text near the most prominent appearance of the work's title,
-preceding the beginning of the body of the text.
-
-
-2. VERBATIM COPYING
-
-You may copy and distribute the Document in any medium, either
-commercially or noncommercially, provided that this License, the
-copyright notices, and the license notice saying this License applies
-to the Document are reproduced in all copies, and that you add no other
-conditions whatsoever to those of this License. You may not use
-technical measures to obstruct or control the reading or further
-copying of the copies you make or distribute. However, you may accept
-compensation in exchange for copies. If you distribute a large enough
-number of copies you must also follow the conditions in section 3.
-
-You may also lend copies, under the same conditions stated above, and
-you may publicly display copies.
-
-
-3. COPYING IN QUANTITY
-
-If you publish printed copies of the Document numbering more than 100,
-and the Document's license notice requires Cover Texts, you must enclose
-the copies in covers that carry, clearly and legibly, all these Cover
-Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
-the back cover. Both covers must also clearly and legibly identify
-you as the publisher of these copies. The front cover must present
-the full title with all words of the title equally prominent and
-visible. You may add other material on the covers in addition.
-Copying with changes limited to the covers, as long as they preserve
-the title of the Document and satisfy these conditions, can be treated
-as verbatim copying in other respects.
-
-If the required texts for either cover are too voluminous to fit
-legibly, you should put the first ones listed (as many as fit
-reasonably) on the actual cover, and continue the rest onto adjacent
-pages.
-
-If you publish or distribute Opaque copies of the Document numbering
-more than 100, you must either include a machine-readable Transparent
-copy along with each Opaque copy, or state in or with each Opaque copy
-a publicly-accessible computer-network location containing a complete
-Transparent copy of the Document, free of added material, which the
-general network-using public has access to download anonymously at no
-charge using public-standard network protocols. If you use the latter
-option, you must take reasonably prudent steps, when you begin
-distribution of Opaque copies in quantity, to ensure that this
-Transparent copy will remain thus accessible at the stated location
-until at least one year after the last time you distribute an Opaque
-copy (directly or through your agents or retailers) of that edition to
-the public.
-
-It is requested, but not required, that you contact the authors of the
-Document well before redistributing any large number of copies, to give
-them a chance to provide you with an updated version of the Document.
-
-
-4. MODIFICATIONS
-
-You may copy and distribute a Modified Version of the Document under
-the conditions of sections 2 and 3 above, provided that you release
-the Modified Version under precisely this License, with the Modified
-Version filling the role of the Document, thus licensing distribution
-and modification of the Modified Version to whoever possesses a copy
-of it. In addition, you must do these things in the Modified Version:
-
-A. Use in the Title Page (and on the covers, if any) a title distinct
- from that of the Document, and from those of previous versions
- (which should, if there were any, be listed in the History section
- of the Document). You may use the same title as a previous version
- if the original publisher of that version gives permission.
-B. List on the Title Page, as authors, one or more persons or entities
- responsible for authorship of the modifications in the Modified
- Version, together with at least five of the principal authors of the
- Document (all of its principal authors, if it has less than five).
-C. State on the Title page the name of the publisher of the
- Modified Version, as the publisher.
-D. Preserve all the copyright notices of the Document.
-E. Add an appropriate copyright notice for your modifications
- adjacent to the other copyright notices.
-F. Include, immediately after the copyright notices, a license notice
- giving the public permission to use the Modified Version under the
- terms of this License, in the form shown in the Addendum below.
-G. Preserve in that license notice the full lists of Invariant Sections
- and required Cover Texts given in the Document's license notice.
-H. Include an unaltered copy of this License.
-I. Preserve the section entitled "History", and its title, and add to
- it an item stating at least the title, year, new authors, and
- publisher of the Modified Version as given on the Title Page. If
- there is no section entitled "History" in the Document, create one
- stating the title, year, authors, and publisher of the Document as
- given on its Title Page, then add an item describing the Modified
- Version as stated in the previous sentence.
-J. Preserve the network location, if any, given in the Document for
- public access to a Transparent copy of the Document, and likewise
- the network locations given in the Document for previous versions
- it was based on. These may be placed in the "History" section.
- You may omit a network location for a work that was published at
- least four years before the Document itself, or if the original
- publisher of the version it refers to gives permission.
-K. In any section entitled "Acknowledgements" or "Dedications",
- preserve the section's title, and preserve in the section all the
- substance and tone of each of the contributor acknowledgements
- and/or dedications given therein.
-L. Preserve all the Invariant Sections of the Document,
- unaltered in their text and in their titles. Section numbers
- or the equivalent are not considered part of the section titles.
-M. Delete any section entitled "Endorsements". Such a section
- may not be included in the Modified Version.
-N. Do not retitle any existing section as "Endorsements"
- or to conflict in title with any Invariant Section.
-
-If the Modified Version includes new front-matter sections or
-appendices that qualify as Secondary Sections and contain no material
-copied from the Document, you may at your option designate some or all
-of these sections as invariant. To do this, add their titles to the
-list of Invariant Sections in the Modified Version's license notice.
-These titles must be distinct from any other section titles.
-
-You may add a section entitled "Endorsements", provided it contains
-nothing but endorsements of your Modified Version by various
-parties--for example, statements of peer review or that the text has
-been approved by an organization as the authoritative definition of a
-standard.
-
-You may add a passage of up to five words as a Front-Cover Text, and a
-passage of up to 25 words as a Back-Cover Text, to the end of the list
-of Cover Texts in the Modified Version. Only one passage of
-Front-Cover Text and one of Back-Cover Text may be added by (or
-through arrangements made by) any one entity. If the Document already
-includes a cover text for the same cover, previously added by you or
-by arrangement made by the same entity you are acting on behalf of,
-you may not add another; but you may replace the old one, on explicit
-permission from the previous publisher that added the old one.
-
-The author(s) and publisher(s) of the Document do not by this License
-give permission to use their names for publicity for or to assert or
-imply endorsement of any Modified Version.
-
-
-5. COMBINING DOCUMENTS
-
-You may combine the Document with other documents released under this
-License, under the terms defined in section 4 above for modified
-versions, provided that you include in the combination all of the
-Invariant Sections of all of the original documents, unmodified, and
-list them all as Invariant Sections of your combined work in its
-license notice.
-
-The combined work need only contain one copy of this License, and
-multiple identical Invariant Sections may be replaced with a single
-copy. If there are multiple Invariant Sections with the same name but
-different contents, make the title of each such section unique by
-adding at the end of it, in parentheses, the name of the original
-author or publisher of that section if known, or else a unique number.
-Make the same adjustment to the section titles in the list of
-Invariant Sections in the license notice of the combined work.
-
-In the combination, you must combine any sections entitled "History"
-in the various original documents, forming one section entitled
-"History"; likewise combine any sections entitled "Acknowledgements",
-and any sections entitled "Dedications". You must delete all sections
-entitled "Endorsements."
-
-
-6. COLLECTIONS OF DOCUMENTS
-
-You may make a collection consisting of the Document and other documents
-released under this License, and replace the individual copies of this
-License in the various documents with a single copy that is included in
-the collection, provided that you follow the rules of this License for
-verbatim copying of each of the documents in all other respects.
-
-You may extract a single document from such a collection, and distribute
-it individually under this License, provided you insert a copy of this
-License into the extracted document, and follow this License in all
-other respects regarding verbatim copying of that document.
-
-
-7. AGGREGATION WITH INDEPENDENT WORKS
-
-A compilation of the Document or its derivatives with other separate
-and independent documents or works, in or on a volume of a storage or
-distribution medium, does not as a whole count as a Modified Version
-of the Document, provided no compilation copyright is claimed for the
-compilation. Such a compilation is called an "aggregate", and this
-License does not apply to the other self-contained works thus compiled
-with the Document, on account of their being thus compiled, if they
-are not themselves derivative works of the Document.
-
-If the Cover Text requirement of section 3 is applicable to these
-copies of the Document, then if the Document is less than one quarter
-of the entire aggregate, the Document's Cover Texts may be placed on
-covers that surround only the Document within the aggregate.
-Otherwise they must appear on covers around the whole aggregate.
-
-
-8. TRANSLATION
-
-Translation is considered a kind of modification, so you may
-distribute translations of the Document under the terms of section 4.
-Replacing Invariant Sections with translations requires special
-permission from their copyright holders, but you may include
-translations of some or all Invariant Sections in addition to the
-original versions of these Invariant Sections. You may include a
-translation of this License provided that you also include the
-original English version of this License. In case of a disagreement
-between the translation and the original English version of this
-License, the original English version will prevail.
-
-
-9. TERMINATION
-
-You may not copy, modify, sublicense, or distribute the Document except
-as expressly provided for under this License. Any other attempt to
-copy, modify, sublicense or distribute the Document is void, and will
-automatically terminate your rights under this License. However,
-parties who have received copies, or rights, from you under this
-License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-
-10. FUTURE REVISIONS OF THIS LICENSE
-
-The Free Software Foundation may publish new, revised versions
-of the GNU Free Documentation License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns. See
-http://www.gnu.org/copyleft/.
-
-Each version of the License is given a distinguishing version number.
-If the Document specifies that a particular numbered version of this
-License "or any later version" applies to it, you have the option of
-following the terms and conditions either of that specified version or
-of any later version that has been published (not as a draft) by the
-Free Software Foundation. If the Document does not specify a version
-number of this License, you may choose any version ever published (not
-as a draft) by the Free Software Foundation.
-
-
-ADDENDUM: How to use this License for your documents
-
-To use this License in a document you have written, include a copy of
-the License in the document and put the following copyright and
-license notices just after the title page:
-
- Copyright (c) YEAR YOUR NAME.
- Permission is granted to copy, distribute and/or modify this document
- under the terms of the GNU Free Documentation License, Version 1.1
- or any later version published by the Free Software Foundation;
- with the Invariant Sections being LIST THEIR TITLES, with the
- Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
- A copy of the license is included in the section entitled "GNU
- Free Documentation License".
-
-If you have no Invariant Sections, write "with no Invariant Sections"
-instead of saying which ones are invariant. If you have no
-Front-Cover Texts, write "no Front-Cover Texts" instead of
-"Front-Cover Texts being LIST"; likewise for Back-Cover Texts.
-
-If your document contains nontrivial examples of program code, we
-recommend releasing these examples in parallel under your choice of
-free software license, such as the GNU General Public License,
-to permit their use in free software.
+See COPYING-DOCS.CCBYSA and COPYING-DOCS.GFDL.
diff --git a/COPYING-DOCS.CCBYSA b/COPYING-DOCS.CCBYSA
new file mode 100644
index 0000000000..3001989366
--- /dev/null
+++ b/COPYING-DOCS.CCBYSA
@@ -0,0 +1,58 @@
+ Creative Commons Attribution-ShareAlike 3.0 License
+
+THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
+
+BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
+
+1. Definitions
+
+"Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License.
+"Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined below) for the purposes of this License.
+"Creative Commons Compatible License" means a license that is listed at http://creativecommons.org/compatiblelicenses that has been approved by Creative Commons as being essentially equivalent to this License, including, at a minimum, because that license: (i) contains terms that have the same purpose, meaning and effect as the License Elements of this License; and, (ii) explicitly permits the relicensing of adaptations of works made available under that license under this License or a Creative Commons jurisdiction license with the same License Elements as this License.
+"Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership.
+"License Elements" means the following high-level license attributes as selected by Licensor and indicated in the title of this License: Attribution, ShareAlike.
+"Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License.
+"Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast.
+"Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work.
+"You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation.
+"Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
+"Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium.
+2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws.
+
+3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below:
+
+to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections;
+to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified.";
+to Distribute and Publicly Perform the Work including as incorporated in Collections; and,
+to Distribute and Publicly Perform Adaptations.
+For the avoidance of doubt:
+
+Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
+Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
+Voluntary License Schemes. The Licensor waives the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License.
+The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved.
+
+4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
+
+You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(c), as requested.
+You may Distribute or Publicly Perform an Adaptation only under the terms of: (i) this License; (ii) a later version of this License with the same License Elements as this License; (iii) a Creative Commons jurisdiction license (either this or a later license version) that contains the same License Elements as this License (e.g., Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible License. If you license the Adaptation under one of the licenses mentioned in (iv), you must comply with the terms of that license. If you license the Adaptation under the terms of any of the licenses mentioned in (i), (ii) or (iii) (the "Applicable License"), you must comply with the terms of the Applicable License generally and the following provisions: (I) You must include a copy of, or the URI for, the Applicable License with every copy of each Adaptation You Distribute or Publicly Perform; (II) You may not offer or impose any terms on the Adaptation that restrict the terms of the Applicable License or the ability of the recipient of the Adaptation to exercise the rights granted to that recipient under the terms of the Applicable License; (III) You must keep intact all notices that refer to the Applicable License and to the disclaimer of warranties with every copy of the Work as included in the Adaptation You Distribute or Publicly Perform; (IV) when You Distribute or Publicly Perform the Adaptation, You may not impose any effective technological measures on the Adaptation that restrict the ability of a recipient of the Adaptation from You to exercise the rights granted to that recipient under the terms of the Applicable License. This Section 4(b) applies to the Adaptation as incorporated in a Collection, but this does not require the Collection apart from the Adaptation itself to be made subject to the terms of the Applicable License.
+If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and (iv) , consistent with Ssection 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties.
+Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise.
+5. Representations, Warranties and Disclaimer
+
+UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
+
+6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. Termination
+
+This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License.
+Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above.
+8. Miscellaneous
+
+Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
+Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
+If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent.
+This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
+The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law.
diff --git a/COPYING-DOCS.GFDL b/COPYING-DOCS.GFDL
new file mode 100644
index 0000000000..ec5d8ee0dd
--- /dev/null
+++ b/COPYING-DOCS.GFDL
@@ -0,0 +1,142 @@
+ GNU Free Documentation License
+ Version 1.3, 3 November 2008
+
+Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. <http://fsf.org/>
+
+Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+0. PREAMBLE
+The purpose of this License is to make a manual, textbook, or other functional and useful document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.
+
+This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.
+
+We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.
+
+1. APPLICABILITY AND DEFINITIONS
+This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The "Document", below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as "you". You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.
+
+A "Modified Version" of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.
+
+A "Secondary Section" is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.
+
+The "Invariant Sections" are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.
+
+The "Cover Texts" are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A "Transparent" copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not "Transparent" is called "Opaque".
+
+Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.
+
+The "Title Page" means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.
+
+The "publisher" means any person or entity that distributes copies of the Document to the public.
+
+A section "Entitled XYZ" means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as "Acknowledgements", "Dedications", "Endorsements", or "History".) To "Preserve the Title" of such a section when you modify the Document means that it remains a section "Entitled XYZ" according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.
+
+2. VERBATIM COPYING
+You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and you may publicly display copies.
+
+3. COPYING IN QUANTITY
+If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.
+
+If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.
+
+It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.
+
+4. MODIFICATIONS
+You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:
+
+A. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
+B. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.
+C. State on the Title page the name of the publisher of the Modified Version, as the publisher.
+D. Preserve all the copyright notices of the Document.
+E. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
+F. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
+G. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.
+H. Include an unaltered copy of this License.
+I. Preserve the section Entitled "History", Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled "History" in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
+J. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the "History" section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
+K. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
+L. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
+M. Delete any section Entitled "Endorsements". Such a section may not be included in the Modified Version.
+N. Do not retitle any existing section to be Entitled "Endorsements" or to conflict in title with any Invariant Section.
+O. Preserve any Warranty Disclaimers.
+If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.
+
+You may add a section Entitled "Endorsements", provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.
+
+5. COMBINING DOCUMENTS
+You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled "History" in the various original documents, forming one section Entitled "History"; likewise combine any sections Entitled "Acknowledgements", and any sections Entitled "Dedications". You must delete all sections Entitled "Endorsements".
+
+6. COLLECTIONS OF DOCUMENTS
+You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.
+
+You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.
+
+7. AGGREGATION WITH INDEPENDENT WORKS
+A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an "aggregate" if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.
+
+8. TRANSLATION
+Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled "Acknowledgements", "Dedications", or "History", the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.
+
+9. TERMINATION
+You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License.
+
+However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
+
+Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it.
+
+10. FUTURE REVISIONS OF THIS LICENSE
+The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.
+
+Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Document.
+
+11. RELICENSING
+"Massive Multiauthor Collaboration Site" (or "MMC Site") means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A "Massive Multiauthor Collaboration" (or "MMC") contained in the site means any set of copyrightable works thus published on the MMC site.
+
+"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization.
+
+"Incorporate" means to publish or republish a Document, in whole or in part, as part of another Document.
+
+An MMC is "eligible for relicensing" if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008.
+
+The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing.
+
+ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:
+
+ Copyright (C) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+ A copy of the license is included in the section entitled "GNU
+ Free Documentation License".
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the "with … Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with the
+ Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.
+
+If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.
diff --git a/COPYING.LGPL2 b/COPYING.LGPL2
new file mode 100644
index 0000000000..eaa2dd9e97
--- /dev/null
+++ b/COPYING.LGPL2
@@ -0,0 +1,503 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+not price. Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+
+
diff --git a/COPYING.LGPL3 b/COPYING.LGPL3
new file mode 100644
index 0000000000..3f7b8b1e5c
--- /dev/null
+++ b/COPYING.LGPL3
@@ -0,0 +1,166 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
+
diff --git a/COPYING.OPENLDAP b/COPYING.OPENLDAP
new file mode 100644
index 0000000000..05ad7571e4
--- /dev/null
+++ b/COPYING.OPENLDAP
@@ -0,0 +1,47 @@
+The OpenLDAP Public License
+ Version 2.8, 17 August 2003
+
+Redistribution and use of this software and associated documentation
+("Software"), with or without modification, are permitted provided
+that the following conditions are met:
+
+1. Redistributions in source form must retain copyright statements
+ and notices,
+
+2. Redistributions in binary form must reproduce applicable copyright
+ statements and notices, this list of conditions, and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution, and
+
+3. Redistributions must contain a verbatim copy of this document.
+
+The OpenLDAP Foundation may revise this license from time to time.
+Each revision is distinguished by a version number. You may use
+this Software under terms of this license revision or under the
+terms of any subsequent revision of the license.
+
+THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS
+CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S)
+OR OWNER(S) OF THE SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+The names of the authors and copyright holders must not be used in
+advertising or otherwise to promote the sale, use or other dealing
+in this Software without specific, written prior permission. Title
+to copyright in this Software shall at all times remain with copyright
+holders.
+
+OpenLDAP is a registered trademark of the OpenLDAP Foundation.
+
+Copyright 1999-2003 The OpenLDAP Foundation, Redwood City,
+California, USA. All Rights Reserved. Permission to copy and
+distribute verbatim copies of this document is granted.
diff --git a/ChangeLog b/ChangeLog
index 3b4565cc3b..c26f1f78cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7912 +1,7 @@
-2002-10-07 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Update version number to 1.1.2.99.
-
-== Version 1.1.2 ==
-
-2002-10-07 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: 1.1.2. Update deps for GAL and GtkHTML.
-
-2002-09-27 gettextize <bug-gnu-gettext@gnu.org>
-
- * Makefile.am (SUBDIRS): Add m4.
- (ACLOCAL_AMFLAGS): New variable.
- (EXTRA_DIST): Add config.rpath.
- * configure.in (AC_OUTPUT): Add po/Makefile.in, m4/Makefile.
-
-2002-09-23 Radek Doulik <rodo@ximian.com>
-
- * configure.in: use pkg-config for gtkhtml
-
-2002-09-23 JP Rosevear <jpr@ximian.com>
-
- * configure.in: fix kde applnk test to not test for things if
- disabled
-
- * configure.in: Fix up mozilla tests and allow static linking of
- nss/nspr (Frank Belew <frb@ximian.com>)
-
-2002-09-23 Aaron Weber <aaron@ximian.com>
-
- * README: Update URLs for mailing lists, Evolution application
- page, help information. Remove note that Evolution is beta. In
- general, changes to the "soft" data. Also, jeff's commit to this
- file from 2001-11-21 seems to have been lost, so I re-removed the
- stuff he took out. And changed libnspr to mozilla-nspr, and
- libnss3 to mozilla-nss.
-
- * data/evolution.1: Update with information about where the real
- help is. Clarify example formatting.
-
-2002-09-16 Ettore Perazzoli <ettore@ximian.com>
-
- * data/cde_app_root/Makefile.am: New.
- * data/cde_app_root/dt/Makefile.am: New.
- * data/cde_app_root/dt/appconfig/Makefile.am: New.
- * data/cde_app_root/dt/appconfig/appmanager/Makefile.am: New.
- * data/cde_app_root/dt/appconfig/appmanager/C/Makefile.am: New.
- * data/cde_app_root/dt/appconfig/appmanager/C/Ximian/Makefile.am: New.
- * data/cde_app_root/dt/appconfig/icons/Makefile.am: New.
- * data/cde_app_root/dt/appconfig/icons/C/Makefile.am: New.
- * data/cde_app_root/dt/appconfig/types/Makefile.am: New.
- * data/cde_app_root/dt/appconfig/types/C/Makefile.am: New.
-
- * configure.in: Add a `--with-cde-path' option. Check for
- dtappintegrate in that path. Define HAVE_DTAPPINTEGRATE and
- GNOME_PREFIX. Also, generate
- data/cde_app_root/dt/appconfig/types/C/Ximian.dt.in and
- shell/evolution-nognome.
-
-2002-09-12 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: 1.1.1.99.
-
-2002-09-11 Ettore Perazzoli <ettore@ximian.com>
-
- * Makefile.am (SUBDIRS): Put po on the top.
-
-== Version 1.1.1 ==
-
-2002-09-09 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: 1.1.1. Also bump some requirements.
-
- * README: Update according to the new requirements.
-
-2002-09-06 Larry Ewing <lewing@ximian.com>
-
- * NEWS: update with some gtkhtml features.
-
-2002-09-05 Ettore Perazzoli <ettore@ximian.com>
-
- * NEWS: Updated with the new 1.2 features (unfinished).
-
- * NEWS-1.0: New, contains the changes up to version 1.0.8.
-
-2002-09-04 Dan Winship <danw@ximian.com>
-
- * acinclude.m4 (EVO_CHECK_TIMEZONE): Remove this from here.
-
- * configure.in: Put it here. (Connector no longer needs to share
- it). Also, check "tm_gmtoff" before "timezone", and if we have
- "timezone", check for "altzone" too.
-
- * acconfig.h: Add HAVE_ALTZONE
-
-2002-08-28 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: e-util now requires soup and gconf flags.
-
-2002-08-12 Dan Winship <danw@ximian.com>
-
- * tools/evolution-addressbook-import.c (main): Use default book,
- not local one.
-
- * tools/evolution-addressbook-export.c (main): Likewise.
-
- * tools/evolution-addressbook-abuse.c (abuse_timeout): Likewise.
-
-2002-08-11 Jeffrey Stedfast <fejj@ximian.com>
-
- * README: Update required gal and gtkhtml dependency information.
-
-2002-08-06 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in (THREADS_CFLAGS): Need to check for gal 0.19.99.18
- for e_xml_save_file().
-
-2002-08-01 Ettore Perazzoli <ettore@ximian.com>
-
- * README: Update Soup information and remove hard spaces.
-
- * configure.in: Check for Soup 0.7 or later. [Hm, we should make
- sure that it's actually a 0.7.x version.]
-
-2002-07-22 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Add checks for IPv6 support.
-
-2002-07-30 Not Zed <NotZed@Ximian.com>
-
- * configure.in (EVOLUTION_MAIL): added soup to compile flags.
-
-2002-07-24 Ettore Perazzoli <ettore@ximian.com>
-
- [Patch by Frank Belew <frb@ximian.com>.]
-
- * configure.in: If no --with-kde-applnk-path is given, try to
- detect the directory using `kde-config'.
-
-2002-07-22 Dan Winship <danw@ximian.com>
-
- * acinclude.m4: Move EVO_CHECK_LIB into here, and also create
- EVO_PURIFY_SUPPORT, EVO_TIMEZONE_CHECK, and EVO_LDAP_CHECK from
- stuff in configure.in. (This stuff is also used by Connector.)
-
- * configure.in: Remove the stuff that was moved to acinclude.m4.
-
- * evolution_addressbookConf.sh.in: Remove db3 and ldap references
- since pas-backend-file and pas-backend-ldap are no longer in
- libpas, and those flags weren't doing anything useful here before
- anyway. (Our attempts to force static linking to those libraries
- end up getting mangled when passed through gnome-config.)
-
- * evolution_calendarConf.sh.in: Likewise, remove db3 references.
-
-2002-07-22 Dan Winship <danw@ximian.com>
-
- * configure.in: Check if we're trying to build with the old
- libversit module borrowed from gnome-pim instead of our own new
- one, and refuse to build if so.
-
- * libversit/Makefile.am: Remove libversit.la stuff since we don't
- want it and it messes up the build slightly.
-
-2002-07-18 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Prepend "$(WERROR)" to all the *_CFLAGS variables
- so you can do `make WERROR=-Werror' to turn all compiler warnings
- into errors.
-
-2002-07-09 Peter Williams <peterw@ximian.com>
-
- * libversit/Makefile.am (privlib_LIBRARIES): Install libversit.a so
- that people compiling against the addressbook can do so successfully.
-
- * Makefile.am: create our *Conf.sh files and dist them and install
- them.
-
- * configure.in: Define and subst some variables that the Conf.sh
- file need.
-
-2002-07-10 Peter Williams <peterw@ximian.com>
-
- * configure.in (privlibdir): Define a versioned library directory
- that we can use for things that are ABI-sensitive: camel
- providers, importers... Define camel_providerder in terms of this,
- resulting in a new location for the providers. Camel will have to
- be rebuilt for it to get the new -D flag.
-
-2002-07-12 Peter Williams <peterw@ximian.com>
-
- * configure.in (E_UTIL_LIBS): e-util relies on bonobo-conf
- in e-passwords.c and e-categories-master-list-wombat.c, so
- reflect that here. And the e-port code needs THREADS_LIBS.
-
-2002-07-09 Peter Williams <peterw@ximian.com>
-
- * tools/Makefile.am (INCLUDES): Add include lines to get
- ebook headers relative to <ebook/foo.h>, not "foo.h".
-
-2002-07-09 <jpr@ximian.com>
-
- * configure.in: re-order nss and nspr flags
-
-2002-07-03 Peter Williams <peterw@ximian.com>
-
- * README: Fix the URL for the DB 3.1.17 package; it's moved.
-
-2002-06-28 Ettore Perazzoli <ettore@ximian.com>
-
- [As suggested by #24466.]
-
- * data/evolution.desktop.in (Categories): Added.
-
-2002-06-27 Dan Winship <danw@ximian.com>
-
- * libversit/Makefile.am: Hack around a libtool/make problem that
- was causing libversit.a to be rebuilt at "make install" time,
- causing further relinking down the line.
-
-2002-06-18 JP Rosevear <jpr@ximian.com>
-
- * configure.in: check for libsoftokn3 if we couldn't link the
- first time
-
-2002-06-14 Chris Toshok <toshok@ximian.com>
-
- * libversit/vobject.c (unUseStr): fix a braindead typo that caused
- us to leak strings in certain circumstances (when the string being
- freed was second in the list, the head of the list would get
- lost.)
-
-2002-06-05 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Changed the required version of gal to 0.19.99.17.
-
-2002-06-04 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Changed the required version of gal to 0.19.99.16.
-
-2002-06-02 Larry Ewing <lewing@ximian.com>
-
- * configure.in: require gtkhtml-1.1.1.1 aka multicite branch.
-
-2002-05-14 Dan Winship <danw@ximian.com>
-
- * data/evolution.1: Document "evolution default:mail"
-
-2002-05-08 Ettore Perazzoli <ettore@ximian.com>
-
- * README: Add an explanation/warning about why we want Berkeley DB
- 3.1.17 and nothing else.
-
-2002-04-28 Larry Ewing <lewing@ximian.com>
-
- * configure.in: require gtkhtml-1.1.1.
-
-2002-04-29 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in (EVO_CHECK_LIB): Bumped the required version number
- of gal to 0.19.99.15.
-
-2002-04-26 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Don't generate libibex/Makefile anymore.
-
- * Makefile.am: Removed libibex from SUBDIRS.
-
- * tools/Makefile.am: Don't link with libibex.
-
- * tests/Makefile.am: Same here.
-
-2002-04-22 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Require gal 0.19.99.14.
-
-2002-04-17 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Require GAL 0.19.99.13.
-
-2002-04-17 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped required gal version number to 0.19.99.12.
-
-2002-04-17 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped required gal version number to 0.19.99.11.
-
-2002-04-16 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Add checks for gethostbyaddr_r
-
-2002-04-14 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Check for socklen_t and if it doesn't exist,
- define it as unsigned int.
-
-2002-04-04 JP Rosevear <jpr@ximian.com>
-
- * configure.in: Fix static linking on solaris which doesn't have a
- static libresolv.
-
-2002-04-01 Chris Toshok <toshok@ximian.com>
-
- * libversit/vobject.c (newStrItem): only include if USE_STRTBL is
- defined.
- (deleteStrItem): same.
- (hashStr): same.
- (lookupStr): if USE_STRTBL is defined, use existing behavior. if
- not defined, just dup the string.
- (unUseStr): if USE_STRTBL is defined, use existing behavior. if
- not defined, just free the string.
-
-2002-04-01 Dan Winship <danw@ximian.com>
-
- Darwin/OS X portability from Max Horn <max@quendi.de>
-
- * libversit/vcc.y: Remove #include <malloc.h>.
-
- * libversit/vobject.c: Likewise, and #include <stdlib.h>
-
-2002-03-30 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Add argument `--enable-shlib-components'. New
- substitutions OAF_SHLIB_LOCATION, OAF_SHLIB_PREFIX,
- OAF_SHLIB_SUFFIX.
-
-2002-03-29 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Check for GConf. Add gthreads to LIBIBEX_CFLAGS
- and LIBIBEX_LIBS.
-
-2002-03-28 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped the required version of gal to 0.19.99.10.
-
-2002-03-24 Peter Williams <peterw@ximian.com>
-
- * tools/killev: Change the OAFIID for the GtkHTML editor to
- have :1.1 at the end.
-
-2002-03-19 Dan Winship <danw@ximian.com>
-
- * tools/Makefile.am (evolution_addressbook_import_LDADD):
- s/libversit.la/libversit.a/
-
-2002-03-13 Chris Toshok <toshok@ximian.com>
-
- * configure.in (EVOLUTION_ADDRESSBOOK_DEPS): add gal.
-
-2002-03-12 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped the required version of gal.
-
-2002-03-06 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Allow the user to enable OpenSSL over Mozilla NSS
- using --enable-openssl or --disable-nss.
-
-2002-02-24 jacob berkman <jacob@ximian.com>
-
- * sounds/Makefile.am (EXTRA_DIST): add $(sounds_DATA)
-
-2002-02-22 Larry Ewing <lewing@ximian.com>
-
- * configure.in: add libglade the to the E_UTIL flags.
-
-2002-02-13 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped the required version of gal.
-
-2002-02-12 Tõivo Leedjärv <leedjarv@interest.ee>
-
- * configure.in: Added et to ALL_LINGUAS.
-
-2002-02-09 JP Rosevear <jpr@ximian.com>
-
- * configure.in: make sure PISOCK cflags are added where
- appropriate
-
-2002-02-08 Damon Chaplin <damon@ximian.com>
-
- * Makefile.am (SUBDIRS): added sounds.
-
- * configure.in (AC_OUTPUT): added sounds/Makefile.
-
- * sounds/Makefile.am: new file.
- * sounds/default_alarm.wav: default alarm sound, currently only used
- when vCalendar files are imported with audio alarms. We need a better
- sound.
-
-2002-02-07 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped the required version of gal.
-
-2002-01-28 Radek Doulik <rodo@ximian.com>
-
- * configure.in: added bonobo to filter flags to avoid compile
- error
-
-2002-01-27 Ettore Perazzoli <ettore@ximian.com>
-
- * tools/Makefile.am: Use GNOME_FULL_LIBS and GNOME_FULL_CFLAGS.
-
- * configure.in: Define the CAMEL_{CFLAGS,LIBS} using
- EVO_SET_COMPILE_FLAGS. Likewise define E_UTIL_{CFLAGS,LIBS},
- E_NAME_{CFLAGS,LIBS}, SHELL_{CFLAGS,LIBS},
- IMPORTERS_{CFLAGS,LIBS}, WOMBAT_{CFLAGS,LIBS} and
- E_WIDGETS_{CFLAGS,LIBS}, LIBFILTER_{CFLAGS,LIBS}. Remove
- GAL_{LIBS,CFLAGS}. Add GNOME_FULL_{CFLAGS,LIBS}. Also, move all
- this stuff after OpenSSL check so they benefit from all the
- cflags/ldflags discoveries for the support libraries.
-
-2002-01-25 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Require gal 0.19.99.1.
-
-2002-01-24 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Define a new macro EVO_SET_COMPILE_FLAGS. Define
- EVOLUTION_ADDRESSBOOK_CFLAGS, EVOLUTION_ADDRESSBOOK_LIBS,
- EVOLUTION_ADDRESSBOOK_CONDUIT_CFLAGS,
- EVOLUTION_ADDRESSBOOK_CONDUIT_LIBS, EVOLUTION_SUMMARY_LIBS,
- EVOLUTION_SUMMARY_CFLAGS, EVOLUTION_CALENDAR_LIBS,
- EVOLUTION_CALENDAR_CFLAGS, EVOLUTION_CALENDAR_CONDUIT_LIBS,
- EVOLUTION_CALENDAR_CONDUIT_CFLAGS through it. Remove SOUP_CFLAGS
- and SOUP_LIBS.
-
-2002-01-15 Iain Holmes <iain@ximian.com>
-
- * configure.in: Add a check for libsoup. Define SOUP_CFLAGS and
- SOUP_LIBS
-
- * README: Update to include the SOUP dependancy.
-
-2002-01-04 Pablo Saratxaga <pablo@mandrakesoft.com>
-
- * configure.in: Added "eu" to ALL_LINGUAS
-
-2001-12-17 Dan Winship <danw@ximian.com>
-
- * configure.in (camel_providerdir): Define this here, using only
- EVOLUTION_MAJOR_VERSION and EVOLUTION_MINOR_VERSION (and not MICRO
- and NANO).
-
-2001-12-13 Chris Toshok <toshok@ximian.com>
-
- * configure.in: check for alloca.h.
-
-2001-12-12 Ettore Perazzoli <ettore@ximian.com>
-
- [Fix #16358, No man page for Evolution.]
-
- * data/Makefile.am (man_MANS): Install the man page.
-
- * data/evolution.1: New man page for Evolution.
-
-2001-12-10 JP Rosevear <jpr@ximian.com>
-
- * configure.in: use UTF-8 as the char set when testing pilot link
-
-2001-12-11 Ettore Perazzoli <ettore@ximian.com>
-
- * data/evolution.desktop.in (_Name): "Ximian Evolution", not
- "Evolution".
-
-2001-12-11 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Up VERSION to 1.1.0.99.
-
-2001-12-06 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: s/PREVIEW_VERSION/VERSION_COMMENT
-
-2001-12-04 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Add a AC_DEFINE for PREVIEW_RELEASE which is a
- string that will be appended to the X-Mailer header.
-
-2001-11-21 Jeffrey Stedfast <fejj@ximian.com>
-
- * README: Updated. Don't say that the user needs to copy their
- mozilla database files into ~/evolution, since Evolution now
- builds it's own default database files if they don't exist and
- also remove instructions for building with OpenSSL.
-
- * acconfig.h: Remove HAVE_OPENSSL define
-
- * configure.in: Remove checks for OpenSSL libraries.
-
-2001-11-20 Wang Jian <lark@linux.net.cn>
-
- * configure.in(ALL_LINGUAS): Re-Added zh_CN. It is checked
- against gettext 0.10.40 and 0.10.35 without any problem.
- Please contact me if anyone wants to disable it (AGAIN).
-
-2001-11-19 Abel Cheung <maddog@linuxhall.org>
-
- * configure.in: I will keep adding zh_TW to ALL_LINGUAS before
- somebody is willing to tell me why it is deleted without
- reason. It was checked against newest gettext (0.10.40) and
- older gettext (0.10.35) without any problem. A few
- translations are not removed from ALL_LINGUAS even though
- they failed in msgfmt checking.
-
-2001-11-14 Ettore Perazzoli <ettore@ximian.com>
-
- * README: Updated.
-
- * configure.in: 0.99.2. Require gtkhtml 0.16.1 and GAL 0.18.1.
-
-2001-11-14 Ettore Perazzoli <ettore@ximian.com>
-
- * NEWS: Redone with the bug #s from Bugzilla.
-
-2001-11-14 Federico Mena Quintero <federico@ximian.com>
-
- * NEWS: Calendar/tasks NEWS.
-
-2001-11-13 JP Rosevear <jpr@ximian.com>
-
- * configure.in: restore cflags and ldflags properly
-
-2001-11-12 JP Rosevear <jpr@ximian.com>
-
- * configure.in: save the ldflags properly
-
-2001-11-09 JP Rosevear <jpr@ximian.com>
-
- * configure.in: Check to make sure pilot-link has the charset
- conversion stuff enabled
-
-2001-11-09 Ettore Perazzoli <ettore@ximian.com>
-
- * tools/killev: Chop the output from `uname -s'. Thanks to
- Michael Gerdts for suggesting the fix.
-
-2001-11-09 Abel Cheung <maddog@linux.org.hk>
-
- * configure.in: Re-added zh_TW to ALL_LINGUAS. Translator keep
- complaining to me, and waste a month before discovering it was
- disabled while I know nothing about it. Please at least complain
- to me if it's gettext problem.
-
-2001-11-06 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Up to 0.99.1 for snapshot purposes.
-
-2001-11-05 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Upgrade version number to 0.99.0. Require GtkHTML
- 0.16 and GAL 0.18.
-
-2001-11-05 JP Rosevear <jpr@ximian.com>
-
- * NEWS: Small update
-
-2001-11-05 Ettore Perazzoli <ettore@ximian.com>
-
- * NEWS: Updated.
-
-2001-10-31 Ettore Perazzoli <ettore@ximian.com>
-
- * data/evolution.desktop.in (Icon): evolution.png instead of
- evolution-icon.png.
-
-2001-10-31 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Update version to 0.17.100.
-
-2001-10-31 JP Rosevear <jpr@ximian.com>
-
- * NEWS (Conduits): update
-
-2001-10-30 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Add oaf to MAILER_CFLAGS and MAILER_LIBS too.
-
-2001-10-30 Jeffrey Stedfast <fejj@ximian.com>
-
- * NEWS (Mailer): Updated mailer NEWS.
-
-2001-10-30 <NotZed@Ximian.com>
-
- * NEWS (Mailer): My mailer news.
-
-2001-10-30 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Add oaf to the BONOBO_VFS_GNOME_CFLAGS too.
-
-2001-10-30 Federico Mena Quintero <federico@ximian.com>
-
- * NEWS (Calendar): Calendar NEWS.
-
-2001-10-30 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Add oaf to the BONOBO_GNOME_LIBS,
- BONOBO_GNOME_CFLAGS, BONOBO_HTML_GNOME_LIBS,
- BONOBO_HTML_GNOME_CFLAGS.
-
-2001-10-30 Federico Mena Quintero <federico@ximian.com>
-
- * configure.in: Require GAL version 0.15.99.10. I know you all
- love this.
-
-2001-10-30 Radek Doulik <rodo@ximian.com>
-
- * configure.in: require gtkhtml version 0.15.99.2
-
-2001-10-29 Damon Chaplin <damon@ximian.com>
-
- * configure.in (ALL_LINGUAS): added en_AU (copied en_GB).
-
-2001-10-30 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Require gal 0.15.99.9.
-
-2001-10-30 <notzed@ximian.com>
-
- * configure.in: Move the configure version number check down
- a bit for gtkhtml/gal, c'ause i'm sick of fixing a manual
- patch i have every bloody time the version changes.
-
-2001-10-29 Joe Shaw <joe@ximian.com>
-
- * configure.in: Require gal 0.15.99.8
-
- * addressbook/backend/ebook/e-card-simple.c,
- addressbook/gui/component/addressbook-storage.c,
- addressbook/gui/widgets/e-addressbook-view.c,
- calendar/gui/e-calendar-table.c,
- calendar/gui/e-itip-control.c,
- calendar/gui/e-meeting-model.c,
- calendar/gui/itip-utils.c,
- calendar/gui/print.c,
- calendar/gui/alarm-notify/alarm-notify-dialog.c,
- filter/rule-editor.c,
- mail/mail-config.c,
- mail/mail-folder-cache.c,
- mail/mail-format.c,
- mail/mail-local.c,
- mail/mail-ops.c,
- mail/mail-vfolder.c,
- shell/e-local-storage.c,
- shell/e-summary-storage.c: Change includes of
- e-util/e-unicode-i18n.h to gal/util/e-unicode-i18n.h
-
- * e-util/Makefile.am: Don't build e-unicode-i18n.[ch] anymore.
-
-2001-10-29 Christopher James Lahey <clahey@ximian.com>
-
- * NEWS (Addressbook): Added my addressbook changes.
-
-2001-10-29 Ettore Perazzoli <ettore@ximian.com>
-
- * AUTHORS: Add Larry and Radek.
-
-2001-10-30 Radek Doulik <rodo@ximian.com>
-
- * configure.in: require gtkhtml version 0.15.99.1
-
-2001-10-29 Rodrigo Moya <rodrigo@ximian.com>
-
- * configure.in: added calendar/importers/Makefile
-
-2001-10-29 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped required version of gal to 0.15.99.7.
-
-2001-10-28 JP Rosevear <jpr@ximian.com>
-
- * data/Makefile.am: no need to use destdir
-
-2001-10-27 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped required version of gal to 0.15.99.6.
-
-2001-10-27 Dan Winship <danw@ximian.com>
-
- * configure.in: Change the help string on "--enable-nntp" to
- mention the fact that NNTP support is incomplete and unsupported.
- If the user doesn't pass --enable-nntp, don't mention NNTP at all
- in the summary at the end. Also, mention which SSL library is
- being used when SSL support is enabled, and don't mention anything
- about S/MIME since it doesn't work.
-
-2001-10-26 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: GAL 0.15.99.5.
-
-2001-10-26 Kevin Breit <mrproper@ximian.com>
-
- * AUTHORS: Updated my email address.
-
-2001-10-26 <NotZed@Ximian.com>
-
- * configure.in: Bump gal requirement.
-
-2001-10-23 Chris Toshok <toshok@ximian.com>
-
- * tools/killev: and add a way to get some more spew about the
- commands we're executing.
-
-2001-10-23 Chris Toshok <toshok@ximian.com>
-
- * tools/killev: use eq instead of ==.
-
-2001-10-23 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped required GAL to 0.15.99.3 so EEntry's
- "draw_button" argument can be used in
- addressbook/gui/component/select-names/e-select-names.c.
-
-2001-10-22 Damon Chaplin <damon@ximian.com>
-
- * configure.in: bumped required GAL to 0.15.99.2.
-
-2001-10-22 Ettore Perazzoli <ettore@ximian.com>
-
- * acconfig.h: HAVE_KDE_APPLNK.
-
- * configure.in (EVO_CHECK_LIB): AC_DEFINE `HAVE_KDE_APPLNK' in the
- case in which the kde applnk dir is found. Also fix the logic
- with the checking so it doesn't get fooled.
-
-2001-10-22 JP Rosevear <jpr@ximian.com>
-
- * data/Makefile.am: include destdir in the path of the kde desktop
- installation dir
-
-2001-10-20 Ettore Perazzoli <ettore@ximian.com>
-
- * data/Makefile.am [HAVE_KDE_APPLNK]: Install `evolution.desktop'
- in the `KDE_APPLNK_DIR'.
-
- * configure.in: New option `--with-kde-applnk-path'. Define the
- `HAVE_KDE_APPLNK' Automake conditional, and the `KDE_APPLNK_DIR'
- value.
-
-2001-10-19 Dan Winship <danw@ximian.com>
-
- * tools/Makefile.am (EXTRA_DIST): Merge the two EXTRA_DIST
- declarations together so they both happen.
-
-2001-10-18 Chris Toshok <toshok@ximian.com>
-
- * tools/killev: use a new fangled perl script that queries oaf for
- interfaces we want to kill.
-
-2001-10-18 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped the required version of gal to 0.15.99.1
- for use in evolution-addressbook-export.
-
- * tools/.cvsignore: Added evolution-addressbook-clean,
- evolution-addressbook-export, evolution-addressbook-import, and
- .libs.
-
- * tools/Makefile.am: Added evolution-addressbook-clean,
- evolution-addressbook-export, and evolution-addressbook-import.
-
- * tools/evolution-addressbook-clean.in: Main script to clean up
- the local contact database.
-
- * tools/evolution-addressbook-export.c: Exports the local
- addressbook to the specified file
- (--output-file). If no --output-file is given, writes out to a
- unique file in the /tmp directory. In either case, prints the
- filename to stdout.
-
- * tools/evolution-addressbook-import.c: Imports the specified file
- (--input-file) to the local addressbook.
-
-2001-10-18 Wang Jian <lark@linux.net.cn>
-
- * configure.in(ALL_LINGUAS): Added zh_CN for Simplified Chinese.
-
-2001-10-17 Christopher James Lahey <clahey@ximian.com>
-
- * NEWS (Addressbook): Wrote Addressbook news.
-
-2001-10-12 Chris Toshok <toshok@ximian.com>
-
- * tools/killev: kill evolution-ldif-importer.
-
-2001-10-11 Federico Mena Quintero <federico@ximian.com>
-
- * configure.in (AC_OUTPUT): Fix the order of the help/ subdirs.
- These must be sorted as a preorder walk for a tree!
-
-2001-10-10 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: 0.16.99.
-
-2001-10-10 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: 0.16. Require GtkHTML 0.15 or later and GAL 0.14
- or later. Also, make $with_nspr_includes default to
- `/usr/include/nspr' instead of `/usr/include/mozilla' and
- $with_nss_includes to `/usr/include/moznss' instead of
- `/usr/include/mozilla'.
-
-2001-10-10 Ettore Perazzoli <ettore@ximian.com>
-
- * NEWS: Added info about the shell, plus some minor fixes for
- consistency.
-
-2001-10-10 Christopher James Lahey <clahey@ximian.com>
-
- * NEWS (Addressbook): Updated.
-
-2001-10-09 Federico Mena Quintero <federico@ximian.com>
-
- * NEWS (Calendar): Calendar NEWS.
-
-2001-10-09 <NotZed@Ximian.com>
-
- * NEWS (Mailer): Updated for beta 6.
-
-2001-10-09 Rodrigo Moya <rodrigo@ximian.com>
-
- * configure.in: add libart to list of libraries to use in
- EXTRA_GNOME_CFLAGS/LIBS, which is needed for latest libart versions
-
-2001-10-09 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: AC_OUTPUT(default_user/local/Makefile) before
- AC_OUTPUT()ing the other subdirs of `default_user/local'. Fix
- pointed out by Dmitry G. Mastrukov <dmitry@fitmark.net>.
-
-2001-10-07 Dan Winship <danw@ximian.com>
-
- * configure.in: Remove movemail check, since it's not relevant any
- more.
-
-2001-10-05 Larry Ewing <lewing@ximian.com>
-
- * configure.in: Bumped required version of gtkhtml to 0.14.99.1
-
-2001-10-05 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped required version of gal to 0.13.99.1.
-
-2001-10-01 Aaron Weber <aaron@ximian.com>
-
- * help/C/Makefile.am: removed an extraneous tab.
-
-2001-10-01 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: 0.15.99.
-
-2001-10-01 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: 0.15. Require gal 0.13 and gtkhtml 0.14.
-
-2001-10-01 Christopher James Lahey <clahey@ximian.com>
-
- * NEWS (Addressbook): Added more news.
-
-2001-09-30 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in (nspr_libs): Order the linkline to be the same as
- the order in Mozilla (it is suggested that they be in this order).
- (nss_libs): Same.
-
-2001-09-27 Dan Winship <danw@ximian.com>
-
- * configure.in: Remove references to the "compose" program, since
- that functionality went into the shell.
- (AC_OUTPUT): Sort and remove duplicates.
-
- * cmdline/*: gone
-
-2001-09-26 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Added a flag to enable pedantic PGP/MIME - this is
- not recommended for end-users. It is mostly meant for testing
- purposes.
-
-2001-09-26 Chris Toshok <toshok@ximian.com>
-
- * configure.in: make sure the solaris network libs get added to
- the LDAP link line before we test for openldap. Thanks to Frank
- Belew for finding this.
-
-2001-09-22 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped the required version of gal to 0.12.99.0.
-
-2001-09-21 Nat Friedman <nat@ximian.com>
-
- * configure.in (EVOLUTION_MICRO_VERSION): Changed to 99.
- (VERSION): Added ".$EVOLUTION_MICRO_VERSION" suffix.
-
-2001-09-21 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Bump version to 0.14. Depend on gal >= 0.12,
- gtkhtml >= 0.13.
-
-2001-09-21 Michael Zucchi <NotZed@Ximian.com>
-
- * NEWS (Mail): Updated.
-
-2001-09-21 Christopher James Lahey <clahey@ximian.com>
-
- * NEWS (Addressbook): Added more NEWS items here.
-
-2001-09-19 JP Rosevear <jpr@ximian.com>
-
- * configure.in: Remove dead directory from AC_OUTPUT
-
-2001-09-16 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Updated required version of gal to 0.11.99.4.
-
-2001-09-14 JP Rosevear <jpr@ximian.com>
-
- * configure.in: remove unneeded conditionals
-
-2001-09-13 Yanko Kaneti <yaneti@declera.com>
-
- * configure.in (ALL_LINGUAS): Added bg to ALL_LINGUAS.
-
-2001-09-13 Larry Ewing <lewing@ximian.com>
-
- * data/evolution.mime: override the gnome-vfs.mime to match .vcf
- as text/x-vcard.
-
-2001-09-11 JP Rosevear <jpr@ximian.com>
-
- * configure.in: temporarily disable zh_TW
-
-2001-09-10 Abel Cheung <maddog@linux.org.hk>
-
- * configure.in: Added "zh_TW" to ALL_LINGUAS.
-
-2001-09-07 Dan Winship <danw@ximian.com>
-
- * configure.in: one-line OpenSSL fix from Yanko Kaneti
- <yaneti@declera.com>
-
-2001-09-05 Ettore Perazzoli <ettore@ximian.com>
-
- * README: Updated slightly.
-
-2001-09-04 Ettore Perazzoli <ettore@ximian.com>
-
- [Fixes by Neil Conway <neilconway@home.com, as per #8090.]
-
- * configure.in: Fix the error message if scrollkeeper is not found.
-
- * README: A bunch of minor fixes, tweaks and cleanups.
-
-2001-09-04 Ettore Perazzoli <ettore@ximian.com>
-
- [Fix #8089, Undocumented Scrollkeeper dependency.]
-
- * README: Add scrollkeeper 0.1.4 to the list of dependencies.
-
-2001-09-04 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Only check for OpenSSL if we were not able to find
- Mozilla's NSS libraries.
-
-2001-09-04 Peter Williams <peterw@ximian.com>
-
- * omf-install/Makefile.am (install-data-local): Don't put
- $(srcdir) in the file path twice.
-
-2001-09-01 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped the required version of gal to 0.11.99.2.
-
-2001-08-31 Zbigniew Chyla <cyba@gnome.pl>
-
- * configure.in: Bumped required version of GAL to 0.11.3
- (for g_utf8_collate)
-
-2001-08-24 Ettore Perazzoli <ettore@ximian.com>
-
- [Patch from Nike Gerdts <michael.gerdts@usa.alcatel.com> for
- #6882, DB3_CFLAGS and DB3_LDFLAGS order messes up CPPFLAGS and
- LDFLAGS.]
-
- * configure.in: Put DB3_CFLAGS before the already-defined CPPFLAGS
- instead of after them; likewise, put DB3_LDADD before the already
- defined LDADD.
-
-2001-08-24 Dan Winship <danw@ximian.com>
-
- * configure.in: We don't need to check for both bonobo-conf 0.11
- AND bonobo-conf 0.2.
-
-2001-08-22 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: 0.13.99.
-
-2001-08-22 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Bump requirements to GAL 0.11, bonobo-conf 0.11,
- GtkHTML 0.12. Don't autogen
- `doc/devel/executive-summary/Makefile'. Bump version number to
- 0.13.
-
-2001-08-21 Ettore Perazzoli <ettore@ximian.com>
-
- * NEWS (Global): Added.
-
-2001-08-21 Christopher James Lahey <clahey@ximian.com>
-
- * NEWS (Addressbook): Updated NEWS for addressbook.
-
-2001-08-21 Peter Williams <peterw@ximian.com>
-
- * NEWS (Mail): Updated some more.
-
-2001-08-21 Jeffrey Stedfast <fejj@ximian.com>
-
- * NEWS: Updated.
-
-2001-08-20 Jon Trowbridge <trow@ximian.com>
-
- * configure.in: Require gal 0.10.99.5.
-
-2001-08-19 Aaron Weber <aaron@ximian.com>
-
- *Makefile.am: added "help" to subdirs.
-
-2001-08-19 Chris Toshok <toshok@ximian.com>
-
- * omf-install/Makefile.am (scrollkeeper_localstate_dir) use
- $(SCROLLKEEPER_LOCALSTATE_DIR), and not something based on
- evolution's local state dir. this should fix the core dumps
- during install on freebsd and solaris.
-
- * configure.in (GLIB_CONFIG): use $GLIB_CONFIG if it's set,
- otherwise default to glib-config. a cheap solution to get this
- working on freebsd (where they have glib12-config, but not
- glib-config.) also, switch all `glib-config`s to `$GLIB_CONFIG`.
- (SCROLLKEEPER_LOCALSTATE_DIR): use scrollkeeper-config to figure
- this out, and AC_SUBST so omf-install/Makefile.am can use it.
-
-2001-08-17 Iain Holmes <iain@ximian.com>
-
- * Makefile.am: Move the libical compile order.
-
-2001-08-16 "Big Iain" Holmes <iain@ximian.com>
-
- * configure.in: Add widgets/e-timezone-dialog/Makefile
-
-2001-08-16 Jason Leach <jleach@ximian.com>
-
- * AUTHORS: I know what you did last summer!
-
-2001-08-16 Jon Trowbridge <trow@ximian.com>
-
- * configure.in: Require gal 0.10.99.3.
-
-2001-08-16 Kjartan Maraas <kmaraas@gnome.org>
-
- * README: Some info on adding --localstatedir to the configure
- options.
- * Makefile.am: Added omf-install to the build.
- * configure.in: Adjust for the move of the user docs.
-
-2001-08-15 Kjartan Maraas <kmaraas@gnome.org>
-
- * configure.in: Addded missing dirs to the build. Add checks for
- scrollkeeper and jw to get the docs building on later Red Hat's.
- * omf-install/*: Added this for integration with scrollkeeper.
-
-2001-08-14 Dan Winship <danw@ximian.com>
-
- * configure.in (LDAP_LIBS): Remove an obvious typo reported by
- Miles
-
-2001-08-11 Kjartan Maraas <kmaraas@gnome.org>
-
- * README: Be truthful about the versions of libs we need.
-
-2001-08-10 Chris Toshok <toshok@ximian.com>
-
- * configure.in: if libldap.la is there, default to static linking
- of openldap. if it's not, default to dynamic. also, provide
- --with-static-ldap for users that want to override these defaults.
-
-2001-08-09 Chris Toshok <toshok@ximian.com>
-
- * configure.in: link statically with OpenLDAP.
-
-2001-08-09 Jon Trowbridge <trow@ximian.com>
-
- * configure.in: Require GAL 0.10.99.2.
-
-2001-08-09 Christopher James Lahey <clahey@ximian.com>
-
- * tools/killev: Added #!/bin/sh
-
-2001-08-08 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Don't link to libnssckbi3 when linking to nss.
-
-2001-08-08 JP Rosevear <jpr@ximian.com>
-
- * README: Update pilot information
-
-2001-08-07 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Require gal 0.10.99.1 or greater.
-
-2001-08-05 Ettore Perazzoli <ettore@ximian.com>
-
- [Fixes #5594, "killev doesn't kill all evolution processes".]
-
- * tools/killev: Added bonobo-moniker-xmldb, gnome-gtkhtml-editor
- and gnome-spell-component.
-
-2001-07-31 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Bump version number to 0.12.99.
-
-2001-07-31 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Ooops. We want GAL >= 0.10.0 and GtkHTML >=
- 0.11.0.
-
-2001-07-31 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Remove `$EVOLUTION_MICRO_VERSION' from `VERSION'.
- (EVO_CHECK_LIB):
-
-2001-07-31 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Bump version number to 0.12.0.
-
-2001-07-31 Ettore Perazzoli <ettore@ximian.com>
-
- * NEWS: Added info about the shell changes and slightly changed
- the formatting for the addressbook ones.
-
- * configure.in: Require GtkHTML 0.10.0 and GAL 0.9.0.
-
-2001-07-31 Christopher James Lahey <clahey@ximian.com>
-
- * NEWS (Addressbook): Updated NEWS for addressbook.
-
-2001-07-31 Larry Ewing <lewing@ximian.com>
-
- * configure.in: bump required version of gtkhtml to 0.10.99.
-
-2001-07-20 JP Rosevear <jpr@ximian.com>
-
- * configure.in: Bump to 0.11.99
-
-2001-07-17 Dan Winship <danw@ximian.com>
-
- * configure.in: Fix up the "exactly version N" case of EVO_CHECK_LIB
-
-2001-07-16 Not Zed <NotZed@Ximian.com>
-
- * configure.in: Changed to use test -h instead of -L for checking
- /var/mail vs /var/spool/mail
-
-2001-07-13 JP Rosevear <jpr@ximian.com>
-
- * NEWS: more updates
-
-2001-07-13 Jeffrey Stedfast <fejj@ximian.com>
-
- * NEWS (Mail): Merged mine and Peter's entries.
-
-2001-07-12 JP Rosevear <jpr@ximian.com>
-
- * NEWS: Start new entry
-
-2001-07-11 Peter Williams <peterw@ximian.com>
-
- * acconfig.h: Add HAVE_BROKEN_SPOOL here.
-
-2001-07-10 Peter Williams <peterw@ximian.com>
-
- * configure.in (have_nss_includes): Fix nss include check to work.
-
-2001-07-11 Not Zed <NotZed@Ximian.com>
-
- * configure.in: Added option --with-broken-spool for solaris mbox
- spool format.
-
-2001-07-10 Marius Andreiana <mandreiana@yahoo.com>
-
- * configure.in: Added ro (Romanian) to ALL_LINGUAS
-
-2001-07-05 Peter Williams <peterw@ximian.com>
-
- * configure.in (SYSTEM_MAIL_DIR): Make sure /var/mail
- isn't a symbolic link such as on Red Hat 7.
-
-2001-07-05 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Upped the required version of gal.
-
-2001-07-03 Dietmar Maurer <dietmar@ximian.com>
-
- * *: use bonobo-conf everywhere
-
-2001-07-03 Damon Chaplin <damon@ximian.com>
-
- * configure.in (MAILER_LIBS):
- (MAILER_CFLAGS): added bonobo_conf.
-
-2001-07-02 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Made evolution depend on bonobo-conf 0.2.
-
-2001-07-02 Larry Ewing <lewing@ximian.com>
-
- * configure.in: Check for gtkhtml 0.9.99.1.
-
-2001-07-02 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Check for libGal 0.8.99.7.
-
-2001-07-02 Peter Williams <peterw@ximian.com>
-
- * configure.in (evolution_db_version): s,AC_DEFINE,AC_DEFINE_UNQUOTED
- to make these not totally useless.
-
-2001-07-01 Ettore Perazzoli <ettore@ximian.com>
-
- * Makefile.am (SUBDIRS): Build the composer after the addressbook,
- as it needs some CORBA stuff from the latter.
-
-2001-06-30 Federico Mena Quintero <federico@ximian.com>
-
- * tools/killev: Added evolution-alarm-notify.
-
-2001-06-29 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Require GAL 0.8.99.6.
-
-2001-06-29 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Add `camel/tests/mime-filter/Makefile' to the
- `AC_OUTPUT()' list.
-
-2001-06-27 Peter Williams <peterw@ximian.com>
-
- * configure.in (gal): Bump required gal version for new accessors
- in ETree.
-
-2001-06-24 Chris Toshok <toshok@ximian.com>
-
- * configure.in: add addressbook/gui/contact-list-editor, and
- correct path of contact-editor.
-
-2001-06-21 Rodrigo Moya <rodrigo@gnome-db.org>
-
- * libwombat/: added new directory for the libwombat library, which
- will contain the implementation of all CORBA interfaces defined
- in the wombat.idl file
-
-2001-06-21 Dan Winship <danw@ximian.com>
-
- * configure.in: Fix the OpenLDAP check to default to "no" if you
- don't specify anything.
-
-2001-06-20 Kevin Breit <battery841@mediaone.net>
-
- * docs/C/usage-sync: Reworded a little bit for more descrip.
-
-2001-06-20 Kevin Breit <battery841@mediaone.net>
-
- * doc/C/usage-calendar.sgml: Documented categorizing an event.
-
-2001-06-20 Kevin Breit <battery841@mediaone.net>
-
- * doc/C/usage-mail.sgml: Updated Bcc: example
-
-2001-06-20 Dan Winship <danw@ximian.com>
-
- * configure.in: Change --enable-ldap to --with-openldap, allow a
- path prefix as an argument. Add some libtooly goodness to the
- libldap check in case it depends on ssl libraries.
-
-2001-06-19 Dan Winship <danw@ximian.com>
-
- * configure.in: Tweak the db3 header check to like our RH7 build
- machine again.
-
-2001-06-19 Christopher James Lahey <clahey@ximian.com>
-
- * libversit/vcc.y (LexBuf): Changed buf to an int here.
- (lexGetQuotedPrintable): Changed cur to an int here.
-
-2001-06-18 Dan Winship <danw@ximian.com>
-
- * configure.in: Add "--with-db3" to fill in both
- --with-db3-includes and --with-db3-libs. Make them get cached
- properly so you don't need to specify it every time. Simplify some
- code.
-
- * acconfig.h: Add #defines for the current supported db3 version
- so that when we change it we don't have to hunt all of them down
-
-2001-06-18 Dan Winship <danw@ximian.com>
-
- * configure.in: Check the modes on $system_mail_dir and set up
- variables for camel/Makefile to make camel-lock-helper
- setuid/setgid.
-
-2001-06-11 JP Rosevear <jpr@ximian.com>
-
- * configure.in: One slight db3 check correction
-
-2001-06-11 Chris Toshok <toshok@ximian.com>
-
- * configure.in: fix typo in -ldb3 check.
-
-2001-06-11 JP Rosevear <jpr@ximian.com>
-
- * configure.in: Update db3 configure checks for RedHat. /me beats
- a sleeping cat to death
-
-2001-06-09 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped required version of gal to 0.8.99.2.
-
-2001-06-09 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Added addressbook/gui/merging/Makefile.
-
-2001-06-08 Jason Leach <jleach@ximian.com>
-
- * my-evolution/Makefile.am (INCLUDES): builddir != srcdir fix.
-
-2001-06-08 Iain Holmes <iain@ximian.com>
-
- * Makefile.am: Byebye executive-summary, hello my-evolution
-
- * configure.in: Remove all the executive-summary Makefiles. Add the
- my-evolution.
-
-2001-06-08 Jon Trowbridge <trow@ximian.com>
-
- * AUTHORS: Vanity, thy name is trow.
-
-2001-06-05 JP Rosevear <jpr@ximian.com>
-
- * config.log: Bump version to 0.10.99
-
-2001-05-31 Christopher James Lahey <clahey@ximian.com>
-
- * README: Included information about db3.
-
- * acconfig.h: Added HAVE_DB_H and HAVE_DB3_DB_H.
-
- * configure.in: Added various checks for db3 libraries and
- includes. Of note are the new configure options
- --with-db3-includes=PREFIX and --with-db3-libs=PREFIX to specify
- the location for your db3 library.
-
-2001-05-31 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in (GTKHTML_DATADIR): Use --moddatadir to derive this.
-
-2001-05-30 Dan Winship <danw@ximian.com>
-
- * configure.in: Bump gal dependency to 0.8.99.1
-
-2001-05-29 JP Rosevear <jpr@ximian.com>
-
- * README: update version requirements
-
-2001-05-23 Dan Winship <danw@ximian.com>
-
- * README: Remove reference to verify-evolution-install.sh since it
- doesn't work any more.
-
- * configure.in (EVO_CHECK_LIB): allow this to take a max version
- too, mostly so we can bound the allowable gal versions for
- releases, but also to require libxml < 2.0.
- (OpenSSL): Fixicate to work on NetBSD (OpenSSL in /usr, no libdl).
-
-2001-05-23 Kjartan Maraas <kmaraas@gnome.org>
-
- * tools/killev: s/evolution-vcard-import/evolution-vcard-importer
-
-2001-05-22 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Create MAILER_CFLAGS and MAILER_LIBS so that we
- don't have the same libs multiple times in the libtool
- command-line.
-
-2001-05-20 Duncan Mak <duncan@ximian.com>
-
- * tools/killev (sysname): Add in evolution-vcard-importer as part
- of the list of processes to kill in killev.
-
-2001-05-18 Jon Trowbridge <trow@ximian.com>
-
- * Makefile.am (SUBDIRS): Changed build order. Now addressbook
- gets built before mail.
-
-2001-05-15 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Create CAMEL_CFLAGS and CAMEL_LIBS so that we
- don't have to link in all sorts of unnecessary garbage from GNOME
- that we don't need.
-
-2001-05-15 Chris Toshok <toshok@ximian.com>
-
- * tools/killev: add the importers.
-
-2001-05-14 Kevin Breit <battery841@mediaone.net>
-
- * doc/C/evolution-C.omf: added file for Scrollkeeper
-
-2001-05-09 Chris Toshok <toshok@ximian.com>
-
- * configure.in: add the nspr includes to the list of includes used
- to test for NSS headers, and don't assume -lpthread in the
- nss/nspr libs - use PTHREAD_LIB.
-
-2001-05-09 Iain Holmes <iain@ximian.com>
-
- * tools/killev: Added rdf-summary killing stuff from R Burton
- (r.burton@180sw.com)
-
-2001-05-09 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: OpenSSL LDFLAGS also needs to include -lcrypt
-
-2001-05-08 Iain Holmes <iain@ximian.com>
-
- * Makefile.am: Add the importers subdir.
-
- * configure.in: Make the importers/Makefile
-
-2001-05-08 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped check for gal to 0.7.99.3.
-
-2001-05-04 Jeffrey Stedfast <fejj@ximian.com>
-
- * acconfig.h: undef HAVE_SSL and HAVE_OPENSSL
-
- * configure.in: Check for OpenSSL.
-
-2001-05-05 Gediminas Paulauskas <menesis@delfi.lt>
-
- * configure.in: upped required gtkhtml version to 0.9.3, even that is
- not enough for idl changes.
- * README: you need LIB_XML_1_BRANCH. updated all version requirements
- from configure.in
-
-2001-04-26 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Don't autogen
- `executive-summary/widgets/Makefile', as that subdir doesn't get
- distributed anymore.
-
-2001-04-26 Dan Winship <danw@ximian.com>
-
- * README: We no longer depend on libunicode.
-
- * configure.in: Remove check for libunicode. Remove unicode cflags
- and libs from all CFLAGS and LIBS variables. Add GAL_LIBS for
- things that need to depend on just gal (for gunicode).
-
- * configure.in: Check for gethostbyname_r so e_gethostbyname_r
- will DTRT.
-
-2001-04-24 Dan Winship <danw@ximian.com>
-
- * configure.in: Bump up the gal requirement
-
-2001-04-23 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Don't autogen the the Makefile for the importer
- docs.
-
- * Makefile.am (SUBDIRS): Build the docs last.
-
-2001-04-21 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in (have_nspr_libs): We need to link in more than just
- libnspr4, we also need libpthread.
- (have_nss_libs): Don't forget to add nsprlibs to the LDFLAGS.
-
-2001-04-21 Duncan Mak <duncan@ximian.com>
-
- * art/Makefile.am (images_DATA): Added in composer-message.png.
-
-2001-04-16 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: `mail/importers/Makefile' must come after
- `mail/Makefile'.
-
-2001-04-16 Ettore Perazzoli <ettore@ximian.com>
-
- * Makefile.am (SUBDIRS): Add `doc'.
-
- * configure.in: Check for Editor.idl using `$GNOME_PATH' as well.
-
-2001-04-12 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Updated the required version of gal to 0.6.99.0.
-
-2001-04-11 JP Rosevear <jpr@ximian.com>
-
- * configure.in: Check if gethostbyname_r take five params
-
- * acconfig.h: add GETHOSTBYNAME_R_FIVE_ARGS
-
-2001-04-10 Gediminas Paulauskas <menesis@delfi.lt>
-
- * AUTHORS: /me is a translator.
- * configure.in (EVO_CHECK_LIB): fail with AC_MSG_ERROR, not echo &&
- exit 1.
-
-2001-04-10 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in (EVOLUTION_DIR): create the makefile in
- camel/tests/smime
-
-2001-04-08 Chris Toshok <toshok@ximian.com>
-
- * tools/killev (sysname): add some more 16 character versions for
- freebsd.
-
-2001-04-04 Kjartan Maraas <kmaraas@gnome.org>
-
- * AUTHORS: Brag.
-
-2001-04-04 Gediminas Paulauskas <menesis@delfi.lt>
-
- * art/evolution-today-mini.png: converted from exec-16-summary.xpm,
- removed the latter.
- * art/evolution-trash.png, art/evolution-trash-mini.png: images for
- trash folder, one converted from deleted_message.xpm, another from mc.
- * art/Makefile.am: install.
-
-2001-04-02 Jeffrey Stedfast <fejj@ximian.com>
-
- * README (SSL): Remind users that they will currently have to copy
- their cert database from their mozilla directory into ~/evolution.
-
-2001-04-01 Gediminas Paulauskas <menesis@delfi.lt>
-
- * art/Makefile.am: added missing (new) files.
-
-2001-03-30 Dan Winship <danw@ximian.com>
-
- * configure.in (EVOLUTION_MICRO_VERSION): Bump this to 10. (We
- forgot to do this before branching *again*...)
-
-2001-03-28 Dan Winship <danw@ximian.com>
-
- * README: add a bit mentioning that if configure claims you don't
- have something installed when you think you do, that it's probably
- because you installed it in the wrong prefix, or because you need
- a -devel package.
-
- * configure.in: Add a new macro EVO_CHECK_LIB that checks for a
- gnome-config-based library of a given version or later, correctly,
- and if doesn't find it, suggests that you consult the README. Fix
- the various library checks to use this. Meanwhile, remove a bunch
- of old cruft and reorganize a little.
-
- * acconfig.h: Remove cruft
-
-2001-03-28 Jon Trowbridge <trow@ximian.com>
-
- * AUTHORS: In a burst of egomania, added myself.
-
-2001-03-26 Radek Doulik <rodo@ximian.com>
-
- * configure.in: create camel/misc/Makefile
-
-2001-03-22 Dan Winship <danw@ximian.com>
-
- * README: Update xml-i18n-tools version
-
-2001-03-22 Jakub Steiner <jimmac@ximian.com>
-
- * art/new-message.xpm: file->new->mail message
- * art/folder.xpm: file->new->folder
- * art/new_appointment.xpm: file->new->appontment
- * art/print-preview.xpm: file->print preview
- * art/configure_16_calendar.xpm: for the tools menu
-
-2001-03-22 Jakub Steiner <jimmac@ximian.com>
-
- * art/splash.png: move it a bit up so the icons fit better
-
-2001-03-22 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped gal requirement to 0.5.99.11.
-
-2001-03-22 Jakub Steiner <jimmac@ximian.com>
-
- * art/configure_16_folder.xpm, configure_16_mail.xpm,
- copy_16_message.xpm, edit.xpm, encrypt.xpm,
- evo-16-address-conduit.png, evo-16-calendar-conduit.png,
- evo-16-todo-conduit.png, exec-16-summary.xpm, import.xpm,
- print.xpm, reply_to_all.xpm, reply.xpm, save.xpm,
- send-receive.xpm, work_offline.xpm, find_contact.xpm,
- send-24-receive.png, evo-48-calendar-conduit.png,
- evo-48-todo-conduit.png, import.png, send-48-receive.png,
- move_message.xpm, all_contacts.xpm, forward.xpm,
- configure_16_addressbook.xpm, Makefile.am,
- evo-48-address-conduit.png: renamed icons to make Miguel's
- speedups possible
- * art/evolution-inbox.png: color coded one
- * art/envelope.png: reverted back to the non-color coded one
- * art/evolution-contacts-plain.png: non-color coded one for
- the "new contact" dialogue
-
-2001-03-21 Dan Winship <danw@ximian.com>
-
- * configure.in: Require bison, not yacc (for vcc.y)
-
-2001-03-20 Miguel de Icaza <miguel@ximian.com>
-
- * art/Makefile.am (images_DATA): Added all the new icons to the
- distribution.
-
-2001-03-20 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: More fixes for NSPR and NSS checks - use fixed it
- to use AC_CHECK_HEADERS instead of AC_CHECK_FILES. Also made it
- not default the nspr lib path to /usr/lib/mozilla which may not be
- in the user's library path when checking for nspr libs.
-
-2001-03-20 Jakub Steiner <jimmac@ximian.com>
-
- * art/48_send-receive.png: send-receive for the s/r dialog
- * art/24_send-receive.png: send-receive to replace the
- fetch-mail-doggie
- * art/16_send-receive.xpm: send-receive for (future) menu
- item
- * art/16_import.xpm: for the file menu
- * art/16_work_offline.xpm: for the file menu
- * AUTHORS: so I can show off
- * art/splash.png: making radek famous ;)
- * art/envelope.png, evolution-calendar.png, evolution-contacts.png,
- evolution-tasks.png, evolution-today.png:
- new concept of color coded apps:
- - mailer: #efb43e
- - calendar: #bab5ab
- - contacts: #9794ab
- - tasks: #6e9e6e
- - exec. summary: #c4757e
-
-2001-03-19 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Fix ettore's fix ;-)
-
-2001-03-19 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Bumped gal requirement to 0.5.99.8.
-
-2001-03-19 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Make sure we never define `NSPR_CFLAGS' or
- `NSS_CFLAGS' as just "-I".
-
-2001-03-19 Jeffrey Stedfast <fejj@ximian.com>
-
- * NEWS: pulled from the 0.9 release.
-
-2001-03-18 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Updated the checks for NSS and NSPR
-
-2001-03-16 Jeffrey Stedfast <fejj@ximian.com>
-
- * README: Added directions on how to build with SSL support.
-
- * configure.in: Updated the checks for NSS and NSPR
-
-2001-03-16 Jakub Steiner <jimmac@ximian.com>
-
- * art/48_import.png: for the import druid
-
-2001-03-15 Dan Winship <danw@ximian.com>
-
- * configure.in: Bump gal requirement to 0.5.99.7
-
-2001-03-15 Gediminas Paulauskas <menesis@delfi.lt>
-
- * configure.in: create doc/devel/executive-summary/Makefile
- * evolution.png: moved to art/.
- * evolution.desktop: moved to data/.
- * Makefile.am: reflect those moves.
- * art/*.xpm: moved 8 files from calendar/gui here.
- * art/Makefile.am: added moved files.
- distribute *.xpm, install *.png and *view.xpm.
-
-2001-03-12 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Updated to AC_SUBST the NSPR/NSS flags.
-
-2001-03-14 Dan Winship <danw@ximian.com>
-
- * README: Pull up some of the clarifications from the 0.9 branch
-
-2001-03-13 Chris Toshok <toshok@ximian.com>
-
- * configure.in: add -lresolv to LDAP_LIBS if it's there.
-
-2001-03-13 Iain Holmes <iain@ximian.com>
-
- * configure.in: Added the mail/importers dir.
-
-2001-03-12 Jeffrey Stedfast <fejj@ximian.com>
-
- * README: Rearranged some of the dependencies to try to get them
- into a more correct order (needed for people building all of these
- packages by hand).
-
-2001-03-12 JP Rosevear <jpr@ximian.com>
-
- * README: Update
-
-2001-03-09 Dan Winship <danw@ximian.com>
-
- * configure.in (EVOLUTION_MICRO_VERSION): Hm... probably would be
- clever to be calling this 0.9 rather than 0.8, since it's almost
- 0.10.
-
-2001-03-09 Christopher James Lahey <clahey@ximian.com>
-
- * libversit/vcc.y: Changed int to char when returning a character
- from a stream (since it needs to be able to hold EOF.)
-
-2001-03-07 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Removed --enable-assbarn-security and replaced it
- with the real options:
- --with-nspr-includes=PREFIX
- --with-nspr-libs=PREFIX
- --with-nss=PREFIX
-
- * acconfig.h: #undef HAVE_NSS
-
-2001-03-07 Ettore Perazzoli <ettore@ximian.com>
-
- * configure.in: Require GAL 0.5.99.6 or later.
-
-2001-03-07 Kjartan Maraas <kmaraas@gnome.org>
-
- * shell/main: /* xgettext:no-c-format */ before the welcome
- message.
- * configure.in: Don't try to generate a Makefile in
- camel/providers/vee as it's empty.
-
-2001-03-05 JP Rosevear <jpr@ximian.com>
-
- * README: Update pilot instructions
-
-2001-03-05 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Check for gal 0.5.99.4.
-
-2001-03-04 Dan Winship <danw@ximian.com>
-
- * configure.in: Reorganize a bit to get rid of warnings about
- AC_TRY_COMPILE being used before AC_ISC_POSIX
-
-2001-03-04 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Added views/addressbook/Makefile.
-
-2001-03-02 JP Rosevear <jpr@ximian.com>
-
- * art/Makefile.am: install conduit icons
-
-2001-03-02 Chris Toshok <toshok@ximian.com>
-
- * configure.in: add logic to make sure we're building against OpenLDAP >= 2
-
-2001-03-01 Christopher James Lahey <clahey@ximian.com>
-
- * Makefile.am (SUBDIRS), configure.in: Added views stuff.
-
-2001-03-01 Dan Winship <danw@ximian.com>
-
- * configure.in: Redo the Kerberos stuff again to deal with the
- stuff currently on my machine. I think it should deal with both
- the MIT and KTH versions of both krb4 and krb5 now.
-
-2001-03-01 Jakub Steiner <jimmac@ximian.com>
-
- * art/48_evo-address-conduit.png: 48^2 version of the
- addressbook pilot conduit. (for the new control center)
- * art/16_evo-address-conduit.png: 16x16 version for current
- gnomecc
- * art/48_evo-todo-conduit.png: for new gnomecc
- * art/16_evo-todo-conduit.png: for old gnomecc
- * art/48_evo-calendar-conduit.png: for new gnomecc
- * art/16_evo-calendar-conduit.png: for old gnomecc
-
-2001-03-01 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Check for gal 0.5.99.2.
-
-2001-02-19 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Check for gal 0.5.99.1.
-
-2001-02-15 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Check for gal 0.5.99.0.
-
-2001-02-14 Dan Winship <danw@ximian.com>
-
- * various .cvsignore files: Ignore generated .oaf files
-
-2001-02-13 JP Rosevear <jpr@ximian.com>
-
- * art/Makefile.am: install new files
-
- * art/*view.xpm: add files from calendar/gui
-
-2001-02-11 Chris Toshok <toshok@ximian.com>
-
- * configure.in: rework ldap check logic so it'll work to
- --disable-ldap if you've previously configured with --enable-ldap.
-
-2001-02-11 Gediminas Paulauskas <menesis@delfi.lt>
-
- * data/evolution.keys, evolution.desktop: removed, they are generated.
- * data/evolution.keys.in, evolution.desktop.in: new untranslated files.
- * data/evolution.desktop: removed, it duplicates above.
- * Makefile.am, data/Makefile.am: reflect above changes, merge
- translations.
-
-2001-02-09 Jeffrey Stedfast <fejj@ximian.com>
-
- * configure.in: Added hacks to check for Mozilla libs like nspr
- and nss that we will need for SSL and S/MIME.
-
-2001-02-09 Michael Meeks <michael@ximian.com>
-
- * configure.in: depend on bonobo >= 0.36
-
-2001-02-08 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Upped the version number of gal required to 0.5.
-
-2001-02-07 JP Rosevear <jpr@ximian.com>
-
- * README: Update to latest requirements
-
-2001-02-05 Jeffrey Stedfast <fejj@ximian.com>
-
- * .cvsignore: Added xml-* files.
-
-2001-02-05 Gustavo Maciel Dias Vieira <gdvieira@zaz.com.br>
-
- * configure.in (ALL_LINGUAS): Added pt_BR to ALL_LINGUAS.
-
-2001-02-04 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Require version 0.4.99.8 of gal.
-
-2001-02-03 Federico Mena Quintero <federico@ximian.com>
-
- * configure.in: Make sure we have gnome-libs 1.2.9 or higher.
-
-2001-02-01 Chris Toshok <toshok@ximian.com>
-
- * configure.in: allow --enable/disable-ldap.
-
-2001-02-01 Jason Leach <jasonleach@usa.net>
-
- * tools/killev: Fix this script to make it work with Solaris.
- Patch from Louise Miller.
-
-2001-01-29 Eskil Heyn Olsen <eskil@eazel.com>
-
- reviewed by: JP Rosevear <jpr@ximian.com>
-
- * acconfig.h:
- Added the ENABLE_NNTP define
-
- * configure.in:
- Fixed the NNTP m4 section.
-
-2001-01-29 Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz>
-
- * configure.in: added sk to ALL_LINGUAS.
- * evolution.desktop: added Slovak messages.
-
-2001-01-27 Jason Leach <jasonleach@usa.net>
-
- * configure.in (AC_OUTPUT): remove
- widgets/shortcut-bar/Makefile from here.
-
-2001-01-25 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Upped the required version of gal in evolution.
-
-2001-01-25 Ettore Perazzoli <ettore@ximian.com>
-
- * art/Makefile.am (images_DATA): Add the missing .xpm files.
-
-2001-01-25 Ettore Perazzoli <ettore@ximian.com>
-
- * art/Makefile.am (images_DATA): Add `24_find_contacts.xpm',
- `16_print_xpm', `16_configure_addressbook'.
-
-2001-01-25 Ettore Perazzoli <ettore@ximian.com>
-
- * art/Makefile.am (images_DATA): Add `24_all_contacts.xpm'.
-
-2001-01-24 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Upped the required version of gal in evolution.
-
-2001-01-22 Tuomas Kuosmanen <tigert@ximian.com>
-
- * art/splash.png: From the "Ideas from the shower" department:
- new splash screen.
-
-2001-01-17 JP Rosevear <jpr@ximian.com>
-
- * README: Update package requirements
-
-2001-01-19 Jason Leach <jasonleach@usa.net>
-
- * configure.in: Changed a leftover $with_x_mailer to
- $with_sub_version. Made it so that if $with_sub_version isn't
- specified, we don't try to output it, and also corrected the way
- SUB_VERSION is defined.
-
-2001-01-18 Federico Mena Quintero <federico@ximian.com>
-
- * Makefile.am: Um, why was the doc directory removed from SUBDIRS?
-
-2001-01-17 Larry Ewing <lewing@helixcode.com>
-
- * configure.in (EVOLUTION_DIR): add the
- doc/devel/importer/Makefile as a target.
-
-2001-01-17 Ettore Perazzoli <ettore@ximian.com>
-
- * acconfig.h: Add `SUB_VERSION', remove `XMAILER_VERSION'.
-
- * configure.in: Removed `--with-x-mailer' option; replaced with a
- more generic `--with-sub-version' option. So, don't define
- `X_MAILER'; instead, define `SUB_VERSION'.
-
-2001-01-16 Chris Toshok <toshok@helixcode.com>
-
- * configure.in: add --enable-nntp switch. default is no.
-
-2001-01-16 Dan Winship <danw@ximian.com>
-
- * configure.in, acconfig.h: Add --with-x-mailer to set the version
- string that appears in the X-Mailer header.
-
-2001-01-15 Christopher James Lahey <clahey@ximian.com>
-
- * configure.in: Changed the required version of gal.
-
-2001-01-15 Tuomas Kuosmanen <tigert@ximian.com>
-
- * art/16_copy_message.xpm, art/16_move_message.xpm: icons for the
- Message->Move/Copy to folder -menu entries.
-
-2001-01-15 Tuomas Kuosmanen <tigert@ximian.com>
-
- * art/evolution-calendar-mini.png: New version of calendar icon that
- looks more like a calendar and not a dictionary or something :)
-
- Btw, the icons get scaled for some reason, even though that is
- not necessary as all of those should be 16x16 pixels. Can anyone look
- into this?
-
-2001-01-15 Dietmar Maurer <dietmar@ximian.com>
-
- * *.c: changed the signature of the property_bag get/set
- functions.
-
-2001-01-14 JP Rosevear <jpr@ximian.com>
-
- * configure.in: remove old config message
-
-2001-01-14 Damon Chaplin <damon@helixcode.com>
-
- * tools/evolution-move-tasks: new script to move tasks from the
- Calendar folder to the new Tasks folder, so people won't lose tasks.
- This can be deleted after a few releases.
-
- * tools/Makefile.am (bin_SCRIPTS): added above.
-
- * configure.in: added default_user/local/Tasks/Makefile to AC_OUTPUT.
-
-2001-01-12 Jeffrey Stedfast <fejj@ximian.com>
-
- * config.h.in: Removed GPG stuff.
-
- * acconfig.h: Take out all refs to PGP and GPG stuff.
-
- * configure.in: Take out the PGP/GPG detection stuff.
-
-2001-01-12 Federico Mena Quintero <federico@ximian.com>
-
- * configure.in: Suggest what to do if gtk-doc is not found.
-
-2001-01-12 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Make evolution depend on the new version of gal.
-
-2001-01-12 Dan Winship <danw@ximian.com>
-
- * MAINTAINERS, AUTHORS, README: Ximianize. Also update the README
- a bit and mention the OAF stable branch.
-
-2001-01-11 Dan Winship <danw@helixcode.com>
-
- * art/priority-high.xpm: Add a white outline around the "!" so it
- still shows up clearly in selected rows when your theme selection
- color is reddish. (Problem pointed out by Federico.)
-
-2001-01-11 Federico Mena Quintero <federico@helixcode.com>
-
- * configure.in: At the end of the configure process, report
- whether the documentation files will be built or not.
-
-2001-01-10 Tuomas Kuosmanen <tigert@helixcode.com>
-
- * art/move-message.png, art/move-message.png: New versions.
-
-2001-01-09 Federico Mena Quintero <federico@helixcode.com>
-
- * configure.in (AC_OUTPUT): Added calendar/gui/alarm-notify/Makefile.
-
-2001-01-05 Tuomas Kuosmanen <tigert@helixcode.com>
-
- * art/evolution-contacts-mini.png: This looks more pretty.
-
-2001-01-03 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Removed camel/providers/mbox/Makefile and
- camel/providers/mh/Makefile.
-
-2001-01-01 Michael Meeks <michael@helixcode.com>
-
- * configure.in: Require bonobo 0.31
-
-2000-12-24 Not Zed <NotZed@HelixCode.com>
-
- * configure.in: If we find threads ok, then always turn on
- ENABLE_THREADS.
-
-2000-12-14 Christopher James Lahey <clahey@helixcode.com>
-
- * NEWS (Addressbook): Added a bit of addressbook NEWS.
-
- * configure.in: Updated the gal check to require gal 0.4.
-
-2000-12-14 Christopher James Lahey <clahey@helixcode.com>
-
- * art/mail-new.xpm, art/mail-read.xpm, art/mail-replied.xpm: Moved
- these images each up one pixel.
-
-2000-12-14 Jeffrey Stedfast <fejj@helixcode.com>
-
- * NEWS: Update.
-
-2000-12-14 JP Rosevear <jpr@helixcode.com>
-
- * NEWS: Update
-
-2000-12-14 Christopher James Lahey <clahey@helixcode.com>
-
- * art/splash.png: New splash from Jimmac.
-
-2000-12-12 Christopher James Lahey <clahey@helixcode.com>
-
- * README: Removed mention of ETable and EText in widgets
- directory.
-
-2000-12-12 Dan Winship <danw@helixcode.com>
-
- * README: Mention the gconf stable branch.
-
-2000-12-07 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Updated the required version of gal.
-
-2000-12-07 Radek Doulik <rodo@helixcode.com>
-
- * configure.in (GTKHTML_LIBS): renamed HTMLEditor.idl to
- Editor.idl
-
-2000-12-06 Kjartan Maraas <kmaraas@gnome.org>
-
- * data/evolution.keys: Added some Norwegian translations.
-
-2000-12-06 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Increased the required version of gal.
-
-2000-12-05 JP Rosevear <jpr@helixcode.com>
-
- * README: minor tweak
-
-2000-12-05 Not Zed <NotZed@HelixCode.com>
-
- * configure.in: Added camel/tests/stream/Makefile.am.
-
-2000-12-01 Dan Winship <danw@helixcode.com>
-
- * README: gnome-vfs depends on gconf, so add that.
-
-2000-11-30 Jeffrey Stedfast <fejj@helixcode.com>
-
- * configure.in: Bumped required gal version to 0.2.99.4 for
- e_str_make_safe.
-
- * README: Added some necessary :'s in the pilot-link cvs stuff.
-
-2000-11-30 Gediminas Paulauskas <menesis@delfi.lt>
-
- * calendar/gui/main.c, executive-summary/component/main.c, mail/main.c,
- shell/main.c, notes/main.c,
- addressbook/gui/component/addressbook-factory.c:
- removed #ifdef ENABLE_NLS/#endif on Miguel's request.
-
-2000-11-29 JP Rosevear <jpr@helixcode.com>
-
- * README: Update pilot info
-
-2000-11-29 Dan Winship <danw@helixcode.com>
-
- * configure.in: Bump required gal version to 0.2.99.3 for iconv
- changes
-
-2000-11-29 Federico Mena Quintero <federico@helixcode.com>
-
- * COPYING-DOCS: Added a copy of the GNU Free Documentation
- License.
-
- * Makefile.am (EXTRA_DIST): Added COPYING-DOCS.
-
-2000-11-28 JP Rosevear <jpr@helixcode.com>
-
- * acconfig.h: Add USE_FLOCK, USE_FCNTL, USE_FLOCK
-
- * configure.in: Auto* magic for various camel locking types
-
-2000-11-28 Not Zed <NotZed@HelixCode.com>
-
- * configure.in (AC_OUTPUT): Added camel/tests/folder/Makefile
-
-2000-11-27 JP Rosevear <jpr@helixcode.com>
-
- * AUTHORS: Update - hopefully I assigned blame correctly :-)
-
- * MAINTAINERS: ditto
-
-2000-11-27 JP Rosevear <jpr@helixcode.com>
-
- * configure.in: Correct the bonobo version error message
-
- * README: Update
-
-2000-11-24 Not Zed <NotZed@HelixCode.com>
-
- * configure.in: Added camel/tests stuff to output macro.
-
-2000-11-14 Not Zed <NotZed@HelixCode.com>
-
- * configure.in: Added local provider dir to output macro.
-
-2000-11-21 Dan Winship <danw@helixcode.com>
-
- * configure.in: Check for libgpgme. (Support not added to mail
- yet.)
-
-2000-11-21 Federico Mena Quintero <federico@helixcode.com>
-
- * configure.in (EVOLUTION_DIR): Removed the
- default_user/local/Tasks/Makefile until the relevant files are on
- CVS.
-
-2000-11-18 Miguel de Icaza <miguel@helixcode.com>
-
- * Added widgets/menus that contains the gal-view-menus.c code from
- Gal that depended on Bonobo.
-
- * configure.in: Update list of Makefiles;
-
- * widgets/Makefile.am: Update.
-
-2000-11-13 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Update the gal reqiurement version.
-
-2000-11-10 Michael Meeks <michael@helixcode.com>
-
- * configure.in: Require Bonobo >= 0.29, due to the XSync
- fix.
-
-2000-11-09 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Require gal 0.2.99.1.
-
-2000-11-06 Jeffrey Stedfast <fejj@helixcode.com>
-
- * configure.in: Require gal 0.2.1.3
-
-2000-11-06 Dan Winship <danw@helixcode.com>
-
- * configure.in (GTKHTML_LIBS): ${prefix} doesn't get defaulted
- until the end of configure, so check if it's "NONE" and use
- ${ac_default_prefix} if so.
-
-2000-11-06 Radek Doulik <rodo@helixcode.com>
-
- * configure.in (GTKHTML_LIBS): also look for HTMLEditor.idl in
- ${prefix}/share/gtkhtml
-
-2000-11-03 Radek Doulik <rodo@helixcode.com>
-
- * configure.in (BONOBO_HTML_GNOME_CFLAGS): raise required version
- number to 0.8
- added check for HTMLEditor.idl file
-
-2000-11-02 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Require gal 0.2.1.2.
-
-2000-11-02 Michael Meeks <michael@helixcode.com>
-
- * configure.in: Require Bonobo-0.27+
-
-2000-11-01 Gediminas Paulauskas <menesis@delfi.lt>
-
- * addressbook/ename/.cvsignore, addressbook/gui/minicard/.cvsignore,
- calendar/doc/.cvsignore, widgets/e-paned/.cvsignore,
- widgets/e-table/.cvsignore, widgets/e-text/.cvsignore: added these
- files.
- * calendar/gui/.cvsignore, composer/.cvsignore,
- executive-summary/.cvsignore, executive-summary/component/.cvsignore,
- po/.cvsignore: added some files to ignore.
-
- * addressbook/gui/component/addressbook-factory.c, mail/main.c,
- shell/main.c, calendar/gui/main.c, notes/main.c,
- executive-summary/component/main.c: call *textdomain() only if
- ENABLE_NLS is defined.
-
-2000-11-01 Gediminas Paulauskas <menesis@delfi.lt>
-
- * configure.in: added lt to ALL_LINGUAS.
-
-2000-10-30 Dan Winship <danw@helixcode.com>
-
- * configure.in: fix up printing of kerberos configuration status
-
-2000-10-27 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Require gal cvs version.
-
-2000-10-27 <jpr@helixcode.com>
-
- * tools/killev: Kill executive summary components
-
-2000-10-25 Iain Holmes <iain@helixcode.com>
-
- * configure.in: Added executive-summary stuff
-
- * Makefile.am: Added the executive-summary subdirs.
-
-2000-10-23 Dan Winship <danw@helixcode.com>
-
- * notes/Makefile.am (INCLUDES): Update EVOLUTION_LOCALEDIR
-
- * configure.in: set localedir here to use in Makefiles.
- (AM_GNOME_GETTEXT doesn't actually always set it to
- $(datadir)/locale).
-
-2000-10-23 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Updated the gal check to check for gal 0.2.1.
-
-2000-10-22 Robert Brady <rwb197@zepler.org>
-
- * configure.in: Added "en_GB" to ALL_LINGUAS.
-
-2000-10-20 Michael Meeks <michael@helixcode.com>
-
- * notes/component-factory.c (control_activate_cb):
-
-2000-10-19 Christopher James Lahey <clahey@helixcode.com>
-
- * NEWS (General, Addressbook): Updated NEWS for addressbook and
- ETable.
-
-2000-10-19 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Updated the gal check to check for gal 0.2.
-
-2000-10-19 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in (EVOLUTION_MICRO_VERSION): 6.
-
- * Makefile.am (EXTRA_DIST): Remove `evolution.spec.in'.
- (dist-hook:): Removed.
-
-2000-10-18 Michael Meeks <michael@helixcode.com>
-
- * notes/component-factory.c (control_activate, control_deactivate),
- (create_view): cripple, not worth updating to new UI code.
-
-2000-10-17 Tuomas Kuosmanen <tigert@helixcode.com>
-
- * art/splash.png: This looks happier than the dark piece of rusty
- metal. And the Big Dig in Boston is ugly looking too. Finnish
- road poles are much more cool!
-
-2000-10-15 Peter Williams <peterw@helixcode.com>
-
- * tools/verify-evolution-install.sh (libcamelvee): Check
- for linkage against version 0.5 libcamelvee, not version 0.3.
- This should track with the version of Evolution itself.
- (rm -f $ldddfile): Remove a temporary file.
-
-2000-10-15 Kjartan Maraas <kmaraas@gnome.org>
-
- * configure.in: Added "nn" to ALL_LINGUAS.
-
-2000-10-14 Ettore Perazzoli <ettore@helixcode.com>
-
- * art/Makefile.am (images_DATA): Add `splash.png'.
-
-2000-10-14 Tuomas Kuosmanen <tigert@helixcode.com>
-
- * art/splash.png: umm.. it's a splash screen image.
-
-2000-10-11 JP Rosevear <jpr@helixcode.com>
-
- * configure.in: Fix bonobo error message
-
-2000-10-11 Jesse Pavel <jpavel@helixcode.com>
-
- * data/evolution.keys: Added support for the text/calendar and
- text/x-calendar MIME types.
-
-2000-10-10 Gediminas Paulauskas <menesis@delfi.lt>
-
- * configure.in: Added lt to ALL_LINGUAS.
-
-2000-10-10 Tuomas Kuosmanen <tigert@helixcode.com>
-
- * calendar/gui/recur.xpm: Updated round-we-go-thingy icon..
-
-2000-10-06 Chris Toshok <toshok@helixcode.com>
-
- * art/empty.xpm: make it transparent instead of white.
-
-2000-10-06 Christophe Merlet <christophe@merlet.net>
-
- * *.desktop: Added french strings.
-
-2000-10-05 Dan Winship <danw@helixcode.com>
-
- * tools/Makefile.am (EXTRA_DIST): Add verify-evolution-install.sh
- to EXTRA_DIST
-
-2000-10-05 Jeffrey Stedfast <fejj@helixcode.com>
-
- * configure.in: Check for isblank
-
- * config.h.in:
- * acconfig.h: #undef HAVE_ISBLANK
-
-2000-10-05 Michael Meeks <michael@helixcode.com>
-
- * configure.in: Bump Bonobo requirement to >= 0.20
-
-2000-10-05 Iain Holmes <iain@helixcode.com>
-
- * executive-summary/*: Added the executive summary stuff.
-
- * ui/evolution-executive-summary.xml: New.
-
- * art/add-service.png: New icon.
-
-2000-10-03 Matt Bissiri <bissiri@eecs.umich.edu>
-
- * ui/evolution-addressbook-ldap.xml,
- * ui/evolution-addressbook.xml,
- * ui/evolution-calendar.xml,
- * ui/evolution-contact-editor.xml:
- Fixed typo `_decr' -> `_descr', so some missing tooltips will appear.
- Also fixed some typos in descr values.
-
-2000-09-29 Peter Williams <peterw@helixcode.com>
-
- * ui/Makefile.am (XML_FILES): Install the new evolution-subscribe.xml
- file.
-
-2000-09-29 Chris Toshok <toshok@helixcode.com>
-
- * ui/evolution-mail.xml: add a Settings/Manage Subscriptions...
- menu item.
-
- * ui/evolution-subscribe.xml: add a File/Close menu item.
-
-2000-09-28 Chris Toshok <toshok@helixcode.com>
-
- * ui/evolution-subscribe.xml: add a FolderSearch control, and
- change "Refresh" to "RefreshList".
-
-2000-09-27 Chris Toshok <toshok@helixcode.com>
-
- * ui/evolution-subscribe.xml: add an Refresh List button..
-
-2000-09-27 Chris Toshok <toshok@helixcode.com>
-
- * ui/Makefile.am (XML_FILES): add evolution-subscribe.xml.
-
- * ui/evolution-subscribe.xml: new file.
-
-2000-09-25 Jeffrey Stedfast <fejj@helixcode.com>
-
- * ui/evolution-mail.xml: Moved the (un)select all menu items over
- to the Edit menu - this looks nicer.
-
-2000-09-25 Jeffrey Stedfast <fejj@helixcode.com>
-
- * ui/evolution-mail.xml: Added some new menu items to the Message
- menu like (un)select all and moved "mark as read" to the Message
- menu.
-
-2000-09-25 Jeffrey Stedfast <fejj@helixcode.com>
-
- * configure.in: Moved addressbook/ename to e-util/ename so
- generate e-util/ename/Makefile and don't generate
- addressbook/ename/Makefile
-
-2000-09-23 Tuomas Kuosmanen <tigert@localhost>
-
- * art/attachment.xpm
- * art/add-attachment.png: OOPS. The attachment.xpm was not the one
- I thought, so I accidentally replaced the paperclip icon in the mail
- list column, which wasnt my intention. I hope this works now. The old
- one is back, instead the toolbar icon to add attachment is now called
- "add-attachment.png" as you can see also from above. Bummer. Sorry :)
-
-2000-09-22 Christopher James Lahey <clahey@helixcode.com>
-
- * libversit/vcc.y: Fixed some warnings. Fixed a bug where quoted
- printable fields were reading in semi-colons that should have been
- field separators.
-
-2000-09-22 Christopher James Lahey <clahey@helixcode.com>
-
- * ui/Makefile.am: Added evolution-addressbook-ldap.xml.
-
- * ui/evolution-addressbook-ldap.xml: New file. (A Variation on
- evolution-addressbook.xml)
-
- * ui/evolution-addressbook.xml: Added View All and Stop buttons.
-
-2000-09-21 Federico Mena Quintero <federico@helixcode.com>
-
- * ui/evolution-calendar.xml: Removed the AboutCalendar stuff.
-
- * ui/evolution.xml: Fix mis-spelling of "calendar".
-
-2000-09-21 Michael Meeks <michael@helixcode.com>
-
- * notes/component-factory.c (control_activate): upd.
-
-2000-09-20 Christopher James Lahey <clahey@helixcode.com>
-
- * ui/.cvsignore: Added a cvsignore file here.
-
-2000-09-20 Christopher James Lahey <clahey@helixcode.com>
-
- * ui/Makefile.am (XML_FILES): Added evolution-contact-editor.xml.
-
- * ui/evolution-contact-editor.xml: New file for the UI for the
- evolution contact editor.
-
-2000-09-20 Tuomas Kuosmanen <tigert@gimp.org>
-
- * art/attachment.xpm
- * art/send.png: new icons for "compose mail" dialog...
-
-2000-09-19 Dan Winship <danw@helixcode.com>
-
- * configure.in: alter the krb4 check a bit to deal with configure
- cache suckage. (If you do AC_CHECK_LIB with the same library and
- function name but different LDFLAGS, it will still use the result
- of the previous check. So use a different function the second
- time.)
-
-2000-09-18 Dan Winship <danw@helixcode.com>
-
- * README: add gal as a dependency
-
-2000-09-18 Jeffrey Stedfast <fejj@helixcode.com>
-
- * art/score-*.xpm: stupid looking icons for use with displaying
- scores in the message-list view. These need a makeover BADLY ;-)
-
-2000-09-18 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Added check for gnome-app-lib. Removed
- directories that have been moved to gal.
-
-2000-09-15 Dan Winship <danw@helixcode.com>
-
- * configure.in, evolution.spec.in: remove spec file. We haven't
- been keeping it up to date, and it's only good for RH anyway, and
- if people really want a spec file they can get it from our SRPMs.
-
-2000-09-07 Michael Meeks <michael@helixcode.com>
-
- * configure.in: Require Bonobo 0.19
-
-2000-09-13 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Added widgets/e-reflow/Makefile. Replaced
- addressbook/gui/minicard/Makefile with
- addressbook/gui/widgets/Makefile.
-
-2000-09-13 Tuomas Kuosmanen <tigert@localhost>
-
- * art/pin.png: added icon for the folder tree "pin down" button
-
-2000-09-12 JP Rosevear <jpr@helixcode.com>
-
- * NEWS (Calendar): Pilot stuff
-
-2000-09-12 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in: The notes subdir isn't actually used, so remove
- it.
-
-2000-09-12 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in: 0.5.
-
-2000-09-12 Jeffrey Stedfast <fejj@helixcode.com>
-
- * NEWS (Mailer): Added Sent/Outbox feature descriptions
-
-2000-09-12 Dan Winship <danw@helixcode.com>
-
- * NEWS (Mailer): add most (but not all) 0.5 Mailer features
-
- * configure.in: s/Sentbox/Sent/
-
-2000-09-12 Ettore Perazzoli <ettore@helixcode.com>
-
- * art/Makefile.am (buttonsdir): Install the new button icons into
- `$(datadir)/images/evolution/buttons'.
-
-2000-09-11 Tuomas Kuosmanen <tigert@helixcode.com>
-
- * art/fetch-mail.png
- * art/compose-message.png
- * art/reply.png
- * art/reply-to-all.png
- * art/forward.png
- * art/move-message.png
- * art/copy-message.png: New icons for the main window toolbar
-
-2000-09-11 Christopher James Lahey <clahey@helixcode.com>
-
- * NEWS: Added 0.5 changes for ETable and Addressbook.
-
-2000-09-07 Dan Winship <danw@helixcode.com>
-
- * README: Add a mention of the verify-evolution-install.sh script
- in tools/.
-
-2000-09-03 Jeffrey Stedfast <fejj@helixcode.com>
-
- Reversed my last change as it broke configure, how do I get it so
- that we can do folders with spaces in the name!?
-
-2000-09-03 Jeffrey Stedfast <fejj@helixcode.com>
-
- * configure.in: Renamed default_user/local/Sentbox to
- default_user/local/Sent\ Mail as Ettore and Danw are picky about
- folder names
-
-2000-09-02 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Added calendar/conduits/Makefile,
- calendar/conduits/calendar/Makefile and
- calendar/conduits/todo/Makefile to the list of makefiles to
- output.
-
-2000-09-01 Jeffrey Stedfast <fejj@helixcode.com>
-
- * configure.in: Add default_user/local/Sentbox/Makefile to the
- list of makefiles to output
-
-2000-08-31 Peter Williams <peterw@helixcode.com>
-
- * configure.in (kerberos): Check and see if krb_sendauth needs
- prototyping. (#define NEED_KRB_SENDAUTH_PROTO). Also check
- for a libkrb that doesn't need -ldes.
-
- * acconfig.h: #undef it
-
-2000-08-30 Lauris Kaplinski <lauris@helixcode.com>
-
- * configure.in: AC_DEFINE(USING_GNOME_PRINT_0_20)
-
- * acconfig.h: #undef that
-
-2000-08-30 Peter Williams <peterw@helixcode.com>
-
- * configure.in: Robustify the kerberos checks.
-
-2000-08-29 Dan Winship <danw@helixcode.com>
-
- * configure.in, acconfig.h: decruft
-
-2000-08-28 Jesus Bravo Alvarez <jba@pobox.com>
-
- * configure.in: Added Portuguese (pt) to ALL_LINGUAS
-
-2000-08-26 JP Rosevear <jpr@helixcode.com>
-
- * configure.in: Require oafized bonobo
-
-2000-08-24 Federico Mena Quintero <federico@helixcode.com>
-
- * configure.in: Ahem. If you add dependencies on libraries, make
- sure things still build. Fixed the libunicode foo.
-
-2000-08-22 Lauris Kaplinski <lauris@helixcode.com>
-
- * widgets/e-text/e-text.c (_get_position_from_xy): Don't crash on illegal string
-
-2000-08-22 Lauris Kaplinski <lauris@helixcode.com>
-
- * widgets/e-text/e-text.c (e_text_event): Use e_utf8_from_gtk_event_key
- to translate GDK_KEY_PRESS to insertable UTF-8 string
-
-2000-08-22 Christopher James Lahey <clahey@helixcode.com>
-
- * announcement-0.4.1.txt: Updated dependency list.
-
-2000-08-22 Lauris Kaplinski <lauris@helixcode.com>
-
- * widgets/e-text/e-text.c: Use byte based UTF-8 syntax
-
-2000-08-22 Christopher James Lahey <clahey@helixcode.com>
-
- * announcement-0.4.1.txt: Announcement message
-
-2000-08-19 Mathieu Lacage <mathieu@gnu.org>
-
- Fixes compile for non-standard prefixes. Mainly in idl
- compilation where -I`gnome-config --datadir`/idl is replaced
- by `gnome-config --cflags idl` (ugly but it works at least)
- and add some random _CFLAGS here and there and _LIBS for linking.
- * addressbook/gui/component/select-names/Makefile.am
- * composer/Makefile.am
- * e-util/Makefile.am
- * filter/Makefile.am
- * mail/Makefile.am
- * shell/Makefile.am
- * widgets/e-text/Makefile.am
-
-
-2000-08-21 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-paned/e-hpaned.c, widgets/e-paned/e-paned.c,
- widgets/e-paned/e-paned.h, widgets/e-paned/e-vpaned.c: Added code
- to make handle position persist across resizes.
-
-2000-08-20 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Fixed a warning.
-
-2000-08-20 arik devens <arik@helixcode.com>
-
- * widgets/e-text/Makefile.am (INCLUDES): added UNICODE_CFLAGS
- support so that compiling in an alternate prefix works.
-
-2000-08-19 Lauris Kaplinski <lauris@helixcode.com>
-
- * widgets/e-text/e-text.h: Commented out Suckfont, added EFont
- * widgets/e-text/e-text.c: Ported to UTF-8
-
-2000-08-18 Peter Williams <peterw@helixcode.com>
-
- * configure.in (gnome-vfs): Check for new enough gnome-vfs
- (needs gnome_vfs_mime_get_default_action_without_fallback)
-
-2000-08-14 Federico Mena Quintero <federico@helixcode.com>
-
- * configure.in (AC_OUTPUT): Generate
- doc/devel/calendar/cal-util/Makefile.
-
-2000-08-14 Peter Williams <peterw@helixcode.com>
-
- * configure.in: Check for db1/db.h too, which is what
- RH 7.0 uses for the old db headers. Patch from Kenny Graunke
- <kwg@teleport.com>
-
-2000-08-13 Chris Toshok <toshok@helixcode.com>
-
- * configure.in: offer --enable-pilot-conduits to add pilot
- conduits if the user wants them.
-
-2000-08-13 Dan Winship <danw@helixcode.com>
-
- * configure.in: Fix the name of the binary to look for for PGP5
-
-2000-08-12 Michael Meeks <michael@helixcode.com>
-
- * configure.in: Check for Bonobo 0.17
-
-2000-08-12 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Added addressbook/gui/search/Makefile.
-
-2000-08-12 Dan Winship <danw@helixcode.com>
-
- * configure.in, README: Depend on gnome-vfs 0.3
-
-2000-08-10 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/.cvsignore, widgets/e-text/Makefile.am,
- widgets/e-text/e-entry-test.c: Added a test for the EEntry widget.
-
-2000-08-09 Dan Winship <danw@helixcode.com>
-
- * data/evolution.keys: New file containing MIME keys for
- Evolution. Currently just the addressbook minicard display.
-
- * data/Makefile.am (mime_DATA): add evolution.keys
-
-2000-08-09 Peter Williams <peterw@helixcode.com>
-
- * configure.in (EVOLUTION_DIR): Remove the warning about camel-async.
-
-2000-08-08 Peter Williams <peterw@helixcode.com>
-
- * Makefile.am (SUBDIRS): Reenable the calendar. Oops.
-
-2000-08-05 Dan Winship <danw@helixcode.com>
-
- * tools/verify-evolution-install.sh: Look for oafinfo files in
- oaf's prefix, not gnome-libs's. Allow binaries to be installed
- anywhere in $PATH.
-
- * configure.in, README: Update the README and the text of the
- Bonobo configure check to match reality. Remove the 0.15 vs
- 0.15-and-a-half check since we require post-0.16 now.
-
-2000-08-03 JP Rosevear <jpr@helixcode.com>
-
- * configure.in: Remove gconf check
-
-2000-08-03 Alastair McKinstry <mckinstry@computer.org>
-
- * configure.in (ALL_LINGUAS): Add Irish translation
-
-2000-08-02 Michael Meeks <michael@helixcode.com>
-
- * configure.in: update for BonoboX
-
-2000-08-02 Dan Winship <danw@helixcode.com>
-
- * configure.in (AC_OUTPUT): Add camel/providers/nntp
-
-2000-08-02 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Made clicking choose the right
- character even if show_borders is on.
-
-2000-08-01 Dan Winship <danw@helixcode.com>
-
- * configure.in, acconfig.h: Add checks for GPG, PGP 5 and PGP 2.
- Only record the first one found.
-
-2000-08-01 Damon Chaplin <damon@helixcode.com>
-
- * configure.in (AC_OUTPUT): removed calendar/doc/*
-
-2000-08-01 Not Zed <NotZed@HelixCode.com>
-
- * configure.in: Added mh provider.
-
-2000-07-27 Dan Winship <danw@helixcode.com>
-
- * configure.in: Check for gconf_client_get_default (gconf 0.5 vs
- newer)
-
-2000-07-26 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in: Bump version number to 0.3.
-
-2000-07-26 Peter Williams <peterw@helixcode.com>
-
- * widgets/e-table/e-table-scrolled.c (right_click_proxy): Default
- the return value to 0.
-
-2000-07-25 Dan Winship <danw@helixcode.com>
-
- * configure.in: some unrelated changes: check for mkdtemp,
- gnome_vfs_mime_get_default_action_without_fallback, and a
- setuid/setgid movemail binary.
-
- * acconfig.h: add MOVEMAIL_PATH
-
-2000-07-25 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Added addressbook/conduit/Makefile.
-
-2000-07-21 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Made focus in not change your selection
- position.
-
-2000-07-21 Szabolcs BAN <shooby@gnome.hu>
-
- * calendar/gui/event-editor.c: Typo fix
-
-2000-07-20 Peter Williams <peterw@helixcode.com>
-
- * configure.in (THREADS_CFLAGS): Make threads mandatory
- again.
-
-2000-07-19 Fatih Demir <kabalak@gmx.net>
-
- * evolution.desktop & data/evolution.desktop: Added
- the Turkish desktop entries.
-
-2000-07-17 Federico Mena Quintero <federico@helixcode.com>
-
- * configure.in (EVOLUTION_DIR): Typo fix.
-
- * configure.in (AC_OUTPUT): Added the doc/devel Makefiles.
- (EVOLUTION_DIR): Substitute EVOLUTION_DIR for the top_srcdir.
- Added checks for gtk-doc.
-
-2000-07-13 Peter Williams <peterw@curious-george.helixcode.com>
-
- * configure.in (end): Bigass warnings for camel-async branch
- (remove them later).
-
-2000-07-12 Federico Mena Quintero <federico@helixcode.com>
-
- * configure.in: Make gnome-print-0.20 mandatory. We will bail out
- with CVS HEAD versions to avoid breakage.
-
-2000-07-10 Ettore Perazzoli <ettore@helixcode.com>
-
- * Version 0.2.
-
- * configure.in: Reverse the GtkHTML check.
-
-2000-07-10 Jeffrey Stedfast <fejj@helixcode.com>
-
- * configure.in: Updated to check for required GtkHTML and
- gnome-print
-
-2000-07-10 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in: Remove the conduits stuff for now. They depend on
- CVS gnome-pilot, and this is not good for the release.
-
-2000-07-10 Dan Winship <danw@helixcode.com>
-
- * README: updates
-
-2000-07-10 Seth Alves <alves@hungry.com>
-
- * configure.in: added makefiles for calendar conduits
-
-2000-07-10 Dan Winship <danw@helixcode.com>
-
- * configure.in: Add a check for Bonobo 0.15 vs Bonobo post-0.15
-
-2000-07-09 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Don't draw quite as large a "flat_box".
- If draw_borders is TRUE, cause the cursor to change even if not
- editing.
-
-2000-07-09 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-entry.c: Removed some border padding and set
- the "draw_borders" argument of the contained GtkText.
-
- * widgets/e-text/e-text.c, widget/e-text/e-text.h: Added a
- "draw_borders" argument which, if set, makes the EText look more
- like a GtkEntry.
-
-2000-07-09 Tuomas Kuosmanen <tigert@gimp.org>
-
- * art/evolution-contacts.png: updated so it has better contrast
- against the background.
-
- * art/evolution-contacts-small.png: Fits the style of the new contacts
- icon, this is a sigle card.
-
-2000-07-09 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text-model.c (e_text_model_real_get_text):
- Return "" instead of NULL.
-
-2000-07-07 Christopher James Lahey <clahey@helixcode.com>
-
- * art/Makefile.am: Fixed EXTRA_DIST for make distcheck.
-
-2000-07-07 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-entry.c: Set "anchor" and "fill_clip_rectangle"
- arguments.
-
- * widgets/e-text/e-text.c, widgets/e-text/e-text.h: Added
- "fill_clip_rectangle" argument which describes whether to accept
- clicks throughout the clipping rectangle.
-
-2000-07-07 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-entry.c: Fixed some typos.
-
-2000-07-07 Tuomas Kuosmanen <tigert@gimp.org>
-
- * art/evolution-contacts.png: Changed icon (hi ettore)
- The old handshake one was a little too firm handshake..
- this is a rolodex icon..
-
-2000-07-07 Dan Winship <danw@helixcode.com>
-
- * configure.in: make pthreads not required again, since they
- aren't, and remove widgets/e-toolbar/Makefile from AC_OUTPUT since
- that dir doesn't exist any more.
-
-2000-07-06 Chris Toshok <toshok@helixcode.com>
-
- * configure.in (AC_OUTPUT): remove the default_user Directories
- dir.
-
-2000-07-06 Christopher James Lahey <clahey@helixcode.com>
-
- * Makefile.am, libical/configure.in: Fixed some make distcheck
- errors.
-
-2000-07-05 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in (GNOME_VFS_CFLAGS): Define.
- (GNOME_VFS_LIBS): Define.
-
-2000-07-03 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in: Add
- `addressbook/gui/component/select-names/Makefile' to the
- `AC_OUTPUT()' list.
-
-2000-07-03 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/Makefile.am: Added e-entry.c and e-entry.h.
-
- * widgets/e-text/e-entry.c, widgets/e-text/e-entry.h: New files to
- be a widget containing a text item.
-
- * widgets/e-text/e-text.c: Fixed some spacing.
-
-2000-06-29 Ettore Perazzoli <ettore@helixcode.com>
-
- * notes/component-factory.c (owner_set_cb): Get an
- EvolutionShellClient instead of an Evolution_Shell to match the
- changes in libeshell.
-
-2000-06-29 Peter Williams <peterw@helixcode.com>
-
- * configure.in: Re-enable GNOME_PILOT_CHECK.
- Change AC_MSG_CHECKING([For...]) to [for...]. It's the little
- things that matter.
-
-2000-06-28 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in: `AM_PATH_GCONF'.
-
-2000-06-27 Peter Williams <peterw@curious-george.helixcode.com>
-
- * configure.in (ctime_r): Check for whether ctime_r takes
- two (Linux) or three (Solaris) arguments.
- (AC_OUTPUT): Don't create notes/Makefile twice.
-
- * acconfig.h: Add CTIME_R_THREE_ARGS to the list.
-
-2000-06-26 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Calculate height including if
- clip_height is set to -1.
-
-2000-06-26 Peter Williams <peterw@curious-george.helixcode.com>
-
- * configure.in (THREADS_CFLAGS): Add option --enable-broken-threads
- to turn on the threading stuff in evolution-mail. Defaults to no.
-
- * acconfig.h: Add USE_BROKEN_THREADS to the list.
-
-2000-06-25 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in: Use `glib-config' instead of `$GLIB_CONFIG' as the
- latter is not actually defined anywhere.
-
-2000-06-25 Peter Williams <peterw@helixcode.com>
-
- * configure.in (pthread stuff): Make threads required due
- to threaded evolution-mail. Subst in the THREADS_LIBS et
- al.
-
- * tests/Makefile.am: Remove USE_THREADS conditional as we
- always use threads now.
-
-2000-06-21 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Fixed some vertical scroll bugs.
-
-2000-06-21 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Fix a bug with intial vertical scroll.
-
-2000-06-21 Christopher James Lahey <clahey@helixcode.com>
-
- * notes/e-note.c, widgets/meeting-time-sel/e-meeting-time-sel.c,
- widgets/shortcut-bar/e-icon-bar.c: Removed the usage of "x" and
- "y" arguments to EText.
-
- * widgets/e-text/e-text.c, widgets/e-text/e-text.h: Removed the
- "x" and "y" arguments to EText. Added vertical scrolling.
-
-2000-06-20 Damon Chaplin <damon@helixcode.com>
-
- * widgets/meeting-time-sel/e-meeting-time-sel-item.c:
- * widgets/meeting-time-sel/e-meeting-time-sel.c: fixed a few warnings.
-
-2000-06-17 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Made EText use the font from the
- canvas's style if one isn't set.
-
-2000-06-17 Damon Chaplin <damon@helixcode.com>
-
- * widgets/meeting-time-sel/*: updated to use EText items rather than
- GtkEntry widgets and added support for adding new rows.
-
-2000-06-15 Dan Winship <danw@helixcode.com>
-
- * README: bye bye goad
-
-2000-06-14 Damon Chaplin <damon@helixcode.com>
-
- * README (http): added command to co ORBit.
-
-2000-06-13 Jeffrey Stedfast <fejj@helixcode.com>
-
- * configure.in: Added IMAP into the build
-
-2000-06-13 Ettore Perazzoli <ettore@helixcode.com>
-
- * notes/Makefile.am (SHELL_OBJS): Removed.
- (evolution_notes_LDADD): Link with
- `$(top_builddir)/shell/libeshell.a'.
-
-2000-06-12 Ettore Perazzoli <ettore@helixcode.com>
-
- * widgets/Makefile.am (SUBDIRS): build `misc' before everything
- else.
-
- * Makefile.am: Install `evolution.png' and `evolution.desktop'
- where appropriate.
-
- * evolution.png: New. For now, it's just a copy of
- `art/evolution-inbox.png'.
-
- * evolution.desktop: New.
-
-2000-06-10 Zbigniew Chyla <chyla@buy.pl>
-
- * configure.in: Added pl (Polish) to ALL_LINGUAS
-
-2000-06-09 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in: Added new directory `shell/glade'.
-
-2000-06-07 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-paned/e-hpaned.c, widgets/e-paned/e-paned.c,
- widgets/e-paned/e-paned.h, widgets/e-paned/e-vpaned.c: Added a
- "quantum" argument for making the panes move in jumps.
-
-2000-06-07 Anders Carlsson <andersca@gnu.org>
-
- * configure.in: Create notes/Makefile
-
- * notes/*: Add preliminary yellow sticky notes.
-
-2000-06-05 Mathieu Lacage <mathieu@gnome.org>
-
- * addressbook/contact-editor/Makefile.am: make it
- compile: add proper bonobo linking params.
- * addressbook/gui/minicard/Makefile.am: idem.
- * wombat/Makefile.am: add BONOBO_VFS_GNOME_CFLAGS.
- cleanup some useless includes and libs.
-
-2000-06-02 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in (ALL_LINGUAS): Add `it' and `de'.
-
-2000-06-02 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Released Evolution 0.1.
-
-2000-06-02 Christopher James Lahey <clahey@helixcode.com>
-
- * tests/test-movemail.c: Reverted removal of e_setup_base_dir.
-
-2000-06-02 Jesus Bravo Alvarez <jba@pobox.com>
-
- * configure.in: Added pt (Portuguese) to ALL_LINGUAS
-
-2000-06-02 Dan Winship <danw@helixcode.com>
-
- * README: Update dependencies. Rewrite the GOAD vs OAF thing some
- more to reflect OAF's new ascendency. Make the fact that you don't
- need pilot stuff clearer. Add some new directories to the
- directory layout section.
-
-2000-06-02 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/misc/e-clipped-label.c: Free the finish data.
-
-2000-06-01 Christopher James Lahey <clahey@helixcode.com>
-
- * tests/test-movemail.c (main): Don't call e_setup_base_dir.
-
-2000-06-01 Dan Winship <danw@helixcode.com>
-
- * configure.in (AC_OUTPUT): add doc, doc/C
-
- * Makefile.am (SUBDIRS): add doc
-
-2000-05-31 Federico Mena Quintero <federico@helixcode.com>
-
- * widgets/misc/e-scroll-frame.[ch]: Imported GtkScrollFrame from
- EOG and renamed it to EScrollFrame.
-
- * widgets/misc/Makefile.am (libemiscwidgets_a_SOURCES): Added
- e-scroll-frame.[ch].
-
-2000-05-30 Ettore Perazzoli <ettore@helixcode.com>
-
- * widgets/e-paned/e-vpaned.c (e_vpaned_handle_shown): Show the
- handle even if the requisition for the child is zero.
- * widgets/e-paned/e-hpaned.c (e_hpaned_handle_shown): Likewise.
-
-2000-05-26 Héctor García Alvarez <hector@scouts-es.org>
-
- * configure.in: Added Spanish language
-
-2000-05-25 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-paned/e-hpaned.c, widgets/e-paned/e-vpaned.c: Fixed a
- bug where we were resizing a non-existent window.
-
-2000-05-25 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-paned/e-hpaned.c, widgets/e-paned/e-paned.c,
- widgets/e-paned/e-paned.h, widgets/e-paned/e-vpaned.c: Made
- the handlebar disappear if either side is empty, hidden, or
- requests 0 size.
-
-2000-05-24 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Added widgets/e-paned/Makefile.
-
- * tests/ui-tests/message-browser.c: Switched from GtkPaned to
- EPaned.
-
- * widgets/Makefile.am: Added e-paned directory.
-
- * widgets/e-paned/, widgets/e-paned/.cvsignore,
- widgets/e-paned/Makefile.am, widgets/e-paned/e-hpaned.c,
- widgets/e-paned/e-hpaned.h, widgets/e-paned/e-paned.c,
- widgets/e-paned/e-paned.h, widgets/e-paned/e-vpaned.c,
- widgets/e-paned/e-vpaned.h: New widget based completely on
- GtkPaned from 1.4. This will be more advanced soon.
-
-2000-05-22 Jeff Stedfast <fejj@helixcode.com>
-
- * configure.in: Readded camel/providers/smtp
-
-2000-05-22 Szabolcs BAN <shooby@gnome.hu>
-
- * configure.in: Added Hungarian language
-
-2000-05-18 Dan Winship <danw@helixcode.com>
-
- * configure.in (AC_OUTPUT): add camel/providers/vee
-
-2000-05-16 Ettore Perazzoli <ettore@helixcode.com>
-
- * art/Makefile.am: Install the mini icons.
-
-2000-05-16 Chris Toshok <toshok@helixcode.com>
-
- * configure.in: add --with-purify-options support, and default it
- to what we at helix need
-
-Tue May 16 06:11:40 2000 Tuomas Kuosmanen <tigert@gimp.org>
-
- * art/evolution-calendar-mini.png art/evolution-inbox-mini.png
- art/evolution-tasks-mini.png art/evolution-contacts-mini.png
- art/evolution-notes-mini.png: new mini-icons for the tree view
- of folders and stuff.
-
-2000-05-14 Federico Mena Quintero <federico@helixcode.com>
-
- * configure.in (AC_OUTPUT): Added calendar/gui/dialogs/Makefile.am.
-
-2000-05-10 Matt Loper <matt@helixcode.com>
-
- * README: Added version and availability of required libunicode
- library.
-
-2000-05-10 Dan Winship <danw@helixcode.com>
-
- * configure.in: Update versions needed for gnome-print, bonobo,
- and gtkhtml.
-
-2000-05-10 Christopher James Lahey <clahey@helixcode.com>
-
- * HACKING: We need a HACKING file.
-
-2000-05-10 Christopher James Lahey <clahey@helixcode.com>
-
- * Makefile.am: Removed dist-hook section.
-
- * configure.in: Set the version number. Added a check for gnome
- window icons. Removed a bunch of unused Makefiles.
-
- * tools/Makefile.am: Created a proper EXTRA_DIST section.
-
- * widgets/e-text/Makefile.am: Added
- e-text-event-processor-types.h.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * art/Makefile.am: Added briefcase.png to get installed.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Remove the tooltip callback when
- destroyed.
-
-2000-05-09 Matt Loper <matt@helixcode.com>
-
- * calendar/pcs/cal-backend.c (cal_backend_add_cal): Return nothing
- for a 'void' function.
-
-2000-05-08 Christopher James Lahey <clahey@helixcode.com>
-
- * widget/e-text/e-text.c, widgets/e-text/e-text.h: Added an
- activate signal.
-
-2000-05-06 Chris Toshok <toshok@helixcode.com>
-
- * configure.in: Added new Directories section for the default_user.
-
-2000-05-06 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in: Updated for the new `default_user' directory
- setup.
-
-2000-05-06 Chris Toshok <toshok@helixcode.com>
-
- * configure.in: check for purify.
-
-2000-05-06 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c, widgets/e-text/e-text.h: Added a
- "changed" signal that gets sent whenever the text changes.
-
-2000-05-05 Ettore Perazzoli <ettore@helixcode.com>
-
- * Added `--enable-purify' flag.
-
-2000-05-05 Chris Toshok <toshok@helixcode.com>
-
- * shell/Makefile.am: add support for building purified evolution.
-
- * shell/.cvsignore: ignore evolution.pure
-
-2000-05-05 Chris Toshok <toshok@helixcode.com>
-
- * addressbook/backend/ebook/.cvsignore,
- addressbook/contact-editor/.cvsignore,
- addressbook/gui/component/.cvsignore,
- addressbook/gui/minicard/.cvsignore,
- addressbook/printing/.cvsignore,
- calendar/cal-client/.cvsignore,
- calendar/gui/.cvsignore,
- calendar/pcs/.cvsignore,
- filter/.cvsignore,
- mail/.cvsignore,
- shell/.cvsignore,
- tests/.cvsignore,
- widgets/e-table/.cvsignore,
- widgets/e-text/.cvsignore,
- widgets/meeting-time-sel/.cvsignore,
- widgets/shortcut-bar/.cvsignore,
- wombat/.cvsignore: ignore the .pure directory
-
-2000-05-04 Dan Winship <danw@helixcode.com>
-
- * configure.in: Oops. The Kerberos check was succeeding when it
- shouldn't have (and thus breaking the pop3 build for "normal"
- people). Fix.
-
-2000-05-03 Michael Meeks <michael@helixcode.com>
-
- * configure.in (xmlversion): Fix to remove older 'libxml' prefix.
-
-2000-05-02 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in: Do not output `doc/Makefile' because there is
- nothing to generate it from.
-
-2000-05-02 Dan Winship <danw@helixcode.com>
-
- * configure.in, acconfig.h: add some minimal Kerberos checking.
- This isn't intended to be generically useful at this point, it's
- just there to give me a second POP auth mechanism to play with.
-
- Also remove a bit of cruft, and reorganize configure.in a bit.
-
-2000-05-02 NotZed <NotZed@HelixCode.com>
-
- * tests/test13.c: And here too.
-
- * tests/test2.c (main): REmoved gmime-utils.h
-
- * tests/Makefile.am (LDADD): Add libeutil to default link line.
- (test_movemail_LDADD): Fixed order for libutil linking.
-
-2000-05-02 Matt Loper <matt@helixcode.com>
-
- * tests/Makefile.am: set G_LOG_DOMAIN.
- * tests/ui-tests/Makefile.am: same.
- * widgets/e-text/Makefile.am: same.
- * widgets/meeting-time-sel/Makefile.am: same.
-
-2000-05-01 NotZed <NotZed@HelixCode.com>
-
- * tests/test11.c (main): *sigh* moved back to sync api.
-
-2000-05-01 NotZed <NotZed@HelixCode.com>
-
- * tests/test11.c (search_cb): Try deleting messages ...
- (main): Fix for provider api changes.
-
-2000-05-01 Anders Carlsson <andersca@gnu.org>
-
- * configure.in: Check if bonobo uses oaf, so you don't
- need to specify --enable-oaf.
-
-2000-04-27 Ettore Perazzoli <ettore@helixcode.com>
-
- * acconfig.h: New configured #define `USING_OAF'.
-
- * configure.in: Added `--enable-oaf' option and corresponding
- `OAF_LIBS' and `OAF_FLAGS' variables. Code friendly provided by
- Maciej Stachowiak <mjs@eazel.com>.
-
-2000-04-27 NotZed <NotZed@HelixCode.com>
-
- * tests/test10.c: Fix for removal of camelmimebodypart, and changes
- to recipient stuff.
-
- * tests/test1.c: Fix for removal of camelmimebodypart, and changes
- to recipient stuff.
-
-2000-04-27 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Added addressbook/ename/Makefile.
-
-2000-04-27 Matt Loper <matt@helixcode.com>
-
- * configure.in: added tools/Makefile.
-
- * Makefile.am: Added tools.
-
- * tools/: New directory for tools relating to evolution.
-
- * tools/killev: New script for killing all evolution-related
- stuff.
-
- * tools/Makefile.am: New file.
-
- * tools/.cvsignore: New file.
-
-2000-04-26 NotZed <NotZed@HelixCode.com>
-
- * tests/test13.c (main): And here too.
-
- * tests/test2.c (main): Same here.
-
- * tests/test1.c (main): Change for removed simpledatawrapper.
-
-2000-04-26 Matt Loper <matt@helixcode.com>
-
- * tests/.cvsignore: Added test13.
-
- * default_user/.cvsignore: New file.
-
- * widgets/e-text/e-text.c (e_text_destroy): Kill text->timer and
- text->timeout on destroy.
-
-2000-04-26 Dan Winship <danw@helixcode.com>
-
- * tests: Update for the camel changes.
-
- * Makefile.am (SUBDIRS): Remove tests. They aren't terribly
- useful/interesting any more for the most part, and they frequently
- don't compile.
-
-2000-04-24 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Made the tooltip show up in the correct
- place and configuration when using the "max_lines", "anchor"
- (untested), or "justification" arguments.
-
-From a patch by Iain Holmes <ih@csd.abdn.ac.uk>
-
- * widgets/e-text/e-text-event-processor-emacs-like.c,
- widget/e-text/e-text-event-processor-types.h,
- widgets/e-text/e-text.c, widgets/e-text/e-text.h: Changed C-w and
- C-y to control the X clipboard. Added double and triple click
- events.
-
-2000-04-24 Fatih Demir <kabalak@gmx.net>
-
- * configure.in : Added tr to ALL_LINGUAS .
-
-2000-04-24 NotZed <NotZed@HelixCode.com>
-
- * tests/test13.c (main): Fixed for method movements.
-
- * tests/test3.c (main): Removed from build, data-wrapper-repository removed.
-
-2000-04-23 NotZed <NotZed@HelixCode.com>
-
- * tests/test2.c (main): Changed to use construct_from_stream.
-
- * tests/test1.c (main): Chagned to use construct_from_stream.
-
-2000-04-24 Matt Loper <matt@helixcode.com>
-
- * default_user/Makefile.am: new file.
-
- * default_user/Main_Shortcuts.xml: New file; is used to fill the
- shortcut bar's "main shortcuts" pane.
-
- * default_user/Other_Shortcuts.xml: New file, used to fill the
- shortcut bar's "other shortcuts" pane.
-
- * default_user/Inbox.mbox: New file. This is the first message a
- new user will see when they fire up Evolution. Needs work.
-
- * Makefile.am: added default_user directory.
- * configure.in: same.
-
-2000-04-23 NotZed <NotZed@HelixCode.com>
-
- * tests/test10.c: Removed some unecessary includes. From
- Ali Abdin <aliabdin@aucegypt.edu>
- (create_sample_mime_message): Changed for date api change.
-
- * tests/Makefile.am (noinst_PROGRAMS): Put test10 back.
-
-2000-04-22 NotZed <NotZed@HelixCode.com>
-
- * tests/test1.c (main): Changed for date api change.
-
-2000-04-20 NotZed <NotZed@HelixCode.com>
-
- * tests/test11.c: Fixed some headers.
-
- * tests/Makefile.am (noinst_PROGRAMS): Removed test9.
- (noinst_PROGRAMS): Removed test12, temporarirly (nntp not being
- built).
- Removed test10.
-
-2000-04-20 Yukihiro Nakai <nakai@gnome.gr.jp>
-
- * configure.in: Add Japanese to ALL_LINGUAS
-
-2000-04-19 Dan Winship <danw@helixcode.com>
-
- * README: More detail on exactly what versions of what libraries
- are needed.
-
-2000-04-18 Dan Winship <danw@helixcode.com>
-
- * tests/*: remove camel-log references
-
-2000-04-17 Dan Winship <danw@helixcode.com>
-
- * configure.in (xmlpatch): Require gnome-xml 1.8.7 (or later,
- but not 2.0). xmlParseMemory's behavior in 1.8.7 is incompatible
- with its behavior in 1.8.6 and earlier.
-
- * tests/test-url.c: New program to test CamelURL
-
-2000-04-16 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/e-card.c,
- addressbook/backend/ebook/e-card.h,
- addressbook/backend/ebook/test-card.c,
- addressbook/backend/pas/pas-backend-file.c,
- addressbook/contact-editor/e-contact-editor.c: Added
- orginizational unit, nickname, and internet free-busy fields.
-
- * addressbook/contact-editor/contact-editor.glade: Renamed some
- incorrectly named fields.
-
-2000-04-16 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/e-card.c,
- addressbook/backend/ebook/e-card.h,
- addressbook/backend/ebook/test-card.c,
- addressbook/backend/pas/pas-backend-file.c,
- addressbook/gui/minicard/e-minicard.c: Added orginization and role
- fields.
-
- * addressbook/contact-editor/contact-editor.glade,
- addressbook/contact-editor/e-contact-editor-strings.h: Renamed
- some incorrectly named fields.
-
- * addressbook/contact-editor/e-contact-editor.c: Added
- orginization and role fields as well as hooking up the birth date
- field.
-
- * addressbook/gui/minicard/e-minicard-view.c: Added a missing include.
-
-2000-04-15 Matt Loper <matt@helixcode.com>
-
- * addressbook/gui/component/addressbook.c
- (search_entry_activated): New function. Gets called when the quick
- search entry is called on to perform a search.
- (make_quick_search_widget): New function; returns a "quick search"
- widget.
- (control_activate): During the construction of the toolbar, a
- "quick search" widget is included.
-
-2000-04-14 Chris Toshok <toshok@helixcode.com>
-
- * tests/.cvsignore: add test12
-
- * tests/test12.c (main): add test for nntp stuff.
-
- * tests/Makefile.am (noinst_PROGRAMS): same.
-
-
-2000-04-14 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/e-card.c,
- addressbook/backend/ebook/e-card.h,
- addressbook/backend/pas/pas-backend-file.c,
- addressbook/backend/pas/pas-backend-ldap.c,
- addressbook/contact-editor/e-contact-editor.c: Added a note field.
-
-2000-04-15 Ettore Perazzoli <ettore@helixcode.com>
-
- * addressbook/backend/ebook/e-card-cursor.h: #include
- "addressbook/backend/ebook" to make sure we pick up the right
- addressbook.h. Butt ugly, but at least it makes it possible for
- me to build Evolution.
-
- * addressbook/gui/minicard/Makefile.am (INCLUDES): Use
- `$(builddir)' so that we pick up the IDL-generated includes
- correctly.
- * addressbook/backend/pas/Makefile.am: Likewise. Also use
- `$(srcdir)'.
-
- * addressbook/backend/ebook/Makefile.am: Use `$(srcdir)' so that
- it works with builddir != srcdir.
- * addressbook/backend/pas/Makefile.am: Likewise.
-
-2000-04-14 Chris Toshok <toshok@helixcode.com>
-
- * addressbook/backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_ensure_connected): don't ldap_simple_bind_s if
- the ldap_open failed, and fix warnings.
- (pas_backend_ldap_build_all_cards_list): don't do search if the
- ensure_connected failed, and fix warnings.
- (pas_backend_ldap_search): same.
- (poll_ldap): fix warnings.
- (pas_backend_ldap_process_get_book_view): same.
- (pas_backend_ldap_get_vcard): same.
- (pas_backend_ldap_load_uri): same.
-
- * configure.in: quiet configure in the case where it can't find
- ldap libs.
-
-2000-04-13 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/contact-editor/e-contact-editor.c (extract_info):
- Check for 0 length fields when building the outgoing ECard.
-
-2000-04-13 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/pas/pas-book-view.c: Give correct warnings.
-
- * addressbook/backend/ebook/e-card.c (e_card_set_arg): g_strdup
- url and title.
-
-2000-04-13 Chris Toshok <toshok@helixcode.com>
-
- * addressbook/contact-editor/e-contact-editor.c
- (fill_in_info): reflect the title attribute in the contact editor.
- (extract_info): same.
-
- * addressbook/backend/pas/pas-backend-ldap.c: add the title attribute.
-
- * addressbook/gui/minicard/test-reflow.c: add a title.
-
- * addressbook/gui/minicard/e-minicard.c (remodel): add support for
- the title attribute.
-
- * addressbook/backend/ebook/e-card.c (e_card_get_vcard): save out
- the title to the vcard.
-
- * addressbook/backend/ebook/test-card.c: add title field foo to
- the test.
-
- * addressbook/backend/ebook/e-card.c: reflect the title field.
-
- * addressbook/backend/ebook/e-card.h: un-#if 0 the title field.
-
- * addressbook/backend/pas/pas-backend-ldap.c (poll_ldap): new
- function that polls ldap for more search responses.
- (pas_backend_ldap_search): use the async search interface and
- register an idle call to poll for the responses.
- (view_destroy): make sure to g_source_remove the idle id.
-
-2000-04-12 Chris Toshok <toshok@helixcode.com>
-
- * addressbook/backend/pas/pas-backend-file.c (entry_compare):
- rework this function to use a table mapping search field names to
- vcard properties and extra information (such as whether or not the
- property is a list.)
-
- * addressbook/backend/pas/pas-backend-ldap.c
- (construct_email_list): new function, to build the ECardList for
- email addresses.
- (construct_phone_list): new function, to build the ECardList for
- phone numbers.
- (pas_backend_ldap_search): use a table mapping ldap attributes to
- ecard properties, and use the special list construction functions
- if the property calls for it. general cleanup. added a comment
- about not calling ber_free if there was a decoding error.
-
-
-2000-04-12 Matt Loper <matt@helixcode.com>
-
- * art/Makefile.am: Add tigert's contact-dlg-related images.
-
- * addressbook/contact-editor/e-contact-editor.c (_add_images): Add
- tigert's images.
-
- * addressbook/contact-editor/Makefile.am: add EVOLUTION_IMAGES.
-
-2000-04-12 Tuomas Kuosmanen <tigert@gimp.org>
-
- * art/house.png, art/malehead.png, art/cellphone.png,
- art/briefcase.png, art/envelope.png, art/globe.png:
- New icons for the contact manager.. more to follow once I get
- around to do more artist work..
-
-2000-04-12 Chris Toshok <toshok@helixcode.com>
-
- * addressbook/backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_build_all_cards_list): delay the setting of the
- ldap variable until we've ensured we were connected. Also, set
- the search limit to LDAP_MAX_SEARCH_RESPONSES (we'll eventually
- want a user setting here i assume.)
- (pas_backend_ldap_search): same here, and also send back lists of
- CARDS_PER_VIEW_NOTIFICATION length in each
- pas_book_view_notify_add call. also, don't call ber_free if there
- was a decoding error, since the ldap library frees it for us.
-
-2000-04-11 Miguel de Icaza <miguel@gnu.org>
-
- * configure.in (have_pthread): Properly use AC_ARG_WITH
-
-2000-04-11 Chris Toshok <toshok@helixcode.com>
-
- * wombat/Makefile.am (wombat_LDADD): add LDAP_LIBS here.
-
- * configure.in: check for -lldap and -llber and if both are
- present include ldap support in the pas/wombat.
-
- * addressbook/backend/pas/Makefile.am (libpas_la_SOURCES): include
- pas-backend.ldap.c if ENABLE_LDAP.
-
- * addressbook/backend/pas/pas-backend-ldap.c: get searching
- working (converting between the sexp and ldap stuff.)
-
- * wombat/wombat.c (setup_pas): register the ldap pas backend if
- HAVE_LDAP is defined.
-
-2000-04-11 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Changed AC_DEFUN to AC_DEFINE.
-
- * acconfig.h: Added HAVE_TIMEZONE and HAVE_TM_GMTOFF.
-
-2000-04-11 Chris Toshok <toshok@helixcode.com>
-
- * configure.in: check for timezone as a variable (as it is in
- linux, but not in freebsd or netbsd.)
-
-2000-04-11 Larry Ewing <lewing@helixcode.com>
-
- * widgets/e-table/e-cell-toggle.c (etog_draw): update for new
- gdk-pixbuf. Added a disabled chuck of code to do alpha blending
- on pixmaps.
-
-2000-04-11 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Moved some logic a bit. Minor changes.
-
-00-04-11 Iain Holmes <ih@csd.abdn.ac.uk>
-
- * widgets/e-text/e-text.c
- (e_text_set_args): Recalculate bounds when width or clip_width changes.
- (tooltip_event): Forward clicks on the tooltip onto the text item.
- (_do_tooltip): Correct the origin co-ordinates to the items co-ords.
- (e_text_point): Return 0 when the mouse is on the item.
- (_do_tooltip): Make the tooltip obey the parent items
- line_wrap and max_lines.
-
-00-04-11 Chris Toshok <toshok@helixcode.com>
-
- * addressbook/backend/pas/pas-backend-file.c
- (get_e_card_prop): new function, taking code from func_contains to
- get string properties.
- (entry_compare): new function generic, taking strstr-like function
- as a parameter.
- (func_contains): rewrite function to use entry_compare.
- (is_helper): new helper function to map strcmp to a strstr-like
- function.
- (func_is): new function, implementing "is" for searches.
- (endswith_helper): new function.
- (func_endswith) new function, implementing "endswith" for
- searches.
- (beginswith_helper): new function.
- (func_beginswith): new function, implementing "beginswith" for
- searches.
- (compare_email): new function for searching all email addresses of
- a contact.
- (compare_phone): new function for searching all phone numbers of a
- contact.
- (compare_address): new function for searching all addresses of a
- contact (unimplemented as yet).
- (entry_compare): add support for searching the list items "email",
- "phone" and "address".
- (vcard_matches_search): free the esexp_result.
- (entry_compare): we want comparison functions to take 2 args.
-
-2000-04-11 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/gui/minicard/e-minicard-view.c: This was setting
- E_REFLOW(view)->items to NULL too soon. Fixed now.
-
-2000-04-11 Chris Toshok <toshok@helixcode.com>
-
- * addressbook/backend/pas/pas-backend-file.c
- (pas_backend_file_search): remove spew.
- (pas_backend_file_process_create_card): move the sync to the
- earliest possible point after the db operation.
- (pas_backend_file_process_remove_card): same.
- (pas_backend_file_process_modify_card): same, and call
- pas_book_respond_modify, not pas_book_respond_remove, here.
-
- * addressbook/gui/component/addressbook.c (card_deleted_cb): new
- function.
- (delete_contact_cb): wire up button to call
- e_minicard_view_remove_selection.
-
- * addressbook/gui/minicard/e-minicard-view.c
- (e_minicard_view_remove_selection): fix warning, and stick "view"
- in the name.
-
-2000-04-10 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/e-book-view.c,
- addressbook/backend/ebook/e-book.c: Changed some incorrect
- gtk_object_refs and gtk_object_unrefs into bonobo_object_refs and
- bonobo_object_unrefs.
-
- * addressbook/backend/pas/pas-card-cursor.c: Changed a
- gtk_object_destroy to a gtk_object_unref.
-
- * addressbook/gui/minicard/e-minicard-view.c,
- addressbook/gui/minicard/e-minicard-view.h: Set a list pointer to
- NULL after freeing its contents. Added
- e_minicard_view_remove_selection function.
-
- * addressbook/gui/minicard/e-reflow.c: Set a list pointer to NULL
- after freeing its contents.
-
-2000-04-11 Chris Toshok <toshok@helixcode.com>
-
- * addressbook/gui/component/addressbook.c (find_contact_cb):
- implement braindead dialog to input the query string for the view.
-
- also, change all callbacks to get the EMinicardView instead of the
- EBook.
-
- * addressbook/gui/minicard/e-minicard-view.c
- (e_minicard_view_get_arg): add missing break.
-
-2000-04-10 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/gui/minicard/e-minicard-view.c,
- addressbook/gui/minicard/e-minicard-view.h: Added a "query"
- argument to the e-minicard-view. Documented all the arguments to
- the e-minicard-view.
-
-2000-04-10 Chris Toshok <toshok@helixcode.com>
-
- * addressbook/gui/minicard/e-minicard-view.c (get_view): change
- the empty search string ("") to the valid (contains "full_name" "").
-
- * wombat/Makefile.am (wombat_LDADD): reorder so libeutil.la comes
- after libpas (since it uses the sexp stuff now.)
-
- * addressbook/backend/pas/Makefile.am (INCLUDES): add
- -I$(top_srcdir)/addressbook/backend/ebook
-
- * addressbook/backend/pas/pas-backend-file.c
- (view_destroy): free the search context and unref the sexp.
- (string_to_dbt): save the zero byte of strings, so we don't have
- to g_strndup everywhere.
- (func_contains): new function, implementing the (contains) search
- function.
- (vcard_matches_search): generic predicate to tell whether or not a
- vcard entry matches the current book view.
- (pas_backend_file_search): rip some of this code out of
- get_book_view (the portion building the list of cards) and make it
- use the e-sexp stuff.
- (pas_backend_file_process_create_card): use vcard_matches_search
- to only notify if the card will appear in the view.
- (pas_backend_file_process_remove_card): use vcard_matches_search
- to only notify if the card will be removed from the view.
- (pas_backend_file_process_modify_card): use vcard_matches_search
- to notify if the modified card was added, removed, or changed in
- the view.
-
-2000-04-10 Miguel de Icaza <miguel@gnu.org>
-
- * configure.in (GNOME_PRINT_CFLAGS): Update to support
- --disable-threads correctly.
-
-2000-04-10 Chris Toshok <toshok@helixcode.com>
-
- * addressbook/backend/pas/pas-backend-file.c
- (pas_backend_file_process_get_book_view): use view != NULL instead
- of checking db_error when we call pas_book_respond_get_book_view)
-
-2000-04-10 Dan Winship <danw@helixcode.com>
-
- * configure.in: check for mkstemp
-
-2000-04-10 Damon Chaplin <damon@helixcode.com>
-
- * configure.in (AC_OUTPUT): removed libical stuff since it has its
- own configure.in.
-
-2000-04-10 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/e-book-view.c: Fixed a bug where I was
- sending the wrong information to some callbacks.
-
- * addressbook/backend/ebook/e-card.c,
- addressbook/backend/ebook/e-card.h: Added an e_card_duplicate
- function. Made ids get stored in vcards. Made sure to delete the
- url if it exists.
-
- * addressbook/backend/pas/Makefile.am: Made pas include
- addressbook/backend/ebook/ in the search path.
-
- * addressbook/backend/pas/pas-backend-file.c: Fixed some bugs and
- made the create card function store the generated id in the card
- being saved.
-
- * addressbook/backend/pas/pas-book-view.c: Fixed a double free
- bug.
-
- * addressbook/contact-editor/e-contact-editor.c: Fixed some bugs.
- Made the contact editor actually return a valid card when
- gtk_object_get(editor, "card", ...) is called.
-
- * addressbook/contact-editor/e-contact-editor.h: Fixed a copy and
- paste error.
-
- * addressbook/gui/component/addressbook.c: Made this get the card
- properly.
-
- * addressbook/gui/minicard/Makefile.am: Made this include
- contact-editor directory in the search path and link against
- libecontacteditor so that double clicking can open a dialog.
-
- * addressbook/gui/minicard/e-minicard.c: Fixed some small bugs.
- Made double clicking open a contact editor dialog if this minicard
- is contained in a minicard view. (It needs the minicard view to
- get the EBook to save to.
-
- * wombat/Makefile.am: Link wombat against libebook, since
- pas-backend-file now uses ECard.
-
-2000-04-09 Matt Loper <matt@helixcode.com>
-
- * addressbook/gui/component/addressbook.c (control_activate): Make
- "New Contact" menuitem add a card with new_contact_cb().
-
- * addressbook/Makefile.am: Compile contact-editor, _then_ gui,
- since the gui now depends on the contact editor (shouldn't the
- contact-editor directory be moved into 'gui'?).
-
- * addressbook/gui/component/addressbook.c (card_added_cb): New
- function. Gets called when a card is successfully added via the
- contact-editor.
- (new_contact_cb): New function. Gets called when a user clicks the
- "new contact" button on the toolbar, and creates a contact-editor
- to edit a new contact entry.
- (control_activate): Call gnome_app_fill_toolbar_with_data()
- instead of gnome_app_fill_toolbar(), so that our toolbar can find
- the right book to add a new card to.
- (addressbook_factory): On an "activate" signal, send the book up
- to control_activate_cb.
-
- * addressbook/gui/component/addressbook-factory.c (init_bonobo):
- Call glade_gnome_init(), so that our contact-editor (which
- requires glade) doesn't barf.
-
- * addressbook/gui/component/Makefile.am: added the contact-editor
- to our libraries and include files.
-
- * addressbook/contact-editor/e-contact-editor.c
- (e_contact_editor_new): Set "card" gtk property to the passed-in
- card property.
-
- * addressbook/gui/component/addressbook.c (addressbook_factory):
- Added gtk_widget_push/pop_colormap/visual, which I assume is
- necessary for canvas use.
-
-2000-04-08 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/contact-editor/Makefile.am,
- addressbook/contact-editor/e-contact-editor.c,
- addressbook/contact-editor/e-contact-editor.h,
- addressbook/contact-editor/test-editor.c: Made the contact editor
- load from an ECard.
-
- * addressbook/backend/ebook/e-card.c,
- addressbook/backend/ebook/e-card.h,
- addressbook/gui/minicard/e-minicard.c: Added support for the URL
- field.
-
-2000-04-08 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/e-card.c (e_card_get_vcard): Fixed a
- small typo.
-
-2000-04-08 Dan Winship <danw@helixcode.com>
-
- * art/Makefile.am: pixmap_DATA should have been images_DATA (after
- pixmapdir was renamed to imagesdir)
-
-2000-04-08 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/gui/minicard/.cvsignore,
- addressbook/gui/minicard/Makefile.am,
- addressbook/gui/minicard/e-minicard-view.c,
- addressbook/gui/minicard/e-minicard-view.h,
- addressbook/gui/minicard/e-minicard.c,
- addressbook/gui/minicard/e-minicard.h,
- addressbook/gui/minicard/e-reflow-sorted.c,
- addressbook/gui/minicard/e-reflow-sorted.h,
- addressbook/gui/minicard/e-reflow.c,
- addressbook/gui/minicard/e-reflow.h,
- addressbook/gui/minicard/test-minicard-view.c,
- addressbook/gui/minicard/test-reflow.c,
- widgets/e-minicard/.cvsignore, widgets/e-minicard/Makefile.am,
- widgets/e-minicard/e-minicard-label.c,
- widgets/e-minicard/e-minicard-label.h,
- widgets/e-minicard/e-minicard-view.c,
- widgets/e-minicard/e-minicard-view.h,
- widgets/e-minicard/e-minicard.c, widgets/e-minicard/e-minicard.h,
- widgets/e-minicard/e-reflow-sorted.c,
- widgets/e-minicard/e-reflow-sorted.h,
- widgets/e-minicard/e-reflow.c, widgets/e-minicard/e-reflow.h,
- widgets/e-minicard/test-minicard-label.c,
- widgets/e-minicard/test-minicard-view.c,
- widgets/e-minicard/test-minicard.c,
- widgets/e-minicard/test-reflow.c: CVS move mistake. Fixed the
- correct changes in the correct places.
-
-2000-04-08 Christopher James Lahey <clahey@helixcode.com>
-
- * art/Makefile.am: pixmap_DATA isn't defined so don't use it as a variable.
-
- * addressbook/gui/component/,
- addressbook/gui/component/.cvsignore, addressbook/gui/Makefile.am,
- addressbook/gui/component/addressbook-factory.c,
- addressbook/gui/component/addressbook.c,
- addressbook/gui/component/addressbook.gnorba,
- addressbook/gui/component/addressbook.h: New directory to proivde
- the component for contact management. Simply uses an e-minicard-view.
-
- * addressbook/gui/minicard/e-minicard-view.c,
- addressbook/gui/minicard/e-minicard-view.h: New subclass of
- e-reflow-sorted that takes an EBook and uses it to compute the
- card data to display.
-
- * addressbook/gui/minicard/e-minicard.c,
- addressbook/gui/minicard/e-minicard.h: This now backends to a
- ECard instead of a ETableModel.
-
- * addressbook/gui/minicard/e-reflow.c,
- addressbook/gui/minicard/e-reflow.h: This now has a virtualized
- add method.
-
- * addressbook/gui/minicard/e-reflow-sorted.c,
- addressbook/gui/minicard/e-reflow-sorted.h: New subclass of
- e-reflow that allows the data to be sorted on the fly.
-
- * addressbook/gui/minicard/test-minicard-view.c: New test to test
- the new minicard view.
-
- * addressbook/gui/minicard/test-reflow.c: Uses the new ECard
- backend of the e-minicard.
-
- * addressbook/gui/minicard/.cvsignore,
- addressbook/gui/minicard/Makefile.am: Added new test. Fixed
- dependencies. Added new files.
-
- * addressbook/gui/, addressbook/gui/Makefile.am,
- addressbook/gui/.cvsignore: New directory for addressbook gui
- bits. Added subdirectories. Created an initial .cvsignore.
-
- * addressbook/Makefile.am (SUBDIRS): Removed demo and added gui.
-
- * addressbook/backend/pas/pas-backend-file.c: Added code to do
- notification on bookviews when changes in the backend are made.
-
- * addressbook/backend/pas/pas-book-view.c,
- addressbook/backend/pas/pas-book-view.h: Added helper functions to
- notify the view about the addition or modification of a single
- card. Fixed a mistaken extra free.
-
- * addressbook/backend/ebook/e-card-list-iterator.h: Fixed
- incorrect parent class.
-
- * addressbook/backend/ebook/test-client.c: Made this accept an
- optional parameter that specifies the vcard to add.
-
- * configure.in: Replaced widgets/e-minicard/Makefile and
- addressbook/demo/Makefile with addressbook/gui/minicard/Makefile
- and addressbook/gui/component/Makefile respectively.
-
- * widgets/Makefile.am: Removed e-minicard since it's being moved
- to addressbook/gui/minicard.
-
- * widgets/e-text/e-text.c: Fixed the border width around tooltips
- and made the main tooltip area yellow.
-
-2000-04-08 Dan Winship <danw@helixcode.com>
-
- * configure.in, acconfig.h: add SYSTEM_MAIL_DIR
-
-2000-04-08 Jesus Bravo Alvarez <jba@pobox.com>
-
- * configure.in (ALL_LINGUAS): Added Galician (gl).
-
-2000-04-07 Jeffrey Stedfast <fejj@stampede.org>
- * configure.in: Modified to create camel/providers/smtp/Makefile
-
-2000-04-07 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Made text tooltips appear in place.
- Iain figured out that to get them to not appear, we hide the
- tooltip when the mouse leaves the tooltip window, not the canvas
- item (this works because the tooltip window always covers the
- canvas item completely.)
-
-2000-04-07 Matt Loper <matt@helixcode.com>
-
- * addressbook/demo/addressbook.c (control_activate_cb): New
- function. Called when the control is (de)activated.
- (control_activate): New function; called when the control is
- activated, and sets up toolbar/menu times.
- (control_deactivate): New function; removes those toolbar/menu
- items.
- (do_nothing_cb): Does nothing :-)
- (addressbook_factory): Hook up to control_activate_cb().
-
-2000-04-07 Chris Toshok <toshok@laptoph.xtoph.org>
-
- * addressbook/backend/pas/pas-backend-file.c
- (pas_backend_file_process_get_book_view): correctly (well,
- untested) implement.
- (view_destroy): new function.
-
-2000-04-06 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/demo/demo.c, addressbook/demo/addressbook-widget.c:
- Changed calls to e_cell_text_new to match new function signature.
-
-2000-04-06 Miguel de Icaza <miguel@gnu.org>
-
- * art/Makefile.am (images_DATA): Renamed from pixmaps to images.
-
-2000-04-05 Matt Loper <matt@helixcode.com>
-
- * README: Added wombat.
-
-2000-04-04 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text-test.c: Got rid of some runtime errors.
- Changed to "fixed" font so that it will work on everyone's
- machine. Added a white background rectangle. Made resizing the
- window resize the contained text item. Changed to using affines
- (e_canvas_item_move_absolute) instead of "x" and "y" attributes.
- Set the text in the entries so that they match the original values
- of the displayed text object.
-
-2000-04-04 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-minicard/e-minicard.c: Fixed some referencing and
- lifetime issues.
-
-2000-04-04 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Removed an unnecessary get_bounds call.
-
- (From a patch by Iain Holmes <ih@csd.abdn.ac.uk>)
-
- * widgets/e-text/e-text.c: Made tooltips look more like the
- underlying text. Made tooltips show up more consistently.
-
-2000-04-04 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/demo/Makefile.am, addressbook/demo/e-test-model.c,
- addressbook/demo/e-test-model.h: Changed this to backend to an
- ebook.
-
- * addressbook/backend/ebook/e-card-iterator.c,
- addressbook/backend/ebook/e-card-iterator.h,
- addressbook/backend/ebook/e-card-list-iterator.c,
- addressbook/backend/ebook/e-card-list.c,
- addressbook/backend/ebook/e-card-list.h,
- addressbook/backend/ebook/e-card.c,
- addressbook/backend/ebook/e-card.h: Fixed const correctness and
- changed a couple of functions to be external.
-
- * addressbook/Makefile.am: Fixed subdir ordering.
-
-2000-04-04 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/e-book-view.c: Fixed an incorrect
- function.
-
- * addressbook/backend/ebook/e-book-view.h,
- addressbook/backend/ebook/e-book.h: Fixed some incorrect function
- pointer declarations.
-
- * addressbook/backend/ebook/e-card-iterator.c,
- addressbook/backend/ebook/e-card-iterator.h,
- addressbook/backend/ebook/e-card-list-iterator.c,
- addressbook/backend/ebook/e-card-list-iterator.h,
- addressbook/backend/ebook/e-card-list.c,
- addressbook/backend/ebook/e-card-list.h,
- addressbook/backend/ebook/e-card.c,
- addressbook/backend/ebook/e-card.h,
- addressbook/backend/ebook/test-card.c: Built new iterator system
- for getting fields with multiple entries.
-
- * addressbook/backend/ebook/Makefile.am: Added new files
- addressbook/backend/ebook/e-card-iterator.c,
- addressbook/backend/ebook/e-card-iterator.h,
- addressbook/backend/ebook/e-card-list-iterator.c,
- addressbook/backend/ebook/e-card-list-iterator.h,
- addressbook/backend/ebook/e-card-list.c, and
- addressbook/backend/ebook/e-card-list.h.
-
-2000-04-04 Yuri Syrota <rasta@renome.rovno.ua>
-
- * configure.in: Added uk to ALL_LINGUAS.
-
-2000-04-04 Andreas Hyden <a.hyden@cyberpoint.se>
-
- * configure.in: Added no and sv to ALL_LINGUAS.
-
-2000-04-03 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/e-card-cursor.h,
- addressbook/backend/ebook/e-card.c: A bit of clean up.
-
- * addressbook/backend/ebook/e-book-types.h,
- addressbook/backend/ebook/e-book-view-listener.c,
- addressbook/backend/ebook/e-book-view-listener.h,
- addressbook/backend/ebook/e-book-view.c,
- addressbook/backend/ebook/e-book-view.h,
- addressbook/backend/pas/pas-book-view.c,
- addressbook/backend/pas/pas-book-view.h: New files for live views.
-
- * addressbook/backend/ebook/Makefile.am,
- addressbook/backend/ebook/e-book-listener.c,
- addressbook/backend/ebook/e-book-listener.h,
- addressbook/backend/ebook/e-book.c,
- addressbook/backend/ebook/e-book.h,
- addressbook/backend/ebook/test-client-list.c,
- addressbook/backend/ebook/test-client.c,
- addressbook/backend/pas/pas-backend-file.c,
- addressbook/backend/pas/pas-book.c,
- addressbook/backend/pas/pas-book.h,
- addressbook/backend/idl/addressbook.idl: Added live views and
- searching to the interface (neither is working yet.)
-
-2000-04-01 Matt Loper <matt@helixcode.com>
-
- * tests/.cvsignore: Added test-movemail.
-
- * art/.cvsignore: New file.
-
-2000-03-31 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/demo/demo.c, addressbook/demo/addressbook-widget.c:
- Added some missing gtk_object_refs.
-
-2000-03-30 Matt Loper <matt@helixcode.com>
-
- * addressbook/backend/pas/pas-backend-file.c
- (pas_backend_file_build_all_cards_list): Get first card (with
- R_FIRST) on first seq().
-
-2000-03-30 Chris Toshok <toshok@laptoph.xtoph.org>
-
- * addressbook/backend/pas/pas-backend-ldap.h: new-file
- * addressbook/backend/pas/pas-backend-ldap.c: new file
-
-2000-03-30 Dan Winship <danw@helixcode.com>
-
- * configure.in:
- * Makefile.am:
- * art/Makefile.am: install new shortcut bar pixmaps.
-
-2000-03-30 Tuomas Kuosmanen <tigert@gimp.org>
-
- * art/evolution-calendar.png art/evolution-inbox.png
- art/evolution-tasks.png art/evolution-contacts.png
- art/evolution-notes.png evolution-today.png:
- added some artwork for the main shortcutbar.. someone
- could stick them in it.
-
-2000-03-29 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/e-card-cursor.c: Fixed management of
- the corba-cursor object by calling CORBA_Object_duplicate on it on
- e-card-cursor creation and calling CORBA_Object_release on
- e-card-cursor destruction. Also, properly free string returned
- from Evolution_CardCursor_get_nth function.
-
-2000-03-29 Matt Loper <matt@helixcode.com>
-
- * addressbook/backend/ebook/test-client.c (get_cursor_cb): Added
- some debugging.
-
- * addressbook/backend/ebook/e-book-listener.c: Added inline
- documentation for exposed functions.
- * addressbook/backend/ebook/e-card-cursor.c: same.
- * addressbook/backend/ebook/e-card.c: same.
-
- * Makefile.am: add calendar compilation back in.
-
- * addressbook/backend/pas/pas-book-factory.c
- (PAS_BOOK_FACTORY_GOAD_ID): changed to
- "evolution:addressbook-server".
-
- * addressbook/backend/pas/Makefile.am: no need to install a
- .gnorba file from here, as the wombat.gnorba file in
- evolution/wombat will do its job.
-
- * addressbook/backend/ebook/test-client.c (ebook_create): if
- ebook_new fails, print a warning and return.
-
- * addressbook/backend/ebook/e-book.c (CARDSERVER_GOAD_ID): changed
- to "evolution:addressbook-server".
-
- * wombat/wombat.c: Changed headerfile path.
-
- * wombat/Makefile.am: Use relative paths to libraries in the build
- tree, rather than requiring libraries (such as libpcs) to already
- be installed.
-
-2000-03-28 Matt Loper <matt@helixcode.com>
-
- * wombat/Makefile.am: new file.
-
- * wombat/wombat.gnorba: Cleaned up.
-
- * wombat/wombat.c (setup_pcs): filled in the rest.
-
- * Makefile.am: added wombat.
-
- * wombat/wombat.gnorba: new file.
-
- * wombat/.cvsignore: new file.
-
- * wombat/wombat.c (setup_pcs): fill out this function some.
-
- * configure.in: added wombat.
-
-2000-03-28 Chris Toshok <toshok@laptoph.xtoph.org>
-
- * addressbook/backend/pas/pas-card-cursor.c (create_cursor): use
- g_new0 to allocate the BonoboObjectServant.
-
- * addressbook/backend/pas/pas-backend-file.c
- (pas_backend_file_build_all_cards_list): remove unnecessary
- strdup/free.
-
-2000-03-28 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/pas/pas-backend-file.c: Removed an infinite
- loop.
-
- * addressbook/backend/ebook/test-client-list.c: New test that
- doesn't add an extra database item.
-
- * addressbook/backend/ebook/Makefile.am,
- addressbook/backend/ebook/.cvsignore: Added test-client-list.
-
-2000-03-28 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/pas/pas-card-cursor.c: Fixed memory
- allocation.
-
- * addressbook/backend/pas/pas-backend-file.c: Fixed memory
- allocation. Made database stuff not do an extra entry.
-
- * addressbook/backend/ebook/test-client.c: Add test for
- get_all_cards functionality. Changed database name to test.db.
-
- * addressbook/backend/ebook/e-card-cursor.c: Changed bonobo_object
- to gtk_object in a couple of places.
-
-2000-03-28 Chris Toshok <toshok@laptoph.xtoph.org>
-
- * addressbook/backend/pas/pas-backend-file.c
- (pas_backend_file_create_unique_id): create id's for entries using
- the following format: ("pas-id-%08lX%08X", time(NULL), c++).
-
-2000-03-27 Dan Winship <danw@helixcode.com>
-
- * tests/test-movemail.c: new test program. Can be used to copy POP
- mail into your evolution inbox.
-
-2000-03-27 Chris Toshok <toshok@laptoph.xtoph.org>
-
- * addressbook/backend/pas/pas-backend-file.c
- (pas_backend_file_get_vcard): remove unneeded g_strdup;
- (get_length): implement function.
- (get_nth): implement function.
- (cursor_destroy): free up the internal glist of vcards, and fix
- warning.
- (pas_backend_file_build_all_cards_list): new function, to build up
- the list of cards in the db.
- (pas_backend_file_process_get_all_cards): call
- pas_backend_file_build_+all_cards_list, and fix warning.
-
-2000-03-27 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/test-card.c: Fixed some warnings.
-
- * addressbook/backend/ebook/test-client.c: Added a section to test
- cursors and returning an id when adding.
-
- * addressbook/backend/ebook/e-card-pairs.h: Removed the address
- pairs since they were added to e-card.c.
-
- * addressbook/backend/ebook/e-card.c,
- addressbook/backend/ebook/e-card.h: Made the set_id function take
- a const char *.
-
- * addressbook/backend/ebook/e-book-listener.c,
- addressbook/backend/ebook/e-book-listener.h,
- addressbook/backend/ebook/e-book.c,
- addressbook/backend/ebook/e-book.h,
- addressbook/backend/idl/addressbook.idl,
- addressbook/backend/pas/pas-backend-file.c,
- addressbook/backend/pas/pas-book.c,
- addressbook/backend/pas/pas-book.h: Added a get_all_cards function
- and made the response to the create_card function include the card
- id.
-
- * addressbook/backend/ebook/Makefile.am: Added e-card-cursor.c and
- e-card-cursor.h.
-
- * addressbook/backend/ebook/e-card-cursor.c,
- addressbook/backend/ebook/e-card-cursor.h: New class for proxying
- to an Evolution_CardCursor.
-
- * addressbook/backend/pas/Makefile.am: Added pas-card-cursor.c and
- pas-card-cursor.h.
-
- * addressbook/backend/pas/pas-card-cursor.c,
- addressbook/backend/pas/pas-card-cursor.h: New bonobo class for
- making an Evolution_CardCursor server.
-
-2000-03-27 NotZed <NotZed@HelixCode.com>
-
- * tests/test9.c (main): This test is basically now invalid.
- * tests/test11.c (main): Fix for async search api. Probably works.
- Removed camel-mbox-*.h headers, should be private.
-
-2000-03-27 Tuomas Kuosmanen <tigert@gimp.org>
- * art/attachment.xpm art/mail-new.xpm art/mail-read.xpm
- art/mail-replied.xpm art/mark.xpm art/meeting.xpm
- art/priority-high.xpm art/priority-low.xpm
-
- Added some new icons for the message-list view..
-
-2000-03-26 Chris Toshok <toshok@laptoph.xtoph.org>
-
- * configure.in: check for db_185.h (present in newer db
- distributions.)
-
- * addressbook/backend/pas/pas-backend-file.c
- (pas_backend_file_create_unique_id): new function.
- (pas_backend_file_process_create_card): call
- pas_backend_file_create_unique_id and pas_book_notify_add (if the
- db->put was successful). also, sync out db.
- (pas_backend_file_process_remove_card): call
- pas_book_notify_remove if the db->del was successful, and sync out
- db.
- (pas_backend_file_process_modify_card): call
- pas_book_notify_change if db->put was successful, and sync out db.
- (string_to_dbt): new function.
- (pas_backend_file_process_create_card): use string_to_dbt
- (pas_backend_file_process_remove_card): likewise
- (pas_backend_file_process_modify_card): likewise
- (pas_backend_file_get_vcard): likewise
- (pas_backend_file_upgrade_db): new function, to upgrade a db file
- if we change the data format.
- (pas_backend_file_maybe_upgrade_db): check db version vs. current
- code version, and upgrade it necessary.
- (pas_backend_file_load_uri): call pas_backend_file_maybe_upgrade.
-
-2000-03-26 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/test-client.c: Load an ECard instead
- of a VCard and then get the VCard from that ECard. Just tests
- ECard and the client stuff at the same time. Also, replaces
- carriage returns with newlines.
-
- * addressbook/backend/ebook/e-book.c: Fixed a small parity error.
-
-2000-03-25 Chris Toshok <toshok@laptoph.xtoph.org>
-
- * addressbook/backend/ebook/test-client.c: create a card and then
- look it up.
-
-2000-03-26 Chris Toshok <toshok@laptoph.xtoph.org>
-
- * addressbook/backend/pas/pas-backend-file.c
- (pas_backend_file_process_create_card): add db calls to flesh out
- the interface. hardcoded id that needs to change, once we decide
- how we're going to create it.
- (pas_backend_file_process_remove_card): add db calls to flesh out
- the interface.
- (pas_backend_file_process_modify_card): likewise
- (pas_backend_file_process_check_connection): likewise
- (pas_backend_file_get_vcard): likewise
- (pas_backend_file_load_uri): likewise
-
-2000-03-26 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/e-book.c: Set the card id properly
- when retrieving a card.
-
-2000-03-22 NotZed <NotZed@HelixCode.com>
-
- * e-util/e-sexp.h: Formatting cleanup.
-
-2000-03-07 NotZed <NotZed@HelixCode.com>
-
- * e-util/Makefile.am (libeutil_la_SOURCES): s-sexp.h -> e-sexp.h.
-
- * addressbook/backend/ebook/e-card.c,
- addressbook/backend/ebook/e-card.h: Added the ability to set the
- card's id (and made getting it work correctly also.)
-
-2000-03-25 Chris Toshok <toshok@laptoph.xtoph.org>
-
- * addressbook/backend/ebook/e-book.c (e_book_pop_op): pass GList*
- as second parameter to g_list_remove_link, not the data pointer.
-
-2000-03-26 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/e-card-types.h: Removed the
- address->description field.
-
- * addressbook/backend/ebook/e-card.c: Added VCard output and
- the use of GtkArguments.
-
- * addressbook/backend/ebook/test-card.c: Updated this to use the
- GtkArguments.
-
- * addressbook/backend/ebook/e-book.c: Fixed a memory leak.
-
-2000-03-25 Matt Loper <matt@helixcode.com>
-
- * ebook/e-book.c,
- ebook/e-book.h,
- ebook/e-book.h,
- ebook/e-card-fields.h,
- ebook/e-card.h,
- ebook/e-commerce.h: old, removed. Up-to-date EBook stuff is kept
- in addressbook/backend/ebook.
-
-2000-03-23 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/e-card.c,
- addressbook/backend/ebook/e-card.h,
- addressbook/backend/ebook/e-card-types.h,
- addressbook/backend/ebook/e-card-pairs.h,
- addressbook/backend/ebook/test-card.c: Added parsing and testing
- for name, full name, birthday, telephone, email, and street
- address properties.
-
-2000-03-22 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/backend/ebook/.cvsignore,
- addressbook/backend/pas/.cvsignore,
- addressbook/backend/idl/.cvsignore,
- addressbook/backend/.cvsignore: Updated .cvsignore files.
-
-2000-03-22 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/Makefile.am, configure.in: Added the
- addressbook/backend directory.
-
- * addressbook/backend/Makefile.am: Removed the libversit directory
- as it's now included in the base evolution directory.
-
- * addressbook/backend/ebook/e-card-pairs.h,
- addressbook/backend/ebook/Makefile.am: Changed the place where
- libversit is looked for.
-
- * addressbook/backend/ebook/e-book-listener.c: Fixed some
- indentation.
-
- * addressbook/backend/ebook/e-card-pairs.h,
- addressbook/backend/ebook/e-card-types.h: Commented out some code
- to get this to compile.
-
- * addressbook/backend/ebook/e-card.c,
- addressbook/backend/ebook/e-card.h: Turned this into a GTK+
- object.
-
- * addressbook/backend/pas/pas.c,
- addressbook/backend/ebook/test-client.c: Include gnome.h and
- gnorba.h.
-
- * addressbook/backend/idl/addressbook.idl: Include Bonobo.idl
- instead of bonobo-unknown.idl.
-
- * addressbook/backend/pas/pas-backend-file.c,
- addressbook/backend/pas/pas-book.c,
- addressbook/contact-editor/test-editor.c,
- addressbook/contact-editor/e-contact-editor.c,
- addressbook/printing/e-contact-print.c,
- addressbook/printing/test-contact-print-style-editor.c,
- addressbook/printing/test-print.c: Killed some warnings.
-
-2000-03-21 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c: Changed gnome_canvas_item_grab_focus to
- e_canvas_item_grab_focus.
-
-2000-03-21 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/demo/addressbook-widget.c: Make background pixmap
- get properly set to NULL.
-
-2000-03-20 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c, widgets/e-text/e-text.h: Added the
- ability to access the text event processor.
-
-2000-03-13 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/demo/addressbook-widget.c: Made the addressbook
- component look in the users home directory for the addressbook.xml
- file.
-
-2000-03-20 Matt Loper <matt@helixcode.com>
-
- * tests/ui-tests/.cvsignore: added filter.
-
- * addressbook/demo/.cvsignore: added test-addressbook.
-
-2000-03-17 Elliot Lee <sopwith@redhat.com>
- * calendar/cal-client/Makefile.am,
- calendar/cal-util/Makefile.am, calendar/gui/Makefile.am,
- calendar/pcs/Makefile.am, mail/Makefile.am,
- widgets/e-text/Makefile.am: Fix for srcdir != builddir.
-
-2000-03-14 Dan Winship <danw@helixcode.com>
-
- * Makefile.am (SUBDIRS): build shell before mail, since mail
- relies on the shell idl files being compiled.
-
-2000-03-13 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/demo/Makefile.am: Added files for addressbook bonobo
- component. Changed non bonobo version to compile as
- test-addressbook.
-
- * addressbook/demo/addressbook.c,
- addressbook/demo/addressbook.gnorba,
- addressbook/demo/addressbook.h,
- addressbook/demo/addressbook-factory.c,
- addressbook/demo/addressbook-widget.c,
- addressbook/demo/addressbook-widget.h: New factory to create an
- addressbook bonobo component.
-
-2000-03-12 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/.cvsignore: Added e-text-test.
-
- * addressbook/demo/e-test-model.c,
- addressbook/demo/e-test-model.h: A model storing data in an array
- of Address objects.
-
- * addressbook/demo/demo.c: Changed to use
- addressbook/demo/e-test-model.c and
- addressbook/demo/e-test-model.h.
-
- * addressbook/demo/Makefile.am: Added e-test-model.c and
- e-test-model.h.
-
-2000-03-12 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/Makefile.am: Rearranged SUBDIRS for dependencies.
-
- * widgets/e-text/e-text-model.c, widgets/e-text-model.h: New
- object which stores a piece of text data. All methods are
- virtual.
-
- * widgets/e-text/e-text.c, widgets/e-text/e-text.h: Modified this
- to use an ETextModel for its data.
-
- * widgets/e-text/Makefile.am: Added e-text-model.c and e-text-model.h.
-
- * widgets/e-minicard/test-minicard-label.c: Made this work again.
-
- * widgets/e-minicard/e-minicard.c,
- widgets/e-minicard/e-minicard.h: Made this use an ETableModel to
- get its data.
-
- * widgets/e-minicard/e-minicard-label.c,
- widgets/e-minicard/e-minicard-label.h: Added the ability to set
- the text model used for the contained text widget.
-
- * widgets/e-minicard/Makefile.am: Added e-table since e-minicard
- is now dependent on an e-table-model for its data.
-
- * addressbook/demo, addressbook/demo/.cvsignore,
- addressbook/demo/Makefile.am, addressbook/demo/demo.c,
- addressbook/demo/spec: A new program to test ETable and EMinicard
- integration.
-
- * configure.in: Added addressbook/demo/Makefile.
-
- * addressbook/Makefile.am: Added the demo/ subdirectory.
-
-2000-03-10 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-minicard/e-minicard.c,
- widgets/e-minicard/e-minicard-label.c,
- widgets/e-minicard/e-minicard-label.h,
- widgets/e-minicard/e-reflow.c, widgets/e-minicard/test-reflow.c,
- widgets/e-text/e-text.c, widgets/e-text/e-text.h: Adapted to use
- the new e-canvas reflow system.
-
-2000-03-07 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c, widgets/e-text/e-text.h: Added a
- "break_characters" argument. It lets you define a set of
- characters which should cause optional linebreaks to occur. Made
- setting the "clip_height" argument to -1 mean no height clipping.
- Moved calling the "resize" signal into an idle handler to avoid
- reentering the canvas update loop. Made EText recalc bounds if
- the affine has changed. Fixed up tooltip_count (this counts the
- number of ENTER and LEAVE events.)
-
- * widgets/e-text/e-text-test.c: Got rid of a few warnings.
-
- * widgets/e-minicard/e-minicard-label.h: Reindent a few lines.
-
- * widgets/e-minicard/e-minicard.c,
- widgets/e-minicard/e-minicard-label.c: Switch from using "x" and
- "y" to set the children's position to using
- e_canvas_item_move_absolute.
-
-2000-03-05 Matt Loper <matt.loper@splashtech.com>
-
- * tests/ui-tests/message-browser.c: Commenting added.
- (on_url_data_requested): renamed from "on_url_requested", to
- reflect that a stream of data is what's actually being asked for.
- (hydrate_persist_stream_from_gstring): New function.
- (camel_stream_to_gstring): New function.
- (on_object_requested): Cleaned up.
-
-2000-03-04 bertrand <bertrand@helixcode.com>
-
- * tests/ui-tests/Makefile.am: add bonobo to the build
- process.
-
- * tests/ui-tests/message-browser.c (main):
- initialize Bonobo. Use bonobo_main.
- (get_gtk_html_contents_window): set signal handlers
- for url requests and objects requests.
- (on_object_requested): answer to object requests.
-
-2000-03-03 bertrand <bertrand@helixcode.com>
-
- * tests/ui-tests/message-browser.c (main): initialize
- gdkrgb. Push visual/colormap.
- (on_url_requested): in the case where a camel url is requested,
- write the camel stream to gtkhtml.
-
- * tests/ui-tests/Makefile.am (filter_LDADD): add
- gnomeprint in the lib list.
-
-2000-03-01 Ettore Perazzoli <ettore@helixcode.com>
-
- * configure.in: Build `filter/Makefile'. Added check for GtkHTML.
- Set `GTKHTML_CFLAGS' and `GTKHTML_LIBS' to the appropriate values
- for linking with GtkHTML.
-
-2000-03-01 Federico Mena Quintero <federico@helixcode.com>
-
- * configure.in (AC_OUTPUT): Added calendar/idl/Makefile,
- calendar/cal-client/Makefile, and calendar/pcs/Makefile to the
- list of files to generate.
-
-2000-02-29 Iain Holmes <ih@csd.abdn.ac.uk>
-
- * widgets/e-text/e-text.c: Don't show the tooltip if the text is being
- editted or isn't clipped. Remove the tooltip when editting starts.
-
- * widgets/e-text/Makefile.am: Build the test program
-
-2000-02-29 NotZed <NotZed@HelixCode.com>
-
- * tests/ui-tests/Makefile.am (filter_LDADD): Added test program.
-
- * tests/ui-tests/filterdescription.xml, saveoptions.xml: Data
- files for test program.
-
- * tests/ui-tests/filter.c (main): Test program for filter ui.
-
-2000-02-28 NotZed <NotZed@HelixCode.com>
-
- * widgets/e-minicard/Makefile.am (INCLUDES): Fixed references to
- eutil.
-
- * Makefile.am (SUBDIRS): Build e-util before other stuff.
- (SUBDIRS): Build filter after camel.
-
-2000-02-28 Chris Lahey <clahey@umich.edu>
-
- * widgets/e-text/e-text.c: Compilation error.
-
-2000-02-28 Chris Lahey <clahey@umich.edu>
-
- * widgets/e-text/e-text.c, widgets/e-text/e-text.h: Updated these
- to use the canvas ::update system properly.
-
-2000-02-24 Dan Winship <danw@helixcode.com>
-
- * acconfig.h:
- * configure.in: define SENDMAIL_PATH with the path to sendmail.
-
-2000-02-24 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text.c, widgets/e-text.h, e-text-event-processor.c,
- e-text-event-processor.h, e-text-event-processor-emacs-like.c,
- e-text-event-processor-emacs-like.h,
- e-text-event-processor-types.h: This were moved to widgets/e-text/
- a while ago but never removed. They have now been removed.
-
- * widgets/e-text/e-text.c, widgets/e-text/e-text.h: Removed some
- warnings from this file. Made tooltips disappear when you're
- finished with them.
-
- * widgets/e-minicard/test-reflow.c,
- widgets/e-minicard/test-minicard.c,
- widgets/e-minicard/test-minicard-label.c: Commented out unused
- about_callback functions.
-
- * widgets/e-minicard/e-reflow.c: Made e-reflow pass an EFocus to
- its e-minicard children.
-
- * widgets/e-minicard/e-minicard.c: Made e-minicard take and return
- an EFocus for its "has_focus" argument. This makes shift-tab work properly.
-
- * widgets/e-minicard/e-minicard-label.c: Made e-minicard-label take and return
- an EFocus for its "has_focus" argument. Made the font that
- e-minicard-label uses only be allocated once.
-
-2000-02-21 Matt Loper <matt@helixcode.com>
-
- * tests/ui-tests/message-browser.c (on_link_clicked): stop
- sscanf() abuse.
-
- * tests/Makefile.am: changed references to libibex.a to
- libibex.la.
-
- * libical/src/libical/.cvsignore: Added *.lo, *.la, and .libs.
- * libical/src/libicalss/.cvsignore: same.
-
- * tests/.cvsignore: Added test11.
-
- * libical/Makefile.in: autogenerated file removed from cvs, and
- added to .cvsignore.
- * libical/src/Makefile.in: same.
- * libical/src/libical/Makefile.in: same.
- * libical/src/libicalss/Makefile.in: same.
-
-2000-02-22 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * tests/ui-tests/message-browser.c (on_link_clicked):
- uggly hack to test part saving and
- b64 streams.
-
-2000-02-21 Dan Winship <danw@helixcode.com>
-
- * tests/test10.c:
- * tests/test11.c: update for camel changes
-
-2000-02-20 Matt Loper <matt@helixcode.com>
-
- * tests/Makefile.am: Changed dependencies on libibex.la to
- libibex.a. In test9_LDADD, placed libcamelmbox.la before
- libibex.la, as the former requires the latter.
-
-2000-02-20 Iain Holmes <ih@csd.abdn.ac.uk>
-
- * widgets/e-text/e-text.[ch] (_do_tooltip): Show the text of the item,
- in a tooltip style.
- (e_text_event): Add a timeout on the Enter and remove it on the Leave
- events.
-
- * e-text-test.c: New file to test e-text items.
-
-2000-02-20 Matt Loper <matt@helixcode.com>
-
- * .cvsignore: added ABOUT-NLS.
- * ABOUT-NLS: removed.
-
-2000-02-19 Matt Loper <matt@helixcode.com>
-
- * tests/ui-tests/message-browser.c (on_link_clicked): When a link
- is clicked, indicate the link with a dialog.
-
- * libical/src/test/.cvsignore: Added Makefile.
-
- * libical/.cvsignore: Added Makefile, configure, config.status.
-
- * libical/src/.cvsignore: New file.
-
- * libical/Makefile: autogenerated file removed from cvs.
- * libical/configure: same.
- * libical/config.status: same.
- * libical/src/Makefile: same.
- * libical/src/test/Makefile: same.
-
- * widgets/e-minicard/.cvsignore: Added minicard-label-test,
- minicard-test, and reflow-test.
-
- * shell/.cvsignore: added files autogenerated from Evolution.idl.
-
- * libversit/.cvsignore: Added .libs, vcc.c, vcc.lo, vobject.lo,
- vcaltmp.lo, libversit.la
-
- * libical/src/test/.cvsignore: New file.
-
- * libical/src/libical/.cvsignore: New file.
-
- * libical/src/libicalss/.cvsignore: New file.
-
- * libical/.cvsignore: New file, with config.log in it.
-
- * tests/ui-tests/message-browser.c: minor cleanup.
-
- * tests/ui-tests/.cvsignore: added message-browser.
-
-2000-02-18 NotZed <NotZed@HelixCode.com>
-
- * tests/test11.c (main): Use a relative path to the mbox provider
- module.
-
-2000-02-18 Matt Loper <matt@helixcode.com>
-
- * tests/ui-tests/message-browser.c (filename_to_camel_msg): Call
- camel_data_wrapper_set_input_stream, rather than
- camel_data_wrapper_construct_from_stream. For the whole message,
- allow someone to see the header ("to", "from", etc.). Clicking on
- tree items to see their elements, now works also.
-
-2000-02-18 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * configure.in: Make gnomeui the last library on the command line,
- as its path is the one most likely to hold other old libraries
- (libxml) and we need newer versions.
-
- (BONOBO_VFS_GNOME_CFLAGS): Add libical to the
- AC_CONFIG_SUBDIRS
-
- (BONOBO_HTML_GNOME_CFLAGS): VFS checking needs to
- go before we rquery them.
-
- Use the new method for gnome-print
- checking instead of the old crufty gtk+ based one that nobody can
- debug. ever.
-
-2000-02-16 Matt Loper <matt@helixcode.com>
-
- * tests/ui-tests/message-browser.c (tree_selection_changed): New
- callback function, which will later change the main html window to
- reflect the newly-selected tree item.
- (get_gtk_html_contents_window): New function. Gets the content
- part of a message.
- (get_gtk_html_header_window): New function. Will get the header
- part of a message, when applicable.
-
- * camel/camel-formatter.c (str_tolower): Now returns a new string,
- rather than changing it in place.
- (initialize_camel_formatter): New function; gives a root
- CamelDataWrapper and a stream to a CamelFormatter.
- (camel_formatter_wrapper_to_html): New function. Translates any
- CamelDataWrapper into html.
- (lookup_unique_id): Allows the root object to be a
- CamelDataWrapper, which is more general than the previously
- required CamelMimeMessage.
-
-
-2000-02-14 NotZed <notzed@zedzone.helixcode.com>
-
- * configure.in (EXTRA_GNOME_CFLAGS): Add libunicode to CFLAGS/LIBS.
-
-2000-02-13 NotZed <notzed@zedzone.helixcode.com>
-
- * configure.in: Added check for libunicode.
-
- * Makefile.am (SUBDIRS): Added libibex.
-
- * tests/test11.c (main): New test, tests search api.
-
-2000-02-13 Matt Loper <matt@helixcode.com>
-
- * tests/ui-tests/test-multipart-mixed.msg: New rfc822 file, which
- crashes message-browser.
-
- * tests/ui-tests/message-browser.c (get_gtk_html_window): Takes a
- CamelMimeMessage as a param, rather than a filename.
- (main): Puts our windows in an hpane rather than a vbox. Also
- opens a file dlg box if a filename wasn't given as a first param.
-
- * camel/camel-stream-fs.c (_init_with_name): Set stream_fs->fd to
- -1 if we fail to load the file.
- (camel_stream_fs_new_with_name): If stream_fs->fd is -1, return
- NULL. These changes make it so that a CamelStreamFs won't be
- created if you give it a bogus filename; they may be replaced once
- exception handling is in place.
-
- * tests/ui-tests/message-browser.c (handle_tree_item): Expand tree
- items.
- (mime_message_to_html): New function; translates a
- CamelMimeMessage into two strings (one for the header, and one for
- the body).
- (get_gtk_html_window): New function; fills out a window with
- html. The html is taken from a processed rfc822 file, via a
- CamelFormatter.
-
- * camel/camel-formatter.c: Added assertions.
- (handle_text_html): Don't call text_to_html on something that's
- already html.
- (multipart_foreach): function deleted.
-
- * tests/ui-tests/message-browser.c: Added preliminary support for
- the viewing of messages via gtkhtml. Lots of commenting.
-
-2000-02-11 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/contact-editor/e-contact-editor.c: Fixed the
- location the first time you see the drop down menus for changing
- which phone, email, or snail mail address you see.
-
-2000-02-11 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.c (e_text_event): Made a click on a text
- widget set the cursor properly.
-
-2000-02-11 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text/e-text.h: Removed some arguments from the .h that
- will never be implemented.
-
-
-2000-02-10 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/data-wrapper-repository.c (data_wrapper_repository_init):
- default the text/* mime types to CamelSimpleDataWrapper so
- that Michael can use get_stream.
-
-2000-02-10 NotZed <notzed@zedzone.helixcode.com>
-
- * camel/camel-simple-data-wrapper-stream.h: The superclass is
- actually a seekable stream, not just a stream.
-
-2000-02-10 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * tests/Makefile.am (THREAD_RELATED_TESTS): don't
- build thread related tests if evolution has been
- compiled with no thread support.
-
- * configure.in (have_pthread): allow user to enable/disable
- thread support at configure time
- (EXTRA_GNOME_CFLAGS):
- (EXTRA_GNOME_LIBS): thread support is directly
- included in this variable if enabled. No more
- EXTRA_GNOME_CFLAGS_THREADS
- Other special support should be added in
- EXTRA_GNOME_LIBS and EXTRA_GNOME_CFLAGS
- instead of redefining a new variable
- each time we want to add a new lib.
- (bonobo, ....)
-
- * camel/camel.c (camel_init): only try to initialize threads if
- we enabled threads support.
-
- * tests/ui-tests/Makefile.am (message_browser_LDADD): use
- EXTRA_GNOME_LIBS
-
- * configure.in (have_pthread): remove HAVE_PTHREADS
- variable. Define ENABLE_THREADS instead.
-
- * camel/Makefile.am: use ENABLE_THREADS not HAVE_PTHREADS
- to test if we build thread relateed code.
-
- * tests/Makefile.am: use EXTRA_GNOME_LIBS,
- not EXTRA_GNOME_LIBS_THREADS
-
-2000-02-10 NotZed <notzed@zedzone.helixcode.com>
-
- * camel/hash-table-utils.c (g_strcase_hash): Removed a bizarre
- comparison construct for converting case.
-
-2000-02-09 NotZed <notzed@zedzone.helixcode.com>
-
- * camel/data-wrapper-repository.c (data_wrapper_repository_init):
- Uses case-insensitive compares.
-
- * camel/gmime-content-field.c (gmime_content_field_new): Uses
- case-insensitive compares.
-
- * camel/data-wrapper-repository.c (data_wrapper_repository_init):
- Use case-insensitive mime types.
-
- * camel/camel-simple-data-wrapper-stream.c (read): Increment the
- copy source address to match the data read offset.
- (seek): Actually implement the seek.
-
- * camel/camel-mime-part-utils.c
- (camel_mime_part_store_stream_in_buffer): If we get a -1 read,
- DONT update the total bytes, and try and truncate the array in
- reverse. Eek.
-
- * camel/camel-mime-part.c (camel_mime_part_encoding_from_string):
- This was DEFINETLEY not the right way to do it. strncmp!=strcmp
- (camel_mime_part_encoding_to_string): Handle the default case.
- : include string.h for strcmp() etc.
-
-2000-02-09 Matt Loper <matt@helixcode.com>
-
- * tests/ui-tests/test-multipart-alt.msg: New test file; run
- message-browser on it, and it will crash.
-
-2000-02-09 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * tests/ui-tests/message-browser.c (handle_tree_item):
- show the item.
- (handle_tree_item): show the containers and the containees
- (get_message_tree_ctrl): call handle_tree_item
- on the message itself
-
- * camel/camel-mime-message.c (camel_mime_message_init):
- set the mime type to "mime/message".
- --- THIS IS NOT THE CONTENT TYPE ---
-
- * camel/camel-mime-body-part.c (camel_mime_body_part_init):
- set the mime type to "body-part".
- --- THIS IS NOT THE CONTENT TYPE ---
-
- * camel/camel-data-wrapper.c (camel_data_wrapper_set_mime_type):
- mime_type is const.
- (_set_input_stream): really set the input stream
- (_set_output_stream): really set the output stream
- various other typo fixes.
-
- * tests/ui-tests/message-browser.c: various typo
- fixes in the ctree construction.
-
- * camel/string-utils.c (string_trim): fix braindead
- trailing trim bug.
-
- * camel/gmime-content-field.c (gmime_content_field_construct_from_string):
- strip the leading and trailing quotes when constructing the
- content field. This should be done in a more generic
- RFC822 approach, but this fixes a bug that prevent
- matt from analysing some multipart messages.
-
- * camel/camel-data-wrapper.h: reorganize the
- deprecated and new methods.
-
- * camel/providers/mbox/camel-mbox-folder.c
- (_check_get_or_maybe_generate_summary_file):
- Use "From " as the message separating string.
-
- * camel/providers/mbox/camel-mbox-folder.c (_append_message):
- set the mode when creating the mbox file.
-
- * camel/providers/mbox/camel-mbox-utils.c (camel_mbox_write_xev):
- ditto
- * camel/providers/mbox/camel-mbox-summary.c (camel_mbox_save_summary):
- ditto
-
-2000-02-09 Matt Loper <matt@helixcode.com>
-
- * tests/ui-tests/message-browser.c (print_usage_and_quit): Minor
- cleanup.
-
-2000-02-09 NotZed <notzed@zedzone.helixcode.com>
-
- * camel/camel-simple-data-wrapper-stream.c (class_init): Actually
- initialise the class. It simple couldn't have worked before.
- (camel_simple_data_wrapper_stream_construct): Commented out code
- which crashes just to get something working, memory corruption??
-
-2000-02-09 Christopher James Lahey <clahey@helixcode.com>
-
- * configure.in: Add new Makefiles to Makefile list.
-
- * widgets/e-text/Makefile.am: Build libetext.
-
- * widgets/e-minicard/Makefile.am: Build libeminicard and test
- programs.
-
- * widgets/Makefile.am: Remove all e-text and e-minicard code and
- add them to the SUBDIRS list.
-
-2000-02-08 Matt Loper <matt@helixcode.com>
-
- * tests/ui-tests/message-browser.c: New file; shows a message in
- tree format, where multipart's have multiple leaves.
-
- * camel/camel-formatter.c: Changed references from
- 'multipart/alternate' to 'multipart/alternative'.
-
- * tests/test-formatter.c (convert_to_html_and_print): Use the
- buffer length of the stream to create strings which are then
- printed, rather than printing the stream (which might not have a
- trailing \0) directly.
-
- * camel/camel-formatter.c (str_tolower): New function; makes a
- string lowercase.
-
- * tests/test-formatter.c (convert_to_html_and_print): Fixed call
- to 'camel_formatter_mime_message_to_html' to contain correct
- params.
-
- * camel/camel-formatter.c: New member to 'CamelFormatterPrivate',
- 'attachments', will be used to let the caller know which items
- should be treated as attachments (as opposed to objects which are
- inline to the body).
- (text_to_html): name changed from 'encode_entities'. Also now
- converts newlines to <br> tags.
- (camel_formatter_mime_message_to_html): Now takes two output
- streams -- one for the header, and one for the body.
- (get_bonobo_tag_for_object): New function; tries to make a tag out
- of (1) the leaf of a mime message and (2) a bonobo object that can
- handle its mime type, but can return NULL if it fails to find the
- mime type.
- (handle_vcard): New function; will write out a vcard as html.
-
-2000-02-07 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text.h, widgets/e-text.c: Added line wrap and a max
- number of lines (max number of lines is only obeyed if text is not
- being edited).
-
-2000-02-07 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/printing/e-contact-print.c: Removed an unneccessary
- include of libhnj. All uses of libhnj are commented out.
-
-2000-02-07 Matt Loper <matt@helixcode.com>
-
- * camel/camel-formatter.c (mime_part_to_html): function deleted.
-
- * tests/test-formatter.c (print_usage_and_quit): New function,
- which gives usage information.
-
- * camel/camel-formatter.c: made the 'stream' a member of the
- CamelFormatter class, so that streams don't have to be explicitly
- sent as a param where a CamelFormatter is also sent..
- (handle_text_plain): Use 'encode_entities' to change '<' to
- '&gt;', etc.
-
-2000-02-03 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-formatter.c (find_preferred_displayable_body_part_in_multipart_alternative):
- (mime_part_to_html): typo fix :
- use find_preferred_displayable_body_part_in_multipart_alternative
- instead of the other names. Allows camel to have no undefined symbols.
-
-2000-02-02 Matt Loper <matt@helixcode.com>
-
- * tests/test-formatter.c: New file; intended to test the
- CamelFormatter class.
-
- * camel/camel-formatter.c: Lots of cleanup, commenting, some new
- functions, and a really basic skeleton for getting bonobo objects
- into the html.
- (encode_entities): New function, stolen from Daniel Velliard.
-
-2000-01-28 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/printing/e-contact-print-style-editor.h,
- addressbook/printing/e-contact-print-style-editor.c,
- addressbook/printing/test-contact-print-style-editor.c: Files to
- load the contact print style editor from the glade file. Doesn't
- really do anything yet.
-
- * addressbook/printing/Makefile.am: Added style editor stuff.
-
- * addressbook/printing/e-contact-print.glade: Changed a bit.
- Fixed an out of place widget.
-
- * addressbook/printing/.cvsignore: Added
- contact-print-style-editor-test.
-
- * addressbook/printing/smallbook.ecps: Fixed up the values to
- match the new types.
-
- * addressbook/printing/medbook.ecps,
- addressbook/printing/phonelist.ecps: Added two new printing
- styles.
-
- * addressbook/printing/e-contact-print.h: Fixed an incorrect
- comment.
-
- * addressbook/printing/e-contact-print.c: Added columns and letter
- tabs. Tweaked spacing all over the place. Fixed card height
- function so that column wrapping is always done correctly. Added
- pulling of style information from a file. Added line wrapping
- within each text field.
-
- * addressbook/printing/e-contact-print-types.h: Added a type field
- for different types of print styles.
-
-
-2000-01-28 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text.c (e_text_command): Handle the grab and ungrab
- command instead of doing focus by hand. This fixes a problem
- related to the scroll wheel.
- (e_text_command): Reset the blink timer in many more command
- situations so that the cursor blinks less when you're interacting
- with it.
-
- * widgets/e-text-event-processor-emacs-like.c: Send the grab focus
- command when starting a selection and the ungrab focus command
- when ending it.
-
- * widgets/e-text-event-processor-types.h: Added grab command type
- so that the event processor can tell the widget to grab the focus.
-
- * widgets/e-reflow.c: Redefined all sizes using #defines so that
- they can be tweaked later. Added scroll wheel handling and set up
- adjustment increments so that the scroll bars will work correctly.
-
- * widgets/e-minicard.h: Added minicard focus type enum. This
- doesn't mean anything yet, but it will later be used to say which
- direction the focus is coming from (below for shift-tab, above for
- tab.)
-
-2000-01-28 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-minicard-label.c, widgets/e-minicard.c: Use
- e_canvas_item_grab_focus so that it will work with old versions of
- gnome-canvas.
-
- * widgets/e-canvas.c, widgets/e-canvas.h: Finished working around
- focus bugs.
-
-2000-01-28 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/test-reflow.c: Set the minimum_width.
-
- * widgets/e-reflow.h, widgets/e-reflow.c: Added one more column
- line so that the right edge of the reflow will have a line. Also
- added a minimum_width so that even if the reflow is thinner than
- the window, when you resize it larger all the lines are drawn.
-
-2000-01-27 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-reflow.h, widgets/e-reflow.c: Added an arrow cursor
- for the draggable columns. Made the clickable column area
- larger.
-
- * widgets/e-text.h, widgets/e-text.c: Added an I beam cursor for
- the text item when it is editable.
-
- * widgets/e-minicard-label.c: Forward enter and leave
- notifications to the contained editable text item.
-
-2000-01-26 Matt Loper <matt@helixcode.com>
-
- * camel/camel-formatter.c: By looking up a mimetype in a
- hashtable, we can now get a handler function for an arbitrary
- mimetype.
-
-2000-01-25 Mathieu Lacage <mathieu@advogato.org>
-
- * .cvsignore s: cvs shutup.
-
-2000-01-25 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-reflow.c, widgets/e-minicard.c: Handle shift-tab
- properly now.
-
- * widgets/e-minicard-label.c: Reindented some areas.
-
- * widgets/test-reflow.c: Use e-canvas. Set the back pixmap to
- NULL for the canvas so that scrolling won't flash grey.
-
- * widgets/e-canvas.c, widgets/e-canvas.h: These subclass
- GnomeCanvas to work around a few bugs so that evolution will work
- well with old versions of gnome-libs.
-
- * widgets/Makefile.am: Added e-canvas.c and e-canvas.h.
-
- * addressbook/contact-editor/contact-editor.glade: Not much
- change. Mostly internal reorganization by glade itself.
-
-2000-01-25 Christopher James Lahey <clahey@helixcode.com>
-
- * addressbook/printing/smallbook.ecps: Example contact printing
- style. Not used yet.
-
- * addressbook/printing/e-contact-print.glade: A glade file for
- editing contact printing styles. Not used yet.
-
- * addressbook/printing/test-print.c: Test file for printing.
-
- * addressbook/printing/e-contact-print.c,
- addressbook/printing/e-contact-print.h,
- addressbook/printing/e-contact-print-types.h,
- addressbook/printing/Makefile.am, addressbook/printing/.cvsignore:
- New files for contact printing support.
-
- * addressbook/Makefile.am (SUBDIRS): Add printing.
-
- * configure.in: Check for gnome-print. Build the
- addressbook/printing Makefile.
-
-2000-01-24 bertrand <bertrand@helixcode.com>
-
- * camel/camel-data-wrapper.h:
- * camel/camel-data-wrapper.c
- (_set_input_stream):
- (_get_input_stream):
- (_set_output_stream):
- (_get_output_stream):
- The CamelDataWrapper can now be provided with input and
- output streams, so that nothing has to be kept in memory.
-
- * camel/camel-stream.c (camel_stream_class_init):
- added the "data_available" signal.
-
-
-2000-01-24 Federico Mena Quintero <federico@helixcode.com>
-
- * configure.in: Added the gnome-pilot and capplet checks; they
- will likely be reworked for the Evolution framework, but for now
- the calendar/ directory needs them.
-
- * configure.in: Added checks for gnome-vfs.
-
-2000-01-24 bertrand <bertrand@helixcode.com>
-
- * camel/camel-seekable-stream.c:
- * camel/camel-seekable-stream.h:
- new files.
-
- * camel/camel-simple-data-wrapper-stream.h: parent class is now
- CamelSeekableStream
- * camel/camel-stream-buffered-fs.h: idem
- * camel/camel-stream-buffered-fs.c: idem
- * camel/camel-stream-mem.h: idem
- * camel/camel-stream-mem.c: idem
- (_seek): change declaration
- * camel/camel-stream-fs.c: parent class is now
- CamelSeekableStream
- (_seek): change declaration
-
- * camel/camel-stream-fs.h: parent class is now
- CamelSeekableStream
-
- * camel/camel-stream-fs.[ch]: converted all
- gint64 variables into guint32.
-
-
- * camel/camel-stream-fs.c (_read): fix stupid bug.
- (_write): ditto.
-
- * camel/camel-exception.c (camel_exception_new): don't
- forget to clean the exception when creating it.
-
- * camel/camel-recipient.c (camel_recipient_table_add_list):
- add recipient_list to the recipients, not recipients_list.
- I don't know what that variable was doing here.
-
-
-2000-01-24 Matt Loper <matt@helixcode.com>
-
- * camel/camel-formatter.c (write_header_info_to_stream): new
- function, broken out from 'camel_formatter_make_html'.
- (write_mimepart_to_stream): same.
- (find_text_body_part_in_multipart_related): new function.
- (camel_formatter_make_html): Now tries to deal with
- multipart/related, multipart/alternate, and text/(plain|html).
-
-
-2000-01-23 bertrand <bertrand@helixcode.com>
-
- * camel/camel-store.c (camel_store_get_session):
- added a public get_session method.
-
- * camel/providers/mbox/camel-mbox-summary.c (camel_mbox_save_summary):
- (camel_mbox_load_summary): load/save message sizes in the summary file
-
- * camel/providers/mbox/camel-mbox-summary.h:
- added a size field to the message information
- structure.
-
- * camel/providers/mbox/camel-mbox-utils.c (parsed_information_to_mbox_summary):
- copy message size to the mbox summary information too.
-
- * camel/camel-stream-fs.c (_seek): updated to
- work with bounded fs streams.
- (_write): ditto.
- (_read): ditto.
-
- * camel/camel-stream-fs.h (struct ):
- added the cur_pos, inf_bound and sup_bound
- members to allow for bounded fs stream.
-
- * camel/camel-stream-fs.c (_set_bounds): new func.
- (_init_with_fd_and_bounds): idem.
- (_init_with_name_and_bounds): idem.
- New functions to allow the usage of bounded fs streams.
-
- The bounded fs stream allow, for example, to make a stream
- from a message stored in an mbox file.
-
-
-2000-01-22 bertrand <bertrand@helixcode.com>
-
- * camel/providers/mbox/camel-mbox-folder.c (_check_get_or_maybe_generate_summary_file):
- use the real summary file path instead of a
- stupid hardcoded one. Fixes yet another bug.
-
- * camel/providers/mbox/camel-mbox-utils.c (parsed_information_to_mbox_summary):
- don't forget to copy the date too. Fix a very annoying bug.
-
- * camel/providers/mbox/camel-mbox-folder.c (_append_message):
- implemented. A lot of fixes too. Works now.
- (_get_uid_list): implemented.
-
-2000-01-21 bertrand <bertrand@helixcode.com>
-
- * tests/test10.c:
- test the mbox provider.
-
- * camel/camel-folder.c (_set_name):
- if camel_folder_get_mode returns an
- exception, return it instead of
- overriding it with a new one.
- (camel_folder_is_open): make the is_open
- method public.
- (_set_name): use the is_open instead of
- get_mode.
- (_set_name): set the fullname even in the case
- where the folder has no parent.
- (_set_name): use %c, not %d to add the
- separator char into the full path.
-
- * camel/camel-store.c: add exception handling everywhere in
- the store related functions arguments.
- * camel/providers/mbox/camel-mbox-folder.c: idem
- * camel/providers/mbox/camel-mbox-folder.h: idem
- * camel/providers/mbox/camel-mbox-store.h: idem
-
- * camel/providers/mbox/Makefile.am (libcamelmbox_la_SOURCES):
- added camel-mbox-provider.c to the mbox provider
- sources.
-
- * camel/providers/mbox/camel-mbox-provider.c:
- provider registration code.
-
- * camel/providers/mbox/camel-mbox-folder.c (_get_message_count): implemented
- (_append_message): implemented
-
- * camel/providers/mbox/camel-mbox-parser.c (initialize_buffer):
- use \0 to mark the end of the buffer.
- (read_next_buffer_chunk): ditto.
- (read_header): test the presence of a \0 instead of
- reading the eof field
- (read_message_begining): idem.
- (camel_mbox_parse_file): idem.
- Remove the eof field from the parser
- structure.
- (read_next_buffer_chunk): removed some nasty bugs
- again.
-
-
-2000-01-21 Federico Mena Quintero <federico@helixcode.com>
-
- * libversit/vcc.y: Removed the VFS crap; my mistake, it should not
- go here.
-
- * configure.in: Added yacc requirements for libversit.
-
-2000-01-21 Matt Loper <matt@helixcode.com>
-
- * camel/camel-formatter.c (camel_formatter_make_html): added a
- CamelMimeMessage as a param to this function, and removed it as a
- member of the object.
-
-2000-01-21 Federico Mena Quintero <federico@helixcode.com>
-
- * configure.in (AC_OUTPUT): Added libversit/Makefile and
- calendar/Makefile.
-
- * Makefile.am (SUBDIRS): Added libversit and calendar.
-
-2000-01-20 bertrand <bertrand@helixcode.com>
-
- * camel/providers/mbox/camel-mbox-parser.c (camel_mbox_parse_file):
- compute and return the file size.
-
-
-2000-01-20 Matt Loper <matt@helixcode.com>
-
- * camel/camel-formatter.c, camel/camel-formatter.h: New
- files. You'll be able to use a CamelFormatter to get
- html-formatted versions of a CamelMimeMessage.
-
-2000-01-20 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text-event-processor-types.h: Changed some line
- spacing.
-
- * widgets/test-reflow.c: Connected to the resize signal of the
- reflow.
-
- * widgets/e-minicard.c: Made width argument set function only
- update if width is different.
-
- * widgets/e-reflow.h, widgets/e-reflow.c: Added draggable column dividers.
-
- * addressbook/contact-editor/test-editor.c: Open two dialogs for
- more interesting testing.
-
- * addressbook/contact-editor/e-contact-editor.h,
- addressbook/contact-editor/e-contact-editor.c: Modified to use
- glade. Added menus to change which phone/address/email entries to
- view. Added images to the dialog.
-
- * addressbook/contact-editor/e-contact-editor-strings.h,
- addressbook/contact-editor/contact-editor.glade: Glade files for
- the contact editor dialog.
-
- * addressbook/contact-editor/Makefile.am: Added images and added
- glade stuff.
-
- * addressbook/contact-editor/arrow.png,
- addressbook/contact-editor/briefcase.png,
- addressbook/contact-editor/netfreebusy.png,
- addressbook/contact-editor/netmeeting.png: Image files for the
- contact editor dialog.
-
-2000-01-19 bertrand <bertrand@helixcode.com>
-
- * camel/providers/mbox/camel-mbox-folder.c (_get_message_count):
- implemented.
-
- * camel/providers/mbox/camel-mbox-summary.c (camel_mbox_save_summary):
- (camel_mbox_load_summary): save/load the next uid.
-
- * camel/providers/mbox/camel-mbox-parser.c (camel_mbox_parse_file):
- Compute the next available uid.
- * camel/providers/mbox/camel-mbox-folder.c (_create):
- (_check_get_or_maybe_generate_summary_file):
- Set and use the next_uid field properly.
- * camel/providers/mbox/camel-mbox-summary.h: added
- an extra field to store the next available uid.
-
- * camel/providers/mbox/camel-mbox-folder.c
- (_check_get_or_maybe_generate_summary_file):
- routine called when the folder is opened.
- Reads or creates the summary file.
- (_create): initialize the internal summary
- structure.
- (_close): save the summary file on closing.
- (_init_with_store): initialize mbox specific
- folder members.
-
-2000-01-18 bertrand <bertrand@helixcode.com>
-
- * tests/test9.c:
- tests for summary and parsing process of mbox files.
-
- * camel/providers/mbox/camel-mbox-parser.c (camel_mbox_parse_file): do
- not use case insensitive comp to detect message separators. Kill
- some nasty bugs in netscape file parsing,
-
- * camel/providers/mbox/camel-mbox-utils.c (parsed_information_to_mbox_summary):
- don't use g_array_append but write directly inside the
- array data instead. Better performance and bug fix.
-
- * camel/providers/mbox/camel-mbox-summary.c (camel_mbox_load_summary):
- fix the name and bugs.
-
- * camel/camel-folder-summary.h: update the class
- method definition to match the public defs.
-
- * camel/providers/mbox/camel-mbox-summary.c (camel_mbox_save_summary):
- (mbox_load_summary): summary file read/write routines.
-
- * camel/providers/mbox/camel-mbox-utils.c (parsed_information_to_mbox_summary):
- routine to construct the summary after the mbox
- file has been parsed and the x-evolution fields
- inserted.
-
-2000-01-17 bertrand <bertrand@helixcode.com>
-
- * camel/providers/mbox/camel-mbox-utils.c (camel_mbox_write_xev):
- dont use the x_evolution field but rather the uid to
- determine the presence of "X-Evolution" in the mail.
-
- * camel/providers/mbox/camel-mbox-parser.c (camel_mbox_parse_file):
- parse the status and uid values if the x-evolution
- has been found.
-
- * camel/providers/mbox/camel-mbox-utils.c (camel_mbox_xev_parse_header_content):
- return the parsed status field correctly.
-
- * camel/providers/mbox/camel-mbox-utils.h:
- fixed bad prototype.
-
- * camel/providers/mbox/camel-mbox-parser.c (camel_mbox_parse_file):
- parse and store the "To:" header.
-
- * camel/providers/mbox/camel-mbox-parser.h:
- added a "to" field
-
- * camel/camel-folder-summary.c:
- create the arrays here.
-
- * camel/camel-folder-summary.h: the list of
- summary information is no longer a GList but
- rather a GArray.
-
-2000-01-17 Chrsitopher James Lahey <clahey@helixcode.com>
-
- * head.png, phone.png, email.png, web.png, snailmail.png: Images
- for e-contact-editor.c.
-
- * addressbook/contact-editor/text-editor.c: Test program
- for contact editor widget.
-
- * addressbook/contact-editor/e-contact-editor.c,
- addressbook/contact-editor/e-contact-editor.h: Contact editor
- widget files.
-
- * addressbook/contact-editor/.cvsignore,
- addressbook/contact-editor/Makefile.am: New directory for contact
- editor files.
-
- * addressbook/.cvsignore, addressbook/Makefile.am: New directory
- for addressbook files.
-
- * widgets/.cvsignore: Added reflow-test.
-
- * Makefile.am (SUBDIRS): Added addressbook subdirectory.
-
- * configure.in, widgets/Makefile.am: Removed widgets/toolbar from
- SUBDIRS since the lack of content was preventing it from
- compiling.
-
- * widgets/e-text.c, widgets/e-text.h: Fixed a crashing bug.
-
-2000-01-17 bertrand <bertrand@helixcode.com>
-
- * tests/test9.c (main): test for the mbox utils.
-
-2000-01-17 Federico Mena Quintero <federico@helixcode.com>
-
- * configure.in: Add the gnomecanvaspixbuf argument to gnome-config
- invocations.
-
-2000-01-17 bertrand <bertrand@helixcode.com>
-
- * camel/providers/mbox/camel-mbox-utils.c (camel_mbox_write_xev):
- (copy_file_chunk):
- (camel_mbox_xev_write_header_content):
- (string_to_flag):
- (flag_to_string):
- (string_to_uid):
- (uid_to_string):
- A bunch of new funcs to handle x-evolution
- private header field.
- (copy_file_chunk): fixed a nasty bug.
- (camel_mbox_write_xev): create the copy file descriptor
- with the proper arguments. Exceptions implememnted.
- (camel_mbox_write_xev): changed the way bytes are counted.
- No more uses the message size cause it did not take into
- account the message separators characters.
- (camel_mbox_write_xev): hopefully fixed the last bugs.
- works ok now.
-
-
-2000-01-15 bertrand <bertrand@helixcode.com>
-
- * camel/providers/mbox/camel-mbox-parser.c
- (camel_mbox_parse_file):
- store the end of headers position.
-
- * camel/providers/mbox/camel-mbox-parser.h:
- added the end_of_header_position to locate the
- begining of the mail body.
-
-
- * camel/providers/mbox/camel-mbox-utils.c (uid_to_string):
- (string_to_uid):
- (flag_to_string):
- (string_to_flag):
- new functions to handle uids and
- flags in the X-Evolution header.
- (camel_mbox_xev_parse_header_content):
- new function to parse an X-Evolution
- header.
- (camel_mbox_xev_write_header_content):
- new function to write the X-Evolution
- header.
-
-2000-01-13 bertrand <bertrand@helixcode.com>
-
- * camel/providers/mbox/camel-mbox-parser.c (read_next_buffer_chunk):
- eof is true when no more chars are available, not
- when we've read the entire file.
- (initialize_buffer): ditto.
- (read_message_begining): documented.
- (read_header): ditto.
- (new_message_detected): ditto.
- (advance_n_chars): ditto.
- (goto_next_char): ditto.
- (read_next_buffer_chunk): ditto.
- (initialize_buffer): ditto.
- (parser_free): ditto.
- (new_parser): ditto.
-
-2000-01-12 <clahey@galapagos.helixcode.com>
-
- * widgets/e-text-event-processor-types.h,
- widgets/e-text-event-processor-emacs-like.c, widgets/e-text.c,
- widgets/e-text.h: Added selection and clipboard support. Added up
- and down arrow keys. Fixed choice of font colors for the
- selection to be based on the current style.
-
- * widgets/e-minicard.c: Caused a click to grab the focus. Changed
- the fake information added.
-
- * widgets/e-minicard-label.c: Forward mouse events to the field
- EText item.
-
-2000-01-13 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-canvas-utils.c, widgets/e-canvas-utils.h:
- e_canvas_item_move_absolute is just a helper function not supplied
- by the gnome_canvas.[ch] I put it here so that multiple items can
- use it.
-
- * widgets/e-reflow.c, widgets/e-reflow.h: This item contains a
- number of other items and places them into multiple columns. The
- items contained must support a number of arguments and signals to
- allow the reflow to interact with them.
-
- * widgets/test-reflow.c: This is a test program for e-reflow.
-
- * widgets/e-text.c, widgets/e-text.h: Added properly drawn
- selected text. Added some preliminary code for X selection
- handling and cut & paste.
-
- * widgets/e-minicard.c, widgets/e-minicard.h: Added ARG_HAS_FOCUS
- handling. Made label display random for more interesting tests of
- multiple cards. Tweaked sizing information for better display.
-
- * widgets/e-minicard-label.c, widgets/e-minicard-label.h: Added
- ARG_HAS_FOCUS handling.
-
- * widgets/Makefile.am: Added the reflow test and reflow files.
-
-2000-01-12 bertrand <bertrand@helixcode.com>
-
- * camel/providers/mbox/camel-mbox-parser.h (camel_mbox_parse_file):
- Added the prototype of camel_mbox_parse_file.
-
- * camel/providers/mbox/camel-mbox-parser.c (camel_mbox_parse_file):
- updated in-line documentation.
-
- * tests/Makefile.am (noinst_PROGRAMS):
- remove non updated tests from the build
- process.
-
- * corrected a bunch of bugs
-
- * camel/providers/mbox/camel-mbox-parser.c
- (camel_mbox_parse_file):
- parser the subject and date.
-
-
- * camel/providers/mbox/camel-mbox-parser.c
- (camel_mbox_parse_file): added the ability to
- follow the parsing progression.
-
- * camel/providers/mbox/camel-mbox-parser.h:
- parse the x-evolution field.
-
- * camel/Makefile.am (libcamel_la_SOURCES):
- disabled gmime-rfc2047 as it depends on libunicode
- and is not used for the moment.
-
-2000-01-12 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-minicard.c, widgets/e-minicard.h: Added a resize
- signal for when the card changes height. Made it so that when you
- press tab inside of a field, it goes to the next field.
-
- * widgets/e-minicard-label.c, widgets/e-minicard-label.h: Added a
- resize signal for when the label changes height.
-
- * widgets/e-text.c, widgets/e-text.h: Added a resize signal for
- multiple lines. Added scrolling based on cursor position.
-
- * widgets/Makefile.am: Removed an extraneous build target.
-
-2000-01-11 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/e-text-event-processor-emacs-like.c: Blocked the tab key
- from getting inserted into the buffer since the renderer doesn't
- know what a tab is.
-
- * widgets/e-text.c, widgets/e-text.h: Fixed a memory leak. Added
- a blinking cursor and scrolling for the text item.
-
-2000-01-11 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/test-minicard.c: Removed some code which got in the way
- of testing properly.
-
- * widgets/e-minicard-label.c (e_minicard_label_realize): Made the
- field text item editable.
-
- * widgets/Makefile.am: Added e-text-event-process*.[ch].
-
- * widgets/e-text.c, widgets/e-text.h: Changed these to support
- editing.
-
- * widgets/e-text-event-processor.c,
- widgets/e-text-event-processor.h,
- widgets/e-text-event-processor-types.h,
- widgets/e-text-event-processor-emacs-like.c,
- widgets/e-text-event-processor-emacs-like.h: These are a new pair
- of classes which handle all events from the text item and convert
- them into commands.
-
-
-2000-01-10 Christopher James Lahey <clahey@helixcode.com>
-
- * widgets/Makefile.am: Added minicard and text stuff.
-
- * widgets/e-minicard.c, widgets/e-minicard.h,
- widgets/e-minicard-label.c, widgets/e-minicard-label.h: Added
- canvas items for the minicard view in the contact manager.
-
- * widgets/test-minicard.c, widgets/test-minicard-label.c: Tests
- for the minicard items.
-
- * widgets/e-text.h, widgets/e-text.c: New canvas item. Based on
- GnomeCanvasText. Adds ellipsis capabilities. Used in
- e-minicard*.[ch].
-
- * widgets/.cvsignore: Added minicard-test and minicard-label-test.
-
-2000-01-06 Miguel de Icaza <miguel@gnu.org>
-
- * configure.in: Add Bonobo detection, Bonobo flags for compilation
- for the components and the shell.
-
-2000-01-06 Elliot Lee <sopwith@redhat.com>
- * composer/Makefile.am, widgets/e-table/Makefile.am: Work with
- builddir != srcdir
-
-2000-01-05 Miguel de Icaza <miguel@gnu.org>
-
- * configure.in (EXTRA_GNOME_CFLAGS_THREADS,
- EXTRA_GNOME_LIBS_THREADS): New variables that hold the thread
- version of the compile/link lines.
-
-1999-11-20 Miguel de Icaza <miguel@gnu.org>
-
- * configure.in (PACKAGE): Raise warning level.
-
-2000-01-04 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/providers/mbox/camel-mbox-folder.c (_list_subfolders):
- in the io_error label does not return before the
- list has been freed.
-
-2000-01-03 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/providers/mbox/camel-mbox-folder.c (_list_subfolders):
- detects netscape ".sdb" folders as well as simple
- non-suffixed folders (as the ones used in pine).
-
-
- * camel/string-utils.c (string_prefix):
- finished implementation.
- (string_prefix): added a boolean flag to indicate if the
- suffix has been found. When the suffix does not match,
- return NULL.
-
-1999-12-26 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-exception.c (camel_exception_setv):
- new function. Allow printf-like description
- string constructions.
-
- * camel/camel-exception.h: cosmetic changes.
-
- * camel/providers/mbox/camel-mbox-store.h:
- * camel/providers/mbox/camel-mbox-store.c:
- * camel/providers/mbox/camel-mbox-folder.h:
- * camel/providers/mbox/camel-mbox-folder.c:
- More work on the mbox provider.
-
-
-1999-12-22 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/providers/mbox/camel-mbox-store.h:
- * camel/providers/mbox/camel-mbox-store.c:
- * camel/providers/mbox/camel-mbox-folder.h:
- * camel/providers/mbox/camel-mbox-folder.c:
- part of the mbox provider.
-
-1999-12-20 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder.c (_set_name):
- check that the folder is closed or raise an exception.
- (_set_name): unset the name fields as soon as possible,
- even if an exception is raised.
-
- * configure.in:
- build mbox provider Makefile
-
- * camel/Makefile.am (SUBDIRS):
- re-enable providers compilation
-
-1999-12-19 Damon Chaplin <damon@karuna.freeserve.co.uk>
-
- * configure.in (AC_OUTPUT): added widgets/meeting-time-sel/Makefile
-
-1999-12-19 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder-utils.c: include camel-log.h
- to avoid unresolved symbols.
-
-1999-12-18 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder.c (camel_folder_get_summary):
- documented.
-
- * camel/camel-folder-pt-proxy.c (_append_message):
- updated to take the change on append into account.
-
- * camel/camel-folder.h:
- updated class def concerning append.
- * camel/camel-folder.c
- (camel_folder_append_message): documented.
- (camel_folder_append_message): don't return the
- message number. Use specific methods instead.
- (_append_message): idem.
-
- (_delete): use exception mechanism.
- (camel_folder_delete): idem.
- (_delete_messages): idem.
- (camel_folder_delete_messages): idem.
- (_get_parent_folder): idem.
- (camel_folder_get_parent_folder): idem.
- (_get_parent_store): idem.
- (_get_mode): idem.
- (camel_folder_get_parent_store): idem.
- (camel_folder_get_mode): idem.
- (_list_subfolders): idem.
- (camel_folder_list_subfolders): idem.
- (_expunge): idem.
- (camel_folder_expunge): idem.
- (_has_message_number_capability): idem.
- (camel_folder_has_message_number_capability): idem.
- (_get_message_by_number): idem.
- (camel_folder_get_message_by_number): idem.
- (camel_folder_get_message_count): idem.
- (_list_permanent_flags): idem.
- (camel_folder_list_permanent_flags): idem.
- (_copy_message_to): idem.
- (camel_folder_copy_message_to): idem.
- (camel_folder_has_summary_capability): idem.
- (camel_folder_get_summary): idem.
- (camel_folder_has_uid_capability): idem.
- (camel_folder_get_message_uid): idem.
- (_get_message_uid_by_number): idem.
- (camel_folder_get_message_uid_by_number): idem.
- (camel_folder_get_message_by_uid): idem.
- (camel_folder_get_uid_list): idem.
-
-1999-12-17 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder.c (_set_name):
- use exception mechanism.
- (camel_folder_set_name): idem.
- (camel_folder_set_full_name): idem.
- (_get_name): idem.
- (camel_folder_get_name): idem.
- (_get_full_name): idem.
- (camel_folder_get_full_name): idem.
- (_can_hold_folders): idem.
- (_can_hold_messages): idem.
- (_exists): idem.
- (camel_folder_exists): idem.
- (_is_open): idem.
- (_get_subfolder): idem.
- (camel_folder_get_subfolder): idem.
-
- * camel/camel-exception.c (camel_exception_clear):
- New function. Clear an exception.
- (camel_exception_get_id):
- New function.
- (camel_exception_get_description):
- New function.
-
- * camel/camel-folder.c (_set_name):
- Use the exception system. When the folder
- has no parent, don't set its full name
- field.
-
-
-1999-12-16 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder.c (camel_folder_expunge):
- (_expunge):
- * camel/camel-folder-pt-proxy.c (_expunge):
- changed the return value. Now returns the list
- of expunged messages
-
- * camel/camel-folder.c (_init_with_store):
- cleaned up. Use the exception system now.
- (_open): ditto.
- (camel_folder_open): ditto.
- (camel_folder_open_async): ditto.
- (_close): ditto.
- (camel_folder_close): ditto.
- (camel_folder_close_async): ditto.
-
- * camel/camel-exception.c (camel_exception_set):
- When no exception is given, do nothing, just
- return.
- (camel_exception_set): documented.
- (camel_exception_new): idem.
- (camel_exception_free): idem.
- (camel_exception_xfer): idem.
-
-
- * camel/camel-folder.c:
- * camel/camel-folder.h: more clean-ups.
- Removed message list related code.
- This was braindead design.
-
-
- * camel/camel-folder-utils.c (camel_aml_expunge_messages):
- implemented. The routines in this file will be
- called by providers to handle the list of
- message already standing in memory.
-
-1999-12-15 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder-utils.c:
- * camel/camel-folder-utils.h:
- New files, misc utilities for the
- folder providers. Includes active message
- list utilities.
-
-
- * camel/camel-folder.c (_has_message_number_capability):
- (camel_folder_has_message_number_capability):
- Added this to know if a folder provides
- number-based message access.
-
- * camel/camel-folder.c (_get_message_count):
- added warning when called directly.
- (_append_message): ditto
- (_open_async): ditto
- (_close_async): ditto
- (_delete_messages): ditto
- (_expunge): ditto
- (_get_message_by_number): ditto
- (_get_message_uid): ditto
- (_get_message_uid_by_number): ditto
- (_get_message_by_uid): ditto
- (_get_uid_list): ditto
-
-
- * camel/camel-folder-pt-proxy.c (_open_async):
- (_open):
- (_close_async):
- (_close):
- (camel_folder_pt_proxy_class_init):
- update
- (_get_message_by_number):
- Update to reflect changes in CamelFolder
-
- * camel/camel-folder.h:
- * camel/camel-folder.c (_get_subfolder):
- (camel_folder_get_subfolder):
- The CamelFolder::get_folder is renamed to
- get_subfolder as it is more intuitive.
-
- * camel/camel-folder.c (_get_message_by_number):
- (camel_folder_get_message_by_number):
- * camel/camel-folder.h
- (camel_folder_get_message_by_number):
- The get_message method is now named
- get_message_by_number for consistency
- with the _by_uid methods.
-
- * camel/camel-folder.[ch]:
- clean-ups.
-
-1999-12-13 Nat Friedman <nat@helixcode.com>
-
- * ebook/e-book.h: New file.
- * ebook/e-book.c: New file.
- * ebook/e-card.h: New file.
- * ebook/e-card-fields.h: New file.
- * ebook/e-commerce.h: New file. :-)
-
-1999-12-08 Ettore Perazzoli <ettore@gnu.org>
-
- * tests/test1.c (main): Removed the strdup()s, which are not
- deeded anymore.
-
- * camel/camel-mime-message.c (_set_subject): `subject' made const.
- (camel_mime_message_set_subject): Likewise.
- (_set_from): `from' made const.
- (camel_mime_message_set_from): Likewise.
- (_set_reply_to): Made `reply_to' const.
- (camel_mime_message_set_reply_to): Likewise.
- (_set_set_received_date): Made `received_date' const.
- (camel_mime_message_set_reply_to): Likewise.
- (_set_field): `value' made const. Also, strdup the string before
- assigning.
-
- * camel/camel-mime-message.h: Virtual methods changed to use const
- strings when setting header values.
-
-1999-11-17 Ettore Perazzoli <ettore@gnu.org>
-
- * composer/Makefile.am (EXTRA_DIST): Added `$(glade_DATA)'.
-
- * camel/Makefile.am (EXTRA_DIST): Added
- `$(libcamel_extra_sources)'.
- (libcamelinclude_HEADERS): Added `gmime-base64.h'.
-
-1999-11-17 Ettore Perazzoli <ettore@gnu.org>
-
- * camel/camel-mime-message.c (_write_to_stream): Removed extra ':'
- in the `Mime-Version' header.
-
- * tests/ui-tests/msg-composer-test.c: Removed.
-
- * Makefile.am (SUBDIRS): Added `composer'.
-
- * configure.in: Create `composer/Makefile'.
-
- * camel/camel-simple-data-wrapper-stream.c
- (camel_simple_data_wrapper_stream_construct): Updated accordingly.
- (camel_simple_data_wrapper_stream_new): Updated accordingly.
- * camel/camel-stream-data-wrapper.c
- (camel_stream_data_wrapper_construct): Updated accordingly.
-
- * camel/camel-data-wrapper.h: Replaced `IS_CAMEL...()' type check
- macro name with `CAMEL_IS...()'.
- * camel/camel-folder-pt-proxy.h: Likewise.
- * camel/camel-folder-summary.h: Likewise.
- * camel/camel-folder.h: Likewise.
- * camel/camel-medium.h: Likewise.
- * camel/camel-mime-body-part.h: Likewise.
- * camel/camel-mime-message.h: Likewise.
- * camel/camel-mime-part.h: Likewise.
- * camel/camel-multipart.h: Likewise.
- * camel/camel-service.h: Likewise.
- * camel/camel-session.h: Likewise.
- * camel/camel-simple-data-wrapper-stream.h: Likewise.
- * camel/camel-simple-data-wrapper.h: Likewise.
- * camel/camel-store.h: Likewise.
- * camel/camel-stream-buffered-fs.h: Likewise.
- * camel/camel-stream-data-wrapper.h: Likewise.
- * camel/camel-stream-fs.h: Likewise.
- * camel/camel-stream-mem.h: Likewise.
- * camel/camel-stream.h: Likewise.
-
- * tests/test1.c (main): Updated to match the `RECIPIENT_TYPE'
- changes.
-
- * camel/camel-mime-message.h: Changed `RECIPIENT_TYPE_TO',
- `RECIPIENT_TYPE_CC' and `RECIPIENT_TYPE_BCC' into
- `CAMEL_RECIPIENT_TYPE_TO', `CAMEL_RECIPIENT_TYPE_CC' and
- `CAMEL_RECIPIENT_TYPE_BCC', respectively.
-
-1999-11-17 Ettore Perazzoli <ettore@gnu.org>
-
- * camel/camel-mime-message.c (_write_to_stream): Write
- "Mime-Version: 1.0" to the stream.
-
- * tests/test1.c: If executed with a file name parameter, attach a
- file with with that name to the email without loading it into
- core, thus demonstrating usage of my latest changes.
-
- * camel/camel-mime-part.c (_set_encoding): Updated to use
- `CamelMimePartEncodingType'.
- (camel_mime_part_set_encoding): Likewise.
- (_get_encoding): Likewise.
- (camel_mime_part_get_encoding): Likewise.
- (_write_content_to_stream): Honour the `encoding' member.
- (_construct_from_stream): Made static.
- (camel_mime_part_encoding_to_string): New function.
- (_write_to_stream): Write the encoding string using it.
- (camel_mime_part_init): Set encoding to
- `CAMEL_MIME_PART_ENCODING_DEFAULT'.
- (_finalize): Don't free `encoding' anymore.
- (camel_mime_part_encoding_from_string): New function.
- (_parse_header_pair): Use it.
-
- * camel/camel-mime-part.h: New enum `CamelMimePartEncodingType'.
- Member `encoding' of `struct _CamelMimePart' changed from `gchar
- *' to `CamelMimePartEncodingType'. All the encoding-related
- methods changed to use this type instead of `gchar *'.
-
- * camel/gmime-base64.c (gmime_encode_base64): Got it to work.
-
- * camel/Makefile.am (libcamel_la_SOURCES): Compile
- `gmime-base64.c'.
-
- * camel/gmime-base64.h: New, previously missing, header.
-
- * camel/camel-stream-data-wrapper.c: New file implementing the
- `CamelStreamDataWrapper' class.
- * camel/camel-stream-data-wrapper.h: Corresponding header.
-
- * camel/camel-simple-data-wrapper.c: Implemented the `get_stream'
- virtual method.
- (_get_stream): New function implementing the method.
- (camel_simple_data_wrapper_class_init): Install it in the class
- struct.
- (camel_simple_data_wrapper_init): New function initializing the
- `stream' member to NULL,
- (camel_simple_data_wrapper_class_init): Set it as the
- GtkObjectInitFunc.
-
- * camel/camel-simple-data-wrapper.h: New member `stream' in
- `struct _CamelSimpleDataWrapper'.
-
- * camel/camel-simple-data-wrapper-stream.c: New file implementing
- the `CamelSimpleDataWrapperStream' class.
- * camel/camel-simple-data-wrapper-stream.h: Corresponding header.
-
- * camel/camel-data-wrapper.c (camel_data_wrapper_get_stream): New
- function.
- (_get_stream): New private function, just returning NULL.
- (camel_data_wrapper_class_init): Install it as the default
- `get_stream' virtual method.
-
- * camel/camel-data-wrapper.h: New virtual method `get_stream' in
- `CamelDataWrapperClass'.
- (camel_data_wrapper_get_stream): New function prototype.
-
-1999-11-05 Ettore Perazzoli <ettore@gnu.org>
-
- * tests/ui-tests/msg-composer-test.c: New file for testing the
- `EMsgComposer' widget.
- * tests/ui-tests/Makefile.am (noinst_PROGRAMS): Compile it. Do
- not compile `store_listing' for now because it's currently broken.
- (INCLUDES): Added the `widgets' source directory to the include
- path list.
- (LDADD): Removed the MH dependency; link with
- `libevolutionwidgets.la' from the `widgets' directory.
-
- * configure.in: Create `widgets/Makefile'.
-
- * camel/gmime-rfc2047.c (rfc2047_clean): Removed C++-like comment.
- * camel/camel-folder.c (camel_folder_get_message_uid_by_number):
- Likewise.
- * camel/gmime-content-field.c (gmime_content_field_get_parameter):
- Likewise.
- * camel/camel.c (camel_init): Likewise.
- * camel/camel-provider.c (camel_provider_register): Likewise.
- * camel/camel-multipart.c (_construct_from_stream): Likewise.
- * camel/camel-mime-part.c (_write_content_to_stream): Likewise.
- * camel/camel-medium.c (camel_medium_class_init): Likewise.
-
- * camel/camel-data-wrapper.h (camel_data_wrapper_get_type): Make
- prototype non-static.
-
- * camel/Makefile.am (libcamelinclude_HEADERS): Move
- `camel-exception-list.def' from `EXTRA_DIST' to
- `libcamelinclude_HEADERS'.
-
- * camel/camel.h: Do not #include <config.h>.
- * camel/data-wrapper-repository.h: Likewise.
-
-1999-11-05 Ettore Perazzoli <ettore@gnu.org>
-
- * tests/Makefile.am (INCLUDES): Add `-I$(top_srcdir)'.
-
-1999-10-13 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder.c (camel_folder_close): the
- folder->close method is now asynchronous.
-
- * camel/camel-folder-pt-proxy.c (_folder_open_cb):
- (_open):
- (_folder_open_cb):
- (_open):
- open/close method implemented in the thread proxy
- folder. More to come.
-
- * camel/camel-exception.c (camel_exception_xfer):
- new utility func.
-
- * camel/camel-marshal-utils.c: some new marshallers
-
- * camel/camel-folder-pt-proxy.c: Some explanations
- on the thread proxy system.
-
-1999-10-11 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-marshal-utils.c:
- camel/camel-marshal-utils.h:
- Handles operation marshalling.
-
- * camel/camel-thread-proxy.c:
- camel/camel-thread-proxy.h:
- new files. Generic proxy system.
-
- * camel/camel-folder-pt-proxy.c
- moved all proxy related code in dedicated files.
-
- (camel_folder_pt_proxy_init):
- removed proxy initialisation code
- (_finalize):
- removed proxy finalization code
-
-
- * camel/camel-exception.c
- (camel_exception_new):
- (camel_exception_set):
- (camel_exception_free):
- New funcs.
-
-1999-09-21 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder-pt-proxy.c (_async_close):
- implemented.
-
- * configure.in:
- Check pthreads.
-
- * camel/Makefile.am:
- camel-folder-pt-proxy.c is only compiled
- when pthreads are available.
-
- * camel/camel-folder-pt-proxy.c:
- Signal proxying implemenatation.
- (_signal_marshaller_server_side):
- (_signal_marshaller_client_side):
- (_init_signals_proxy):
- Code not is tested and has to be best
- explained as it uses threads conditions and
- gtk signal system.
- (_thread_notification_catch): notify pending signals
- as well as thread availability.
-
-1999-09-20 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder-pt-proxy.c (_op_exec_or_plan_for_exec):
- completed
-
- Binch of new funcs:
- (_maybe_run_next_op):
- Called by the watch notification when
- a threaded op is completed
- (_thread_notification_catch):
- notification watch call back
- (_init_notify_system):
- set up the notification channel
- (notify_availability):
- called by threads before completion.
-
-1999-09-18 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder-pt-proxy.c (_op_exec_or_plan_for_exec):
- new func. Try to exec an operation in a thread
- or queue it if a thread is already busy.
-
- * camel/camel-op-queue.c (camel_op_queue_set_service_availability):
- (camel_op_queue_get_service_availability):
- new funcs.
-
- * camel/camel-op-queue.c (camel_op_new):
- (camel_op_free):
- new funcs. Uses glib mem chunks.
-
-
-1999-09-17 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder-pt-proxy.c (_init_with_store):
- added notify io_channel.
-
- * camel/camel-op-queue.h:
- * camel/camel-op-queue.c:
- New object. Operation queue. Meant to be used in
- non-blocking proxy objects.
- (camel_op_queue_run_next_op): new func.
- run the next operation.
-
-1999-09-14 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/Makefile.am (libcamel_la_SOURCES):
- added camel-folder-pt-proxy.[ch] to the build
- process.
-
- * camel/camel-folder-pt-proxy.c (_init_with_store):
- started implementation of the pthread-based
- folder proxy.
-
-
-1999-09-08 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/providers/MH/mh-summary.c
- (mh_load_summary):
- (mh_save_summary):
- (mh_create_summary):
- implemented summary (files) for MH folders.
-
- * camel/providers/MH/camel-mh-folder.c
- (_get_message_by_uid): implemented.
- (camel_mh_folder_class_init):
- (_get_message_uid): implemented
-
- * camel/camel-folder.c (camel_folder_has_uid_capability):
- (camel_folder_get_message_uid):
- (camel_folder_get_message_uid_by_number):
- (camel_folder_get_message_by_uid):
- (camel_folder_get_uid_list):
- Documented UID methods.
- (camel_folder_get_message_uid_by_number):
- const'ified uid.
- (camel_folder_get_message_by_uid): idem
- removed stupid camel_folder_get_message_uid_by_number
- method.
-
- * tests/ui-tests/store_listing.c (close_all):
- close all open folders and stores. (necessary
- for UID list saving ).
-
- * camel/providers/MH/mh-uid.c (mh_generate_uid_list):
- fix: store UID list in CamelMHFolder object.
-
- * camel/providers/MH/camel-mh-folder.c (_open):
- read or create UID list.
- (_close): save UID list.
-
-1999-09-07 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/md5-utils.c (md5_get_digest_from_file):
- correct parameter decl (const)
-
- * camel/md5-utils.h: typo.
-
- * camel/providers/MH/mh-uid.c
- More work on UID stuff for MH.
- (mh_save_uid_list):
- (mh_load_uid_list):
- (mh_generate_uid_list):
- new funcs. Manage on-disk uid list.
-
- * camel/providers/MH/mh-utils.c (mh_is_a_message_file):
- Util routines live here now.
-
- * camel/md5-utils.c
- Documented all funcs.
-
- (md5_get_digest_from_stream):
- correct typo.
- (md5_get_digest_from_file):
- same typo corrected.
-
-
- * camel/md5-utils.h :
- raw routines are declared public now.
- Md5 use has to be versatile.
-
- * camel/providers/MH/mh-uid.c (mh_uid_get_for_file):
- new func. Returns an UID for an MH message.
-
-1999-09-06 bertrand <Bertrand.Guiheneuf@aful.org>
-
-
- * camel/md5-utils.h:
- * camel/md5-utils.c:
- changed names to follow camel style.
- (md5_get_digest_from_stream):
- new methods.
- (md5_get_digest_from_file):
- new function : get file md5 signature.
- To be used in providers code.
-
- * camel/md5-utils.c: imported md5 coding
- routine from rpm. Compiles.
-
-
-1999-09-05 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder.c (camel_folder_has_uid_capability):
- (camel_folder_get_message_uid):
- (camel_folder_get_message_uid_by_number):
- (camel_folder_get_message_by_uid):
- (camel_folder_get_uid_list):
- Basic UID framework.
-
- * devel-docs/misc/ref_and_id_proposition.txt:
- New revision. Some fixes.
-
- * camel/camel-folder.h (struct _CamelFolder): added
- uid_capability field.
-
-
- * camel/camel-folder.c (camel_folder_close): publicized
- the close method.
-
- * tests/ui-tests/store_listing.c (show_folder_messages):
- use folder summary instead of opening all messages.
- (show_folder_messages): re-enabled old CPU/Mem consumming
- method. Useful for pop3 for instance.
-
- * camel/providers/MH/camel-mh-folder.c (_create_summary):
- basic and highly non-efficient summary implementation.
- Should be seen as a proof of concept only.
- subfolder summary still has to be implemented.
-
- * camel/providers/maildir/camel-maildir-folder.c (_init_with_store):
- hasn't summary for the moment.
- * camel/providers/maildir/camel-maildir-folder.c
- cosmetic changes.
-
-
-1999-09-04 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/providers/MH/camel-mh-folder.c (_create_summary):
- started summary implementation.
- (_open): correct use of open.
-
- * camel/camel-folder.c (camel_folder_get_summary):
- get folder associated summary object.
-
- * camel/Makefile.am:
- added summary files build
-
- * camel/camel-folder-summary.[ch]:
- basic summary framework
-
-1999-09-03 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * devel-docs/camel/Makefile.am:
- sgml doc has camel-recipient now.
-
- * camel/camel-recipient.c (camel_recipient_foreach_recipient_type):
- added in-line documentation.
-
-1999-09-02 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/providers/maildir: Added (experimental) maildir
- provider written by Jukka Zitting <hukka@greywolves.org>
-
- * camel/providers/Makefile.am (SUBDIRS): build maildir
- provider.
-
- * camel/camel-provider.c (camel_provider_get_for_protocol):
- bug fix. patch from Jukka Zitting <hukka@greywolves.org>
-
- * camel/camel-mime-message.c (_write_one_recipient_to_stream):
- changed decl to fit CRLFunc.
- (_write_recipients_to_stream):
- calls camel_recipient_foreach_recipient_type now.
-
- * camel/camel-recipient.c (camel_recipient_foreach_recipient_type):
- new convinience function. Iterate over all recipient types.
-
- * camel/gmime-utils.c (gmime_write_header_table_to_stream):
- s/write_header_table_to_stream/gmime_write_header_table_to_stream/
- (gmime_write_header_with_glist_to_stream):
- s/write_header_with_glist_to_stream/gmime_write_header_with_glist_to_stream/
-
-1999-09-01 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-message.c (_finalize):
- (_add_recipient):
- (_remove_recipient):
- (_get_recipients): now use CamelRecipientTable
-
- * camel/gmime-content-field.c:
- (gmime_content_field_unref): test if object
- to free is non void.
-
- * camel/camel-folder.c (_finalize):
- (_set_name):
- * camel/camel-mime-part.c (_finalize):
- (_set_description):
- (_set_disposition):
- * camel/camel-service.c (_finalize):
- * camel/camel-stream-fs.c (_finalize):
- * camel/gmime-content-field.c:
- (gmime_content_field_construct_from_string):
-
- * camel/url-util.c (g_url_free):
-
- When using g_free (obj) don't test if obj != NULL
- g_free () already do that. Thanks to elerium for
- the feedback.
-
-1999-08-30 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-recipient.c (camel_recipient_get):
- (camel_recipient_remove):
- (camel_recipient_add):
- new func. More work on new independant recipient code.
-
-1999-08-29 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * MAINTAINERS: updated my e-mail address.
-
-1999-08-28 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-part.c (camel_mime_part_set_text):
- text parameter declared const
-
- * camel/camel-mime-part-utils.c (camel_mime_part_store_stream_in_buffer):
- actually test correctly nb_bytes_read_chunk is >0
-
- * camel/gstring-util.c:
- * camel/gmime-content-field.c:
- * camel/providers/MH/camel-mh-folder.c:
- * camel/camel-stream-fs.c:
- include string.h
-
- * camel/camel-stream-mem.c (_write): return
- the numver of written bytes.
-
- * camel/camel-stream-buffered-fs.c (_eos):
- return sthg
-
- * camel/camel-stream.c (default_camel_seek):
- return something.
-
-1999-08-26 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-part.c (_get_content_object):
- contruct the content from the buffer before calling
- CamelMedium implementation.
- (_construct_from_stream): Do not construct the content
- by default, just store the content bytes in
- a temporary buffer. Content will be constructed only
- at caller request (when calling CamelMedium::get_content_object)
- Providers with better access to the messages (mbox/MH ...)
- will have to provider lighter implementation, that is
- shall not read content at all unless the caller asks
- for it (again with get_content).
-
- * camel/camel-mime-part-utils.c: new file, groups
- mime-part related utils. Meant to be used by providers
- subclassing MimeMessage.
- (camel_mime_part_construct_headers_from_stream):
- (camel_mime_part_construct_content_from_stream):
- no more useless temporary hash table.
-
- * camel/camel-mime-part.c (_construct_from_stream): calls
- mime-part-utils functions now.
-
- * camel/gmime-utils.c (_store_header_pair_from_string):
- do not use hash table to store header, use an array instead.
-
-1999-08-25 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-part.c: now descend from CamelMedium.
-
- * tests/test1.c (main): all headers must be strdup'ed
- (main): unref created objects
-
- * camel/camel-medium.c (_set_content_object):
- (_get_content_object): these methods are
- in CamelMedium now.
-
-1999-08-24 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-medium.c (camel_medium_class_init):
- new class. Will handle all sort of information media
- (Mime mail messages, Lotus Notes mail messages,
- postit notes, faxes, who knows .... :)
- CamelMimePart will inherit from it.
-
- * camel/camel-mime-part.c (_set_disposition):
- (_set_description):
- description and disposition parameters are now const.
-
-
- * camel/gmime-content-field.c (gmime_content_field_free): added
- assertion code.
-
- * camel/providers/MH/camel-mh-folder.c (_get_message):
- uses buffered stream.
-
- * camel/camel-stream-buffered-fs.c:
- new stream to accelerate file ops.
-
-1999-08-20 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-stream-fs.c (camel_stream_fs_new_with_name):
- name parameter is const. This fixes a bug in destroy ()
-
-1999-08-18 Robert Brady <rwb197@ecs.soton.ac.uk>
-
- * camel/gmime-rfc2047.c: more work on encoder.
-
-1999-08-17 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-stream.c (camel_stream_read):
- return the number of bytes read.
- How can this have ever worked ?
- (camel_stream_flush): don't return anything.
-
- * camel/gmime-utils.c (get_header_table_from_stream):
- mem leak fixed.
-
-1999-08-16 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * tests/ui-tests/store_listing.c:
- Now has a popup menu on mailbox tree to allow
- easier tests. Implemented the copy stuff.
- Works well for the MH provider :)))
-
- * camel/providers/MH/camel-mh-folder.c (_copy_message_to):
- Test MH provider fast copy implemented.
-
-
-1999-08-15 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder.c (camel_folder_expunge):
- moved the active list readjustment code here.
- Much saner, providers won't have to worry about
- that.
- (_copy_message_to): new method.
-
- * camel/providers/MH/camel-mh-folder.c (_expunge):
- no more active list readjustment stuff.
-
- * camel/camel-folder.h: the expunge virtual no more
- returns a list of expunged messages. Now providers
- only have to set the expunge flag on the expunged
- messages.
-
- * camel/camel-folder.c (camel_folder_get_message):
- moved the caching code here. Finally, I don't want
- providers to crash the libs with a bad message cache
- implementation.
- (_close): do not call the CamelFolder virtual expunge
- method directly, use camel_folder_expunge() instead.
- (camel_folder_expunge): added the want_list param.
- The client can decide if it wants the expunged message
- list or not. If yes, it'll have to unref the messages
- itself.
-
-1999-08-14 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * tests/ui-tests/store_listing.c (delete_selected_messages):
- (expunge_selected_folders):
- Implemented deletion/expunge mechanism.
-
- * camel/camel-folder.c (_get_message):
- Added some debug info.
-
- * camel/providers/MH/camel-mh-folder.c (_expunge):
- implemented and tested.
-
- * camel/camel-mime-message.c (_set_flag):
- changed the old braindead implementation.
- boolean are inserted in the flag hash
- table casted as gpointers.
-
-
- * camel/camel-mime-message.c: indentation fix
-
-
-1999-08-13 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder.c (_get_message): default implementation
- to be called first by providers methods. It looks in the
- folder message list (in memory) to see if the message has
- not already been retrieved, and in this case, returns
- the same CamelMimeMessage object
-
- * camel/providers/MH/camel-mh-folder.c (_get_message): set
- message->message_number correctly.
-
- * camel/camel-folder.h (struct _CamelFolder):
- New field (message_list) which will hold a
- reference on each message obtained by the folder,
- which is necessary in order for the caching procedure
- to work (Getting the same message from a folder twice
- will return the same CamelMimeMessage object).
-
- * camel/camel-folder.c (camel_folder_get_message):
- When the store retreives a message put it in its
- message list.
- (_finalize): free message list.
-
- * ChangeLog: fix typo (parmanent)
-
- * camel/camel-folder.c (_get_permanent_flag_list):
- (camel_folder_get_permanent_flag_list):
- new method, returns the list of permanent
- flags supported by the folder.
-
- * camel/camel-mime-message.c (_get_flag_list):
- (camel_mime_message_get_flag_list): new method,
- return the list of flag name used by this message.
-
- * camel/hash-table-utils.c (g_strcase_equal):
- (g_strcase_hash): those two func go here now.
-
- * camel/hash_table_utils.c (hash_table_generic_free):
- free a (gpointer, gpointer) hash table pair.
-
- * camel/camel-mime-message.c (camel_mime_message_init): use
- case insensitive hash table functions.
- (_set_flag):
- (camel_mime_message_set_flag):
- (_get_flag):
- (camel_mime_message_get_flag):
- Use const for flag name, they are now
- duplicated.
-
-1999-08-12 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * tests/ui-tests/store_listing.c (show_folder_messages):
- remove stupid debug code.
- (add_mail_store): use camel_session_get_store instead
- of creating MH store directly.
- (main): load MH provider.
-
- * camel/camel-provider.c (camel_provider_register_as_module):
- register new provider.
- (camel_provider_get_for_protocol):
- Now, implementation is correct.
-
- * camel/camel-store.c (_finalize):
- * camel/camel-store.h (struct _CamelStore):
- further disabled url_name field use.
- URL will be generated dynamically.
-
- * camel/camel-session.c (camel_session_get_store_for_protocol):
- compilation and runtime fixes.
-
- * camel/providers/MH/camel-mh-store.c (_init):
- synced with CamelStore.
-
- * camel/camel-store.c (_init):
- in CamelStore::init, url_name is now const.
- disabled url_name copy.
-
- * camel/camel-session.c (camel_session_get_store):
- new function: returns a store for an URL.
- (camel_session_get_store_for_protocol):
- new functionc: returns a store for a given
- store protocol (as IMAP/POP/MH ...)
- * camel/string-utils.c (g_strcase_equal):
- (g_strcase_hash): case insensitive hash table
- funcs.
-
- * camel/camel-session.c (camel_session_init): hash table
- keys are case insensitive.
-
- * camel/camel-provider.c (camel_provider_get_for_protocol):
- new function, returns the last registered
- provider for a protocol.
-
- * camel/providers/MH/camel-mh-provider.c:
- new file. MH provider registration stuff.
-
- * camel/camel-provider.c (camel_provider_register_as_module):
- load a provider from a shared object (plugin).
- (camel_provider_register): register a provider
- "by hand". Used for statically defined providers.
-
- * tests/test7.c: new test.
- tests providers loading framework.
-
-1999-08-11
-
- * camel/camel-service.c (_finalize):
- * camel/camel-stream-fs.c (_finalize):
- (_destroy): close file descriptor.
- * camel/camel-stream-mem.c (_finalize):
- * camel/camel-store.c (_finalize):
- * camel/camel-folder.c (_finalize):
- * camel/camel-multipart.c (_finalize):
- * camel/camel-simple-data-wrapper.c (_finalize):
- * camel/camel-mime-part.c (_finalize):
- implemented destructors.
-
-
- * camel/gmime-content-field.c (gmime_content_field_ref):
- (gmime_content_field_unref):
- New reference mechanism for GMimeContentField objects.
-
- * camel/camel-data-wrapper.c (_finalize):
- Started implementing destructors.
-
- * camel/camel-mime-part.c (_construct_from_stream):
- * camel/gmime-content-field.c (gmime_content_field_write_to_stream):
- * camel/camel-multipart.c (_construct_from_stream):
- removed forgotten anarchic traces.
-
-1999-08-10 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * tests/ui-tests/store_listing.c:
- * tests/ui-tests/store_listing.glade:
- Quick and (very) dirty hack to test Camel more
- easily.
-
- * camel/camel-folder.c (camel_folder_append_message):
- new method.
-
-1999-08-09 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * devel-docs/misc/ref_and_id_proposition.txt:
- new file. Document message UID and vfolder
- implementation.
-
-1999-08-08 Robert Brady <rwb197@ecs.soton.ac.uk>
-
- * camel/gmime-rfc2047.c: more advanced RFC2047 encoder started.
-
-1999-08-08 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/providers/MH/camel-mh-folder.c (_get_message):
- fix. In MH, message number is not related to
- message position in folder.
-
- * camel/providers/MH/camel-mh-folder.c (_is_a_message_file):
- util func.
- (_get_message_count): implemented.
-
-1999-08-06 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * devel-docs/camel/:
- updated some autogen doc stuff.
- Still don't understand warnings :(
-
- * camel/camel-data-wrapper.c:
- * camel/providers/MH/camel-mh-store.c:
- * camel/url-util.c:
- * camel/gmime-content-field.c:
- * camel/camel-store.c:
- various inline doc corrections.
-
- * camel/camel-folder.c (get_message_count):
- new method. Returns the number of message
- in the folder.
-
-
-
-1999-08-06 Robert Brady <rwb197@ecs.soton.ac.uk>
-
- * tests/test6.c: encoder test.
-
- * camel/gmime-rfc2047.c: Fixed decoder bug : sequence
- ?= is not always the terminator for an encoded-string.
-
-
-1999-08-06 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/providers/MH/camel-mh-folder.c (_list_subfolders):
- stat was not testing the good file. Fixed.
-
- * tests/test4.c (main): added real test for MH folder
- provider. All tested things seem to work OK :)
-
-1998-08-06 Robert Brady <rwb197@ecs.soton.ac.uk>
-
- * tests/test5.c: test for RFC2047 decoder.
-
- * camel/gmime-rfc2047.c: Improved RFC2047 decoder.
-
-1999-08-06 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/providers/MH/camel-mh-folder.c (_exists): add debug information
- (_list_subfolders): test if first char in folder name is not '.'
- before adding it to the folder list.
-
- * camel/camel-store.c (_init):
- disable session check temporarily
- (_get_separator):
- (_get_folder): new static func.
- Fixed several oddities in class definition.
-
- * camel/providers/MH/camel-mh-store.c (camel_mh_store_get_type):
- parent type is CAMEL_STORE_TYPE not CAMEL_FOLDER_TYPE
-
- * camel/camel-store.c:
- prent class is CamelServiceClass not GtkObjectClass
-
- * camel/url-util.c :
- cosmetic changes + use of const when possible.
- (find_host):
- fix a bug: when there is no host and no port don't skip the '/'
- all static find_* func are now named _func_*
- (g_url_free): destructor func.
- cache field has been disabled. Constructing the url string
- won't be too slow and will occur rarely enough that we
- do not need to add complexity to this code.
-
- * camel/providers/MH/camel-mh-store.c:
- parent class is CamelStorClass not GtkObjectClass
-
-1999-08-05 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * tests/test4.c:
- test mh provider.
-
- * camel/providers/MH/camel-mh-folder.c (_get_message):
- implemented
-
- * camel/camel-folder.c (_get_message):
- new method.
- (camel_folder_get_message):
- corresponding public call
-
- * camel/README.HACKING:
- Some notes.
-
- * camel/CODING.STYLE:
- short note about coding style.
-
- * camel/README.COPYRIGHT:
- Note about copyright policy.
-
- * camel/providers/MH/camel-mh-folder.c (_list_subfolders):
- minor typo fixes.
-
-
-1999-08-04 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/gmime-rfc2047.c:
- * camel/gmime-rfc2047.h:
- indentation and cosmetic changes.
-
- * camel/providers/MH/camel-mh-folder.c (_list_subfolders):
- implemented.
- * camel/providers/MH/camel-mh-folder.c (_delete):
- finshed implementation
- (_delete_messages): implemented.
-
-
-1999-08-04 Robert Brady <rwb197@ecs.soton.ac.uk>
-
- * camel/gmime-rfc2047.[ch]: added an implemention of RFC2047
- (support for character sets other than US-ASCII in MIME
- headers). Not actually called from anywhere yet.
-
-
-1999-08-03 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/providers/MH/camel-mh-folder.c (_create):
- implemented.
- (_delete): started implementation.
-
- * camel/camel-folder.c (_get_folder): default implementation
- calls camel_store_get_folder ().
-
- * camel/providers/MH/camel-mh-folder.c (_init_with_store):
- implemented.
-
- * camel/camel-folder.h (struct _CamelFolder):
- remove useless exist_on_store field.
-
- * camel/camel-folder.c (_exists):
- do not use exist_on_store field.
-
- * camel/camel-folder.c (camel_folder_set_name):
- (camel_folder_get_name):
- new public functions
- (_set_name): set full_path.
-
- (_set_full_name):
- (camel_folder_set_full_name):
- commented out this functions def.
- It would make things very difficult to handle, and would not
- be very useful.
-
- * camel/providers/MH/camel-mh-store.h:
- * camel/providers/MH/camel-mh-store.c (camel_mh_store_set_toplevel_dir):
- (camel_mh_store_get_toplevel_dir):
- * camel/providers/MH/camel-mh-folder.c (_set_name):
- * camel/providers/MH/camel-mh-folder.h:
- use (gchar *) instead of (GString *) everywhere.
- use const when necessary.
-
- * camel/camel-folder.h (struct _CamelFolder):
- removed unused message_list field.
-
- * camel/camel-mime-part.c (_set_content_object):
- There is a probleme here. We can not allow mime part
- content-type field and content_object mime-type to be
- different. I thus chosed to set mime part object
- content field to be freed (if necessary) and set
- to be a pointer to content_object mime type
- field.
- (_construct_from_stream): set content_object mime type
- to be the same as mime_part's one. This is necessary
- because we use _set_content_type.
-
- This two things are a bit hackish ansd may need
- to be redesigned.
-
- * camel/gmime-utils.c (gmime_write_header_pair_to_stream):
- use g_strdup_printf and remove a bug.
-
- * camel/camel-simple-data-wrapper.c (_construct_from_stream):
- more debugging output + nb_bytes_read is now a signed int
- to avoid bug when eos is encountered.
-
- * camel/camel-mime-part.c (_construct_from_stream):
- sync to data_wrapper_repository function name changes.
- Use default "text/plain" type when conten-type field
- is not found. (following RFC 2046 spec).
-
- * camel/data-wrapper-repository.c (data_wrapper_repository_set_data_wrapper_type):
- (data_wrapper_repository_get_data_wrapper_type):
- change function name prefix (s/data_wrapper/data_wrapper_repository/)
-
- * camel/camel-multipart.c (_read_part):
- add `\n` at eol but not before boundary.
-
- * camel/gmime-utils.c (get_header_table_from_stream):
- correct implementation of end of stream detection.
-
-1999-08-01 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-multipart.c (_read_part):
- use a stream to store the part instead of GString.
-
- * camel/camel-mime-part.c (camel_mime_part_set_text):
- set data wrapper content type to "text/plain".
-
- * camel/camel-stream-mem.c:
- * camel/camel-stream-mem.h:
- new memory buffer based stream.
-
- * camel/camel-stream-fs.c (_seek):
- implementation for file system based stream.
-
- * camel/camel-stream.c (camel_stream_seek):
- new method.
-
- * camel/camel-stream-fs.c (camel_stream_fs_class_init):
- pass CamelStreamFsClass instead of CamelStreamClass.
-
-1999-08-01 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/gmime-utils.c (gmime_write_header_pair_to_stream):
- corrected a bug with memory not allocated for '\0' in strtmp
-
- * camel/gmime-utils.c (gmime_read_line_from_stream):
- do not return NULL when line is empty.
-
- * camel/camel-multipart.c (_read_part): return true when end
- of multipart is found, not the opposite
-
-1999-07-31 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/gmime-utils.c (gmime_read_line_from_stream):
- Don't return crlf at end of line.
-
-1999-07-30 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/gmime-utils.c (gmime_read_line_from_stream):
- new function: reads a line from a stream.
- should be in streams utils maybe.
-
-1999-07-29 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-part.c (_construct_from_stream):
- Uses data wrapper repository to find what data wrapper
- to use to construct the content from a stream. When
- no object is registered for the mime type found in
- content type field a CamelSimpleDataWrapper is
- used.
-
- * camel/camel-mime-part.c (_get_content_type):
- (camel_mime_part_get_content_type): returns
- a pointer on the content_type field instead
- of the gchar * mime "type/subtype".
-
-1999-07-28 bertrand <Bertrand.Guiheneuf@aful.org>
-
-
- * camel/data-wrapper-repository.c
- * camel/data-wrapper-repository.h
- New files. Handles mime type <-> camel object
- (for example "multipart" <-> CamelMultipart
- * tests/tesst3.c: test data repository thing.
-
-1999-07-26 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-multipart.c (_write_to_stream):
- implemented output of multipart.
-
- * tests/test1.c (main): testing content objects operations.
-
-1999-07-25 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-part.c (camel_mime_part_set_text):
- new util function to set a mime part content to be
- a text string.
-
- * camel/camel-simple-data-wrapper.c (camel_simple_data_wrapper_set_buffer_from_text):
- new util func.
- (camel_simple_data_wrapper_new): new func.
-
- * camel/camel-multipart.c (_write_to_stream):
- implemented output of multiparts.
-
-1999-07-24 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/gmime-content-field.c (gmime_content_field_get_parameter):
- New function. Returns the value associated to a
- mime parameter.
-
-
-1999-07-22 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-multipart.h:
- * camel/camel-multipart.c:
- New class. Models multipart mime objects.
-
- * camel/camel-mime-body-part.h:
- * camel/camel-mime-body-part.c:
- New class. Body part is a mime part contained in
- a multipart object.
-
-
-1999-07-21 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-log.h:
- implemented hard log level stuff.
- * came/*.c use "CAMEL_LOG_*" instead of "CAMEL_LOG (*"
- in order to allow hard level switch.
-
- * tests/test1.c:
- * tests/test2.c:
- updated to use gchar instead of GString. Tests passed.
-
-
-1999-07-19 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-stream.c:
- * camel/camel-stream.h:
- "const"-antified
-
-
- * camel/camel-simple-data-wrapper.c: (_construct_from_stream)
- do not use any limit when constructing the object from a stream
-
- * camel/camel-stream-fs.c:
- * camel/camel-stream-fs.h:
- * camel/camel-mime-message.c:
- * camel/camel-mime-message.h:
- * camel/camel-session.c:
- * camel/camel-session.h:
- * camel/camel-service.c:
- * camel/camel-service.h:
- * camel/camel-store.c:
- * camel/camel-store.h:
- * camel/camel-folder.c:
- * camel/camel-folder.h:
- * camel/gmime-utils.c:
- * camel/gmime-utils.h:
- GString -> gchar
- constantified what had to be.
-
- * camel/string-utils.c:
- * camel/string-utils.h:
- New files. Meant to replace gstring-util for gchar *
-
-1999-07-16 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/gmime-content-field.c (gmime_content_field_construct_from_string):
- GString -> gchar
- use const to indicate copied parameter.
-
-1999-07-15 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-simple-data-wrapper.c:
- * camel/camel-simple-data-wrapper.h:
- Gstring -> gchar
-
-1999-07-15 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/url-util.c:
- * camel/url-util.h:
- Do not use GStrings any more.
- Added assertion code.
- Cosmetic reformating
-
- * AUTHORS:
- * ChangeLog:
- Changed my email address.
-
-
-1999-07-13 Miguel de Icaza <miguel@gnu.org>
-
- * camel/gmime-base64.c (gmime_encode_base64): Implemented base64
- encoder based on CamelStreams. Should the encoder/decoder be a
- Stream itself?
-
- * camel/gmime-utils.c: include config.h here.
- * camel/url-util.c: ditto.
- * camel/gstring-util.c: ditto.
- * camel/gmime-content-field.c: ditto.
- * camel/camel-stream.c: ditto.
- * camel/camel-stream-fs.c: ditto.
- * camel/camel-store.c: ditto.
- * camel/camel-simple-data-wrapper.c: ditto.
- * camel/camel-session.c: ditto.
- * camel/camel-service.c: ditto.
- * camel/camel-mime-part.c: ditto.
- * camel/camel-mime-message.c: ditto.
- * camel/camel-log.c: ditto.
- * camel/camel-data-wrapper.c: ditto
- * camel/camel-folder.c: ditto.
-
- * camel/camel-stream.c (camel_stream_write): Moved api
- documentation to the places that they document.
- (camel_stream_class_init): Virtual classes do not need to have a
- default implementation. So null them all.
- (camel_stream_write): Return value from write.
- (camel_stream_available): implement.
- (camel_stream_write_strings): documented.
-
- * devel-docs/query/virtual-folder-in-depth.sgml: Small
- reformatting
-
-1999-06-28 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * tests/test2.c (main): now use
- CamelDataWrapper::contruct_form_stream to test
- message parsing
-
- * camel/camel-data-wrapper.c:
- * camel/camel-data-wrapper.h:
- construct_from_stream no longer has maximimum size arg.
-
- * camel/camel-mime-part.c (_construct_from_stream): new.
- Construct the mime_part from a stream.
-
- * camel/camel-mime-part.c:
- new field (content_type) and associated methods.
- (camel_mime_part_init): initialize content_type field.
- (_parse_header_pair): now set content_type MimePart field
- instead of using DataWrapper Mime typing facility.
-
-1999-06-28 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-data-wrapper.h:
- s/content_type/mime_type/
-
-1999-06-24 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-simple-data-wrapper.[ch]:
- new class. Simple implementation of a data wrapper:
- simply keeps the stream result in a byte array.
-
- * camel/camel-mime-part.c (_parse_header_pair): added a warning.
- Have to think about the correct way to store content type stuff.
-
-1999-06-24 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-message.c (_write_one_recipient_to_stream):
- includes gmime-utils header.
- patch from Ulrich Drepper <drepper at cygnus.com>
- set separator string in write_header_with_glist_to_stream()
-
- * camel/camel-log.c (camel_log):
- patch from Ulrich Drepper <drepper at cygnus.com>
- Do not use stderr in initialization of logfile descriptor.
-
- * camel/camel-stream-fs.c (camel_stream_fs_new_with_name):
- patch from Ulrich Drepper <drepper at cygnus.com>
- initialize mode field in open().
-
-1999-06-22 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-data-wrapper.c (_get_content_type):
- moved all the content-type stuff here.
- (camel_data_wrapper_init): initialize the instance
- content-type field.
-
- * camel/camel-mime-part.c (_parse_header_pair):
- parse Content-Type stuff in header.
- (_write_to_stream): write the content type stuff to
- the stream.
-
- * camel/gmime-content-field.c (gmime_content_field_get_mime_type):
- new function, returns "type/subtype" mime type string.
- (gmime_content_field_construct_from_string):
- new function, construbt a content_field object
- form a string. be used to set the mime_type from a
- string.
-
- * camel/camel-mime-part.c (_set_content_type):
- (camel_mime_part_set_content_type):
- (_get_content_type):
- (_get_content_type):
- new methods.
-
-1999-06-21 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/gmime-utils.c (get_header_table_from_stream):
- replace CR/LF+'\t' with ' '
-
- * camel/camel-mime-message.c (_set_recipient_list_from_string):
- trim \t when splitting
-
- * camel/gmime-utils.c (get_header_table_from_file):
- corrected bug in scanning tabulations ('t' -> '\t')
-
- * tests/test2.c (main): read mail.test instead
- of mail1.test
-
- * camel/camel-mime-part.c (_add_header):
- added comments
-
-1999-06-03 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * devel-docs/query/virtual-folder-in-depth.sgml:
- sgmlized Giao's doc about virtual folders.
-
-1999-05-31 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * tests/test2.c (main):
- use new stream code instead of raw file * stuff.
-
- * camel/gmime-utils.c (get_header_table_from_stream):
- new func. Will replace get_header_table_from_file and will
- be used to parse headers from files as well as from
- memory buffers.
-
- * camel/camel-stream-fs.c:
- CamelStream Subclass. File system based
- stream.
-
-
-1999-05-30 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-stream.h: new class. Represents an
- abstract stream object.
-
- * camel/camel-mime-message.c (_set_recipient_list_from_string):
- remove leading and trailing spaces in recipient addresses.
-
- * camel/gmime-utils.c (_store_header_pair_from_gstring):
- remove leading and trailing spaces from header values.
-
- * camel/gstring-util.c (g_string_trim): new
- func: remove leading or trailng chars from
- a specified char set.
- (g_string_split): allow trimming of substrings.
-
- * tests/test1.c (main): remove gtk_main call
-
-1999-05-28 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-part.c
- (_parse_header_pair):
- (_init_header_name_table):
- More header parsing code.
-
-
-1999-05-27 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * tests/test2.c (main): rewrite message obtained via
- parsing into a file. Actually, it works pretty well :))
-
- * camel/camel-mime-message.c (_set_recipient_list_from_string):
- create recipient list form a comma separated string.
- (_parse_header_pair): added recipient lists parsing.
-
- * camel/camel-mime-part.c (_parse_header_pair):
- new (protected) method. Parse a head pair and
- decides what to do with it.
-
- (_add_header): Call in _parse_header_pair
-
- * camel/camel-mime-message.c (_parse_header_pair):
- overload header parsing MimePart mthod.
-
- * camel/gstring-util.c (g_string_split):
- new func: split a gstring into a GList of
- substring.
-
-1999-05-26 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/gmime-utils.c (get_header_lines_from_file):
- new func. Parses message header zone and returns
- a Glist of all header lines.
-
- * tests/test2.c: tests message parsing
-
- * camel/gmime-utils.c (write_header_table_to_file):
- new func to write a table of headers.
-
-1999-05-20 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-message.c (_write_to_file):
- recipient list printing
-
- * tests/test1.c (main): more tests.
-
-1999-05-19 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-part.c (_write_to_file): test if content
- exists before calling its write_to method.
-
- * camel/camel-mime-message.c (_write_to_file): bugs fix.
-
- * camel/camel-mime-message.c (camel_mime_message_new_with_session):
- new func. Creates a message with the session field set
- up correctly.
-
-1999-05-18 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * tests/test1.c (main): tests
-
- * camel/camel-mime-message.c (_write_to_file):
- started write_to framework for mime_messages
-
- * camel/camel-mime-message.c (*_message_number):
- message number funcs.
-
-1999-05-15 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-message.c (*_flag):
- flags handling methods
-
-1999-05-14 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-message.c (camel_mime_message_class_init):
- added recipient handling class funcs.
-
-1999-05-13 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-message.c (camel_mime_message_init):
- create recipients hash table
- (_remove_recipient):
- (_add_recipient):
- (_get_recipients): new funcs.
- Internal Recipients data structure is
- a bit complicated though.
-
- * camel/camel-mime-part.c (camel_mime_part_init):
- create headers hash table
-
- * camel/camel-mime-message.h:
- a bunch of get/set header field
- method done. Does nothing yet though.
-
- * camel/camel-mime-message.[ch] :
- new file.
-
-1999-05-12 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-part.h (struct ):
- disposition is now a full GMimeContentField
- object.
-
- * camel/gmime-content-field.c: new file
- handle "type/subtype ;parameter=value ; parameter=value ..."
- BNF grammar elements
- (gmime_content_field_write_to_file): new func
-
- * camel/gmime-utils.c (gmime_write_header_pair_to_file):
- namespace change
-
-1999-05-11 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-part.c (_write_to_file):
- overload wrapper class method.
- (_write_to_file): start to write some text in
- file.
-
- * camel/camel-store.c: typo fix.
-
- * camel/camel-store.c:
- * camel/camel-service.c:
- * camel/camel-folder.c:
- * camel/camel-data-wrapper.c:
- * camel/camel-mime-part.c:
- static functions naming follows gnome
- coding style guide.
-
- * camel/camel-mime-part.h: implemented public interfaces
-
-
-1999-05-10 Bertrand Guiheneuf <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-part.c (__camel_mime_part_get_header_lines):
- (__camel_mime_part_set_header_lines):
- (__camel_mime_part_get_content_languages):
- (__camel_mime_part_set_content_languages):
- (__camel_mime_part_get_encoding):
- (__camel_mime_part_set_encoding):
- (__camel_mime_part_get_content_MD5):
- (__camel_mime_part_set_content_MD5):
- (__camel_mime_part_get_content_id):
- (__camel_mime_part_set_content_id):
- A bunch of new set/get func.
-
- * camel/gstring-util.c (g_string_list_free):
- convenience function for string list
- complete deallocation.
-
-1999-05-09 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-part.c (__camel_mime_part_add_header):
- new method
-
- * camel/camel-mime-part.h (struct CamelMimePart):
- added core fields.
-
-1999-05-08 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-mime-part.[ch]:
- new class. models a mime mail part.
-
- * camel/camel-data-wrapper.c
- (camel_data_wrapper_write_to_buffer): method to
- stream data content in a buffer.
- (camel_data_wrapper_write_to_file):
- (camel_data_wrapper_construct_from_buffer):
- (camel_data_wrapper_construct_from_file):
- new methods.
-
-1999-05-07 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-data-wrapper.[ch]:new class.
- This should not be a class but rather an
- interface. The day Gtk support interfaces,
- it dataWrapper should become an interface.
-
-1999-05-04 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-service.c (camel_service_get_url):
- new method.
-
- * devel-docs/camel/camel-sections.txt: added
- function doc references
-
- * camel/camel-folder.c (__camel_folder_close):
- fixed indentation.
- (camel_folder_expunge): new method.
- (__camel_folder_close): used expunge flag
-
-1999-05-03 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder.c (camel_folder_get_mode):
- typo fix
-
- * camel/camel-folder.c (__camel_folder_list_subfolders):
- new func.
-
- * some doc stuffs
-
-
-1999-05-01 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder.c
- (__camel_folder_get_mode):
- (camel_folder_get_mode):
- (camel_folder_get_parent_store):
- (__camel_folder_get_parent_store):
- (camel_folder_get_parent_folder):
- (__camel_folder_get_parent_folder):
- new methods
-
- * camel/camel-service.c: put __ prefix before
- private virtual funcs.
-
- * camel/camel-folder.c (camel_folder_delete):
- (camel_folder_delete_messages):
- new methods.
-
- * camel/url-util.c (g_url_new): some
- more comments
-
-1999-04-27 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder.c (camel_folder_create):
- new public function.
-
-1999-04-25 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-session.c (camel_session_get_store_from_provider):
- initialize folder object.
-
- * camel/camel-store.c (init): new method.
- called by session object at instantiation time.
-
- * camel/camel-store.h (struct _CamelStore):
- new fields : session and url_name
-
-1999-04-25 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-session.c (camel_session_set_provider):
- new method to set the default provider for a protocol.
- (camel_session_get_store_from_provider):
- new method to instantiate a folder from a provider.
-
- * camel/camel-provider.h: s/GString/gchar/g
- + typo fix.
-
- * camel/camel-provider.[ch]:
- basic provider structure. Have to write the
- code for dynamic loading.
-
-1999-04-24 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/url-util.[ch]: s/new_g_url/g_url_new
-
- * camel/url-util.c (new_g_url): URL
- rewritten completely. Error handling not
- implemented in public functions.
- But URL scan works pretty well :)))
-
-1999-04-24 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/url-util.[ch]: I needed the url
- functions to use GString, and I wanted a more
- general scheme so I finally started rewriting
- the whole thing from scratch.
- No more code from gzilla :(
-
-1999-04-23 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/url-util.[ch]:
- Utility functions to parse URLs.
- Stolen shamelessly from gzilla (www.gzilla.com)
- written by Raph Levien <raph@acm.org>
-
- * camel/Makefile.am: added url-util.[ch]
- compilation.
-
- * Makefile.am (SUBDIRS): removed devel-docs
- until I come up with a correct Makefile.am
-
- * camel/camel-store.h:
- * camel/camel-folder.h:
- correct declarations of structs
-
-
-1999-04-22 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/providers/MH/camel-mh-store.c:
- more test implementation.
-
- * camel/camel-store.c (camel_store_get_type): typo fix
-
-
-1999-04-21 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/providers/MH/camel-mh-folder.c (camel_mh_folder_get_type):
- start test provider.
-
-1999-04-20 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-store.h: now CamelStore inherits from
- CamelService.
-
- * camel/camel-service.c (camel_service_class_init):
- basic abstract service class.
-
-1999-04-19 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/README: added some (few) explanations.
-
-1999-04-18 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-store.[ch]: started implementation
- * camel/camel-folder.c (camel_folder_get_type): typo
- uncommented the store related code.
- (camel_folder_create): enable som store relted code.
- Not finished. Have to define public methods first.
-
- * camel/camel-log.h: some explanation about the
- log system
-
-1999-04-18 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder.c:
- (camel_folder_create): implemented (partially)
- have to write CamelStore before finishing it.
-
- * camel/camel-folder.h (CamelFolder): added full_name field
- (CamelFolderClass): added set/get_full_name methods
-
-1999-04-18 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * camel/camel-folder.c: some work
- * camel/camel-log.c: log system for camel
- * camel/gstring-util.c: some utilities for GString objects
-
-
-1999-04-18 bertrand <Bertrand.Guiheneuf@aful.org>
-
- * autogen.sh (PKG_NAME): groomf -> gnome-mailer
+2012-12-05 The Evolution Team <evolution-hackers@gnome.org>
+ The ChangeLog is no longer auto-generated when releasing.
+ Get a clone of git repository and list changes with 'git log' there,
+ $ git clone git://git.gnome.org/evolution
+ or browse changes online at
+ http://git.gnome.org/browse/evolution/log/?h=master
diff --git a/HACKING b/HACKING
index e69de29bb2..7de98a31e3 100644
--- a/HACKING
+++ b/HACKING
@@ -0,0 +1,59 @@
+1 Patch guidelines
+
+Procedures that should be followed when submitting patches for
+Evolution are available on
+http://projects.gnome.org/evolution/patch.shtml
+
+Further information:
+
+1.1 Subject Lines
+
+If the patch addresses a specific bug in bugzilla.gnome.org, then the
+bug number must be included in the subject line, preferably near the
+beginning of the subject line. A concise summary of the bug(s) being
+addressed, should be the remainder of the subject.
+
+It is unnecessary to add "[PATCH]", "patch" or similar to the subject
+line, unless it is being cross-posted to other non-patch lists.
+
+It is absolutely unnecessary to add "please consider", "please review",
+or "seeking review", or similar, to the subject line. Please do not do
+this.
+
+Where the patch does not address a specific bug number, then the subject
+line should simply be a concise summary of the problem/feature it
+addresses.
+
+In all cases the subject line should include the module(s) to which the
+patch applies, and would generally match the component on the bug or
+the top-level module directory (e.g. camel, mail, addressbook, use 'all'
+for more than 3 or 4 modules).
+
+2.2 Message Body
+
+Patches should be attached as attachments, preferably as a single
+diff, when possible, and the changes are related. The diff must be in
+unified diff format, "-up" is a suitable argument to give to "cvs
+diff" (-p may be dropped if not supported by your diff). If you have
+added files, then -N should also be used, but if you are using cvs,
+"cvs add" is needed, and requires write access to the repository.
+
+If the patch does not address a specific bug, then the patch email
+should describe which feature or problem it addresses. If it does
+address a specific bug, then further explanation beyond the bug
+commentary is optional, although often convenient.
+
+It would also be helpful to summarise the module to which it applies
+in the message body.
+
+In all cases you should include which branch, or branches, the patch
+is intended to apply to. If this is not given it will be assumed to
+be the trunk (HEAD), and such patches will and must not be applied to
+any stable branch without further approval.
+
+2.3 Stable branches
+
+Generally, any patch to the stable branch from non-core developers
+must address a specific bug in bugzilla.gnome.org. The patch should
+also be attached to the bug in question. The patch must not be
+applied until reviewed.
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index b42a17ac46..0000000000
--- a/INSTALL
+++ /dev/null
@@ -1,182 +0,0 @@
-Basic Installation
-==================
-
- These are generic installation instructions.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, a file
-`config.cache' that saves the results of its tests to speed up
-reconfiguring, and a file `config.log' containing compiler output
-(useful mainly for debugging `configure').
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If at some point `config.cache'
-contains results you don't want to keep, you may remove or edit it.
-
- The file `configure.in' is used to create `configure' by a program
-called `autoconf'. You only need `configure.in' if you want to change
-it or regenerate `configure' using a newer version of `autoconf'.
-
-The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system. If you're
- using `csh' on an old version of System V, you might need to type
- `sh ./configure' instead to prevent `csh' from trying to execute
- `configure' itself.
-
- Running `configure' takes awhile. While running, it prints some
- messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package.
-
- 4. Type `make install' to install the programs and any data files and
- documentation.
-
- 5. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
-Compilers and Options
-=====================
-
- Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. You can give `configure'
-initial values for variables by setting them in the environment. Using
-a Bourne-compatible shell, you can do that on the command line like
-this:
- CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
-
-Or on systems that have the `env' program, you can do it like this:
- env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
-
-Compiling For Multiple Architectures
-====================================
-
- You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
- If you have to use a `make' that does not supports the `VPATH'
-variable, you have to compile the package for one architecture at a time
-in the source code directory. After you have installed the package for
-one architecture, use `make distclean' before reconfiguring for another
-architecture.
-
-Installation Names
-==================
-
- By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc. You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
- Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
- There may be some features `configure' can not figure out
-automatically, but needs to determine by the type of host the package
-will run on. Usually `configure' can figure that out, but if it prints
-a message saying it can not guess the host type, give it the
-`--host=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name with three fields:
- CPU-COMPANY-SYSTEM
-
-See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the host type.
-
- If you are building compiler tools for cross-compiling, you can also
-use the `--target=TYPE' option to select the type of system they will
-produce code for and the `--build=TYPE' option to select the type of
-system on which you are compiling the package.
-
-Sharing Defaults
-================
-
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Operation Controls
-==================
-
- `configure' recognizes the following options to control how it
-operates.
-
-`--cache-file=FILE'
- Use and save the results of the tests in FILE instead of
- `./config.cache'. Set FILE to `/dev/null' to disable caching, for
- debugging `configure'.
-
-`--help'
- Print a summary of the options to `configure', and exit.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`--version'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`configure' also accepts some other, not widely useful, options.
diff --git a/MAINTAINERS b/MAINTAINERS
index 602e3bf73b..5625868aff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1,5 +1,5 @@
-Email: ettore@ximian.com
-Email: danw@ximian.com
-Email: chris@ximian.com
-Email: federico@ximian.com
-Email: iain@ximian.com
+Matthew Barnes <mbarnes@redhat.com>
+Milan Crha <mcrha@redhat.com>
+
+User Documentation:
+Andre Klapper <ak-47@gmx.net>
diff --git a/Makefile.am b/Makefile.am
index c66a8aaff6..856e459102 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,91 +1,151 @@
-changelogs = \
- ChangeLog
+ACLOCAL_AMFLAGS=-I m4
-confexecdir = $(libdir)
-confexec_DATA = \
- camelConf.sh \
- evolution_shellConf.sh \
- evolution_addressbookConf.sh \
- evolution_calendarConf.sh
+pkgconfigdir = $(libdir)/pkgconfig
+INTERFACE_VERSION=3.0
-EXTRA_DIST = \
+%-$(INTERFACE_VERSION).pc: %.pc
+ cp $< $@
+
+pkgconfig_in_files = \
+ evolution-calendar-$(INTERFACE_VERSION).pc \
+ evolution-mail-$(INTERFACE_VERSION).pc \
+ evolution-plugin-$(INTERFACE_VERSION).pc \
+ evolution-shell-$(INTERFACE_VERSION).pc
+pkgconfig_DATA = $(pkgconfig_in_files:.pc.in=-$(INTERFACE_VERSION).pc)
+
+EXTRA_DIST = \
+ $(pkgconfig_DATA) \
AUTHORS \
- $(changelogs) \
COPYING-DOCS \
+ COPYING.LGPL2 \
+ COPYING.LGPL3 \
+ COPYING.OPENLDAP \
README \
HACKING \
MAINTAINERS \
NEWS \
NEWS-1.0 \
- xml-i18n-merge.in \
- xml-i18n-update.in \
- xml-i18n-extract.in \
- $(confexec_DATA:.sh=.sh.in)
+ enumtypes.c.template \
+ enumtypes.h.template \
+ marshal.mk \
+ iconv-detect.c \
+ plugin.mk \
+ intltool-merge.in \
+ intltool-update.in \
+ intltool-extract.in \
+ evolution-zip.in \
+ gtk-doc.make
-SUBDIRS = \
- intl \
- macros \
- data \
- po \
- e-util \
- libical \
- widgets \
- shell \
- camel \
- filter \
- libversit \
- libwombat \
- addressbook \
- composer \
- mail \
- calendar \
- wombat \
- importers \
- my-evolution \
- art \
- sounds \
- ui \
- default_user \
- views \
- tools \
- doc \
- help \
- omf-install
+if ENABLE_SMIME
+SMIME_SUBDIR=smime
+endif
-%Conf.sh: %Conf.sh.in Makefile
- sed -e 's?\@EVOLUTION_LIBDIR\@?$(EVOLUTION_LIBDIR)?g' \
- -e 's?\@EVOLUTION_DATADIR\@?$(EVOLUTION_DATADIR)?g' \
- -e 's?\@EVOLUTION_INCLUDEDIR\@?$(EVOLUTION_INCLUDEDIR)?g' \
- -e 's?\@CAMEL_INCLUDEDIR\@?$(CAMEL_INCLUDEDIR)?g' \
- -e 's?\@VERSION\@?$(VERSION)?g' \
- -e 's?\@privlibdir\@?$(privlibdir)?g' \
- -e 's?\@SHELL_LIBS\@?$(SHELL_LIBS)?g' \
- -e 's?\@SHELL_CFLAGS\@?$(SHELL_CFLAGS)?g' \
- -e 's?\@CAMEL_LIBS\@?$(CAMEL_LIBS)?g' \
- -e 's?\@CAMEL_CFLAGS\@?$(CAMEL_CFLAGS)?g' \
- -e 's?\@LDAP_LIBS\@?$(LDAP_LIBS)?g' \
- -e 's?\@LDAP_CFLAGS\@?$(LDAP_CFLAGS)?g' \
- -e 's?\@EVOLUTION_ADDRESSBOOK_LIBS\@?$(EVOLUTION_ADDRESSBOOK_LIBS)?g' \
- -e 's?\@EVOLUTION_ADDRESSBOOK_CFLAGS\@?$(EVOLUTION_ADDRESSBOOK_CFLAGS)?g' \
- -e 's?\@EVOLUTION_CALENDAR_LIBS\@?$(EVOLUTION_CALENDAR_LIBS)?g' \
- -e 's?\@EVOLUTION_CALENDAR_CFLAGS\@?$(EVOLUTION_CALENDAR_CFLAGS)?g' \
- < $(srcdir)/$< > $@.tmp \
- && mv $@.tmp $@
+if WITH_HELP
+HELP_SUBDIR=help
+endif
-# CDE Stuff
+# For maintainers only.
+if GLADE_CATALOG
+MAINT_SUBDIR=maint
+endif
-if HAVE_DTAPPINTEGRATE
+SUBDIRS = \
+ m4 \
+ data \
+ libgnomecanvas \
+ e-util \
+ libemail-engine \
+ shell \
+ $(SMIME_SUBDIR) \
+ em-format \
+ addressbook \
+ composer \
+ mail \
+ calendar \
+ art \
+ plugins \
+ modules \
+ $(MAINT_SUBDIR) \
+ doc \
+ ui \
+ views \
+ po \
+ sounds \
+ $(HELP_SUBDIR)
-# This installs Evolution into the Application Manager on CDE
-dtappintegrate:
- ( cd data && make dtappintegrate )
+DISTCLEANFILES = \
+ $(builddir)/iconv-detect.h \
+ $(pkgconfig_in_files)
-# ...And this uninstalls it
-dtappunintegrate:
- ( cd data ; make dtappunintegrate )
+MAINTAINERCLEANFILES = \
+ $(srcdir)/ABOUT-NLS \
+ $(srcdir)/INSTALL \
+ $(srcdir)/aclocal.m4 \
+ $(srcdir)/autoscan.log \
+ $(srcdir)/compile \
+ $(srcdir)/config.guess \
+ $(srcdir)/config.h.in \
+ $(srcdir)/config.rpath \
+ $(srcdir)/config.sub \
+ $(srcdir)/configure.scan \
+ $(srcdir)/depcomp \
+ $(srcdir)/install-sh \
+ $(srcdir)/ltmain.sh \
+ $(srcdir)/missing \
+ $(srcdir)/mkinstalldirs \
+ $(srcdir)/gtk-doc.make \
+ $(srcdir)/m4/codeset.m4 \
+ $(srcdir)/m4/gettext.m4 \
+ $(srcdir)/m4/glibc2.m4 \
+ $(srcdir)/m4/glibc21.m4 \
+ $(srcdir)/m4/gtk-doc.m4 \
+ $(srcdir)/m4/iconv.m4 \
+ $(srcdir)/m4/intdiv0.m4 \
+ $(srcdir)/m4/intl.m4 \
+ $(srcdir)/m4/intldir.m4 \
+ $(srcdir)/m4/intlmacosx.m4 \
+ $(srcdir)/m4/intltool.m4 \
+ $(srcdir)/m4/intmax.m4 \
+ $(srcdir)/m4/inttypes-pri.m4 \
+ $(srcdir)/m4/inttypes_h.m4 \
+ $(srcdir)/m4/lcmessage.m4 \
+ $(srcdir)/m4/lib-ld.m4 \
+ $(srcdir)/m4/lib-link.m4 \
+ $(srcdir)/m4/lib-prefix.m4 \
+ $(srcdir)/m4/libtool.m4 \
+ $(srcdir)/m4/lock.m4 \
+ $(srcdir)/m4/longlong.m4 \
+ $(srcdir)/m4/ltoptions.m4 \
+ $(srcdir)/m4/ltsugar.m4 \
+ $(srcdir)/m4/ltversion.m4 \
+ $(srcdir)/m4/lt~obsolete.m4 \
+ $(srcdir)/m4/nls.m4 \
+ $(srcdir)/m4/po.m4 \
+ $(srcdir)/m4/printf-posix.m4 \
+ $(srcdir)/m4/progtest.m4 \
+ $(srcdir)/m4/size_max.m4 \
+ $(srcdir)/m4/stdint_h.m4 \
+ $(srcdir)/m4/uintmax_t.m4 \
+ $(srcdir)/m4/visibility.m4 \
+ $(srcdir)/m4/wchar_t.m4 \
+ $(srcdir)/m4/wint_t.m4 \
+ $(srcdir)/m4/xsize.m4 \
+ $(srcdir)/po/Makefile.in.in~ \
+ $(srcdir)/po/Makevars.template \
+ $(srcdir)/po/Rules-quot \
+ $(srcdir)/po/boldquot.sed \
+ $(srcdir)/po/en@boldquot.header \
+ $(srcdir)/po/en@quot.header \
+ $(srcdir)/po/insert-header.sin \
+ $(srcdir)/po/quot.sed \
+ $(srcdir)/po/remove-potcdate.sin
-# Install/uninstall for CDE
-cde-install: install dtappintegrate
-cde-uninstall: dtappunintegrate uninstall
+DISTCHECK_CONFIGURE_FLAGS = \
+ --enable-gtk-doc \
+ --disable-goa \
+ --disable-image-inline \
+ --disable-pst-import \
+ --disable-weather \
+ --with-help
-endif
+-include $(top_srcdir)/git.mk
diff --git a/NEWS b/NEWS
index 5c5ebf65d0..4936da89c7 100644
--- a/NEWS
+++ b/NEWS
@@ -1,480 +1,10518 @@
-Evolution 1.1.2, 2002-10-07
+Evolution 3.9.5 2013-07-29
+--------------------------
+
+Bug Fixes:
+ Bug 386113 - Show custom alarm message in pop-up alerts
+ (Fabiano Fidêncio)
+ Bug 697575 - ESourceConfig: Avoid calling check_complete() too soon
+ (Matthew Barnes)
+ Bug 697878 - Image popup menu not always shown for images in HTML mails
+ (Matthew Barnes)
+ Bug 702664 - Settings migration issue from "headers" to "show-headers"
+ (Matthew Barnes)
+ Bug 703153 - Forgotten signal callbacks for freed objects (Milan Crha)
+ Bug 703244 - Work around GtkBox regression in GTK 3.9.1
+ (Matthew Barnes)
+ Bug 703389 - Proxy ignored for images (Milan Crha)
+ Bug 703490 - Stop invoking spamc, just use spamassassin
+ (Matthew Barnes)
+ Bug 703899 - Moving a meeting does not ask for confirmation
+ (Fabiano Fidêncio)
+ Bug 703991 - Crash when using -fstack-protector-strong (Matthew Barnes)
+ Bug 704259 - Fix "reply-style" key migration logic (Matthew Barnes)
+ Bug 704459 - GnomeCanvasItem: Implement all methods (Matthew Barnes)
+ Bug 704494 - EStockRequest calls into GTK+ from worker thread
+ (Matthew Barnes)
+ Bug 704558 - Crash when using -fstack-protector-strong (Matthew Barnes)
+ Bug 704682 - Runtime warning in MailFolderCache (Matthew Barnes)
+ Bug 704778 - Default Free/Busy dialog view to zoom-in (Milan Crha)
+
+Other Changes:
+ * User documentation improvements. (Andre Klapper)
+ * Remove nautilus-sendto integration. (Matthew Barnes)
+ * EMailParserMessage: Better handle message bodies as attachments.
+ (Matthew Barnes)
+ * EaMinicardView: Create a minicard object, if not present in a list.
+ (Milan Crha)
+ * EDayView's event resize abort doesn't always restore original event
+ size. (Milan Crha)
+ * EContactStore: Stop book views in a dedicated thread (Milan Crha)
+ * MailFolderCache: Thread-safety improvements and other cleanups.
+ (Matthew Barnes)
+ * EMailRequest: Handle empty message bodies more gracefully.
+ (Matthew Barnes)
+ * Do not mask CAMEL_ERROR_GENERIC in composer_send_completed()
+ (Milan Crha)
+ * Only use the alarm description if the client supports it.
+ (Fabiano Fidêncio)
+
+Translations:
+ Andika Triwidada (id)
+ Daniel Mustieles (es)
+ Dimitris Spingos (el)
+ Kjartan Maraas (nb)
+ Marek Černocký (cs)
+ Shankar Prasad (kn)
+
+
+Evolution 3.9.4 2013-07-08
+--------------------------
+
+Bug Fixes:
+ Bug 386113 - Show custom alarm message in pop-up alerts (Milan Crha)
+ Bug 641711 - Crash in remove_queued_alarm (Milan Crha)
+ Bug 689640 - Print Preview of composer text is empty (Milan Crha)
+ Bug 693216 - Email type is changed to other after merging (Milan Crha)
+ Bug 699576 - Mail reader frame is black (in the mail view) (Milan Crha)
+ Bug 702006 - Select All does not select collapsed threads
+ (Matthew Barnes)
+ Bug 702454 - EMailBrowser fails to show message (Matthew Barnes)
+ Bug 702664 - Settings migration issue from "headers" to "show-headers"
+ (Matthew Barnes)
+ Bug 702710 - MessageList: Delay state capture for regen.
+ (Matthew Barnes)
+ Bug 702796 - Work around GNode's O(N) tail insertions (Matthew Barnes)
+ Bug 703053 - Error on setting reminder 'after start of appointment'
+ (Fabiano Fidêncio)
+ Bug 703181 - Asked for password which is never used (David Woodhouse)
+ Bug 703194 - Custom alarm message is REMINDER (Fabiano Fidêncio)
+ Bug 703638 - Keep ItipView alive while connecting to calendar
+ (Matthew Barnes)
+ Bug 703732 - Unnecessary localedir override in configure.ac
+ (Evgeny Bobkin)
+
+Other Changes:
+ * User documentation updates. (Andre Klapper)
+ * More ETable/ETree refactoring. (Matthew Barnes)
+ * Heavy GalView refactoring, replace "Define Views..." menu item
+ with "Delete Current View", delete GalViewFactory. (Matthew Barnes)
+ * Make Ctrl+C/V/X work while editing text in calendar views.
+ (Milan Crha)
+ * EMFolderTreeModel: Listen for "folder-info-stale" signals and
+ regenerate the folder tree for that mail store. (Matthew Barnes)
+ * EUrlEntry: Replace the big, bulky "open" button with clickable
+ inline icon. (Matthew Barnes)
+ * Notify user about question dialogs (Milan Crha)
+ * Add ETreeViewFrame. (Matthew Barnes)
+ * Set network-available on a CamelSession when going online (Milan Crha)
+ * Fix typo: appointmenet -> appointment (Fabiano Fidêncio)
+ * Contacts view: Add 'Refresh' into books context menu (Milan Crha)
+
+Translations:
+ Marek Černocký (cs)
+ Benjamin Steinwender (de)
+ Daniel Mustieles (es)
+ Kjartan Maraas (nb)
+
+
+Evolution 3.9.3 2013-06-17
+--------------------------
+
+Bug Fixes:
+ Bug 250046 - Empty group address as recipient prevents message send
+ (Milan Crha)
+ Bug 555130 - Redesign task editor (Milan Crha)
+ Bug 684302 - Prompt to close message window on reply should be inline
+ (Matthew Barnes)
+ Bug 700277 - EClientCache allocates memory ad infinity (Matthew Barnes)
+ Bug 700812 - Search in Calendar view is broken (Milan Crha)
+ Bug 701669 - Bad assumption in prefer-plain module (Matthew Barnes)
+
+Other Changes:
+ * Rename some base libraries to libevolution-$FOO. (Matthew Barnes)
+ * Use F9 to toggle sidebar visibility. (Matthew Barnes)
+ * Update Quick Reference Card to show F12 shortcut. (Matthew Barnes)
+ * Remove Evolution icon from header section. (Matthew Barnes)
+ * Make EAlertDialog non-resizable. (Matthew Barnes)
+ * Ask for a Smart Card password with a token name too (Milan Crha)
+ * GnomeCalendar: Get rid of the async message dispatcher.
+ (Matthew Barnes)
+ * Make the "Headers" print dialog tab actually work. (Matthew Barnes)
+ * Reimplement the main toolbar's prefer-item feature. (Matthew Barnes)
+ * Fix various causes for crashes after closing a 2nd Evolution window.
+ (Matthew Barnes)
+ * Heavily refactor MessageList and ETreeModel. (Matthew Barnes)
+ * Remove lots of unused legacy APIs. (Matthew Barnes)
+
+Translations:
+ Jorge Pérez Pérez (an)
+ Dimitris Spingos (el)
+ Daniel Mustieles (es)
+ Fran Diéguez (gl)
+ Jiro Matsuzawa (ja)
+ Aurimas ÄŒernius (lt)
+ Sandeep Sheshrao Shedmake (mr)
+ Kjartan Maraas (nb)
+ ManojKumar Giri (or)
+ Matej UrbanÄiÄ (sl)
+ Shantha kumar (ta)
+
+
+Evolution 3.9.2 2013-05-27
+--------------------------
+
+Bug Fixes:
+ Bug 301323 - "Edit as new message" doesn't strip signature properly
+ (Milan Crha)
+ Bug 696531 - Force white background for HTML parts (Milan Crha)
+ Bug 697632 - [mail-to-task] Invalid unref of a CamelFolder
+ (Samarjit Adhikari)
+ Bug 699334 - Calendar: reply all doesn't quite work (Milan Crha)
+ Bug 699551 - Signature is not removed on reply (Milan Crha)
+ Bug 699555 - prompt-on-mark-all-read doesn't work in context menu
+ (Milan Crha)
+ Bug 699980 - Calendar delete does not remove events from view
+ (Milan Crha)
+ Bug 700028 - Drag-n-drop export of a file produces 0 sized PDF file
+ (Matthew Barnes)
+
+Other Changes:
+ * Make sure EAddressbookModel has a fresh EBookClient. (Matthew Barnes)
+ * Merge [mark-all-read] plugin into core code (Milan Crha)
+ * contact-photos: Obtain an EClient asynchronously. (Matthew Barnes)
+ * Right-align mail header names. (Matthew Barnes)
+ * Improve mail header layout in right-to-left locales. (Matthew Barnes)
+ * Remove "drag-and-drop-save-name-format" setting. (Matthew Barnes)
+ * Convert EMailPart to a GObject. (Matthew Barnes)
+ * Use an user-friendlier message when update comp-editor fails
+ (Fabiano Fidêncio)
+ * Make EAttachment a little more thread-safe. (Matthew Barnes)
+ * EMailSession: Add helper functions for sending messages.
+ (Matthew Barnes)
+
+Translations:
+ Nilamdyuti Goswami (as)
+ Marek Černocký (cs)
+ Daniel Mustieles (es)
+ Sweta Kothari (gu)
+ OKANO Takayoshi (ja)
+ Kjartan Maraas (nb)
+ ManojKumar Giri (or)
+ Piotr DrÄ…g (pl)
+ Yuri Myasoedov (ru)
+ Matej UrbanÄiÄ (sl)
+
+
+Evolution 3.9.1 2013-04-29
+--------------------------
+
+* The Express Mode feature developed for MeeGo has been removed.
+ The MeeGo project is long dead and the Express Mode feature has
+ been unmaintained quite for some time. It served its purpose,
+ but it's dead weight now.
+
+* Dependency change: Evolution no longer links to libgoa-1.0.
+ GNOME Online Accounts support is now contained entirely within
+ Evolution-Data-Server.
+
+* Evolution now queries gravatar.com in addition to address books
+ to find email sender images.
+
+Bug Fixes:
+ Bug 271262 - Allow Send/Receive of local stores in offline (Milan Crha)
+ Bug 626215 - Prefer mail saving in order by UI (Milan Crha)
+ Bug 662568 - Use-after-free in Templates plugin signal handlers
+ (Milan Crha)
+ Bug 677300 - Add 3 px padding above and below the searchbar
+ (Jean-François Fortin Tam)
+ Bug 681837 - Make enum type registration thread safe (Milan Crha)
+ Bug 684245 - Disable 3rd-party browser plugins (Tomas Popela)
+ Bug 687412 - Crash under mail_folder_cache_service_removed()
+ (Milan Crha)
+ Bug 696173 - Various memory leaks (Milan Crha)
+ Bug 696175 - bbdb: Blocks main thread when obtaining an EBookClient
+ (Matthew Barnes)
+ Bug 696185 - Disable WebKit's caching (Milan Crha)
+ Bug 696257 - Handle default values for "primary" selection settings
+ (Matthew Barnes)
+ Bug 696663 - Save without close should update comp-editor
+ (Fabiano Fidêncio)
+ Bug 696715 - ESelectNamesEditable needs an EClientCache (Matthew Barnes)
+ Bug 697141 - User docs: Remove express mode (Andre Klapper)
+ Bug 697228 - User Docs: Remove CSS page now that we have WebKit
+ rendering (Andre Klapper)
+ Bug 697268 - Incorrect mnemonic widget in 'Add Reminder' dialog
+ (Matthew Barnes)
+ Bug 697710 - Going offline doesn't disconnect remote stores
+ (Milan Crha)
+ Bug 698042 - Crash when sending e-mail with attachment (Matthew Barnes)
+ Bug 698487 - Contact Editor's Image's file chooser must show only
+ images files (Fabiano Fidêncio)
+ Bug 698488 - Attachment file chooser should preview attachments'
+ content when possible (Fabiano Fidêncio)
+ Bug 699083 - X-GNOME-Bugzilla-OtherBinares missing trailing semicolon
+ (Matthew Barnes)
+
+Other Changes:
+ * User documentation improvements. (Andre Klapper)
+ * Convert all settings usage to GSettings and remove EShellSettings.
+ (Matthew Barnes)
+ * Fix mbox-to-Maildir conversion... again. (Matthew Barnes)
+ * Fix for typing in ITIP comments when some keys triggered actions.
+ (Tomas Popela)
+ * EMailAccountManager: Add Online Account blurbs. (Matthew Barnes)
+ * Show parts with Content-ID of multipart/mixed as attachments
+ (Milan Crha)
+ * e_mail_folder_uri_parse: Handle local mbox folder URIs.
+ (Matthew Barnes)
+ * Update copyright year on About dialog. (Matthew Barnes)
+ * Remove Evolution's implementation of highlighting and use WebKit
+ highlighting. (Tomas Popela)
+ * web-inspector: Change the shortcut key to match Chrome.
+ (Matthew Barnes)
+ * ECalModel: Make view handling thread-safe. (Matthew Barnes)
+ * Restore "Automatic Contacts" plugin preferences page.
+ (Matthew Barnes)
+ * Remove backward-compatibility cruft for goa-1.0 < 3.8.
+ (Matthew Barnes)
+ * alarm-queue: Remove the "mail notifications not supported" dialog
+ (Matthew Barnes)
+ * EShellBackend: Log outstanding activities during shutdown.
+ (Matthew Barnes)
+ * Workaround broken Free/Busy fetching (Bug #692361) (Milan Crha)
+ * Remove "Search for sender photograph only in local address books".
+ (Matthew Barnes)
+
+Translations:
+ Nilamdyuti Goswami (as)
+ Gil Forcada (ca)
+ Carles Ferrando (ca@valencia)
+ Jiri Eischmann (cs)
+ Flemming Christensen (da)
+ Dimitris Spingos (el)
+ Daniel Mustieles (es)
+ Inaki Larranaga Murgoitio (eu)
+ Danial Behzadi (fa)
+ Alexandre Franke (fr)
+ Fran Diéguez (gl)
+ Gabor Kelemen (hu)
+ OKANO Takayoshi (ja)
+ Shankar Prasad (kn)
+ Changwoo Ryu (ko)
+ Ani Peter (ml)
+ Anish A (ml)
+ ManojKumar Giri (or)
+ A S Alam (pa)
+ Enrico Nicoletto (pt_BR)
+ Yuri Myasoedov (ru)
+ Matej UrbanÄiÄ (sl)
+ Shantha kumar (ta)
+
+
+Evolution 3.7.92 2013-03-18
+---------------------------
+
+Bug Fixes:
+ Bug 415371 - Create Incoming filter for messages with Received header
+ (Milan Crha)
+ Bug 645476 - Avoid scroll to cursor on folder change in message list
+ (Milan Crha)
+ Bug 676696 - Automatic EXIF image rotation doesn't work
+ (Matthew Barnes)
+ Bug 690092 - Crash under format_full_headers() (Milan Crha)
+ Bug 690930 - Launching calendar from clock-applet applies timezone
+ twice (Milan Crha)
+ Bug 693254 - Mail reply uses wrong "From:" account (Milan Crha)
+ Bug 695193 - Window size resets to default at exit with gtk 3.7.10+
+ (Fabien Tassin)
+ Bug 695477 - Crash in EContactListEditor (Matthew Barnes)
+ Bug 695570 - Don't use gtk_container_add() to pack a GtkBox
+ (Matthew Barnes)
+ Bug 695693 - Handle <authentication> tags during auto-configuration
+ (Matthew Barnes)
+
+Other Changes:
+ * [itip-formatter] Reference a view when searching for a calendar
+ (Tomas Popela)
+ * org.gnome.evolution.calendar.gschema.xml.in: Define a 'Duration'
+ enum. (Matthew Barnes)
+ * [backup-restore] Dir separator removal breaks DConf settings restore
+ (Milan Crha)
+ * Add utility functions for manipulating weekdays. (Matthew Barnes)
+ * evolution-addressbook-export: Remove main loop event flushing.
+ (Matthew Barnes)
+ * e_mail_config_notebook_commit: Skip non-writable sources.
+ (Matthew Barnes)
+ * Do not leak each sent message (Milan Crha)
+
+Translations:
+ Nilamdyuti Goswami (as)
+ Ihar Hrachyshka (be)
+ Jiri Eischmann (cs)
+ Christian Kirbach (de)
+ Bruce Cowan (en_GB)
+ Andika Triwidada (id)
+ Rūdolfs Mazurs (lv)
+ Duarte Loreto (pt)
+ Enrico Nicoletto (pt_BR)
+ Rafael Ferreira (pt_BR)
+ Martin Srebotnjak (sl)
+ Matej UrbanÄiÄ (sl)
+ Dr.T.Vasudevan (ta)
+ Gheyret Kenji (ug)
+
+
+Evolution 3.7.91 2013-03-04
+---------------------------
+
+Bug Fixes:
+ Bug 674236 - Extra ref in e_action_combo_box_set_action() (Milan Crha)
+ Bug 693250 - Signature HTML problem using <...> (Milan Crha)
+ Bug 693420 - Crash when adding contact list as attendee (Milan Crha)
+ Bug 693625 - [itip-formatter] Save button insensitive for multiple
+ events (Milan Crha)
+ Bug 694159 - Malformed content-type header causes infinite recursion
+ (Matthew Barnes)
+ Bug 694170 - Accepted invitation not removed from Inbox when it should
+ (Milan Crha)
+ Bug 694363 - CALDAV navigation through Calendars or Tasklist is wrong
+ (Milan Crha)
+ Bug 694460 - 'Email' section toggle button in contact editor has
+ incorrect name (Vadim Rutkovsky)
+
+Other Changes:
+ * Keep EClient instances in a central cache for more consistent
+ event-handling. (Matthew Barnes)
+ * Add status icons in sidebar for calendar, contact, task and memo
+ backends. Similiar icons for mail accounts are not yet finished.
+ (Matthew Barnes)
+ * Rewrite the contact photo in email feature to avoid deadlocks.
+ (Matthew Barnes)
+ * EAttachment: Use Subject as fallback filename for message attachments
+ (Milan Crha)
+ * Show local images in Signature preview (Milan Crha)
+ * Speed-up auto-completion results showing (Milan Crha)
+ * Autocompletion - do not use quick timeout when user types text
+ (Milan Crha)
+ * Add mnemonic widgets for Status and Priority comboboxes
+ (Vadim Rutkovsky)
+ * Correct label for "Country:" textbox in Work section on "Mailing
+ Address" tab of contact editor (Vadim Rutkovsky)
+ * evolution-addressbook-export: Remove --async option. (Matthew Barnes)
+ * Remove obsolete "mime-types" mail setting. (Matthew Barnes)
+ * Added mnemonic widget for 'Time zone' field in event editor
+ (Vadim Rutkovsky)
+
+Translations:
+ Ihar Hrachyshka (be)
+ Dimitris Spingos (el)
+ Daniel Mustieles (es)
+ Fran Diéguez (gl)
+ Sweta Kothari (gu)
+ Aurimas ÄŒernius (lt)
+ Kjartan Maraas (nb)
+ Piotr DrÄ…g (pl)
+ МироÑлав Ðиколић (sr)
+ Gheyret Kenji (ug)
+ Nguyá»…n Thái Ngá»c Duy (vi)
+ Chao-Hsiung Liao (zh_HK)
+
+
+Evolution 3.7.90 2013-02-18
+---------------------------
+
+Bug Fixes:
+ Bug 683867 - Schedule actions with higher idle priority (Michel Dänzer)
+ Bug 693132 - Editing a signature does not refresh preview after save
+ (Milan Crha)
+
+Other Changes:
+ * Add a centralized cache for EClient instances and adapt most
+ of the application to use it. (Matthew Barnes)
+ * [web-inspector] Add a secret debugging shortcut. (Matthew Barnes)
+ * Add mnemonic widgets for title and suffix comboboxes.
+ (Vadim Rutkovsky)
+ * Add mnemonic widget for Start date field in memo editor.
+ (Vadim Rutkovsky)
+
+Translations:
+ Fran Diéguez (gl)
+ Piotr DrÄ…g (pl)
+ Gheyret Kenji (ug)
+ Nguyá»…n Thái Ngá»c Duy (vi)
+
+
+Evolution 3.7.5 2013-02-04
+--------------------------
+
+Bug Fixes:
+ Bug 639698 - Crash in mail_shell_view_execute_search() (Milan Crha)
+ Bug 680537 - Reply to individual message in digest generates empty
+ body (Milan Crha)
+ Bug 685757 - [userdocs] Update cache location in user docs
+ (Andre Klapper)
+ Bug 688294 - [userdocs] Update how online/offline mode works nowadays
+ (Andre Klapper)
+ Bug 689476 - Slow composer open (ENameSelector object leaks)
+ (Milan Crha)
+ Bug 690696 - [userdocs] Remove references to the old IMAP backend
+ (Andre Klapper)
+ Bug 690697 - [userdocs] Document using real (non-virtual) Junk and
+ Trash folders with IMAP+ (Andre Klapper)
+ Bug 691194 - Import .ics preview shows UTC time instead of local time
+ (Milan Crha)
+ Bug 691640 - Distinguish the word "Title" for translation (Milan Crha)
+ Bug 691732 - multipart/related hides attachments (Milan Crha)
+ Bug 692003 - Print of text/html with no html/body end tag cuts content
+ (Milan Crha)
+ Bug 692005 - Changing character encoding doesn't work (Milan Crha)
+ Bug 692009 - text/css always formatted as attachment (Milan Crha)
+ Bug 692143 - Auto-configured MSN account should use POP, not IMAP
+ (Matthew Barnes)
+ Bug 692213 - [userdocs] Remove evolution-exchange recommendation
+ (Andre Klapper)
+ Bug 692775 - Double-quoting message with HTML and text (Milan Crha)
+ Bug 692777 - Crash on folder rename (Milan Crha)
+ Bug 692781 - [pine-importer] Abort on book failure during contact
+ import (Milan Crha)
+ Bug 692783 - [mail-to-task] Crash on edit prompt cancel (Milan Crha)
+ Bug 692818 - [userdocs] Remove documentation on Novell GroupWise
+ (Andre Klapper)
+
+Other Changes:
+ * Bump libsoup dependency to 2.40.3 (Milan Crha)
+ * Add a "settings" module. (Matthew Barnes)
+ * Contact's print doesn't decode QP encoded email addresses
+ (Milan Crha)
+ * Use e_book_client_connect(). (Matthew Barnes)
+ * Use e_cal_client_connect(). (Matthew Barnes)
+ * Incorporate ESourceUOA. (Matthew Barnes)
+ * EMailAccountStore: Use an appropriate icon for online accounts.
+ (Matthew Barnes)
+ * Add a priority field for mail formatter and parser extensions.
+ (Matthew Barnes)
+
+Translations:
+ Nilamdyuti Goswami (as)
+ Daniel Mustieles (es)
+ Aurimas ÄŒernius (lt)
+ Kjartan Maraas (nb)
+ Patrick Holthuizen (nl)
+ Marián Čavojský (sk)
+ Matej UrbanÄiÄ (sl)
+ МироÑлав Ðиколић (sr)
+ Akom Chotiphantawanon (th)
+ Theppitak Karoonboonyanan (th)
+ Gheyret Kenji (ug)
+ Chao-Hsiung Liao (zh_HK)
+
+
+Evolution 3.7.4 2013-01-14
+--------------------------
+
+Bug Fixes:
+ Bug 588216 - 'Unsubscribe' disabled for newsgroups (Matthew Barnes)
+ Bug 690177 - Use trust-prompt for certificate verification in WebDAV
+ backends (Milan Crha)
+ Bug 691047 - Support notification filtering (Matthew Barnes)
+ Bug 691133 - Evolution creates 'highlight' zombies (Matthew Barnes)
+ Bug 691134 - New contact lists always saved to a default book
+ (Milan Crha)
+ Bug 691134 - Only autocompleted name is added to a contact list
+ (Milan Crha)
+ Bug 691470 - ENameSelectorEntry: Copy to clipboard issue with
+ multi-byte characters (Milan Crha)
+
+Other Changes:
+ * evolution-shell.pc.in: Remove libedataserverui-3.0 (Matthew Barnes)
+ * Reset the maintainer list in the About dialog. (Matthew Barnes)
+ * Remove the "imap-features" module. (Matthew Barnes)
+ * Move CamelSaslXOAuth2 to libemail-engine. (Matthew Barnes)
+ * Remove --with-kde-applnk-path configure option. (Matthew Barnes)
+ * Be more strict in inline PGP mime filter/part parser (Milan Crha)
+ * Do not hide 'attachment' images with Content-ID (Milan Crha)
+
+Translations:
+ Nilamdyuti Goswami (as)
+ Ihar Hrachyshka (be)
+ Krasimir Chonov (bg)
+ Dimitris Spingos (el)
+ Daniel Mustieles (es)
+ Alexandre Franke (fr)
+ Aurimas ÄŒernius (lt)
+ Kjartan Maraas (nb)
+ Rafael Ferreira (pt_BR)
+ Yuri Myasoedov (ru)
+ Martin Srebotnjak (sl)
+
+
+Evolution 3.7.3 2012-12-16
+--------------------------
+
+Bug Fixes:
+ Bug 202576 - A way to refresh IMAP folder list (Milan Crha)
+ Bug 315317 - Add option to expunge messages on folder leave
+ (Milan Crha)
+ Bug 449081 - Drop read-only calendar error message (Milan Crha)
+ Bug 502516 - Avoid "source" string in user visible dialogs
+ (Milan Crha)
+ Bug 525932 - Unhelpful "Error while Filtering Selected Messages."
+ (Milan Crha)
+ Bug 529743 - Add "Any header" filter and search folder condition
+ (Milan Crha)
+ Bug 579315 - Identify filter names in filtering errors (Milan Crha)
+ Bug 671200 - Inherit source message crypto options when reply on
+ selection (Milan Crha)
+ Bug 671628 - Size of backup window is big (Milan Crha)
+ Bug 672200 - Skip Reply-To-List check for list administrative messages
+ (Milan Crha)
+ Bug 674678 - Event notification uses wrong app name (Milan Crha)
+ Bug 677378 - Alert about self-signed certificates when checking auth
+ types (Milan Crha)
+ Bug 678606 - Crash under mail_backend_folder_deleted_cb() (Milan Crha)
+ Bug 680201 - Backup restore doesn't migrate accounts from GConf
+ (Milan Crha)
+ Bug 680244 - CalDAV URL should be configured in once, not separated
+ (Milan Crha)
+ Bug 685808 - Search bar entry background does not change on search
+ (Milan Crha)
+ Bug 686212 - Cannot print html mails with defined <style> (Milan Crha)
+ Bug 687360 - Crash on quit in gtk_style_context_get_valist()
+ (Milan Crha)
+ Bug 687503 - Improve error message »Failed to refresh folders«
+ (Milan Crha)
+ Bug 687670 - Signing with both pgp and S/MIME shows only one signature
+ (Milan Crha)
+ Bug 687974 - No displaying of extended free/busy (XFB) information
+ (Christian Hilberg)
+ Bug 688819 - It's possible to make Evolution stop sending emails
+ (Milan Crha)
+ Bug 689639 - File -> Print Preview in composer brings up Print dialog
+ (Matthew Barnes)
+ Bug 689966 - MDN bar shown in Sent folder (Milan Crha)
+
+Other Changes:
+ * Identify calendar/memo/task sources in error messages (Milan Crha)
+ * Use version-based GLib/GDK/GTK+ warnings. (Matthew Barnes)
+ * Avoid GTK+ APIs deprecated in 3.0. (Matthew Barnes)
+ * Coverity scan cleanups. (Milan Crha)
+ * Do not empty trash/delete junk in disabled accounts on exit
+ (Milan Crha)
+ * Do not generate a ChangeLog file from 'git log' (Milan Crha)
+ * Simplify class design of mail formatter. (Matthew Barnes)
+ * backup-restore: Remove references to ~/.camel_certs.
+ (Matthew Barnes)
+ * Use the same certificate-viewer as the trust-prompt from eds
+ (Milan Crha)
+ * Consolidate base utility libraries into libeutil and generate
+ API documantation. (Matthew Barnes)
+
+Translations:
+ Nilamdyuti Goswami (as)
+ Mario Blättermann (de)
+ Christian Kirbach (de)
+ Shankar Prasad (kn)
+ Dr.T.Vasudevan (ta)
+
+
+Evolution 3.7.2 2012-11-17
+--------------------------
+
+Bug Fixes:
+ Bug 267787 - Preferences too large for small screens (Milan Crha)
+ Bug 268618 - Add: Save replies in the folder of the message being
+ replied to (Milan Crha)
+ Bug 317153 - Contact editor too large for small screens (Milan Crha)
+ Bug 422273 - Wrap searchbar widgets for smaller minimum width request
+ (Milan Crha)
+ Bug 627244 - Bold days in "Select Date" dialog not updated when
+ changing month (Fabiano Fidêncio)
+ Bug 656143 - Stop using deprecated Gtk[HV]Box(Class)
+ (Dominique Leuenberger)
+ Bug 663844 - [CalDAV] Fails to parse iCloud XML response (Milan Crha)
+ Bug 680497 - POP3 re-adds messages to local Inbox (Milan Crha)
+ Bug 683877 - No more contextual menus for links (Milan Crha)
+ Bug 686325 - Preview message window keyboard use severely limited
+ (Milan Crha)
+ Bug 686785 - Port of WebDAV source doesn't match SSL check (Milan Crha)
+ Bug 686813 - ECaldavChooser: Deadlock on cancellation (Matthew Barnes)
+ Bug 687010 - Add keywords to the desktop file (Matthias Clasen)
+ Bug 687060 - Identity page shows read-only GOA properties as editable
+ (Matthew Barnes)
+ Bug 687137 - Google account user name overwritten with email address
+ (Matthew Barnes)
+ Bug 687155 - Text/plain signatures wrap in an editor (Milan Crha)
+ Bug 687400 - Composer settings not applied (Matthew Barnes)
+ Bug 687442 - Magic spacebar avoids iTip formatter comment write
+ (Milan Crha)
+ Bug 688084 - Cannot configure connection to webdav address book
+ (Alban Browaeys)
+
+Other Changes:
+ * Fixed squished labels on Identity page of Account Assistant.
+ (Matthew Barnes)
+ * Require WebKitGtk 1.10.0 for webkit_web_frame_get_dom_document()
+ (Milan Crha)
+ * Restrict geocode-glib dependency to 0.99.0. (Matthew Barnes)
+ * Missing search buttons in Calendar view (Milan Crha)
+ * Make auto-configuration cancellable. (Matthew Barnes)
+ * EMailConfigAssistant: Make revising auto-configuration easier.
+ (Matthew Barnes)
+ * Bump minimum GLib requirement to 2.34. (Matthew Barnes)
+
+Translations:
+ Marek Černocký (cs)
+ Tom Tryfonidis (el)
+ Chris Leonard (en_GB)
+ Fran Diéguez (gl)
+ Andika Triwidada (id)
+ Kjartan Maraas (nb)
+ Piotr DrÄ…g (pl)
+ Yuri Myasoedov (ru)
+
+
+Evolution 3.7.1 2012-10-15
+--------------------------
+
+Dependency Changes:
+ * Both geocode-glib and geoclue now required for contact maps.
+
+Bug Fixes:
+ Bug 201807 - Cannot specify sendmail parameters (Milan Crha)
+ Bug 268618 - Add: Save replies in the folder of the message being
+ replied to (Milan Crha)
+ Bug 310978 - USENET always requires authentication (Milan Crha)
+ Bug 344579 - Vertical view: Drafts column header states "Sent Messages"
+ (Milan Crha)
+ Bug 549819 - Cannot specify a custom sendmail program (Milan Crha)
+ Bug 588959 - Expanding appointment crashes Evolution (Vibha Yadav)
+ Bug 663844 - [CalDAV] calendar-home-set/href may contain full URI
+ (Milan Crha)
+ Bug 676141 - Use GtkApplication for session management (Matthew Barnes)
+ Bug 678408 - WebKit renders frames with plain/text parts too small
+ (Dan Vrátil)
+ Bug 678750 - Use geocode-glib instead of geoclue (Matthew Barnes)
+ Bug 681314 - Add address dialog should follow composer's view settings
+ (Milan Crha)
+ Bug 683849 - Add account name to »Checking for new mail« (Milan Crha)
+ Bug 684249 - Signatures get compounded, not replaced (Matthew Barnes)
+ Bug 684447 - Check for highlight during configure. (Dan Vrátil)
+ Bug 684691 - EMailConfigFormatHTML: Signal handler never disconnected
+ (Matthew Barnes)
+ Bug 685262 - Attachments disappear when dragged in message preview
+ (Milan Crha)
+ Bug 685675 - Fix packing of spell check language options
+ (Matthew Barnes)
+ Bug 685786 - EWebView: Signal handlers never disconnected
+ (Matthew Barnes)
+ Bug 686278 - Prefer-plain can break parts list (Milan Crha)
+
+Other Changes:
+ * User documentation improvements. (Andre Klapper)
+ * Check for Bogofilter during configure. (Matthew Barnes)
+ * Check for SpamAssassin during configure. (Matthew Barnes)
+ * Fix contact maps. (Matthew Barnes)
+ * Don't rely on user's $PATH, use HIGHLIGHT_COMMAND defined by
+ configure (Dan Vrátil)
+ * CamelSaslXOAuth: Use GHmac to sign the client request.
+ (Matthew Barnes)
+ * Prototype CamelSaslXOAuth2. (Matthew Barnes)
+ * evolution.convert: Remove leftover "force-message-limit" entry.
+ (Matthew Barnes)
+ * Do not crash in create_default_shell() (Milan Crha)
+ * Remove "Disable Account" menu item for GOA-based accounts.
+ (Matthew Barnes)
+
+Translations:
+ Nilamdyuti Goswami (as)
+ Alexander Shopov (bg)
+ Krasimir Chonov (bg)
+ Gil Forcada (ca)
+ Carles Ferrando (ca@valencia)
+ Jiri Eischmann (cs)
+ Flemming Christensen (da)
+ Tom Tryfonidis (el)
+ Jiri Grönroos (fi)
+ Alexandre Franke (fr)
+ Gabor Kelemen (hu)
+ Shankar Prasad (kn)
+ Žygimantas BeruÄka (lt)
+ Rūdolfs Mazurs (lv)
+ Ani Peter (ml)
+ Rafael Ferreira (pt_BR)
+ Yuri Myasoedov (ru)
+ Matej UrbanÄiÄ (sl)
+ Dr.T.Vasudevan (ta)
+ Krishnababu Krothapalli (te)
+ Sasi Bhushan Boddepalli (te)
+ Akom Chotiphantawanon (th)
+ Theppitak Karoonboonyanan (th)
+ Daniel Korostil (uk)
+ Nguyá»…n Thái Ngá»c Duy (vi)
+
+
+Evolution 3.6.0 2012-09-24
+--------------------------
+
+Bug Fixes:
+ Bug 678408 - WebKit renders frames with plain/text parts too small
+ (Dan Vrátil)
+
+Translations:
+ Nilamdyuti Goswami (as)
+ Krasimir Chonov (bg)
+ Tom Tryfonidis (el)
+ Daniel Mustieles (es)
+ Sweta Kothari (gu)
+ Gabor Kelemen (hu)
+ Shankar Prasad (kn)
+ Rūdolfs Mazurs (lv)
+ ManojKumar Giri (or)
+ A S Alam (pa)
+ Rafael Ferreira (pt_BR)
+ Yuri Myasoedov (ru)
+ Matej UrbanÄiÄ (sl)
+ Krishnababu Krothapalli (te)
+ Daniel Korostil (uk)
+
+
+Evolution 3.5.92 2012-09-17
+---------------------------
+
+Bug Fixes:
+ Bug 678291 - Identifies application/mbox as text/plain attachment
+ (Milan Crha)
+ Bug 678806 - Flush Outbox doesn't remove sent messages (Milan Crha)
+ Bug 678835 - Disconnect signal handlers from WebKit plugin widgets on
+ dispose (Milan Crha)
+ Bug 679382 - Saving attachments takes too long, maxes CPU usage
+ (Milan Crha)
+ Bug 679780 - Offline mode doesn't work in mailer (Milan Crha)
+ Bug 680537 - Reply to individual message in digest generates empty body
+ (Milan Crha)
+ Bug 680611 - Hibernation shifts alarm notification time (Milan Crha)
+ Bug 681279 - Reply on selection doesn't work (Milan Crha)
+ Bug 682295 - Fix deadlock in EHttpRequest (Dan Vrátil)
+ Bug 682425 - Can do network operations on disabled accounts
+ (Milan Crha)
+ Bug 682820 - Settings not converted on backup restore (Milan Crha)
+ Bug 682873 - Prefer-plain shows text plain in meeting invite
+ (Milan Crha)
+ Bug 683130 - Folder hangs when reading mail with an attachment
+ (Dan Vrátil)
+ Bug 683349 - Crash when sending a mail from the Outbox folder
+ (Milan Crha)
+ Bug 683407 - Preserve week views in calendar when clicking one day
+ (Milan Crha)
+ Bug 683548 - Initialize webkit's web view before other threads are
+ run (Milan Crha)
+ Bug 683663 - Attachment bar missing when showing 'All Message Headers'
+ (Lucian Langa)
+ Bug 683665 - Crash on displaying message with broken Content-Type
+ attachment (Lucian Langa)
+ Bug 683676 - Message source does not work when 'All Message Headers'
+ enabled (Milan Crha)
+ Bug 683736 - Calendar work week view drops Monday's entries
+ (Milan Crha)
+ Bug 683758 - Crash on display meeting invite (Lucian Langa)
+ Bug 683866 - Leaks of EMailFormatter object (Milan Crha)
+ Bug 683949 - Cannot create new LDAP Addressbook (Milan Crha)
+ Bug 684021 - EBookConfigWebdav: Invalid callback on property binding
+ (Matthew Barnes)
+
+Other Changes:
+ * Honor CAMEL_PROVIDER_DISABLE_SENT_FOLDER in account preferences
+ (Milan Crha)
+ * Blacklist WebKitGTK+ 1.9.90. (Matthew Barnes)
+ * Make sure selection in ECalendar is visible (Milan Crha)
+ * Make sure the selected days in the calendar matches shown days
+ (Milan Crha)
+ * Autocompletion in meeting editor doesn't work (Milan Crha)
+ * Could not set custom port for LDAP addressbook (Milan Crha)
+ * Fails to import calendar events due to used incorrect enum values
+ (Milan Crha)
+
+Translations:
+ Ihar Hrachyshka (be)
+ Mario Blättermann (de)
+ Christian Kirbach (de)
+ Dimitris Spingos (el)
+ Tom Tryfonidis (el)
+ Bruce Cowan (en_GB)
+ Daniel Mustieles (es)
+ Alexandre Franke (fr)
+ chandankumar (hi)
+ Gabor Kelemen (hu)
+ Dirgita (id)
+ Shankar Prasad (kn)
+ Changwoo Ryu (ko)
+ Sandeep Sheshrao Shedmake (mr)
+ Piotr DrÄ…g (pl)
+ Duarte Loreto (pt)
+ Yuri Myasoedov (ru)
+ Matej UrbanÄiÄ (sl)
+ МироÑлав Ðиколић (sr)
+ Daniel Nylander (sv)
+ Nguyá»…n Thái Ngá»c Duy (vi)
+ Chao-Hsiung Liao (zh_HK)
+
+
+Evolution 3.5.91 2012-09-03
+---------------------------
+
+Bug Fixes:
+ Bug 586186 - Calendar print uses too small font (Conrad Steenberg)
+ Bug 678476 - Critical warnings on calendar factory console (Milan Crha)
+ Bug 679862 - Do not use ENameSelectorEntry in .ui files (Milan Crha)
+ Bug 680786 - [text-highlight] Correctly display binary patches
+ (Dan Vrátil)
+ Bug 681431 - Expanded attachment bar hides headers (Dan Vrátil)
+ Bug 681669 - 'Select today' in work week view goes to wrong week
+ (Milan Crha)
+ Bug 681877 - Postpone window changes saving for a second (Milan Crha)
+ Bug 682494 - Add some defensive checks in gal-a11y-e-text.c (Mike Gorse)
+ Bug 682519 - vcard-inline: Typo in translatable string (Matthew Barnes)
+ Bug 682678 - Entering the end date for a recurring event is very
+ difficult (Milan Crha)
+ Bug 682811 - Can edit properties of local/vfolder stores
+ (Matthew Barnes)
+ Bug 682955 - Support GStreamer 1.0 (Dominique Leuenberger)
+
+Other Changes:
+ * cal-config-webcal: Accept URIs with webcal:// scheme.
+ (Matthew Barnes)
+ * Adjust for webkit 1.9.90 API change. (Dominique Leuenberger)
+ * Fix visibility of parts in prefer-plain (Dan Vrátil)
+ * Add support for application/ics to ITIP formatter (Dan Vrátil)
+ * Make sure evolution-alarm-notify is running on Evolution's start
+ (Milan Crha)
+
+Translations:
+ Daniel Mustieles (es)
+ Fran Diéguez (gl)
+ Andika Triwidada (id)
+ Aurimas ÄŒernius (lt)
+ Kjartan Maraas (nb)
+ Piotr DrÄ…g (pl)
+ Yuri Myasoedov (ru)
+ Nguyá»…n Thái Ngá»c Duy (vi)
+ Chao-Hsiung Liao (zh_HK)
+
+
+Evolution 3.5.90 2012-08-20
+---------------------------
+
+Bug Fixes:
+ Bug 246530 - Rules editor lacks "Label is (not) 'None'" (Milan Crha)
+ Bug 555325 - Delete key should not delete a whole address book
+ (Matthew Barnes)
+ Bug 559815 - Empty Reminders editor when opened second time
+ (Milan Crha)
+ Bug 676785 - Enables wrong calendar after saving appointment
+ (Milan Crha)
+ Bug 677695 - Crash on quit under emu_free_mail_cache() (Milan Crha)
+ Bug 678408 - Mail view is very small for some mails (Milan Crha)
+ Bug 680702 - Freeze/crash when loading remote images (Dan Vrátil)
+ Bug 680724 - Attachment bar regression (Dan Vrátil)
+ Bug 680786 - [text-highlight] Prefer Content-Type header over file
+ name extension (Dan Vrátil)
+ Bug 680947 - Multiselect doesn't clear message preview panel
+ (Dan Vrátil)
+ Bug 681017 - Bogus SMTP port in the account manager UI (Milan Crha)
+ Bug 681279 - Reply on selection doesn't work (Dan Vrátil)
+ Bug 681318 - Filter by Source account doesn't show accounts (Milan Crha)
+ Bug 681321 - Support both old and new-buf libxml2 APIs (Matthew Barnes)
+ Bug 681400 - Fix build against WebKitGtk+ 1.9.6 (Dan Vrátil)
+ Bug 681432 - Runtime warnings from e_mail_display_reload() (Dan Vrátil)
+ Bug 681641 - Port to new documentation infrastructure (Javier Jardón)
+ Bug 681783 - Critical warning and freeze with libsoup-2.39 and
+ webkitgtk-1.9.2 (Dan Vrátil)
+ Bug 681882 - Account signature not selected in new composer window
+ (Matthew Barnes)
+ Bug 682019 - Always display text/plain when there's nothing else in
+ multipart/alternative (Dan Vrátil)
+ Bug 682102 - Upstream Debian's 04_gettext_intltool.patch
+ (Matthew Barnes)
+
+Other Changes:
+ * User documentation improvements. (Andre Klapper)
+ * Return of the "mark messages as read" preference. (Matthew Barnes)
+ * Remove all references to JavaScriptCore and use of JavaScript
+ (Dan Vrátil)
+ * EDayView: Hide tooltip on context menu popup (Milan Crha)
+ * backup-restore: Add version info to evolution.dirs file.
+ (Matthew Barnes)
+ * Run mbox-to-Maildir conversion before loading modules.
+ (Matthew Barnes)
+ * Remove the settings capplet. (Matthew Barnes)
+ * express: Remove clutter-based email tabs. (Matthew Barnes)
+ * Add e_mail_session_append_to_local_folder(). (Matthew Barnes)
+ * Add event/memo/task "Save As" item to File menu. (Matthew Barnes)
+
+Translations:
+ Andre Klapper (cs)
+ Dimitris Spingos (el)
+ Daniel Mustieles (es)
+ Fran Diéguez (gl)
+ Sweta Kothari (gu)
+ Sandeep Sheshrao Shedmake (mr)
+ A S Alam (pa)
+ МироÑлав Ðиколић (sr)
+ Chao-Hsiung Liao (zh_HK)
+
+
+Evolution 3.5.5 2012-08-06
+--------------------------
+
+Bug Fixes:
+ Bug 677635 - Vanished message list with filled preview panel
+ (Dan Vrátil)
+ Bug 678635 - File->Send/Receive lists too many sources (Milan Crha)
+ Bug 679049 - [itip-formatter] Cannot reply to meeting invitation
+ (Dan Vrátil)
+ Bug 679404 - Read colors for message preview from Gtk theme
+ (Dan Vrátil)
+ Bug 679726 - Move button for expanding headers behind header label
+ (Dan Vrátil)
+ Bug 679843 - Double free when printing (Dan Vrátil)
+ Bug 680123 - Freeze on message/disposition-notification email parsing
+ (Dan Vrátil)
+ Bug 680164 - Print Preview action should open preview immediatelly
+ (Dan Vrátil)
+ Bug 680331 - Crash when replying to a message (Dan Vrátil)
+ Bug 680535 - Reply to message with text attachments formats them
+ inline (Dan Vrátil)
+ Bug 680577 - [text-highlight] - Failed to load part (Dan Vrátil)
+ Bug 680634 - Missing image attachment (Dan Vrátil)
+ Bug 680635 - Inline GPG shown as source (Dan Vrátil)
+ Bug 680643 - First message Print preview without CSS (Dan Vrátil)
+ Bug 680666 - Contacts/Tasks/Memos preview pane does not follow theme
+ colors (Dan Vrátil)
+ Bug 680682 - Segfault after label attempted deletion (Milan Crha)
+ Bug 681075 - Add tooltips to signature editor toolbar (Michael Wood)
+
+Other Changes:
+ * Various mail formatter and highlighter improvements (Dan Vrátil)
+ * Improvements to user documentation. (Andre Klapper)
+ * Disable CompEditor when saving changes (Milan Crha)
+ * Use template files to generate GEnumClass types. (Matthew Barnes)
+ * mail-send-recv: Improve presentation. (Matthew Barnes)
+ * Fix few more memory leaks (Milan Crha)
+ * Support creating and deleting remote resources. (Matthew Barnes)
+ * Remove all GDK threads usage. (Matthew Barnes)
+
+Translations:
+ Ihar Hrachyshka (be)
+ Dimitris Spingos (el)
+ Tom Tryfonidis (el)
+ Daniel Mustieles (es)
+ Fran Diéguez (gl)
+ Sweta Kothari (gu)
+ Andika Triwidada (id)
+ Aurimas ÄŒernius (lt)
+ Kjartan Maraas (nb)
+ МироÑлав Ðиколић (sr)
+ tuhaihe (zh_CN)
+ Chao-Hsiung Liao (zh_HK)
+
+
+Evolution 3.5.4 2012-07-16
+--------------------------
+
+Bug Fixes:
+ Bug 223309 - Add "Include Subfolders" to "Search Folder Sources"
+ (Milan Crha)
+ Bug 246231 - Add Filter Rule dialog - UI suggestions (Milan Crha)
+ Bug 257283 - Can't select multiple folders at once in vFolder sources
+ (Milan Crha)
+ Bug 332115 - Remove Camel module names from Send/Receive window
+ (Matthew Barnes)
+ Bug 349875 - Dragging an email from a vFolder should link to source
+ folder (Milan Crha)
+ Bug 515004 - Allow toggling between text and HTML view of mail
+ (Dan Vrátil)
+ Bug 524737 - Replace radio buttons in Search folder editor (Milan Crha)
+ Bug 548778 - Use original location when replying in Search Folder
+ (Milan Crha)
+ Bug 602425 - Search in "Current Account"/"All Accounts" depends on
+ vfolders (Milan Crha)
+ Bug 617557 - Can close composer while message is sending (Milan Crha)
+ Bug 653529 - Alarm Notification window events list is too small
+ (Milan Crha)
+ Bug 661886 - Avoid vertical scrolling in the filtering rules editor
+ (Milan Crha)
+ Bug 674427 - Crash when formatting contact in addressbook (Dan Vrátil)
+ Bug 677604 - Critical warnings on evolution start (Milan Crha)
+ Bug 677695 - Freeze on quit in emu_free_mail_cache() (Milan Crha)
+ Bug 677885 - Deleting account is chatty on console (Matthew Barnes)
+ Bug 677993 - Remember screen used in previous session (Milan Crha)
+ Bug 678606 - Crash under mail_backend_folder_deleted_cb()
+ (Matthew Barnes)
+ Bug 678667 - 'All Message Headers' option is broken (Lucian Langa)
+ Bug 678783 - Crash under e_attachment_set_file_info() (Milan Crha)
+ Bug 678834 - [prefer-plain] Setting change works only after restart
+ (Dan Vrátil)
+ Bug 678946 - Port entry in Account Assistant is unset (Matthew Barnes)
+ Bug 679323 - Formatting errors when replying in inline mode
+ (Dan Vrátil)
+ Bug 679649 - Remove "Recent Messages" from Quick Search Bar
+ (Matthew Barnes)
+ Bug 679726 - Can't unfold long recipient list in message window
+ (Dan Vrátil)
+ Bug 679814 - Calendar invitation shows both calendar and html part
+ (Dan Vrátil)
+
+Other Changes:
+ * google: Remove SSL option for Google Contacts address books
+ (Philip Withnall)
+ * google: Remove the offline caching option for Google Contacts
+ address books (Philip Withnall)
+ * [prefer-plain] Fix displaying suppressed HTML parts (Dan Vrátil)
+ * Add CamelDebug to e_mail_parser_parse_sync (Dan Vrátil)
+ * Display text/plain in fixed-width font (Dan Vrátil)
+ * Fix displaying photos in contacts preview (Dan Vrátil)
+ * Display local contact photos in EContactEditor's EImageChooser
+ (Dan Vrátil)
+ * Don't load images in preview pane when openning Preferences Dialog
+ (Dan Vrátil)
+ * Trust attachments from ~/.kde and ~/.kde4. (Matthew Barnes)
+ * killev.c: Don't kill D-Bus services. (Matthew Barnes)
+ * Remove "last-upgraded-version" GSettings key. (Matthew Barnes)
+ * Remove evolution-nognome script. (Matthew Barnes)
+ * Delay saving Evolution version until later in initialization.
+ (Matthew Barnes)
+ * EMailConfigWindow: Add a "changes-committed" signal. (Matthew Barnes)
+ * Disconnect a CamelService after editing its settings. (Matthew Barnes)
+ * e_web_view_update_fonts(): Fix memory corruption. (Matthew Barnes)
+ * Use folder display name in status messages when possible.
+ (Matthew Barnes)
+ * Remove em_folder_tree_get_selected_folder(). (Matthew Barnes)
+ * Avoid crash on folder rename (Milan Crha)
+ * Add "auto-update" option to Search Folder Editor (Milan Crha)
+ * Preset timeout on SoupSession-s to 90 seconds (Milan Crha)
+ * Update to libgweather 3.5 (Giovanni Campagna)
+ * Don't display SMIME signature as an attachment (Dan Vrátil)
+ * Make alarm notifications work again (Milan Crha)
+ * Rework handling of GOA mail. (Matthew Barnes)
+
+Translations:
+ Ihar Hrachyshka (be)
+ Daniel Mustieles (es)
+ Fran Diéguez (gl)
+ Kjartan Maraas (nb, nn)
+ Sasi Bhushan Boddepalli (te)
+ Chao-Hsiung Liao (zh_HK)
+
+
+Evolution 3.5.3 2012-06-25
+--------------------------
+
+!!! MAJOR DESIGN CHANGES AND API BREAKS IN THIS RELEASE !!!
+
+* GConf dependency has been dropped.
+
+* Account data now resides in plain text files rather than GConf XML blobs.
+ As part of this effort, a good part of libedataserver was rewritten from
+ scratch. For further details and links to documentation see:
+ https://mail.gnome.org/archives/evolution-list/2012-May/msg00214.html
+
+Bug Fixes:
+ Bug 300677 - vFolder rules shouldn't refer to the Unmatched folder
+ (Milan Crha)
+ Bug 431497 - Offline mode should disable loading of images from the
+ internet (Dan Vrátil)
+ Bug 569540 - Remove unused message-display-style GSettings key
+ (Milan Crha)
+ Bug 670876 - Missing mnemonics for buttons for vcard attached to email
+ (Dan Vrátil)
+ Bug 674887 - Hang on sender's photo lookup (Dan Vrátil)
+ Bug 676179 - Memos/Tasks - Update preview when it's shown (Dan Vrátil)
+ Bug 676563 - Cannot create folders directly under store node
+ (Milan Crha)
+ Bug 677597 - Crash on vFolder source folder removal (Milan Crha)
+ Bug 677607 - Closing Mail Browser emits critical warnings (Dan Vrátil)
+ Bug 677608 - Fails to open message which is not yet downloaded
+ (Dan Vrátil)
+ Bug 677624 - Disable Properties when Search Folders is selected
+ (Matthew Barnes)
+ Bug 677628 - Remove account and folder name from mail notifications
+ (Matthew Barnes)
+ Bug 677631 - Some HTML links don't work (Dan Vrátil)
+ Bug 677673 - Reply contains quoted top headers (Dan Vrátil)
+ Bug 677679 - Folder tree unread counts don't decrease (Matthew Barnes)
+ Bug 677686 - Account editor missing refresh interval setting
+ (Matthew Barnes)
+ Bug 677706 - Crash in spell_entry_recheck_all() (Milan Crha)
+ Bug 677882 - Cannot create account with Sendmail (Matthew Barnes)
+ Bug 677995 - Asks password for disabled mail account (Matthew Barnes)
+ Bug 678292 - Due Date does not display in follow-up flag dialogue box
+ (Milan Crha)
+ Bug 678293 - Already downloaded images are not shown (Dan Vrátil)
+ Bug 678304 - Save Draft prevents Evolution's quit (Milan Crha)
+ Bug 678345 - Runtime warning when sender photo is disabled (Dan Vrátil)
+ Bug 678347 - Put spamd pid/socket files in $XDG_RUNTIME_DIR
+ (Matthew Barnes)
+ Bug 678393 - Disable Properties for built-in mail stores
+ (Matthew Barnes)
+ Bug 678397 - Move "mail-to-task" actions to a submenu (Matthew Barnes)
+ Bug 678608 - Please enter password for mail account "Unnamed"
+ (Matthew Barnes)
+ Bug 678609 - No suggested name for new mail account (Matthew Barnes)
+ Bug 678613 - Keep display name synchronized across all mail sources
+ (Matthew Barnes)
+ Bug 678634 - Criticals warnings when creating new book/cal
+ (Matthew Barnes)
+ Bug 764467 - URL popup shows all Copy options (Dan Vrátil)
+
+Other Changes:
+ * User documentation improvements. (Andre Klapper)
+ * Adapt to single-include E-D-S libraries. (Matthew Barnes)
+ * Remove mail-guess-servers.[ch]. (Matthew Barnes)
+ * Remove local mail autoconfiguration data. (Matthew Barnes)
+ * Mail formatter rewrite (Dan Vrátil)
+ * Bump minimum libnotify version to 0.7. (Matthew Barnes)
+ * Fix possible use of uninitialized variable (Milan Crha)
+ * Adapt to evolution-data-server's port from GConf to GSettings
+ (Milan Crha)
+ * Make em_utils_in_addressbook() cancellable (Dan Vrátil)
+ * Remove the last remaining usage of GConf (Milan Crha)
+ * Remove -Werror from AM_INIT_AUTOMAKE. (Matthew Barnes)
+ * Do not call g_object_notify() when property didn't change
+ (Milan Crha)
+ * Clarify that libcanberra-gtk3 is optional. (Matthew Barnes)
+ * No more experimental plugins. (Matthew Barnes)
+ * Remove Mono and Python EPlugin bindings. (Matthew Barnes)
+ * Remove --enable-plugins=list variation. (Matthew Barnes)
+ * Delete unused GnomeCanvasRichText. (Matthew Barnes)
+ * Use SoupURI instead of EUri. (Matthew Barnes)
+ * Reduce amount or EMailDisplay reloads when displaying Preferences
+ dialog (Dan Vrátil)
+ * Avoid crash for providers without configuration backend (Milan Crha)
+
+Translations:
+ Ihar Hrachyshka (be)
+ Tom Tryfonidis (el)
+ Daniel Mustieles (es)
+ Bruno Brouard (fr)
+ Fran Diéguez (gl)
+ Matej UrbanÄiÄ (sl)
+
+
+Evolution 3.5.2 2012-06-04
+--------------------------
+
+Bug Fixes:
+ Bug 200683 - Composer subject spell checking (Milan Crha)
+ Bug 206484 - Add year scrolling to date picker (Milan Crha)
+ Bug 246581 - Replies in Sent folder goes to myself (Milan Crha)
+ Bug 559710 - Do not close Event/Task/Memo editor on save (Milan Crha)
+ Bug 669111 - Lost charset in replies to encrypted mails (Milan Crha)
+ Bug 669133 - Import Assistant preview widget is too small (Milan Crha)
+ Bug 669295 - Choice made for 'setup Google contact/calendar' is not
+ remembered (Milan Crha)
+ Bug 669445 - A way of turning Message Preview off by default
+ (Milan Crha)
+ Bug 669463 - HTML signature opens in editor as Plain text (Milan Crha)
+ Bug 669657 - Move External Editor plugin to standard plugins
+ (Holger Macht)
+ Bug 669674 - EMailBrowser doesn't copy search settings (Milan Crha)
+ Bug 669893 - Send/Receive dialog content too tall (Milan Crha)
+ Bug 669983 - Add "To" only search option (like for CC and BCC exists)
+ (Milan Crha)
+ Bug 671585 - Add support for smooth scrolling devices (Milan Crha)
+ Bug 671585 - e-week-view.c: Use page_increment for smooth scrolling
+ (Volker Sobek)
+ Bug 672827 - 'Mark as read' confirmation dialog is too big
+ (Matthew Barnes)
+ Bug 673514 - Crash in WebKit after printing (Dan Vrátil)
+ Bug 673946 - Cannot delete search folders (Milan Crha)
+ Bug 674997 - Collapsing contact lists broken in Contacts preview
+ (Dan Vrátil)
+ Bug 675061 - Evolution 3.5.1 does not build (Dan Vrátil)
+ Bug 675347 - No 'Retrieving message...' in preview panel (Dan Vrátil)
+ Bug 675391 - Remove support for EVOLUTION_PLUGIN_PATH. (Matthew Barnes)
+ Bug 675723 - UI lock from action_mail_show_source_cb (Dan Vrátil)
+ Bug 675725 - SMTP configuration window forgets custom port (Milan Crha)
+ Bug 675728 - Crash in strcmp, e_filter_rule_find_list (Milan Crha)
+ Bug 675863 - Cannot load webview.css from Tasks/Memos (Dan Vrátil)
+ Bug 675871 - Hide gnu make extensions warnings for automake 1.12
+ (Milan Crha)
+ Bug 676226 - Changing GOA mail account looses GOA key (Milan Crha)
+ Bug 676410 - Add Unity to OnlyShowIn whitelist (Jeremy Bicha)
+ Bug 676492 - Mail backend properties with underscores stopped working
+ (David Woodhouse)
+ Bug 677045 - pkg-config files missing libebackend-1.2 requirement
+ (Matthew Barnes)
+ Bug 677273 - Bad default for month-hpane-position setting
+ (Matthew Barnes)
+ Bug 677280 - "Help - Quick Reference" opens multiple PDF documents
+ (Matthew Barnes)
+
+Other Changes:
+ * Require libsoup >= 2.38.1. (Matthew Barnes)
+ * Spell checking for 'Summary' in Event/Task/Memo editors (Milan Crha)
+ * Make Yahoo! mail-autoconfig use IMAP, instead of POP3 and preconfig
+ also Tasks (Milan Crha)
+ * Avoid New unread icon emblem on virtual folders (Milan Crha)
+ * Make the settings capplet optional. (Matthew Barnes)
+ * Fix memory leaks around gtk_tree_model_get() function (Milan Crha)
+
+Translations:
+ Christian Kirbach (de)
+ Daniel Mustieles (es)
+ Bruno Brouard (fr)
+ Fran Diéguez (gl)
+ Luca Ferretti (it)
+ Jiro Matsuzawa (ja)
+ Kjartan Maraas (nb)
+ Dmitry Shachnev (ru)
+ Nguyá»…n Thái Ngá»c Duy (vi)
+
+
+Evolution 3.5.1 2012-04-30
+--------------------------
+
+* Evolution now uses WebKit/GTK+ instead of GtkHtml to display emails,
+ contacts, tasks and memos. A huge thanks to the heroic efforts of Dan
+ Vrátil for this! It's been a long time coming. Note that for the time
+ being Evolution still uses GtkHtml to compose emails, but work will soon
+ be underway to transition the email composer to WebKit/GTK+ as well.
+ GtkHtml will then be retired.
+
+Bug Fixes:
+ Bug 245025 - Popup confirmation when moving a folder (via drag and
+ drop) (Milan Crha)
+ Bug 465076 - INBOX confusion with outbox (Milan Crha)
+ Bug 528508 - Wrap long lines when printing emails (Dan Vrátil)
+ Bug 560654 - Better description for message list filter (Milan Crha)
+ Bug 564820 - Search filter persists when changing folders (Milan Crha)
+ Bug 584143 - Global Search Function withing Calendar (Milan Crha)
+ Bug 593444 - templates-plugin: minor tweak to configuration tab
+ (Ashwini Oruganti)
+ Bug 593449 - custom-header-plugin: minor tweak to configuration tab
+ (Ashwini Oruganti)
+ Bug 593450 - attachment-reminder-plugin: minor tweak to configuration
+ tab (Ashwini Oruganti)
+ Bug 600860 - Opening IMAP message with large attachment blocks UI
+ (Milan Crha)
+ Bug 617930 - Crash under mail_sidebar_model_loaded_row_cb (Milan Crha)
+ Bug 655753 - Improve offline notification for network outage
+ (Milan Crha)
+ Bug 667046 - Outgoing filter cannot override used Sent folder
+ (Milan Crha)
+ Bug 667912 - Remove name field from formatted address label
+ (Milan Crha)
+ Bug 668481 - Account order is not remembered (Milan Crha)
+ Bug 668543 - Crash in view_modify_contact_cb() if contact has no UID
+ (Milan Crha)
+ Bug 668687 - MDN panel left shown when moving to an empty folder
+ (Milan Crha)
+ Bug 668768 - Copy&paste of appointment occurrence creates two
+ appointments (Milan Crha)
+ Bug 668769 - Recurrence editor weekday items slightly cropped
+ (Milan Crha)
+ Bug 668976 - Capplet settings depends on local etable (Alban Browaeys)
+ Bug 668988 - Handle a "minutes" entry greater than 59 intelligently
+ (Milan Crha)
+ Bug 668989 - Add a twitter username to IM in contacts (Milan Crha)
+ Bug 668998 - Consistent UI for saving Contacts like in Events/Tasks/
+ Memos (Milan Crha)
+ Bug 669088 - Add a Column dialog draws incorrectly (Milan Crha)
+ Bug 670445 - Folder deletion in offline shows strange behavior
+ (Vibha Yadav)
+ Bug 670609 - Delete /data/evolution.mime (Matthew Barnes)
+ Bug 670967 - Moving event in offline doesn't delete event from
+ original calendar (Vibha Yadav)
+ Bug 670967 - Moving event in offline mode (Vibha Yadav)
+ Bug 671537 - Option to validate SSL certificates with libsoup
+ (Milan Crha)
+ Bug 671874 - autocontacts.gschema: GAIM is called Pidgin now
+ (Matthew Barnes)
+ Bug 671876 - Improve schema descriptions for mail-notification keys
+ (Matthew Barnes)
+ Bug 672175 - Make CamelFolderSearch cancellable (Milan Crha)
+ Bug 672916 - Spam is not detected automatically (Milan Crha)
+ Bug 672986 - User docs are too big for git.mk (Sam Thursfield)
+ Bug 673013 - Doesn't expose webkit Cflags/Libs (Dan Vrátil)
+ Bug 673065 - Black rectangle around text in Source view (Dan Vrátil)
+ Bug 673067 - [itip-formatter] Shows one long line for the meeting
+ description (Dan Vrátil)
+ Bug 673108 - Font settings and monospace fonts don't work (Dan Vrátil)
+ Bug 673123 - Crash in http_request_write_to_cache (Dan Vrátil)
+ Bug 673225 - White box in message preview not wide enough for very
+ long strings (Dan Vrátil)
+ Bug 673228 - Fails to display attached image in attached email
+ (Dan Vrátil)
+ Bug 673420 - Itip formatter lost all mnemonics (Dan Vrátil)
+ Bug 673430 - Can't read messages in virtual Junk/Trash folders
+ (Dan Vrátil)
+ Bug 673525 - Crash under efh_write_message() (Dan Vrátil)
+ Bug 673895 - "Send To..." doesn't work anymore (Matthew Barnes)
+ Bug 673955 - Can not display email and calendar in separate windows
+ anymore (Matthew Barnes)
+ Bug 674034 - Attached images from IMAP provider email not shown
+ (Dan Vrátil)
+ Bug 674037 - [attachment-reminder] Parses message body inefficiently
+ (Milan Crha)
+ Bug 674060 - Preview panel on folder change not updated (Dan Vrátil)
+ Bug 674062 - Runtime warning from e_attachment_load_handle_error()
+ (Milan Crha)
+ Bug 674176 - Sender's photo not shown properly (Dan Vrátil)
+ Bug 674194 - Missing text in email (Dan Vrátil)
+ Bug 674248 - Lost new lines from text/plain (Dan Vrátil)
+ Bug 674249 - Crash when showing message with large text/plain
+ (Dan Vrátil)
+ Bug 674272 - Contacts preview differs with mailer running and not
+ (Dan Vrátil)
+ Bug 674282 - Don't crash on reply with empty selection (Yanko Kaneti)
+ Bug 674340 - Evolution hangs on startup (Dan Vrátil)
+ Bug 674380 - Deselected contact keeps preview filled (Dan Vrátil)
+ Bug 674381 - Show contact photo from address book doesn't work
+ (Dan Vrátil)
+ Bug 674466 - Mail's preview panel can show listing of local filesystem
+ root (Dan Vrátil)
+ Bug 674701 - Clicking address in preview composes to default account
+ (Milan Crha)
+
+Miscellaneous Changes:
+ * Limit supported gweather to < 3.5. (Matthew Barnes)
+ * Require gnome-doc-utils >= 0.20.10. (Matthew Barnes)
+ * Add ability to specify INBOX for non-storage type accounts.
+ (Srinivasa Ragavan)
+ * EMFormat: Add "session" as a constructor property. (Matthew Barnes)
+ * Use GNetworkMonitor to drive EShell:network-available.
+ (Matthew Barnes)
+ * Drop the ConnMan/NetworkManager/WindowsSENS modules. (Matthew Barnes)
+ * Remove EMSyncStream. (Matthew Barnes)
+ * EMFolderTreeModel: Remove COL_STRING_URI. (Matthew Barnes)
+ * Fix backward buttons in "restore-confirm" dialog. (Matthew Barnes)
+ * EWebView: Make antialiasing settings optional. (Matthew Barnes)
+ * Show calendar Find Next/Prev/Stop buttons beside Search text entry
+ (Milan Crha)
+
+Translations:
+ Ibrahim Saed (ar)
+ Jordi Serratosa (ca)
+ Carles Ferrando (ca@valencia)
+ Christian Kirbach (de)
+ Mario Blättermann (de)
+ Daniel Mustieles (es)
+ Mattias Põldaru (et)
+ Bruno Brouard (fr)
+ Fran Diéguez (gl)
+ Hideki Yamane (ja)
+ Kjartan Maraas (nb)
+ Piotr DrÄ…g (pl)
+ Matej UrbanÄiÄ (sl)
+ Daniel Nylander (sv)
+ Sasi Bhushan (te)
+
+
+Evolution 3.4.0 2012-03-26
+--------------------------
+
+Bug Fixes:
+ Bug 672474 - Flaw in GOA synchronization logic (Matthew Barnes)
+ Bug 672593 - Typos in evolution.convert (Dimitri)
+
+Translations:
+ Ibrahim Saed (ar)
+ David Planella (ca)
+ Carles Ferrando (ca@valencia)
+ Jiri Eischmann (cs)
+ Flemming Christensen (da)
+ Kenneth Nielsen (da)
+ Mattias Põldaru (et)
+ Bruno Brouard (fr)
+ Chandan Kumar (hi)
+ Gabor Kelemen (hu)
+ Shankar Prasad (kn)
+ Aurimas ÄŒernius (lt)
+ Kjartan Maraas (nb)
+ Duarte Loreto (pt)
+ Djavan Fagundes (pt_BR)
+ Sasi Bhushan Boddepalli (te)
+ Daniel Korostil (uk)
+
+
+Evolution 3.3.92 2012-03-19
+---------------------------
+
+Bug Fixes:
+ Bug 671509 (2/2) - Some small UI/theming improvements (Cosimo Cecchi)
+ Bug 671509 (1/2) - Some small UI/theming improvements (Cosimo Cecchi)
+ Bug 665399 - Cannot change File Under to custom value (Milan Crha)
+ Bug 659756 - Initialize dbus-glib threading for GConf (Milan Crha)
+ Bug 665130 - Memory leaks in Preferences and ETable (Milan Crha)
+ Bug 665129 - Memory leak in EBufferTagger (Milan Crha)
+ Bug 665106 - Memory leak from composer setup when opening Preferences (Milan Crha)
+ Bug 669490 - Window resizes with many activities (gtk 3.3.14+) (Milan Crha)
+ Bug 671716 - Fails to build with --enable-contact-maps (Matthew Barnes)
+ Bug 664326 - Buttons to handle exceptions in event is always disabled (Milan Crha)
+ Bug 664323 - Too late initialization of Gnome/GailCanvas ATK support (Milan Crha)
+ Bug 664205 - Improve UX when creating a new mail folder (Milan Crha)
+ Bug 664169 - Default port is not selected by default (Milan Crha)
+ Bug 671233 - Unable to choose port 587 for SMTP (Milan Crha)
+ User Docs: Link 'Deleting attachments' into Attachments overview page. See bug #671633 (Andre Klapper)
+ User Docs: Clarify Bogofilter usage again. Fixes bug #665008 (Andre Klapper)
+ User Docs: Rewrite Spam Marking. Fixes bug #665008 (Andre Klapper)
+ User Docs: Explain how Bogofilter and SpamAssassin work and link to their FAQs. See bug #665008 (Andre Klapper)
+ User Docs: Explain order in mail folder list pane and how to change. Fixes bug #661654 (Andre Klapper)
+ User Docs: Mention 'Apply the same view settings to all folders' mail setting. Fixes bug #669246 (Andre Klapper)
+ User Docs: Use conditional processing for package install links; Add EWS to first start page. Fixes bug #671068. (Andre Klapper)
+
+Miscellaneous Fixes:
+ Add dbus-glib flags to evolution binary. (Matthew Barnes)
+ Add a comment about Bcc headers to searchtypes.xml. (Matthew Barnes)
+ Revert "Include searching Bcc header while looking for recipients" (Matthew Barnes)
+ Mention the return of dbus-glib in a NEWS blurb. (Matthew Barnes)
+ Fix too large allocation for alert-bar in shell-content (Milan Crha)
+ EConfig: Support custom page skip callbacks. (Matthew Barnes)
+ User Docs: Move page to Advanced section (Andre Klapper)
+ User Docs: Add page about message source and all mail headers view (Andre Klapper)
+ User Docs: Add 'Advanced' section for Message Displaying to dump all the Headers/Source stuff (Andre Klapper)
+ User Docs: Remove Source and Headers stuff from 'Message list sorting' section. Wrong place. (Andre Klapper)
+ User Docs: Link also into mail-layout-changing (Andre Klapper)
+ User Docs: Fix wrong syntax (Andre Klapper)
+ User Docs: Add missing markup (Andre Klapper)
+ startup-wizard: Avoid em_account_editor_get_widget(). (Matthew Barnes)
+
+Translations:
+ Changwoo Ryu (ko)
+ Bruce Cowan (en_GB)
+ Nilamdyuti Goswami (as)
+ Daniel Mustieles (es)
+ Daniel Korostil (uk)
+ Christian Kirbach (de)
+ Martin Srebotnjak (sl)
+ Timo Jyrinki (fi)
+ Pavol KlaÄanský ()
+ Bruno Brouard (fr)
+ Piotr DrÄ…g (pl)
+ Matej UrbanÄiÄ (sl)
+ Yuri Myasoedov (ru)
+ Kjartan Maraas (nn)
+ A S Alam (pa)
+ Praveen Arimbrathodiyil ()
+ Gabor Kelemen (hu)
+ Rudolfs Mazurs (lv)
+ Chao-Hsiung Liao (zh_HK)
+
+
+* The dbus-glib dependency has temporarily returned. GConf now uses
+ dbus-glib instead of libbonobo but it does not initialize threading
+ support, so we have to initialize it to avoid thread-safety issues.
+ When we're ready to drop GConf we will drop dbus-glib along with it.
+
+
+Evolution 3.3.91 2012-03-05
+---------------------------
+
+Bug Fixes:
+ Bug 670432 - Check for EggSMClient dependencies with pkg-config
+ (Matthew Barnes)
+ Bug 670512 - Crash in ecp_set_target at e-cal-config.c:93 (Milan Crha)
+ Bug 661265 - Move to Calendar breaks google:// URI (Milan Crha)
+ Bug 669294 - Settings of 'sending email' tab is not remembered
+ (Milan Crha)
+ Bug 617557 - Can lost message after send failed (Milan Crha)
+ Bug 670934 - Was saving ESourceList first, rather than last (Milan Crha)
+ Bug 663745 - Option to create Google Calendar not available (Milan Crha)
+ Bug 671211 - 'Mark Citations' preferences not applied (Dan Vrátil)
+
+Other Changes:
+ * Further staging of mailer code to be moved to evolution-data-server.
+ New libevolution-utils introduced as a temporary bridge during the
+ staging phase. (Srinivasa Ragavan)
+ * Various user documentation improvements. (Andre Klapper)
+ * Show account properties on remote folders. (Milan Crha)
+ * Show errors on message load. (Milan Crha)
+ * Avoid crash when formatting broken message. (Milan Crha)
+ * Show composer window on "Continue editing". (Milan Crha)
+ * Handle cut-paste appointments better. (Chenthill Palanisamy)
+
+Translations:
+ Ihar Hrachyshka (be)
+ Alexander Shopov (bg)
+ Krasimir Chonov (bg)
+ Daniel Mustieles (es)
+ Fran Diéguez (gl)
+ Aurimas ÄŒernius (lt)
+ Yuri Myasoedov (ru)
+ Matej UrbanÄiÄ (sl)
+ МироÑлав Ðиколић (sr)
+ Dr.T.Vasudevan (ta)
+ Nguyá»…n Thái Ngá»c Duy (vi)
+ Chao-Hsiung Liao (zh_HK)
+
+
+Evolution 3.3.5 2012-02-06
+--------------------------
+
+Bug Fixes:
+ Bug 670414 - Whitespace following backslash in Makefile.am (Jiro Matsuzawa)
+ Bug 670301 - User Docs: Document improved ways to add/edit mail accounts. (Andre Klapper)
+ Bug 670389 - User Docs: Add sorting for available Exchange providers. Fixes bug #670389 (Andre Klapper)
+ Bug 668620 - User Docs: Explain how to enable Search Folders. Fixes bug #668620 (Andre Klapper)
+ Bug 670252 - User Docs: Clarify the 'Account' term in mail quick search scope. Fixes bug #670252. (Andre Klapper)
+ Bug 552873 - User Docs: Also cover mail composer in 'Character Encodings' page. See bug 552873. (Andre Klapper)
+ Bug 471795 - Clarify CSV importers as being for contact info only (Matthew Barnes)
+ Bug 670278 - Poorly worded "confirm overwrite" alert (Matthew Barnes)
+ Bug 670280 - Remove "Recent Documents" attachment feature (Matthew Barnes)
+ Bug 663110 - Crash on copy events between calendars (Milan Crha)
+ Bug 663077 - Reorder mx-1.0 and clutter-gtk-1.0 in PKG_CHECK_MODULES (Alexandre Rostovtsev)
+ Bug 320976 - Remember last New button choice in Calendar view (Milan Crha)
+ Bug 332043 - Free/Busy Colors Causing User Confusion (Milan Crha)
+ Bug 668482 - Edit account properties from menu on folder store (Milan Crha)
+ Bug 669113 - Add "File > New > Mail Account" (Milan Crha)
+ Bug 668848 - Whitespaces in front of colons (Milan Crha)
+ Bug 659396 - Missing plural handling for "You have selected %d mails to..." (Milan Crha)
+ Bug 659394 - Missing plural handling for "Failed to send %d of %d messages" (Milan Crha)
+ Bug 655955 - Harmonize mnemonic for New > Shared Memo > Organizer (Milan Crha)
+ Bug 670014 - Remove-duplicates reads all messages into memory (Milan Crha)
+ Bug 655485 - Change "cards" to "contacts" in LDAP Address Book dialog (Milan Crha)
+ Bug 655021 - "Character set" vs "Character encoding" (Milan Crha)
+ Bug 637200 - Add mnemonics to Folder Properties dialog checkboxes (Gabor Kelemen)
+ Bug 662743 - Translation context needed for "Attachment" (Milan Crha)
+ Bug 670073 - Non-working help button in Preferences dialog (Milan Crha)
+ Bug 591436 - Add -avoid-version to LDFLAGS (H. Habighorst)
+ Bug 637354 - Add missing mnemonics and make existing ones unique. (Andre Klapper)
+ Bug 669097 - Cannot save column setup: File name too long (Milan Crha)
+ Bug 669433 - Add missing linker flags to pst-import (Dominique Leuenberger)
+ Bug 210105 - Error assigning negative scores in filtering (Milan Crha)
+ Bug 384838 - Filter editor should default to "AND" instead of "OR" (Milan Crha)
+ Bug 391472 - Add ability to match headers by words (Milan Crha)
+ Bug 418520 - Disable Folder -> Expunge in virtual folders (Matthew Barnes)
+ Bug 553796 - Unable to Reset Message Color (Milan Crha)
+ Bug 309945 - Ability to filter folders other than INBOX too (Milan Crha)
+
+Miscellaneous Fixes:
+ User Docs: Add missing markup (Andre Klapper)
+ User Docs: Update list of files in Makefile.am (Andre Klapper)
+ User Docs: Remove outdated info about version specific common errors (Andre Klapper)
+ User Docs: Update gconf locations to GSettings/dconf (Andre Klapper)
+ User docs: Fix broken sentence (Andre Klapper)
+ User Docs: Fix inappropriate usage of <em> tags (Andre Klapper)
+ User Docs: Fix broken markup (Andre Klapper)
+ User Docs: Fix inappropriate usage of <code> tag (Andre Klapper)
+ User Docs: Use <cmd> tag consistently (Andre Klapper)
+ User Docs: Use <app> tag consistently (Andre Klapper)
+ User Docs: Fix dconf path; recommend using terminal command instead of dconf-editor (Andre Klapper)
+ User Docs: Use consistent terminology (folder pane vs folder list) (Andre Klapper)
+ User Docs: Fix position of <note> so it is actually displayed (Andre Klapper)
+ Use same mnemonic for 'Categories' button in Task editor as in all other dialogs as it does not collide with other mnemonics (Andre Klapper)
+ Use GSettings for EProxy (Milan Crha)
+ User docs: Actually describe how to set up the Free/Busy querying URL (Andre Klapper)
+ Change 'file name' to 'filename' according to the GDP Style Guide (Andre Klapper)
+ Use i as mnemonic for Filename string everywhere. This does not conflict with other mnemonics in the affected dialogs. (Andre Klapper)
+ Correct spelling of the word 'Username' (Andre Klapper)
+ User help: Replace the term program by application, as recommended by the GDP style guide (Andre Klapper)
+ Fix a crash in capplet. (Srinivasa Ragavan)
+ Make Capplet work again with new CamelSettings and other stuffs. Also add EPlugin support to capplet so that exchange and other accoutns can be configured via this. now. (Srinivasa Ragavan)
+ Be able to define help target for Preferences pages (Milan Crha)
+ Fix broken Help menu entries after Mallard transition. (Andre Klapper)
+ Fix broken Help button link for 'Insert > Custom Header' dialog after Mallard transition. (Andre Klapper)
+ Clarify that value for mark-seen-timeout is in milliseconds (Andre Klapper)
+ Make alarm daemon start in Dawat/Tizen. (Srinivasa Ragavan)
+ Add missing mnemonics; change some mnemonics to avoid conflicts (Andre Klapper)
+ Add missing mnemonic to string (Andre Klapper)
+
+Translations:
+ Daniel Mustieles (es)
+ МироÑлав Ðиколић (sr)
+ Christian Kirbach (de)
+ Chao-Hsiung Liao (zh_HK)
+ Fran Diéguez (gl)
+ Ihar Hrachyshka (be)
+ Kjartan Maraas (nn)
+ Gabor Kelemen (hu)
+
+
+Evolution 3.3.4 2012-01-16
+--------------------------
+
+Bug Fixes:
+ Bug 343499 - Contacts not sorted the right way on print out
+ (Milan Crha)
+ Bug 353743 - Add Print button to meeting notification dialog
+ (Milan Crha)
+ Bug 357175 - IMAP alerts still too intrusive (Milan Crha)
+ Bug 612257 - Sanitize widgets in alarm notification dialog (Milan Crha)
+ Bug 636214 - Use CamelSettings instead of CamelURL (Punit Jain)
+ Bug 638810 - Crash in camel_folder_search_set_folder with IMAP account
+ (Milan Crha)
+ Bug 641154 - Crash in emae_check_authtype_done (Milan Crha)
+ Bug 661087 - Add ability to remove localized "Re:" prefixes in subject
+ (Milan Crha)
+ Bug 661885 - Disable horizontal scrolling in filter rule editor
+ (Milan Crha)
+ Bug 664003 - Cannot modify account name in account assistant
+ (Punit Jain)
+ Bug 664370 - Crash when putting same component into icalcomponent
+ (Kai Juse)
+ Bug 665036 - Memory leaks spot in Contacts view (Milan Crha)
+ Bug 666490 - Crash in e-mail-session.c:user_message_response
+ (Milan Crha)
+ Bug 666675 - Remove evolution-addressbook-clean (Matthew Barnes)
+ Bug 666695 - Wrong schema for relocatable path in evolution.convert
+ (Matthew Barnes)
+ Bug 666706 - MailFolderCache: Crash on visiting a renamed folder
+ (Matthew Barnes)
+ Bug 666832 - Skip local/vfolder services from Send/Receive update
+ (Milan Crha)
+ Bug 667119 - Hard to change Attendee role in meeting editor
+ (Milan Crha)
+ Bug 667185 - Menu items from plugins not translated (Milan Crha)
+ Bug 667281 - Deadlock on evolution start (Milan Crha)
+ Bug 667346 - Fix build with libpst 0.6.54 and require this version
+ (Vincent Untz)
+ Bug 667384 - Misspelling: "Olsen" timezone database (Matthew Barnes)
+ Bug 667398 - Automatic mark-as-seen too aggressive (Milan Crha)
+ Bug 667528 - Crash in pine-importer.c with no book source defined
+ (Milan Crha)
+
+Miscellaneous Changes:
+ * Make sure EAlertDialog has at least one button, to be able to
+ closed it (Milan Crha)
+ * Move EMailLabelListStore to EMailSession. (Matthew Barnes)
+ * Inherit smaller time division from preferences in day calendar
+ printout (Milan Crha)
+ * Make em_utils_generate_account_hash() private. (Matthew Barnes)
+ * Do not call gtk_main_quit() on shell quit when none is running
+ (Milan Crha)
+ * mail-folder-cache: Update folders only on stores whose support it
+ (Milan Crha)
+ * Slow start due to instant saving of no change in an EAccountList
+ (Milan Crha)
+ * EMailSession does not respect user settings on start (Milan Crha)
+ * Do not auto-mark-as-seen when changing filter type (Milan Crha)
+ * User documentation improvements (Brian Grohe and Andre Klapper)
+
+Translations:
+ Kristjan SCHMIDT (eo)
+ Daniel Mustieles (es)
+ Fran Diéguez (gl)
+ Kjartan Maraas (nb)
+ Yuri Myasoedov (ru)
+ Muhammet Kara (tr)
+
+
+Evolution 3.3.3 2011-12-19
+--------------------------
+Bug Fixes:
+ Bug 661043 - Printing causes email images to download (Milan Crha)
+ Bug 666341 - [bbdb] Invalid free in bbdb_do_it (Milan Crha)
+ Bug 561696 - Invitation's "Open Calendar" button jumps to current day (Milan Crha)
+ Bug 566793 - Support Drop And Drag Into Nautilus As PDF File (pepp)
+ Bug 666081 - Duplicate typedefs (Matthew Barnes)
+ Bug 582649 - Toggle for coloring today and overdue tasks (Milan Crha)
+ Bug 666106 - libical 0.47 handles CATEGORIES as multiple parameters (Milan Crha)
+ Bug 665981 - Use OpenStreetMap geoclue provider (Alban Browaeys)
+ Bug 665980 - Bump minimum champlain-gtk version to 0.12 (Alban Browaeys)
+ Bug 665782 - configure.ac: Add gmodule-2.0 to GNOME_PLATFORM (Christophe Fergeau)
+ Bug 578245 - View settings for threads getting lost (Milan Crha)
+ Bug 577322 - Rename of a system ESource doesn't persist (Milan Crha)
+ Bug 665149 - Do not ref window in e_restore_window() (Milan Crha)
+ Bug 663122 - Doesn't quit on exit with GLib's git master (Milan Crha)
+ Bug 664708 - Composer's headers preference is reset on From change (Milan Crha)
+ Bug 665103 - Blank composer/mail/network preferences windows (Milan Crha)
+ Bug 665123 - Incorrect unref of ESource in pine-importer (Milan Crha)
+ Bug 580394 - Comment field in a meeting request is too small (Milan Crha)
+ Bug 616561 - Don't check read-only calendars in the itip-formatter (Tim Piessens)
+ Bug 376075 - Accepting a meeting invitation defaults to wrong calendar (Milan Crha)
+ Bug 659491 - Hung when accepting calendar invite (Milan Crha)
+ Bug 664753 - Avoid unnecessary requirements in evolution-shell-3.0.pc (Josselin Mouette)
+ Bug 664654 - Sanitize subjects before suggesting a save filename (Matthew Barnes)
+ Bug 664634 - Deadlock when processing completed tasks filter (Milan Crha)
+ Bug 664707 - Tasks & Memos panel size not remembered (Matthew Barnes)
+ Bug 664678 - Bad defaults for SpamAssassin GSettings keys (Matthew Barnes)
+ Bug 585066 - Add Auto-Submitted header to outgoing MDNs (Matthew Barnes)
+ Bug 663615 - Saving calendar duplicates the first event (Milan Crha)
+ Bug 664018 - Cannot create task/memo from a mail (Milan Crha)
+
+Miscellaneous Fixes:
+ EMailSession: Add "activity-added" signal. (Matthew Barnes)
+ mail-send-recv.c: Avoid using EAccount and CamelURL if possible. (Matthew Barnes)
+ Upstreamed patch from Meego Bugzilla: 23097 (Srinivasa Ragavan)
+ Upstreamed patch from MeeGo Bugzilla: 22945 (Srinivasa Ragavan)
+ Fix a crash in pdf_drag_drop. Ref the objects while cloning format_html. (Chenthill Palanisamy)
+ MailFolderCache: Fix a double-free on unsubscribe. (Matthew Barnes)
+ EMSubscriptionEditor: Use alternating row colors. (Matthew Barnes)
+ EMSubscriptionEditor cleanups. (Matthew Barnes)
+ Bump minimum geoclue version to 0.12. (Alban Browaeys)
+ EMAccountEditor: Fix handling of auth-mechanism. (Matthew Barnes)
+ MailFolderCache: Don't respond to "service-added" signals. (Matthew Barnes)
+ EMailSession: Fix silly mistake in constructed(). (Matthew Barnes)
+ Adapt to camel_session_remove_service() changes. (Matthew Barnes)
+ User Docs: Grammar and spelling fixes (Christian Kirbach)
+ Reorder accounts by drag-and-drop. (Matthew Barnes)
+ Add a hidden --version option. (Matthew Barnes)
+ Move folder URI caching to MailFolderCache. (Matthew Barnes)
+ mail_folder_cache_note_store: CamelSession arg is unnecessary. (Matthew Barnes)
+ MailFolderCache: Add class methods for signals. (Matthew Barnes)
+ Miscellaneous EShellView-related cleanups. (Matthew Barnes)
+ Remove unused function vfolder_create_part(). (Matthew Barnes)
+ Remove unused function vfolder_revert(). (Matthew Barnes)
+ Remove 'vfolder_store' global variable. (Matthew Barnes)
+ EMFolderTreeModel: Check for vfolder store by its UID. (Matthew Barnes)
+ Remove unnecessary 'vfolder_store' declaration. (Matthew Barnes)
+ Composer: "mailto" blacklist touch ups. (Matthew Barnes)
+ EMailReader: Avoid more runtime warnings. (Matthew Barnes)
+ Avoid a runtime warning in mail_reader_message_seen_cb(). (Matthew Barnes)
+ Remove more "Click \"Forward\" to continue." sentences (Milan Crha)
+ Remove some unnecessary GConf crud. (Matthew Barnes)
+ "citation-colour" -> "citation-color" (Matthew Barnes)
+ Remove GConfBridge. (Matthew Barnes)
+ Use e_restore_window() and "org.gnome.evolution.window". (Matthew Barnes)
+ Add e_restore_window(). (Matthew Barnes)
+ Add relocatable "org.gnome.evolution.window" schema. (Matthew Barnes)
+ Updated asturian language (Xandru Armesto)
+ Remove almost all *_DISABLED_DEPRECATED_FLAGS. (Matthew Barnes)
+ Remove *_DISABLE_SINGLE_INCLUDES macros. (Matthew Barnes)
+ Remove e_shell_get_gconf_client(). (Matthew Barnes)
+ Updated POTFILES.in (Piotr DrÄ…g)
+ Merge branch 'wip/gsettings' (Matthew Barnes)
+ Include git.mk in mail/mail-autoconfig/Makefile.am. (Matthew Barnes)
+ Split MDN handling into a module. (Matthew Barnes)
+ EPreviewPane: Implement EAlertSink. (Matthew Barnes)
+ EAlertBar: Add a close button to all alerts. (Matthew Barnes)
+ Add EMailReader:message-loaded signal. (Matthew Barnes)
+ Add EMailReader:message-seen signal. (Matthew Barnes)
+
+Translations:
+ Daniel Mustieles (es)
+ Christian Kirbach (de)
+ Jorge González (es)
+ Fran Diéguez (gl)
+ Matej UrbanÄiÄ (sl)
+ Mario Blättermann (de)
+ Kjartan Maraas (nn)
+ Gabor Kelemen (hu)
+
+
+Evolution 3.3.2 2011-11-21
+--------------------------
+
+Bug Fixes:
+ Bug 440316 - Improve SSL Certificate check bad signature dialog
+ (Milan Crha)
+ Bug 565483 - "All folders" does not search all folders (Milan Crha)
+ Bug 627952 - 'Local delivery' mbox's aren't read properly (Milan Crha)
+ Bug 636214 - Fetch configuration details from server (Punit Jain)
+ Bug 659557 - Duplicate mnemonic in ldap address book creation dialog
+ (Vibha Yadav)
+ Bug 659736 - GOA Google calendar prevents settings change (Milan Crha)
+ Bug 659945 - "New" button in toolbar for new mail message not working
+ (Milan Crha)
+ Bug 660782 - [pst-import] Missing 'To' on message replies (Milan Crha)
+ Bug 660878 - Configuration options are not autofilled (Punit Jain)
+ Bug 661126 - Meeting Free/busy dialog dates don't follow locale
+ (Milan Crha)
+ Bug 662589 - 'Retrieve List' for new Google calendar does not use proxy
+ (Milan Crha)
+ Bug 662742 - Double free when expunging completed tasks (Milan Crha)
+ Bug 662914 - Reply to gnupg signed mails should be signed (Milan Crha)
+ Bug 662929 - POP3 prevents expunge of local Inbox in offline
+ (Milan Crha)
+ Bug 663286 - Changing view clears Contact preview (Milan Crha)
+ Bug 663372 - Actions not updated after disabling account
+ (Matthew Barnes)
+ Bug 663376 - Folder->Properties enabled when no folder selected
+ (Matthew Barnes)
+ Bug 663746 - Can't finish new account configuration for POP
+ (Milan Crha)
+ Bug 663748 - Unable to reconfigure GOA GMail account (Milan Crha)
+ Bug 663836 - emae_send_page() gets wrong CamelProvider (Matthew Barnes)
+ Bug 664001 - Account setup asks to configure SMTP when not needed
+ (Milan Crha)
+ Bug 664016 - [evolution-alarm-notify] Try to reconnect offline
+ calendars (Milan Crha)
+
+Other Changes:
+ * Remove g_thread_init() calls. (Matthew Barnes)
+ * Teach Evolution about Photo/Logo EContact fields stored as URIs
+ (Tristan Van Berkom)
+ * Add EAuthComboBox widget. (Matthew Barnes)
+ * EMAccountEditor: Start using CamelNetworkSettings. (Matthew Barnes)
+ * Call e_gdbus_templates_init_main_thread() in main() (Milan Crha)
+ * Kill gtk-doc tmpl files. (Matthew Barnes)
+ * Removing a redundant virtual function (Punit Jain)
+ * Remove SQLite mail summary migration. (Matthew Barnes)
+ * EMAccountEditor: Add a review page. (Punit Jain)
+ * Preset 'width-chars' for account type description labels (Milan Crha)
+ * Use CamelSExp instead of ESExp in filter, mail. (Matthew Barnes)
+
+Translations:
+ Mario Blättermann (de)
+ Daniel Mustieles (es)
+ Jorge González (es)
+ Fran Diéguez (gl)
+ Algimantas MargeviÄius (lt)
+ Kjartan Maraas (nb)
+
+
+Evolution 3.3.1 2011-10-24
+--------------------------
+
+Bug Fixes:
+ * Bug 235665 - Heavy hard disk access when resizing columns in views
+ (Milan Crha)
+ * Bug 351025 - Make the order of the mail accounts configurable
+ (Milan Crha)
+ * Bug 451377 - Timezone map resizes on mouseover (Milan Crha)
+ * Bug 455271 - A moved/renamed mail folder loses focus (Milan Crha)
+ * Bug 527614 - Valgrind shows a nice amount of lost memory (Milan Crha)
+ * Bug 576478 - [Windows] Redirect Help->Contents to a web page
+ (Milan Crha)
+ * Bug 601898 - SOCKS proxy does not work with mailer (Milan Crha)
+ * Bug 616981 - Mail marking as read is hard (Milan Crha)
+ * Bug 632619 - Recurring events can clutter month view (Milan Crha)
+ * Bug 637673 - Make phone fields one row and auto-expand when needed
+ (Milan Crha)
+ * Bug 655252 - Need to escape the comp_uid part of a path (Milan Crha)
+ * Bug 655625 - Crash in atk_state_set_contains_state (Milan Crha)
+ * Bug 656378 - Attachment name corruption (Punit Jain)
+ * Bug 656473 - Store server folder cache in user's cache directory
+ (Milan Crha)
+ * Bug 657170 - Disallow creating assigned tasks when not supported
+ (Milan Crha)
+ * Bug 657374 - mailto: attachment parameter can lead to accidental
+ data exfiltration (Vibha Yadav)
+ * Bug 658066 - Security dialog is too big (Dan Vrátil)
+ * Bug 658835 - Color Scheme off in calendar (Milan Crha)
+ * Bug 659440 - Doesn't mark messages as replied when sending offline
+ (Milan Crha)
+ * Bug 659486 - EAlert default response is ignored by EAlertDialog
+ (Matthew Barnes)
+ * Bug 659517 - Calendar reminds of old events following upgrade
+ (Milan Crha)
+ * Bug 659555 - Add custom icons in a folder Subscription dialog
+ (Milan Crha)
+ * Bug 659558 - Missing set mnemonic widgets (Milan Crha)
+ * Bug 659568 - One day delay in calendar view (Milan Crha)
+ * Bug 659726 - Search Folders contain ambiguous reference to accounts
+ (Matthew Barnes)
+ * Bug 659828 - Selecting a message with a sound attached loses focus
+ (Milan Crha)
+ * Bug 659874 - Address Cards Render extra Phone Number (Milan Crha)
+ * Bug 659876 - Make automatic contact address formatting optional
+ (Dan Vrátil)
+ * Bug 659932 - 'Use system time zone' in not honored immediately
+ (Milan Crha)
+ * Bug 660224 - Assertion failure when forwarding message (Milan Crha)
+ * Bug 660530 - Improve folder Subscription interface (Milan Crha)
+ * Bug 660584 - Fix crash when removing user certificate (Dan Vrátil)
+ * Bug 660721 - Online Account services not always activating
+ (Milan Crha)
+ * Bug 660738 - Font changes ignored since 3.2 (Milan Crha)
+ * Bug 660782 - [pst-import] Missing tasks after import (Milan Crha)
+ * Bug 660799 - Bad GOptionEntry in evolution-addressbook-export
+ (Matthew Barnes)
+ * Bug 660829 - Allow 'Mark as read' in right click menu on spam folder
+ (Milan Crha)
+ * Bug 660850 - Missing set mnemonic widgets in composer preferences
+ (Milan Crha)
+ * Bug 660861 - Avoid mark-all-read on a non-folder selection
+ (Milan Crha)
+ * Bug 660878 - Account configuration options are not auto-filled
+ (Dan Vrátil)
+ * Bug 661399 - Crash when hovering over calendar entry (Matthew Barnes)
+ * Bug 661404 - Adding multiple e-mails to contact list is too hard
+ (Milan Crha)
+ * Bug 661409 - Contact display drops address lines (Dan Vrátil)
+ * Bug 661434 - Unfriendly search result (Milan Crha)
+ * Bug 661534 - "Current View" tooltip untranslated (Matthew Barnes)
+ * Bug 661542 - Weird "Cannot upgrade from version 0.xxxx" on first use
+ (Vincent Untz)
+ * Bug 661549 - Avoid fetching from backend when calculating summary
+ (Milan Crha)
+ * Bug 661650 - "Certificate Authority Trust" strings miss mnemonics
+ (Matthew Barnes)
+
+Other Changes:
+ * User documentation improvements. (Andre Klapper)
+ * The EExtension framework is now in libebackend. (Matthew Barnes)
+ * Require GLib 2.30. (Matthew Barnes)
+ * ETableHeader: Rework the header button drawing code for GTK+ 3
+ (Cosimo Cecchi)
+ * Increase dependency on gtk+ to 3.2.0 (Milan Crha)
+ * GtkApplication has some new EShell-like features. (Matthew Barnes)
+ * EAttachmentPaned: Add "resize-toplevel" property. (Matthew Barnes)
+ * Remove EHintedEntry. (Matthew Barnes)
+ * Let GtkFileChooser track its own last-used-folder. (Matthew Barnes)
+ * Require libgdata >= 0.10. (Matthew Barnes)
+ * Fix invalid read on vCard drop (Milan Crha)
+
+Translations:
+ Gil Forcada (ca)
+ Carles Ferrando (ca@valencia)
+ Marek Černocký (cs)
+ Jiri Eischmann (cs)
+ Mario Blättermann (de)
+ Daniel Mustieles (es)
+ Jorge González (es)
+ Daniel Mustieles (es)
+ Inaki Larranaga Murgoitio (eu)
+ Seán de Búrca (ga)
+ Fran Dieguez (gl)
+ Gabor Kelemen (hu)
+ Shankar Prasad (kn)
+ Algimantas MargeviÄius (lt)
+ Kjartan Maraas (nb)
+ Manoj Kumar Giri (or)
+ Matej UrbanÄiÄ (sl)
+ Nguyá»…n Thái Ngá»c Duy (vi)
+ Chao-Hsiung Liao (zh_HK, zh_TW)
+
+
+Evolution 3.2.0 2011-09-26
+--------------------------
+
+Translations:
+ Abderrahim Kitouni (ar)
+ Marek Černocký (cs)
+ Mario Blättermann (de)
+ Jorge González (es)
+ Daniel Mustieles (es)
+ Fran Dieguez (gl)
+ Sweta Kothari (gu)
+ Rajesh Ranjan (hi)
+ Luca Ferretti (it)
+ Changwoo Ryu (ko)
+ Hannie Dumoleyn (nl)
+ A S Alam (pa)
+ Djavan Fagundes (pt_BR)
+ Matej UrbanÄiÄ (sl)
+ Muhammet Kara (tr)
+
+
+Evolution 3.1.92 2011-09-19
+---------------------------
+
+Bug Fixes:
+ Bug 659125 - Reference counting issues in calendar (Milan Crha)
+ Bug 655253 - Do not show detached instances twice in a calendar (Milan Crha)
+ Bug 635347 - Message lacks ID when submitted for sending (Matthew Barnes)
+ Bug 657611 - Hidden error of invalid attendee on send (Milan Crha)
+ Bug 658460 - alarm-notify issues runtime warning (Matthew Barnes)
+ Bug 657386 - Changing default source doesn't unmark previous one (Milan Crha)
+ Bug 655728 - Read proxy settings from GSettings since Gnome 3 (Milan Crha)
+ Bug 655564 - Express remembers settings of not finished account (Milan Crha)
+ Bug 655568 - Cursor lost after Collapse all threads called (Milan Crha)
+ Bug 655709 - Hide 'Group by' in views when not supported (Milan Crha)
+
+Miscellaneous Fixes:
+ Make sure GConf schemas have defined default values (Milan Crha)
+ User Docs: Fix order of sentences. (Andre Klapper)
+ User Docs: Hide 'Other Settings' if there is no content. Thanks to Michael Hill for pointing this out (Andre Klapper)
+ User Docs: Add TODOs as pointed out by Michael Hill (Andre Klapper)
+ Make maintiner mode enabled by default (Javier Jardón)
+ Added hu to DOC_LINGUAS (Gabor Kelemen)
+ User Docs: Update CSS/WebKit integration version statement (Andre Klapper)
+ User Docs: Add subsections to Receiving settings for better readability, use lists everywhere (Andre Klapper)
+ User Docs: Include Security and Default tab pages in new EWS account settings page (Andre Klapper)
+ User Docs: Add missing includes for Exchange account types (Andre Klapper)
+ User Docs: Add initial docu for EWS account setup. Thanks to Akhil Laddha for screenshots. (Andre Klapper)
+
+Translations:
+ Dr.T.Vasudevan (ta)
+ Fran Dieguez (gl)
+ Mario Blättermann (de)
+ Duarte Loreto (pt)
+ Jiro Matsuzawa (ja)
+ Bruce Cowan (en_GB)
+ A S Alam (pa)
+ Gabor Kelemen (hu)
+ Luca Ferretti (it)
+ Kenneth Nielsen (da)
+ Jorge González (es)
+ Piotr DrÄ…g (pl)
+ Mojca Ograjšek (sl)
+ dmustieles (es)
+ Matej UrbanÄiÄ (sl)
+ Rudolfs Mazurs (lv)
+ Andika Triwidada (id)
+ Hannie Dumoleyn (nl)
+ Alexander Shopov (bg)
+ Daniel Mustieles (es)
+
+Evolution 3.1.91 2011-09-05
+---------------------------
+
+Bug Fixes:
+ Bug 657765 - Explicitly link libgnomecanvas against libm
+ (Frederic Peters)
+ Bug 657836 - Work around g_unix_signal API changes. (Matthew Barnes)
+
+Other Changes:
+ * Various user documentation improvements. (Andre Klapper)
+ * Disable inline-image plugin by default. (Matthew Barnes)
+ * Create tar.xz files for 'make dist' only (Milan Crha)
+
+Translations:
+ Jorge González (es)
+ Daniel Mustieles (es)
+ Bruno Brouard (fr)
+ Andika Triwidada (id)
+ Daniel Nylander (sv)
+ Cheng-Chia Tseng (zh_HK)
+
+
+Evolution 3.1.90 2011-08-29
+---------------------------
+
+* New user documentation in Mallard format by Andre Klapper.
+
+Bug Fixes:
+ Bug 362366 - Dragging selected folder to message pane duplicates
+ messages (Milan Crha)
+ Bug 650839 - Add option for alarms into calendar preferences
+ (Milan Crha)
+ Bug 651633 - Hidden task/memo sidebar always automagically re-appears
+ (Milan Crha)
+ Bug 651741 - Find in text message doesn't warn about no matching found
+ (Milan Crha)
+ Bug 652092 - 'Mark messages as read' doesn't work with search folder
+ (Milan Crha)
+ Bug 652914 - IMAP: moving mail puts a copy into real Trash too
+ (Milan Crha)
+ Bug 655254 - Cropped Junk settings text (Milan Crha)
+ Bug 655419 - "Save as iCalendar" misses mnemonic (Milan Crha)
+ Bug 655490 - Location chooser dialog for Weather calendar is too small
+ (Milan Crha)
+ Bug 655549 - [mail-to-task] Ignores cancel of source select dialog
+ (Milan Crha)
+ Bug 655551 - [mail-to-task] Pick organizer based on selected folder's
+ store (Milan Crha)
+ Bug 655629 - "Path:" label for spool file should be "File:" label
+ (Milan Crha)
+ Bug 655666 - Split task preferences into its own tab (Milan Crha)
+ Bug 655708 - Unreadable tooltip for Memo/Task (Milan Crha)
+ Bug 655942 - Shows 'Storing folder...' when deleting a local folder
+ (Milan Crha)
+ Bug 656258 - Critical runtime warning on comp-editor close (Milan Crha)
+ Bug 656537 - Fix mallard relaxng validation errors in help pages
+ (Alexandre Rostovtsev)
+ Bug 656620 - Account editor doesn't update on settings change
+ (Milan Crha)
+ Bug 656622 - 'Check for supported types' fails again (Milan Crha)
+ Bug 656718 - Runtime warning in folder_tree_get_folder_info_cb()
+ (Matthew Barnes)
+ Bug 656720 - Exclude NNTP stores from Create Folder dialog
+ (Matthew Barnes)
+ Bug 656722 - Incorrect prototype of notify:: signal callback
+ (Milan Crha)
+ Bug 656723 - Forgets 'Use secure connection' setting during account
+ configuration (Milan Crha)
+ Bug 656733 - GUI no longer allows for non-default ports for email
+ (Milan Crha)
+ Bug 656810 - Too strict checking for validity of received calendars
+ (Milan Crha)
+ Bug 657310 - Crash when editing transport-only accounts (Milan Crha)
+ Bug 657396 - Rename Alarms tab to Reminders in preferences (Milan Crha)
+
+Other Changes:
+ * Adapt to new CamelSettings API. (Matthew Barnes)
+ * Adapt to new CamelSubscribable interface. (Matthew Barnes)
+ * Notify about all newly received messages since the last check
+ (Milan Crha)
+ * Using of uninitialized memory in
+ em-folder-tree-model.c:store_info_free (Milan Crha)
+ * Simplify em_config_target_new_account_update_settings().
+ (Matthew Barnes)
+ * Change license of Czech Help translation as per
+ https://mail.gnome.org/archives/gnome-cs-list/2011-August/msg00013.html
+ (Andre Klapper)
+ * Use new CamelService:display-name property. (Matthew Barnes)
+ * e_mail_store_foreach(): Take an EMailSession parameter.
+ (Matthew Barnes)
+ * Do not show IM icons, a workaround till bug #473862 is fixed
+ (Milan Crha)
+ * Update EMailBrowser actions when MessageList reloads. (Matthew Barnes)
+ * Invalidate region by one more pixel in width and height (Milan Crha)
+ * plugin-mono: Remove Camel.cs and Evolution.cs (Matthew Barnes)
+ * Cannot add folder to previously saved Search folder (Milan Crha)
+ * Add translator comment for screenshot in docs (Andre Klapper)
+ * Very slow filling of EMSubscriptionEditor tree view (Milan Crha)
+ * Changing source in CompEditor blocks UI (Milan Crha)
+ * [mail-to-task] Uses incorrect function to free array of message
+ uids (Milan Crha)
+ * Stick Account Editor widgets at the top, like it used to before gtk3
+ (Milan Crha)
+ * Fix enum generation problems in glib-gen.mak. (Matthew Barnes)
+
+Translations:
+ Christian Kirbach (de)
+ Jorge González (es)
+ Daniel Mustieles (es)
+ Fran Dieguez (gl)
+ Andika Triwidada (id)
+ OKANO Takayoshi (ja)
+ Kjartan Maraas (nb)
+ A S Alam (pa)
+ Yuri Myasoedov (ru)
+ МироÑлав Ðиколић (sr)
+ Daniel Nylander (sv)
+ Dr.T.Vasudevan (ta)
+
+
+Evolution 3.1.5 2011-08-14
+--------------------------
+
+Bug Fixes:
+ Bug 656290 - "Always carbon-copy (cc) to:" option not honored (Milan Crha)
+ Bug 656267 - Checking for auth types doesn't work properly (Milan Crha)
+ Bug 655957 - Current account / all accounts search changes column (Milan Crha)
+ Bug 645476 - Message list unnecessarily scrolls back to selected row (Milan Crha)
+ Bug 656133 - Mail-local not initialized when adding/editing account (Milan Crha)
+ Bug 655843 - Copy to calendar doesn't add timezone information (James Bottomley)
+ Bug 655944 - Import dialog is not showing operation progress (Milan Crha)
+ Bug 655492 - Move 'Automatic contacts' tab to 'Contacts' part (Milan Crha)
+ Bug 655494 - Move 'Calendar and Tasks' tab out of Mail Preferences (Milan Crha)
+ Bug 655872 - [pst-import] Fails to properly open remote client (Milan Crha)
+ Bug 655669 - Can't save inline pictures embedded in HTML Mails (Milan Crha)
+ Bug 656136 - Remove time field in task editor (Milan Crha)
+ Bug 656035. Add missing colon to string (Andre Klapper)
+ Bug 655943 - Meeting request mails are not imported properly (Milan Crha)
+ Bug 655870 - Uses incorrect pointer as string in error message (Milan Crha)
+ Bug 655702 - Do not call Lists Groups when they are Lists anywhere else (Andre Klapper)
+ Bug 655507 - Do not unload extensions, keep them preloaded (Milan Crha)
+ Bug 655507 - Crash on startup when initializing spamassassin (Matthew Barnes)
+ Bug 655893 - Crash on pst folder hierarchy import (Milan Crha)
+ Bug 646646 - Incomplete and folder-incorrect import of pst file (Milan Crha)
+ Bug 655190 - Sluggish performance interacting with calendar/tasks (Milan Crha)
+ Bug 635211 - Select-all processed on timeout when not needed (Milan Crha)
+ Bug 655444 - Alarm/reminder settings split in two tabs in Settings (Milan Crha)
+ Bug 655441 - Fix typo (Andre Klapper)
+ Bug 655430 - Forgotten EMailJunkOptions type init for mail-config.ui (Milan Crha)
+ Bug 655353 - Add translator comment (Andre Klapper)
+ Bug 655255 - Make comp-editor toolbar buttons' tooltips saner (Milan Crha)
+ Bug 654889 - Closes when clicking on year/month selector (Milan Crha)
+ Bug 654261 - Importing ics files into Evolution fails silently (Milan Crha)
+ Bug 340614 - Replace alarm by reminder for UI consistency. (Andre Klapper)
+
+Miscellaneous Fixes:
+ git.mk: Add support for mallard. (Matthew Barnes)
+ EConfig: Broadcast abort/commit events by way of signals. (Matthew Barnes)
+ Fix duplicated section ID (Andre Klapper)
+ Gtk-Doc updates. (Matthew Barnes)
+ EMAccountEditor: Simplify real junk/trash folder selection. (Matthew Barnes)
+ EMFolderSelectionButton: Add an "account" property. (Matthew Barnes)
+ EMFolderSelector: Add a "model" construct-only property. (Matthew Barnes)
+ Add em_folder_tree_new_with_model(). (Matthew Barnes)
+ EMFolderSelectionButton: Add a "folder-uri" property. (Matthew Barnes)
+ Bugfixes and corrections pointed out by Akhil Laddha (Andre Klapper)
+ Remove non-existing option as pointed out by Akhil Laddha (Andre Klapper)
+ Fix TODO now that the code is fixed (Andre Klapper)
+ EShell: Remove unused macro. (Matthew Barnes)
+ Cannot reply to message without preview panel enabled (Milan Crha)
+ Help->FAQ menu item and action are gone (Milan Crha)
+ Fix typos in new docs (Yuri Chornoivan)
+ EModule: Make all modules resident. (Matthew Barnes)
+ Remove link to FAQ as content is covered by new user docs (Andre Klapper)
+ Rename picture to new name (Andre Klapper)
+ Add the one reused translatable picture again (Andre Klapper)
+ Put new user documentation in place (Andre Klapper)
+ Remove outdated instructions for doc translators (Andre Klapper)
+ EMAccountEditor: Readability improvements. (Matthew Barnes)
+ Avoid crashes when moving between messages quickly (Milan Crha)
+ Do not leak memory on each mail folder change (Milan Crha)
+ Use the same term 'Secure connection' everywhere instead of SSL (Andre Klapper)
+ Use email instead of e-mail spelling, like anywhere else (Andre Klapper)
+ Replace user name by username as used anywhere else in Evolution (Andre Klapper)
+ Fix spelling of "Basic Headers" option to be consistent with the rest (Andre Klapper)
+ Drop the duplicated 'Format' from filetype descriptionsto also sync strings with the ones used in shell/e-shell-utils.c (Andre Klapper)
+ Forward button in Evolution Mail Configuration Assistant is actually called Continue (Andre Klapper)
+
+Translations:
+ Fran Dieguez (gl)
+ Christian Kirbach (de)
+ Chao-Hsiung Liao (zh_HK)
+ Jorge González (es)
+ Mario Blättermann (de)
+ Daniel Nylander (sv)
+ Aurimas ÄŒernius (lt)
+ Daniel Mustieles (es)
+
+Evolution 3.1.4 2011-07-25
+--------------------------
+
+Bug Fixes:
+ Bug 652629 - GnomeCanvas: Disregard synthesized crossing events
+ (Matthew Barnes)
+ Bug 652634 - Runtime warning on second search dialog (Matthew Barnes)
+ Bug 653568 - Forward as Redirect doesn't work (Matthew Barnes)
+ Bug 653699 - Improve mail notifications (Matthew Barnes)
+
+Other Changes:
+ * Adapt to CamelSession and e-passwords changes. (Matthew Barnes)
+ * Prefer g_seekable_seek() over camel_stream_reset(). (Matthew Barnes)
+ * Avoid camel_stream_printf(). (Matthew Barnes)
+ * EShellContent: Fix underallocation of EAlertBar. (Matthew Barnes)
+ * online-accounts: Give Google calendars a color. (Matthew Barnes)
+ * connman: Recover from dropped D-Bus connections faster.
+ (Matthew Barnes)
+ * network-manager: Recover from dropped D-Bus connections faster
+ (Matthew Barnes)
+ * network-manager: Keep network availablility state accurate.
+ (Matthew Barnes)
+ * Fix OpenBSD/FreeBSD support (Antoine Jacoutot)
+ * Add more categories to settings desktop file. (Antoine Jacoutot)
+ * Convert junk filtering EPlugins to EExtensions. (Matthew Barnes)
+ * Make "open_calendar" function as expected. (Chenthill Palanisamy)
+ * EMailBackend: Explicitly remove CamelServices during dispose.
+ (Matthew Barnes)
+ * error in mail notification (Punit Jain)
+
+Translations:
+ Marek Černocký (cs)
+ Jorge González (es)
+ Daniel Mustieles (es)
+ Tommi Vainikainen (fi)
+ Fran Dieguez (gl)
+ Gabor Kelemen (hu)
+ Shushi Kurose (ja)
+ Rudolfs Mazurs (lv)
+ Kjartan Maraas (nb)
+ Abduxukur Abdurixit (ug)
+
+
+Evolution 3.1.3 2011-07-04
+--------------------------
+
+Bug Fixes:
+ Bug 650671 - Service connect/disconnect not cancelled properly (Milan Crha)
+ Bug 499739 - "Flag for follow-up" should be easier to set (Milan Crha)
+ Bug 652958 - Evolution Account Assistant jumps steps (Matthew Barnes)
+ Bug 653247 - Don't show TIFF documents inline (Matthew Barnes)
+ Bug 653644 - Warning when adding plain address into a contact list (Dan Vrátil)
+ Bug 224687 - Various fixes in contact list editor (Dan Vrátil)
+ Bug 652627 - Invalid unref on a NULL pointer from query_cb (Milan Crha)
+ Bug 653618 - Sending email doesn't disconnect from a server (Milan Crha)
+ Bug 224687 - Create lists of lists (Dan Vrátil)
+ Bug 653358 - Do not duplicate google address book (Gustavo Noronha Silva)
+ Bug 653466 - Crash in efh_format_headers (Milan Crha)
+ Bug 653154 - Crash when constructing calendar view (Milan Crha)
+ Bug 637402 - No quoted mail when replying to html email (Milan Crha)
+ Bug 650278 - Tab doesn't exit port field (Milan Crha)
+ Bug 646442 - [mail-to-task] Edit event details before adding to calendar (Dan Vrátil)
+ Bug 653008 - Preference window for imap accounts is too large (Milan Crha)
+ Bug 648468 - Disconnect service after mail fetching is done (Milan Crha)
+ Bug 631954 - itip formatter makes synchronous calls to ecal (Milan Crha)
+ Bug 269413 - Search treats "4 weeks" and "1 month" as synonymous (Milan Crha)
+ Bug 650223 - Do not wait on evolution's exit when done with backup/restore (Milan Crha)
+ Bug 638307 - Error when sending mail after converting to maildir (Milan Crha)
+ Bug 652620 - Can use uninitialized memory in alarm-notification-dialog (Milan Crha)
+ Bug 652626 - Fix initial position of contact maps markers (Dan Vrátil)
+ Bug 252670 - Remember columns settings in Certificates tab (Dan Vrátil)
+ Bug 530335 - Allow Reply to selected address only (Rathin)
+
+Miscellaneous Fixes:
+ Autocompletion in contact list editor didn't work (Milan Crha)
+ online-accounts: Set GoaAccount ID in calendar and contact sources. (Matthew Barnes)
+ Add a bit more error checking and do not leak icalcomponent-s (Milan Crha)
+ Fix crash when adding account in express mode (Gustavo Noronha Silva)
+ Limit the size of tab labels to a reasonable size (Gustavo Noronha Silva)
+ Check for cancelled GIO operation error code too (Milan Crha)
+ Keep opening EClient-s till they report busy error (Milan Crha)
+ Prototype an online-accounts module. (Matthew Barnes)
+ Postpone ENameSelector loading as much as possible (Milan Crha)
+ [itip-formatter] stock_animation is gone, use GtkSpinner instead (Milan Crha)
+ Add "Open With Other Application" to attachment menu. (Matthew Barnes)
+ Allow the startup-wizard to be delayed. (Matthew Barnes)
+ Could not select real Junk/Trash folder (Milan Crha)
+ Fix typo in a GConf key for alarm-notification dialog timezone setting (Milan Crha)
+ Fix few memory leaks (Milan Crha)
+
+Translations:
+ Kristjan SCHMIDT (eo)
+ Kjartan Maraas (nn)
+ МироÑлав Ðиколић (sr)
+ Jorge González (es)
+ Mario Blättermann (de)
+ Matej UrbanÄiÄ (sl)
+ Fran Diéguez (gl)
+ Daniel Mustieles (es)
+ Marek Černocký (cs)
+
+
+Evolution 3.1.2 2011-06-13
+--------------------------
+
+Bug Fixes:
+ Bug 229244 - Re-ordering email addresses in contact list editor
+ (Dan Vrátil)
+ Bug 243938 - Clicking on week numbers changes work week to week view
+ (Milan Crha)
+ Bug 332907 - Contact editor duplication alert misleading (Dan Vrátil)
+ Bug 537691 - Account editor window HIG (Matthew Barnes)
+ Bug 578245 - View settings for threads getting lost (Milan Crha)
+ Bug 601541 - Add 'Copy Image' Option On Inline Email Images (Milan Crha)
+ Bug 608203 - Left pane of mailer window is narrow at startup
+ (Milan Crha)
+ Bug 614274 - Labeling many messages is very slow (Matt McCutchen)
+ Bug 619347 - Decode QP in email in Contact List Editor (Milan Crha)
+ Bug 633948 - Try harder to use -lresolv in LDAP_LIBS
+ (Mathieu Trudel-Lapierre)
+ Bug 636809 - Address labels formatting improvements (Dan Vrátil)
+ Bug 640083 - Cannot configure LDAPS on port 636 (Milan Crha)
+ Bug 642557 - Display maps in contact preview (Dan Vrátil)
+ Bug 643526 - Crash in et_get_n_children (Milan Crha)
+ Bug 643819 - Autocomplete the Location field (Dan Vrátil)
+ Bug 645476 - Avoid scroll to cursor on folder change in message list
+ (Milan Crha)
+ Bug 646033 - Update progress in Send/Receive dialog (Milan Crha)
+ Bug 646109 - Fix use of include <config.h> to make sure translations
+ work (Milan Crha)
+ Bug 646615 - Bad single form (Milan Crha)
+ Bug 647785 - Pasting an 24h event in month and week view doesn't work
+ (Milan Crha)
+ Bug 648612 - Crash during drag & drop of recurring events (Punit Jain)
+ Bug 649310 - Calendar only shows midnight to noon (Milan Crha)
+ Bug 649392 - Improve calendar's "Goto" dialog and move it to dialogs
+ (Dan Vrátil)
+ Bug 649757 - 'Local delivery' accounts stopped working (Milan Crha)
+ Bug 649939 - Cann't create new folder (Milan Crha)
+ Bug 649939 - Cann't create new folder (Milan Crha)
+ Bug 649939 - Cann't create new folder (second shot) (Milan Crha)
+ Bug 649952 - Do not unref result of camel_session_get_service()
+ (Milan Crha)
+ Bug 649990 - Remove get_font_options() from e-util.c. (Matthew Barnes)
+ Bug 649993 - Change behavior of --component option (Matthew Barnes)
+ Bug 650088 - Cannot send message from Contacts view (Matthew Barnes)
+ Bug 650223 - evolution-backup does not terminate without --gui
+ (Matthew Barnes)
+ Bug 650491 - Shell handles forwarding uris to existing process wrong
+ (Matthew Barnes)
+ Bug 650522 - em-format-html: Fix uninitialized variable (Colin Walters)
+ Bug 650524 - Use g_unix_signal_add_watch_full() for SIGTERM
+ (Colin Walters)
+ Bug 650525 - Don't install a SEGV handler (Colin Walters)
+ Bug 650587 - Hide Search Folder actions when Search Folders are
+ disabled (Matthew Barnes)
+ Bug 651001 - Cannot send message from accounts not having a provider
+ (Lucian Langa)
+ Bug 651039 - Always update signature in composer on account change
+ (Milan Crha)
+ Bug 651062 - refresh_folders_exec() reports progress incorrectly.
+ (Matthew Barnes)
+ Bug 651135 - Crash using saved search with an empty expression
+ (Milan Crha)
+ Bug 651316 - Crash with Outgoing mail filters (Milan Crha)
+ Bug 651684 - Creates a copy of message in Outbox instead of replacing
+ (Milan Crha)
+ Bug 651761 - Message window doesn't mark message seen (Milan Crha)
+ Bug 651976 - Reply/Forward setting isn't respected in message window
+ (Milan Crha)
+
+Other Changes:
+ * Simplified the format of folder URIs and refactored the
+ evolution-mail library to use CamelFolder objects as much as
+ possible instead of folder URIs.
+ * Chip away at the legacy message passing infrastructure for
+ mail operations. Prefer GIO-style async ops using EActivity.
+ * Cannot send message with just enabled account (Milan Crha)
+ * Remove unused e_get_gnome2_user_dir(). (Matthew Barnes)
+ * Add EPortEntry to the Glade catalog. (Matthew Barnes)
+ * EMailReader: Support multiple action groups. (Matthew Barnes)
+ * EMailReader: Remove the forward/reply style hack. (Matthew Barnes)
+ * Handle SIGTERM instead of SIGQUIT. (Matthew Barnes)
+ * Fix crash when opening message window. (Matthew Barnes)
+ * Remove emfu_create_folder_real(). (Matthew Barnes)
+ * Updated the help license from GFDL 1.2 to GFDL 1.3 and
+ CC-BY-SA 3.0 (Chenthill Palanisamy)
+ * Replace deprecated g_atomic_int_exchange_and_add() (Milan Crha)
+ * Move EPopupMenu to /widgets/table. (Matthew Barnes)
+ * Embed e_hsv_tweak() directly in e-table-item.c. (Matthew Barnes)
+ * Do not add 'Local delivery' accounts into folder tree (Milan Crha)
+ * Replace G_CONST_RETURN with 'const'. (Matthew Barnes)
+
+Translations:
+ Alexander Shopov (bg)
+ Carles Ferrando (ca@valencia)
+ Marek Černocký (cs)
+ Jorge González (es)
+ Daniel Mustieles (es)
+ Seán de Búrca (ga)
+ Fran Diéguez (gl)
+ Kjartan Maraas (nb)
+ Yuri Kozlov (ru)
+ Matej UrbanÄiÄ (sl)
+ МироÑлав Ðиколић (sr)
+ Abduxukur Abdurixit (ug)
+
+
+Evolution 3.1.1 2011-05-09
+--------------------------
+
+Bug Fixes:
+ Bug 303653 - Make headers collapsable in preview pane (Dan Vrátil)
+ Bug 303862 - Cannot scroll message after clicking image attachment
+ button (Dan Vrátil)
+ Bug 332497 - Add Edit -> Available Categories (Dan Vrátil)
+ Bug 418954 - Add a separate entry combo for port numbers (Dan Vráti)
+ Bug 502188 - Store 'Remember password' for calendars (Milan Crha)
+ Bug 547954 - Clarify delete-from-search-folder warning (Dan Vrátil)
+ Bug 588891 - Spam settings dialog terribly un-higgy (Dan Vrátil)
+ Bug 597082 - Crash while migrating folder info (Matthew Barnes)
+ Bug 619782 - Characters override in contact editor express mode
+ (Matthew Barnes)
+ Bug 627952 - 'Local delivery' mbox's aren't read properly (Milan Crha)
+ Bug 641154 - Crash in emae_check_authtype_done (Milan Crha)
+ Bug 641845 - Add default expansion variables to templates plugin
+ (Dan Vrátil)
+ Bug 644310 - Rework "Set as Background" image option (Matthew Barnes)
+ Bug 645545 - Attachment reminder dialog uses wrong expand
+ (Matthew Barnes)
+ Bug 645551 - Mailer statusbar jumping in size (Matthew Barnes)
+ Bug 645610 - Editing contact doesn't refresh view (Milan Crha)
+ Bug 645721 - Fix build error when enabling kerberos without specifying
+ path (Niki Guldbrand)
+ Bug 645825 - Search bar not changing color when showing results
+ (Dan Vrátil)
+ Bug 646197 - Crash with VALARM without ACTION property (Milan Crha)
+ Bug 646200 - Insufficient requirement on libsoup (Matthew Barnes)
+ Bug 646384 - Updated App Icon (Matthew Barnes)
+ Bug 646817 - Hide View->Preview menu in express mode (Matthew Barnes)
+ Bug 647116 - Crash in g_error_matches,
+ e_contact_editor_contact_modified (Milan Crha)
+ Bug 647429 - Hide port-entry for providers without port (Dan Vrátil)
+ Bug 647698 - Selected calendar doesnt authenticate after offline/online
+ (Matthew Barnes)
+ Bug 647708 - e_plugin_xml_prop() can return libxml2 allocated memory
+ (Matthew Barnes)
+ Bug 647816 - Moving folder hierarchy causes error (David Woodhouse)
+ Bug 648308 - Do not display full folder URI in "Opening folder"
+ activity (Dan Vrátil)
+ Bug 648317 - MeeGo shell looking for the wrong atom (Abner Silva)
+ Bug 648346 - Add style class to message browser toolbar
+ (Matthew Barnes)
+ Bug 648756 - Custom imap port forgotten (Dan Vrátil)
+ Bug 649046 - crash on startup with latest CamelURL modifications
+ (Lucian Langa)
+ Bug 649365 - Creation of new repository evolution-groupwise
+ (Vibha Yadav)
+ Bug 649381 - Memory leaks in contact editor (Dan Vrátil)
+
+Other Changes:
+ * Remove unique-3.0 dependency from configure.ac. (Matthew Barnes)
+ * Port EShell to GtkApplication. (Matthew Barnes)
+ * Port AlarmNotify to GtkApplication. (Matthew Barnes)
+ * evolution-settings doesn't really need to be unique. (Matthew Barnes)
+ * Fix alignment of extra widgets in EAlertDialogs. (Matthew Barnes)
+ * Fix an EShell reference leak. (Matthew Barnes)
+ * Change the accelerator map file location. (Matthew Barnes)
+ * Reduce EAlertBar height. (Matthew Barnes)
+ * EAlertBar: Make warnings time out after 5 minutes (Matthew Barnes)
+ * Change "mail:async-error" alerts to warnings. (Matthew Barnes)
+ * Restore lockdown integration. (Matthew Barnes)
+ * Rip out Anjal-specific cruft we don't need. (Matthew Barnes)
+ * Remove the profiler plugin. (Matthew Barnes)
+ * Remove no longer existing files from POTFILES.in (Wouter Bolsterlee)
+ * Don't crash on missing EAlert definitions. (Matthew Barnes)
+ * EWebView: Implement the EAlertSink interface (Matthew Barnes)
+ * EWebView: Fix icon retrieval when showing EAlerts. (Matthew Barnes)
+ * Demonstrate EWebView as an EAlertSink. (Matthew Barnes)
+ * Don't try to refresh or sync mail folders when offline.
+ (Matthew Barnes)
+ * Kill em_composer_prefs_new_signature(). (Matthew Barnes)
+ * Adapt to sealed up CamelService. (Matthew Barnes)
+ * evolution-alarm-notify: replace Moblin by Meego (Alban Crequy)
+ * Adapt to CamelService changes. (Matthew Barnes)
+ * Do not require unique-3.0 in .pc files (Milan Crha)
+ * e_mail_local_init(): Improve error handling. (Matthew Barnes)
+ * Adapt to new CamelSession background job API. (Matthew Barnes)
+ * Bump gladeui-2.0 minimum version to 3.10.0. (Matthew Barnes)
+ * EMailBackend: Ignore cancelled background jobs. (Matthew Barnes)
+ * Some modules missing CFLAGS/LIBS for EShell. (Matthew Barnes)
+ * Remove redundant EAccountList utilities. (Matthew Barnes)
+ * Add e_meeting_store_find_self(). (Matthew Barnes)
+ * Add itip_address_is_user(). (Matthew Barnes)
+ * Refactor CompEditor pages to isolate EAccount usage. (Matthew Barnes)
+ * Add itip_get_user_identities(). (Matthew Barnes)
+ * Fix a memory leak (Milan Crha)
+ * Add itip_get_fallback_identity(). (Matthew Barnes)
+ * Make EAlertBar messages selectable (Milan Crha)
+ * Adapt to extra arg in camel_session_get_service_by_url().
+ (Matthew Barnes)
+ * EMFolderSelectionButton: Remove unused multiselect functions.
+ (Matthew Barnes)
+ * groupwise-features: Fix a compiler warning. (Matthew Barnes)
+ * MailFolderCache: Remove 'folders_uri' hash table (Matthew Barnes)
+ * e_get_account_by_uid(): Also handle CamelTransport UIDs.
+ (Matthew Barnes)
+ * EMEventTargetFolder: Add an EAccount member. (Matthew Barnes)
+ * EMConfigTargetAccount: Add original_account member. (Matthew Barnes)
+ * Simplify mail_session_get_password(). (Matthew Barnes)
+ * Remove e_get_account_by_transport_url(). (Matthew Barnes)
+ * EMailSession: Fix popb4smtp authentication. (Matthew Barnes)
+ * Add em_folder_tree_get_selected_account(). (Matthew Barnes)
+ * EMailShellView: Open the selected folder ourselves. (Matthew Barnes)
+ * Remove e_mail_reader_set_folder_uri(). (Matthew Barnes)
+ * Drop 'folder_uri' param from message_list_set_folder().
+ (Matthew Barnes)
+ * Add some handy folder URI utility functions. (Matthew Barnes)
+ * Replace camel_store_folder_uri_equal() with
+ e_mail_folder_uri_equal(). (Matthew Barnes)
+ * em-utils.c: Simplify guess_account_from_folder(). (Matthew Barnes)
+ * Drop 'folder_uri' param from em_utils_folder_is_drafts().
+ (Matthew Barnes)
+ * Drop 'folder_uri' param from em_utils_folder_is_templates().
+ (Matthew Barnes)
+ * Drop 'folder_uri' param from em_utils_folder_is_sent().
+ (Matthew Barnes)
+ * Drop 'folder_uri' param from em_utils_folder_is_outbox().
+ (Matthew Barnes)
+ * Change em_folder_tree_model_user_marked_unread() params.
+ (Matthew Barnes)
+ * Remove 'from_uri' params from e-msg-composer-utils.c.
+ (Matthew Barnes)
+ * Build vfolder rules with CamelFolders instead of folder URIs.
+ (Matthew Barnes)
+ * Remove e_mail_reader_get_folder_uri(). (Matthew Barnes)
+ * Drop 'folder_uri' member from MessageList. (Matthew Barnes)
+ * groupwise-features: Avoid e_get_account_by_source_url().
+ (Matthew Barnes)
+ * MessageList: Simplify the "Location" column. (Matthew Barnes)
+ * EMFolderSelectionButton: Avoid e_get_account_by_source_url().
+ (Matthew Barnes)
+ * Remove EMFolderTreeModel::folder-added signal. (Matthew Barnes)
+ * Use e_mail_folder_uri_from_folder() instead of
+ camel_folder_get_uri(). (Matthew Barnes)
+ * Simplify em_folder_tree_set_selected_list(). (Matthew Barnes)
+ * Teach e_mail_folder_uri_parse() to parse 'email://' URIs.
+ (Matthew Barnes)
+ * Simplify e_mail_session_uri_to_folder_sync(). (Matthew Barnes)
+ * Drop support for command-line 'email://' URIs. (Matthew Barnes)
+ * Simplify emae_account_folder(). (Matthew Barnes)
+ * Simplify em_utils_folder_is_templates(). (Matthew Barnes)
+ * Simplify em_utils_folder_is_drafts(). (Matthew Barnes)
+ * Simplify em_utils_folder_is_sent(). (Matthew Barnes)
+ * Simplify em_folder_tree_model_set_folder_info(). (Matthew Barnes)
+ * EMFolderTreeModel: Always populate the CamelStore column.
+ (Matthew Barnes)
+ * EMFolderTreeModel: Avoid e_get_account_by_source_url().
+ (Matthew Barnes)
+ * EMAccountEditor: Fix a runtime warning. (Matthew Barnes)
+ * Introduce a new, simpler folder URI format. (Matthew Barnes)
+ * EMFolderTreeModel: Use the new folder URI format. (Matthew Barnes)
+ * EMFilterFolderElement: Use the new folder URI format. (Matthew Barnes)
+ * EMVFolderRule: Use the new folder URI format. (Matthew Barnes)
+ * e_mail_local_init(): Use the new folder URI format. (Matthew Barnes)
+ * Simplify e_mail_session_unsubscribe_folder_sync(). (Matthew Barnes)
+ * Simplify em_vfolder_rule_from_message(). (Matthew Barnes)
+ * Simplify em_vfolder_rule_from_address(). (Matthew Barnes)
+ * Simplify vfolder_adduri_desc(). (Matthew Barnes)
+ * MailFolderCache: Emit folder names instead of URIs in signals.
+ (Matthew Barnes)
+ * mail-config.c: Don't try to rename obsolete config files.
+ (Matthew Barnes)
+ * Remove em_uri_from_camel() and em_uri_to_camel(). (Matthew Barnes)
+ * fetch_mail_exec(): Remove hack for local Inbox. (Matthew Barnes)
+ * Remove uid_cachename_hack(). (Matthew Barnes)
+ * Adapt to X-Evolution-Source headers storing UIDs. (Matthew Barnes)
+ * Remove e_get_account_by_source_url(). (Matthew Barnes)
+ * em_folder_utils_copy_folder(): Change function parameter.
+ (Matthew Barnes)
+ * em_folder_utils_create_folder(): Change function parameters.
+ (Matthew Barnes)
+ * Remove em_folder_tree_get_selected_folder_info(). (Matthew Barnes)
+ * MailFolderCache: Drop folder URI in "folder-changed" signal.
+ (Matthew Barnes)
+ * mail-send-recv.c:get_folders(): Adapt to CamelVeeStore change.
+ (Matthew Barnes)
+ * Adapt to CamelFolderInfo.name -> display_name. (Matthew Barnes)
+ * Adapt to CamelFolder:name -> display-name. (Matthew Barnes)
+
+Translations:
+ Abderrahim Kitouni (ar)
+ Krasimir Chonov (bg)
+ Alexander Shopov (bg)
+ David Planella (ca)
+ Jordi Serratosa (ca)
+ Jiří Eischmann (cs)
+ Kenneth Nielsen (da)
+ Christian Kirbach (de)
+ Daniel Mustieles (es)
+ Ivar Smolin (et)
+ Inaki Larranaga Murgoitio (eu)
+ Fran Diéguez (gl)
+ Gabor Kelemen (hu)
+ Luca Ferretti (it)
+ Takayuki KUSANO (ja)
+ Takayoshi OKANO (ja)
+ Shankar Prasad (kn)
+ Žygimantas BeruÄka (lt)
+ Kjartan Maraas (nb)
+ Wouter Bolsterlee (nl)
+ Hannie Dumoleyn (nl)
+ Djavan Fagundes (pt_BR)
+ Yuri Myasoedov (ru)
+ Daniel Nylander (sv)
+ Dr.T.Vasudevan (ta)
+ Abduxukur Abdurixit (ug)
+ Daniel Korostil (uk)
+ Aron Xu (zh_CN)
+ Chao-Hsiung Liao (zh_HK)
+
+
+Evolution 3.0.0 2011-04-04
+--------------------------
+
+Bug Fixes:
+ Bug 646200 - Insufficient requirement on libsoup (Matthew Barnes)
+ Bug 646384 - Updated App Icon (Matthew Barnes)
+ Bug 645551 - Mailer statusbar jumping in size (Matthew Barnes)
+
+Other Changes:
+ * Fix translations being broken by removing calls to bindtextdomain()
+ from plugins. It shouldn't be needed for plugins that live in
+ the evolution source tree anyway since they should just use the
+ translation domain they inherit from main(). (Kjartan Maraas)
+
+Translations:
+ Khaled Hosny, Abderrahim Kitouni (ar)
+ David Planella, Jordi Serratosa (ca)
+ Jiří Eischmann (cs)
+ Kenneth Nielsen (da)
+ Wolfgang Stöggl (de)
+ Inaki Larranaga Murgoitio (eu)
+ Bruno Brouard (fr)
+ Rajesh Ranjan (hi)
+ Gabor Kelemen (hu)
+ Luca Ferretti (it)
+ Takayuki KUSANO (ja)
+ Shankar Prasad (kn)
+ Žygimantas BeruÄka (lt)
+ Sandeep Shedmake (mr)
+ Wouter Bolsterlee, Hannie Dumoleyn (nl)
+ Djavan Fagundes (pt_BR)
+ Daniel Nylander (sv)
+ Dr.T.Vasudevan (ta)
+ Daniel Korostil (uk)
+ Aron Xu (zh_CN)
+ Chao-Hsiung Liao (zh_HK)
+
+
+Evolution 2.91.92 2011-03-21
+----------------------------
+
+Bug Fixes:
+ Bug 223838 - Do not share global Sent folder view with regular folders
+ (Milan Crha)
+ Bug 586461 - Remove signature also from HTML formatted emails on reply
+ (Milan Crha)
+ Bug 615204 - Adding AOL mail account as IMAP results in POP account
+ (Milan Crha)
+ Bug 618440 - "Reply" does not always strip signatures (Milan Crha)
+ Bug 637641 - Crash on audio alarms with invalid file URI set
+ (Milan Crha)
+ Bug 641939 - Doesn't read online state on start (Milan Crha)
+ Bug 643507 - Font preferences don't work (Matthew Barnes)
+ Bug 644053 - Fix packing in "Network Preferences" (Matthew Barnes)
+ Bug 644066 - Text selection is cleared when right-clicking on a link
+ (Matthew Barnes)
+ Bug 644107 - Local addressbooks created without relative_uri set
+ (Milan Crha)
+ Bug 644164 - Using outdated Connman D-Bus names (Hao H Li)
+ Bug 644166 - Add style class to primary toolbars (Matthew Barnes)
+ Bug 644194 - EAddressbookModel: Logic error in remove_contact
+ (Jari Urpalainen)
+ Bug 644232 - Support NetworkManager 0.9 (Dan Williams)
+ Bug 644235 - Make EActivityProxy a GtkFrame (Cosimo Cecchi)
+ Bug 644301 - Invalid GVariant format in NetworkManager module
+ (Milan Crha)
+ Bug 644792 - Crash when sending D-Bus message (Milan Crha)
+
+Miscellaneous Fixes:
+ * Typo in comment: s/datefime-formats/datetime-formats/ (Paul Menzel)
+ * Do not prompt for offline when mail backend not started (Milan Crha)
+ * Use message subject for attachment description if no filename
+ provided (Milan Crha)
+ * Minor glitches in Account Editor (Milan Crha)
+ * Fix build break after recent eds changes (Milan Crha)
+ * Fix few invalid reads caused by ECanvas (Milan Crha)
+ * Save account list when changing account (Milan Crha)
+ * Select IMAP+ by default in new account setup (Matthew Barnes)
+
+Translations:
+ Mario Blättermann (de)
+ Bruce Cowan (en_GB)
+ Ivar Smolin (et)
+ Bruno Brouard (fr)
+ Fran Diéguez (gl)
+ Gabor Kelemen (hu)
+ Luca Ferretti (it)
+ Changwoo Ryu (ko)
+ Rudolfs Mazurs (lv)
+ Manoj Kumar Giri (or)
+ Piotr DrÄ…g (pl)
+ Duarte Loreto (pt)
+ Lucian Adrian Grijincu (ro)
+ Yuri Myasoedov (ru)
+ Andrej ŽnidarÅ¡iÄ (sl)
+ Daniel Nylander (sv)
+ Daniel Korostil (uk)
+
+
+Evolution 2.91.91 2011-03-07
+----------------------------
+
+Bug Fixes:
+ Bug 434972 - Reply does not detect "RE :" subject prefix (Milan Crha)
+ Bug 550867 - Showing location in meetings (Milan Crha)
+ Bug 608804 - Some attachments make evolution crash in libical
+ (Milan Crha)
+ Bug 614480 - Avoid using G_TYPE_INSTANCE_GET_PRIVATE repeatedly
+ (Milan Crha)
+ Bug 623593 - Cannot drag&drop attached messages from mails (Milan Crha)
+ Bug 635002 - Fix invalid use of .la file in contact-editor
+ (Pacho Ramos)
+ Bug 637091 - Crash in g_str_hash, task_shell_sidebar_client_removed
+ (Matthew Barnes)
+ Bug 640829 - Can drop text/plain message lines in message preview
+ (Milan Crha)
+ Bug 641343 - Cannot scroll to bottom of folder list while dragging
+ (Milan Crha)
+ Bug 641374 - "Send new mail to..." popup action doesn't work
+ (Milan Crha)
+ Bug 641456 - Crash in pst_process_appointment at pst-importer.c
+ (Milan Crha)
+ Bug 641805 - Clicking links in mail composer opens URL twice
+ (Milan Crha)
+ Bug 642093 - Frees message attachment content on Reply (Milan Crha)
+ Bug 642447 - Invalid reads while disabling groupwise account
+ (Milan Crha)
+ Bug 642954 - Doesn't commit/abort sequence on modification error
+ (Milan Crha)
+ Bug 643218 - Local delivery doesn't deliver after maildir migration
+ (Milan Crha)
+ Bug 643297 - multipart/related formatter skips the last part
+ (Milan Crha)
+ Bug 643402 - Fails to build with --disable-smime (Milan Crha)
+ Bug 643635 - Typo in the code from commit for bug #434972 (Milan Crha)
+ Bug 643693 - Crash opening attached text/html mail (Milan Crha)
+
+Other Changes:
+ * Write state.ini immediately in EShellView::dispose method
+ (Milan Crha)
+ * Use G_SIGNAL_TYPE_STATIC_SCOPE for all GdkEvent signal params.
+ (Matthew Barnes)
+ * Fix incorrect use of ngettext from a patch for bug #635414
+ (Milan Crha)
+ * Slightly smaller dialogs for Reply type questions (but not all)
+ (Milan Crha)
+ * Let Esc behave like Cancel in Reply questions and do not leak
+ message (Milan Crha)
+ * Do not leak attachments in a mail view (Milan Crha)
+ * Merge duplicate local sources (Milan Crha)
+ * Do not flush Outbox when mail shell backend not started (Milan Crha)
+ * Construct attachment bars for correct message part ids (Milan Crha)
+ * Bump BASE_VERSION to 3.0. (Matthew Barnes)
+
+Translations:
+ Daniel Mustieles (es)
+ Mattias Põldaru (et)
+ Bruno Brouard (fr)
+ Rudolfs Mazurs (lv)
+ Kjartan Maraas (nb)
+ Nguyá»…n Thái Ngá»c Duy (vi)
+ Wei Li (zh_CN)
+ Chao-Hsiung Liao (zh_HK)
+
+
+Evolution 2.91.90 2011-02-21
+----------------------------
+
+Bug Fixes:
+ Bug 639483 - Category list includes weather information (Milan Crha)
+ Bug 639043 - Alarm notify snooze time not properly adjustable (Chris Hemsing)
+ Bug 642121 - Won't build with --with-clutter due missing include (Dan Vrátil)
+ Bug 642566 - Picture Gallery, not Image Gallery (Matthew Barnes)
+ Bug 638307 - Error when sending mail after converting to maildir (Milan Crha)
+ Bug 642088 - Crash when changing advanced send options in GroupWise (Milan Crha)
+ Bug 638478 - During sending fails to parse X-Evolution-PostTo field (Milan Crha)
+ Bug 638391 - Always passing NULL to emu_addr_cancel_book() (Milan Crha)
+ Bug 638333 - Critical warning when invoking File->New->Mail Folder (Milan Crha)
+ Bug 640802 - [express] Message preview automatically switches to vertical view (Milan Crha)
+ Bug 255973 - Contact preview waste space and cosmetic correction (Dan Vrátil)
+ Bug 642171 - Implicit libgnome dependency for lockdown GConf keys (Matthew Barnes)
+ Bug 638057 - Evolution --express doesn't remember status bar setting (Milan Crha)
+ Bug 637924 - Shows duplicate sentence while click "Back-Sending" button (Gary Lin)
+ Bug 637923 - Wrap long text in Yahoo email setup (Frederic Crozat)
+ Bug 637727 - Sent/Draft folder not set in startup-wizard account (Milan Crha)
+ Bug 637493 - Fails to build with --enable-profiling configure option (Milan Crha)
+ Bug 636408 - Loss of data on removal of an IMAP folder with an asterisk (Milan Crha)
+ Bug 641502 - Flickering while resizing the mail list (Milan Crha)
+ Bug 641701 - Issues with pst-import plugin (Milan Crha)
+ Bug 641756 - Fix warnings from GCC 4.6 (Kjartan Maraas)
+ Bug 634571 - Check for 'mono-2' rather than 'mono' package (Milan Crha)
+ Bug 641451 - Crash in folder_selection_button_new (Bharath Acharya)
+ Bug 641011 - Ugly appointment editing windows (Milan Crha)
+ Bug 222423 - Support Face headers (Dan Vrátil)
+ Bug 640801 - Workaround gtk3 bug (Milan Crha)
+ Bug 635144 - Using external editor duplicates signature (Milan Crha)
+
+Miscellaneous Fixes:
+ Order matters, process master object first, then detached instances (Milan Crha)
+ Slightly nicer EAlertDialog after move to gtk3 (Milan Crha)
+ Require libsoup-gnome-2.4 instead of libsoup-2.4. (Matthew Barnes)
+ Remove NULL checks for GObject methods. (Matthew Barnes)
+ Bump GTK+ requirement to 3.0. (Matthew Barnes)
+ Do not perform the summary consistency check on local folders, 'On this Computer' (Chenthill Palanisamy)
+ Composer: Add Edit -> Preferences (Matthew Barnes)
+ Fix cairo-gobject.h include path (Milan Crha)
+ Fix image dropping in composer while in HTML mode. (Matthew Barnes)
+
+Translations:
+ Changwoo Ryu (ko)
+ Daniel Mustieles (es)
+ Ivar Smolin (et)
+ Petr Kovar (cs)
+ Jorge González (es)
+ Fran Diéguez (gl)
+ Xandru Armesto (ast)
+ Mario Blättermann (de)
+ Kjartan Maraas (nn)
+ Sweta Kothari ()
+
+Evolution 2.91.6 2011-01-11
+---------------------------
+
+Bug Fixes:
+ Bug 640760 - New mail "stuck" if missing attachment dialog cancelled (Matthew Barnes)
+ Bug 640707 - Crash on 'Add to address book'->'Edit full' click (Milan Crha)
+ Bug 640706 - Can't edit filter/advance search condition (Milan Crha)
+ Bug 640704 - Replace GtkWindow::allow_shrink/grow with resizable (Milan Crha)
+ Bug 640536 - Warnings when adding a google account in express mode (Milan Crha)
+ Bug 640526 - Default column width in address card view is small (Matthew Barnes)
+ Bug 640522 - Set minimal height on Description fields in event editors (Milan Crha)
+ Bug 640516 - Information bar above folder list is empty (Milan Crha)
+ Bug 640517 - Runtime warnings when launching composer (Milan Crha)
+ Bug 640083 - Cannot configure LDAPS on port 636 (Matthew Barnes)
+ Bug 640025 - Silence debug output in spamassassin plugin (Matthew Barnes)
+ Bug 640091 - Improve error handling during send post-processing (Matthew Barnes)
+ Bug 634403 - Mails Label popup menu is not updated properly (Milan Crha)
+ Bug 604534 - Evolution "ignores" key-usage info in certificates (Milan Crha)
+ Bug 633982 - Crash when trying to Create a search folder from a search (Milan Crha)
+ Bug 633788 - Mail plugin's update-actions handler is never called (Milan Crha)
+ Bug 553438 - Deletes lines of a reply when changing address (Milan Crha)
+ Bug 600013 - Crash in mail_reader_message_loaded_cb (Milan Crha)
+ Bug 634305 - Crash on move of contacts between books (Milan Crha)
+ Bug 638087 - Crash at merging duplicate contact (Vibha Yadav)
+ Bug 638808 - camel_shutdown() called too early (Milan Crha)
+ Bug 593020 - Do not check Bcc in "Sender or Recipients" condition (Milan Crha)
+
+Miscellaneous Fixes:
+ libchamplain-0.8 exists now. (Matthew Barnes)
+ gladeui is 2.0 now (Milan Crha)
+ Require the latest gtk+-3.0 release until 3.0. (Matthew Barnes)
+ No more "expose-event" on GtkWidget (Milan Crha)
+ Most (but not all) packing issues from Mail preferences (Milan Crha)
+ Do not oversize New and Send/Receive toolbar buttons (Milan Crha)
+ Adapt size_request vfuncs to latest gtk+-3.0 API. (Rodrigo Moya)
+ Adapt smclient to latest gtk+-3.0 API. (Kjartan Maraas)
+ Adapt gdk_window_get_geometry for gtk+-3.0 (Vibha Yadav)
+ Adapt to GtkComboBox class reorg. (Matthew Barnes)
+ Avoid using deprecated GTK_SELECTION_EXTENDED (Vibha Yadav)
+ Use latest gnome-desktop API (Rodrigo Moya)
+ gdk_cursor_unref() -> g_object_unref() (Matthew Barnes)
+ Dialogs no longer have separators. (Matthew Barnes)
+ Drop support for gtk+-2.0. (Matthew Barnes)
+ Adapt to Camel API changes. (Matthew Barnes)
+ mail: Use G_DEFINE_TYPE for EmFolderTreeModel (Benjamin Otte)
+ Use e_load_book_source_async() for all EBook loading. (Matthew Barnes)
+ Use e_source_selector_get_source_by_path(). (Matthew Barnes)
+ Fudge GtkScrollable for gtk2. (Matthew Barnes)
+ Fudge gtk_widget_get_preferred_size() for gtk2. (Matthew Barnes)
+ Do not hide maildir accounts from UI (Milan Crha)
+ GtkSelectionData is sealed in GTK3. (Matthew Barnes)
+
+Translations:
+ Andrej ŽnidarÅ¡iÄ (sl)
+ Ivar Smolin (et)
+ Klemen Košir (sl)
+ Jorge González (es)
+ Fran Diéguez (gl)
+ Daniel Nylander (sv)
+ Daniel Mustieles (es)
+ Michael Kotsarinis (el)
+
+Evolution 2.91.5 2010-01-10
+---------------------------
+
+Bug Fixes:
+ Bug 567879 - Add View >> Gallery Option In Email Composer (Milan Crha)
+ Bug 633854 - Crash in build_template_menus_recurse (Milan Crha)
+ Bug 637482 - Flushing outbox gives up on first error (Matthew Barnes)
+ Bug 637906 - Don't ask again when sending to non-mail recipients
+ (Milan Crha)
+ Bug 638245 - Crash when printing Work Week view (Milan Crha)
+
+Other Changes:
+ * Disconnect signal handlers from actions in alert_dispose()
+ (Milan Crha)
+ * Temporarily remove GDK_DISABLE_DEPRECATED (again). (Matthew Barnes)
+ * Call setlocale() instead of gtk_set_locale(). (Matthew Barnes)
+ * Fix menu item capitalizaion. (Matthew Barnes)
+ * Add e_shell_submit_alert(). (Matthew Barnes)
+ * Fix wrong button name in Restore instructions (Andre Klapper)
+ * Fix all back up that should be backup (Andre Klapper)
+ * Improve wording of Maildir migration dialog. (Matthew Barnes)
+ * Avoid idle callbacks in EMailBackend initialization. (Matthew Barnes)
+ * Improve Maildir migration. (Matthew Barnes)
+ * EMFolderTree: Fully implement ESelectableInterface. (Matthew Barnes)
+ * EActionComboBox: Fix runtime warnings with GTK3. (Matthew Barnes)
+ * EAttachmentIconView: Fix runtime warnings with GTK3. (Matthew Barnes)
+
+Translations:
+ Ask H. Larsen (da)
+ Jorge Gonzalez (es)
+ Daniel Mustieles (es)
+ Ivar Smolin (et)
+ Fran Diéguez (gl)
+ Torstein Adolf Winterseth (nv)
+ A S Alam (pa)
+ Daniel Nylander (sv)
+ Gheyret T.Kenji (ug)
+ Yinghua Wang (zh_CN)
+ Aron Xu (zh_CN)
+
+
+Evolution 2.91.4 2010-12-20
+---------------------------
+
+Bug Fixes:
+ Bug 250046 - Quote names in addresses when necessary in mail preview (Milan Crha)
+ Bug 634385 - Crash in smtp_connect (Milan Crha)
+ Bug 637162 - May not add toolbar Send/Receive button multiple times (Milan Crha)
+ Bug 436914 - Reply to inline GPG quotes raw GPG message (Milan Crha)
+ Bug 616452 - Do not set '-Wl,--no-undefined' on freebsd/openbsd (Milan Crha)
+ Bug 633702 - Forget password when saving account without "Remember password" (Milan Crha)
+ Bug 633611 - Do not close Add Filter Rule dialog on error (Milan Crha)
+ Bug 633332 - Preserve port number in WebDAV address book (Milan Crha)
+ Bug 631568 - Scheduling Meetings with CalDAV calendars (Milan Crha)
+ Bug 593587 - Fails to retrieve free/busy info if auth required (Milan Crha)
+ Bug 590245 - 'evolution --force-shutdown' should kill factories (Milan Crha)
+ Bug 627536 - Open meeting as meeting, not as appointment, in week view (Milan Crha)
+ Bug 620234 - Invalid writes during free/busy (Milan Crha)
+ Bug 636265 - Trash is untranslated in the window title (Matthew Barnes)
+ Bug 635755 - Authenticate books in addressbook importers on open (Milan Crha)
+ Bug 567415 - Remove "Nettiquette" section. (Andre Klapper)
+ Bug 544328 - Fix right-click, right click, double-click, double click spellings. (Andre Klapper)
+ Bug 608527 - Remove non-existing images/figures linked from User Guide. (Andre Klapper)
+ Bug 566240 - Remove useless part of sentence. (Andre Klapper)
+ Bug 588572 - Fix invalid sentence. (Andre Klapper)
+ Bug 587153 - Fix broken sentence. (Andre Klapper)
+ Bug 587152 - Fix broken sentence. (Andre Klapper)
+ Bug 588570 - Fix weird sentence. (Andre Klapper)
+ Bug 634734 - Fix steps for contact list creation. (Andre Klapper)
+ Bug 555324 - Ask for destination before "Save in Addressbook" inline vCard (Milan Crha)
+ Bug 627176 - Do not spawn other process when clicking mailto: uri (Milan Crha)
+ Bug 621150 - Add the possibility to modify locale of the quoting messages (Jan Holesovsky)
+ Bug 602183 - Crash in Mini Calendar View (bnc) (Vibha Yadav)
+ Bug 636058 - Account setup issues express mode. (Punit Jain)
+
+Miscellaneous Fixes:
+ Show common addressbook and calendar errors in an alert sink (Milan Crha)
+ Remove duplicated info listed already in Quick Reference PDF anyway. (Andre Klapper)
+ Remove useless listing of all categories available. No additional value to have that in the docs. (Andre Klapper)
+ Check for the existence of .Outbox folder while migrating. Make sure the dummy account is created only once.
+ Revert couple of fixes (Chenthill Palanisamy)
+ Free/busy meeting view doesn't work due to non-working extension (Milan Crha)
+ Remove confusing and isolated "Contact list" line. (Andre Klapper)
+ Set the provider's defaults on when CamelURLs get refreshed with a new protocol (Federico Mena Quintero)
+ Avoid a crash when building templates menu. (Matthew Barnes)
+ CalDAV plugin - use saved password, if available, for server browsing (Milan Crha)
+ Revert the doc changes committed. (Bharath Acharya)
+ Default to beginning of the day for the last alarm notification (Milan Crha)
+
+Translations:
+ Nguyá»…n Thái Ngá»c Duy (vi)
+ Chao-Hsiung Liao (zh_HK)
+ Jorge González (es)
+ Philip Withnall (en_GB)
+ Ani Peter (ml)
+ Marcos Lans (gl)
+ Kjartan Maraas (nn)
+ A S Alam (pa)
+
+Evolution 2.91.3 2010-11-29
+---------------------------
+Bug Fixes:
+ Revert certain parts from commit for bug #635738 (Milan Crha)
+ Bug #635828 - Do not send meeting mails with no recipient (Milan Crha)
+ Bug #635738 - Sanitize Previous/Next buttons when not usable (Milan Crha)
+ Bug #634387 - Crash in bbdb_sync_buddy_list_in_thread (Milan Crha)
+ Bug #207580 - Allow new mail check on individual accounts (Milan Crha)
+ Bug #635673 - Stack overflow when opening slow calendar (Milan Crha)
+ Bug #632962 - Duplicate "On this computer" sources after update (Milan Crha)
+ Bug #371705 - Calendar's day view does not reset its IM context (Milan Crha)
+ Bug #635087 - Leftover files after migration of config/data/cache to XDG directories (Mathieu Trudel-Lapierre)
+ Bug #633783 - Folder->Expunge enabled when no folder selected (Milan Crha)
+ Bug #633779 - GtkComboBoxText issues (Milan Crha)
+ Bug #633774 - Headers are gone in grouped view (Vibha Yadav)
+ Bug #632781 - Cannot disable search folders (Milan Crha)
+ Bug #632683 - Remove-duplicates should work on selection (Milan Crha)
+ Bug #632293 - Do not add POP accounts into folder tree (Milan Crha)
+ Bug #632676 - Only "Checking for new mail" in status bar and nothing else (Milan Crha)
+ Bug #632671 - "Search interrupted" status message forever (Milan Crha)
+ Bug #632176 - Force user name on Google calendar/address book (Milan Crha)
+
+Miscellaneous Fixes:
+ [vCard-inline] Check also text/directory parts (Milan Crha)
+ Reset IM context when entering ECellText editing (Milan Crha)
+ Maildir migration: allow subfolders for Inbox (Chenthill Palanisamy)
+ Migrate the local store from mbox to maildir format (Chenthill Palanisamy)
+ Fix windows build of backup-restore plugin (Fridrich Å trba)
+ Drop accessibility support for ECellText. (Matthew Barnes)
+ Workaround crash when pasting nothing into html message composer (Milan Crha)
+ Use gtk_paned_new() instead gtk_[v|h]paned_new() (Javier Jardón)
+
+Translations:
+ Ville-Pekka Vainio (fi)
+ Gheyret T.Kenji (ug)
+ Ivar Smolin (et)
+ Jorge González (es)
+ Fran Diéguez (gl)
+ Marcos Lans (gl)
+ Kjartan Maraas (nn)
+
+Evolution 2.91.2 2010-11-08
+---------------------------
+
+Bug Fixes:
+ Bug 445439 - Delete mail from pop-server when deleted from Inbox/Trash
+ (Milan Crha)
+ Bug 484554 - Day names can overlap in calendar printouts (Milan Crha)
+ Bug 534453 - Incorporate 'Remove attachments' plugin (Rex Tsai)
+ Bug 567265 - BCC kept on message forward from Sent folder (Milan Crha)
+ Bug 592045 - Use week-day names in abbreviated date (Milan Crha)
+ Bug 597567 - Crash in comp_subject() (Milan Crha)
+ Bug 612181 - Show recurring events in italic in date navigator
+ (Milan Crha)
+ Bug 628139 - Thread-safety issues in libical time zone loading
+ (Matthew Barnes)
+ Bug 629479 - Runtime critical warnings from e-print.c (Milan Crha)
+ Bug 630504 - Precache collate keys before sorting in EReflowModel
+ (Milan Crha)
+ Bug 630695 - Invalid read when enable/disable the account in
+ preferences (Milan Crha)
+ Bug 630969 - Implement also Message->Go to->Previous Thread
+ (Milan Crha)
+ Bug 631451 - Add handlers for x-scheme-handler/mailto (Milan Crha)
+ Bug 631526 - Loading images doesn't use proxy credentials (Milan Crha)
+ Bug 631731 - Remove status icon from mail notifier (William Jon McCann)
+ Bug 631870 - Memory leak in e_week_view after GtkObject removal
+ (Milan Crha)
+ Bug 631956 - Reset renderer properties in
+ action_combo_box_render_pixbuf (Milan Crha)
+ Bug 631981 - Change reply_close_browser short description text
+ (Milan Crha)
+ Bug 631982 - Hide Page properties in signature editor (Milan Crha)
+ Bug 632199 - Opening calendar from panel clock goes to previous day
+ (Milan Crha)
+ Bug 632278 - Double .vcf extension on addressbook save (Milan Crha)
+ Bug 632280 - Backup file name should include date (YYYYMMDD)
+ (Milan Crha)
+ Bug 632483 - [WinXP] Does not start when updated from 2.8 (Milan Crha)
+ Bug 632562 - Disabled account in preferences not remove in folder tree
+ (Milan Crha)
+ Bug 632580 - Freezes UI on account disable (Milan Crha)
+ Bug 632641 - Handle combo box text API going away (Matthias Clasen)
+ Bug 632679 - Add 'Remove attachments' in pop up menu (Milan Crha)
+ Bug 632767 - Some widgets removed from mail-config.ui (Milan Crha)
+ Bug 632768 - Message list not realized when opening new folder
+ (Milan Crha)
+ Bug 632769 - EMeetingTimeSelector can be unrealized in express mode
+ (Milan Crha)
+ Bug 632870 - Cut and paste broken in ESignatureEditor (Matthew Barnes)
+ Bug 632903 - Support libnotify-0.7 (Flo Gravo)
+ Bug 632941 - Calendar ignores preference "show/hide end times"
+ (Milan Crha)
+ Bug 633155 - Incorrect signal connection with
+ mail-vfolder.c:folder_deleted_cb (Milan Crha)
+ Bug 633158 - Importer stops after single mail import (Milan Crha)
+ Bug 633172 - Folder->Subscriptions is always enabled (Matthew Barnes)
+ Bug 633371 - Remote pop folder no longer emptied (Milan Crha)
+ Bug 633471 - EAttachmentStore store folder name where uri is expected
+ (Matthew Barnes)
+ Bug 634088 - Uses uninitialized variable in action_contact_new_cb
+ (Milan Crha)
+
+Other Changes:
+ * Add an EOfflineAlert module. (Matthew Barnes)
+ * Send errors to an EAlertSink instead of the task bar.
+ (Matthew Barnes)
+ * Kill mail_config_get_gconf_client(). (Matthew Barnes)
+ * Kill mail_config_service_set_save_passwd(). (Matthew Barnes)
+ * Move more account utilities to e-account-utils.c. (Matthew Barnes)
+ * Collect mail enum types in e-mail-enums.h. (Matthew Barnes)
+ * Add an "ellipsize" property to EMFolderTree. (Matthew Barnes)
+ * Crash on start with vfolders configured (Milan Crha)
+ * Reduce GConf usage in em-composer-utils.c. (Matthew Barnes)
+ * Deal with GtkComboBoxEntry removal in gtk+-3.0. (Matthew Barnes)
+ * Add missing gtk-compat.h include to various files (Milan Crha)
+ * Memory leaks around g_value_set_string (Milan Crha)
+ * Kill mail_store_set_offline(). (Matthew Barnes)
+ * Fix build on platforms when ngettext is a macro (Fridrich Å trba)
+ * Drop usage of GtkAnchorType. (Matthew Barnes)
+ * Workaround GtkComboBoxText/GtkComboBoxEntry in .ui files (Milan Crha)
+ * More detailed runtime warning on message list pre-sorting
+ (Milan Crha)
+ * Port gnome-canvas drawing from GDK to cairo. (Benjamin Otte)
+ * Kill mail_append_mail(). (Matthew Barnes)
+ * Skip writing to Outbox when sending. (Matthew Barnes)
+ * EMailReader: Rewrite message retrieval tracking. (Matthew Barnes)
+ * Kill mail_get_messagex(). (Matthew Barnes)
+ * Kill em_folder_utils_unsubscribe_folder(). (Matthew Barnes)
+ * EMailBrowser: Implement EAlertSink. (Matthew Barnes)
+ * EMailReader: Add a get_alert_sink() method. (Matthew Barnes)
+ * Add missing stock appointment-reminder icons (Milan Crha)
+ * Set checkspin label mnemonic widget in account editor (Milan Crha)
+ * Utilize the new ESourceSelector:primary-selection property.
+ (Matthew Barnes)
+ * Use @valuenick@ in glib-gen.mak. (Matthew Barnes)
+ * Rename CalUnits to EDurationType. (Matthew Barnes)
+ * Add GBinding transform funcs for enum types. (Matthew Barnes)
+ * Move calendar preferences to the calendar module. (Matthew Barnes)
+
+Translations:
+ Carles Ferrando (ca@valencia)
+ Mario Blättermann (de)
+ Jorge González (es)
+ Mattias Põldaru (et)
+ Claude Paroz (fr)
+ Takayuki KUSANO (ja)
+ Matej UrbanÄiÄ (sl)
+ Yinghua Wang (zh_CN)
+
+Evolution 2.91.1 2010-10-18
+---------------------------
+
+Bug Fixes:
+ Bug 630506 - "You have %d alarms" needs ngettext (Milan Crha)
+ Bug 631968 - Date wrongly displayed as Tomorrow. (Punit Jain)
+ Bug 604981 - Always bcc ignored for Contacts. (Bharath Acharya)
+ Bug 587011 - Integrate remove-duplicates into evolution (Milan Crha)
+ Bug 632171 - "New Address Book" dialog accepts whitespace for name (Matthew Barnes)
+ Bug 632127 - Composer is editable while sending message (Matthew Barnes)
+ Bug 305425 - Toolbar cancel button is always sensitive (Matthew Barnes)
+ Bug 461769 - Add a --force-online command line option (Matthew Barnes)
+ Bug 630490 - Not visible calendar color change immediately (Milan Crha)
+ Bug 630375 - Character encoding of GPG encrypted message not honored (Milan Crha)
+ Bug 617611 - redo_queries calls gtk+ functions in non-main thread (Milan Crha)
+ Bug 619387 - EMailBrowser doesn't honour sorting of a mail window (Milan Crha)
+ Bug 240302 - Print the work week view (Carlos Martín Nieto)
+ Bug 223337 - Auto-close message-browser when replying to them (Milan Crha)
+ Bug 552121 - Drop UUENCODE inline filter (Milan Crha)
+ Bug 631341 - On This Computer/Inbox sub-folders lost (Milan Crha)
+ Bug 631588 - Sort by Subject doesn't work (Milan Crha)
+ Bug 631320 - GtkObject is gone in GTK3 (Milan Crha)
+ Bug 630390 - Operation stuck: Generating message list (cancelled) (Milan Crha)
+ Bug 617953 - Hide Junk messages in Search folders (Milan Crha)
+ Bug 618102 - Single event print doesn't show time (Milan Crha)
+ Bug 211593 - Show week numbers on calendar printout (Milan Crha)
+ Bug 500591 - Crash when viewing a large message (Milan Crha)
+ Bug 588851 - Don't show unsubscribe option for local folders (Matthew Barnes)
+ Bug 630295 - Inline GPG encrypted message is not always recognized (Milan Crha)
+ Bug 629825 - Hide Free/Busy tab if not needed in express mode (Milan Crha)
+ Bug 615835 - Alarm not working for authenticated calendars (Milan Crha)
+ Bug 616250 - Restore and Backup options aren't fully descriptive (Milan Crha)
+
+Miscellaneous Fixes:
+ Widget 'label-comments' gone in Contact editor (Milan Crha)
+ Replace EBinding with GBinding. (Matthew Barnes)
+ EAlertBar: Always show the most recent alert. (Matthew Barnes)
+ EShellBackend: Respond to EShell::prepare-for-quit signals. (Matthew Barnes)
+ Adjust EAlertBar text attributes. (Matthew Barnes)
+ Remove mail_tools_folder_to_url(). (Matthew Barnes)
+ Composer: Show cancellable operations and errors inline. (Matthew Barnes)
+ Day view print: Put day name in its box (Carlos Martín Nieto)
+ Add a missing week number offset (Carlos Martín Nieto)
+ autogen.sh: remove unneded call to autopoint (Javier Jardón)
+ MailFolderCache notifies in reverse order (Milan Crha)
+ Realli fix srcdir != builddir builds (Javier Jardón)
+ Calendar's "Open Web Page" actions doesn't work (Milan Crha)
+ Fix srcdir != builddir builds. (Javier Jardón)
+ Get rid of deprecated GtkObject in EMap widget (Milan Bouchet-Valat)
+
+Translations:
+ Gil Forcada (ca)
+ David Planella (ca)
+ Jorge González (es)
+ Mario Blättermann (de)
+ Matej UrbanÄiÄ (sl)
+ Kjartan Maraas (nn)
+
+Evolution 2.91.0 2010-10-04
+---------------------------
+
+Bug Fixes:
+ Bug 346438 - Error dialog too wide. (Vibha Yadav)
+ Bug 510020 - Add "Manage Subscriptions" to store context menus
+ (Matthew Barnes)
+ Bug 563471 - Printing tasks fails when grouped by category
+ (Vibha Yadav)
+ Bug 604080 - Predefined account SSL not propagated to UI (Milan Crha)
+ Bug 611154 - problem in accessing folder property (Vibha Yadav)
+ Bug 616250 - Restore and Backup options aren't fully descriptive
+ (Milan Crha)
+ Bug 624321 - Reply requested today does not work. (Bharath Acharya)
+ Bug 626066 - work around NSS bug #595861 (David Woodhouse)
+ Bug 626066 - log in to NSS database on demand for changing trust
+ (David Woodhouse)
+ Bug 628522 - invalid access off end of array in e_bit_array_delete()
+ (David Woodhouse)
+ Bug 629150 - Empty calendar view (Milan Crha)
+ Bug 629266 - Crash on search in Current Account (Milan Crha)
+ Bug 629462 - Tasks 'Due' filters don't work properly (Milan Crha)
+ Bug 629480 - calendar-gui-WARNING: Couldn't find event window
+ (Milan Crha)
+ Bug 629482 - assertion `child->parent==NULL' fail (Bharath Acharya)
+ Bug 629636 - Doesn't recognize local ESource-s (Milan Crha)
+ Bug 629645 - Sets negative 'width' property (Milan Crha)
+ Bug 629735 - Mail preference glitch (Punit Jain)
+ Bug 629737 - [publish-calendar] Could not find widget 'file_label'
+ (Milan Crha)
+ Bug 629799 - Crash importing a mail with an ics attachment (Milan Crha)
+ Bug 629934 - Month view defaults to Monday as start of week
+ (Milan Crha)
+ Bug 629972 - [backup-restore] Problems restoring old data (Milan Crha)
+ Bug 630118 - Endless recursive loop in mail_msg_cancel()
+ (Matthew Barnes)
+ Bug 630269 - Hang on mail operation cancel (Milan Crha)
+ Bug 630294 - Shouldn't send invitation reply when has no organizer
+ (Milan Crha)
+ Bug 630700 - Crash on message send (Milan Crha)
+
+Other Changes:
+ * Convert plugin-manager to an EExtension. (Matthew Barnes)
+ * Remove uninteresting mail options from Preferences. (Matthew Barnes)
+ * Reorganize composer preferences (Matthew Barnes)
+ * Avoid dll hijacking Load sensapi.dll only from system directory
+ where it should normally be and not from any random place.
+ (Fridrich Å trba)
+ * Kill the subject-thread plugin. (Matthew Barnes)
+ * Adapt to CamelOperation API changes. (Matthew Barnes)
+ * Increase safety on Windows Call SetDllDirectory() to reduce risk of
+ DLL hijacking, and call SetProcessDEPPolicy() to reduce risk of rogue
+ code execution. (Fridrich Å trba)
+ * Use new GDK keysym names if available. (Matthew Barnes)
+ * Add a GCancellable to EActivity. (Matthew Barnes)
+ * Adapt to Camel API changes. (Matthew Barnes)
+ * Bump gtk+-2.0 requirement to 2.22.0. (Matthew Barnes)
+ * camel_operation_new() now returns a GCancellable pointer.
+ (Matthew Barnes)
+ * Kill em_utils_temp_save_part(). (Matthew Barnes)
+ * EAttachmentPaned: Use gtk_expander_set_label_fill() (Matthew Barnes)
+ * Remove MailAsyncEvent. (Matthew Barnes)
+ * Use upstream gettext instead the glib one (Javier Jardón)
+ * Rewrite the folder subscription editor. (Matthew Barnes)
+ * Remove unused mail_tools_x_evolution_message_parse() (Matthew Barnes)
+ * Get rid of deprecated GtkObject in EMap widget (Milan Bouchet-Valat)
+
+Translations:
+ Marek Cernocky (cs)
+ Kenneth Nielsen (da)
+ Mario Blättermann (de)
+ Christian Kirbach (de)
+ Bakaoukas Nikolaos (el)
+ Mattias Põldaru (et)
+ Ivar Smolin (et)
+ Inaki Larranaga Murgoitio (eu)
+ Andika Triwidada (id)
+ Luca Ferretti (it)
+ Takayuki KUSANO (ja)
+ Žygimantas BeruÄka (lt)
+ Kjartan Maraas (nb)
+ Wouter Bolsterlee (nl)
+ Hannie Dumoleyn (nl)
+ Piotr DrÄ…g (pl)
+ Duarte Loreto (pt)
+ Djavan Fagundes (pt_BR)
+ Miloš Popović (sr)
+ Daniel Nylander (sv)
+
+Evolution 2.31.92 2010-09-13
+----------------------------
+
+Bug Fixes:
+ Bug 629037 - Email operations existed in Contacts (Hao H Li)
+ Bug 627812 - GW shouldn't use global folder tree. (Milan Crha)
+ Bug 629132 - set_attachments: assertion failed. (Punit Jain)
+ Bug 626066 - log in to NSS database before invoking certificate manager (David Woodhouse)
+ Bug 629413 - use-after-free in bad cert dialog (David Woodhouse)
+ Bug 629393 - git.mk breaks parallel builds (Matthew Barnes)
+ Bug 628591 - Incorrect English message in Evolution (Matthew Barnes)
+ Bug 616073 - Various translation issues (Matthew Barnes)
+ Bug 629250 - Fix translatable string format in mail-settings-view.c (Gabor Kelemen)
+ Bug 629253 - Remove unnecessary markup (Gabor Kelemen)
+ Bug 626579 - [bbdb] Crash in free_gaim_body() (gaimbuddies.c) (Milan Crha)
+ Bug 629089 - Accepting a meeting request sends a Tentative reply (Milan Crha)
+ Bug 629115 - Missing mnemonic_widget property in mail-config.ui (Milan Crha)
+ Bug 629046 - Empty reply quotation for HTML messages (Milan Crha)
+ Bug 629054 - Memory leak in memo_table_constructed() (Matthew Barnes)
+ Bug 629052 - Memory leak in task_table_constructed() (Matthew Barnes)
+ Bug 629051 - Memory leak in gnome_calendar_constructed() (Matthew Barnes)
+ Bug 629050 - Memory leak in e_day_view_recalc_cell_sizes() (Matthew Barnes)
+ Bug 629049 - Memory leak in e_composer_pose_header_set_account() (Matthew Barnes)
+ Bug 627952 - 'Local delivery' mbox's aren't read properly (Milan Crha)
+ Bug 628694 - Customize options for local calendar are missing (Milan Crha)
+ Bug 628653 - e_alert_new_valist memory leak (Matthew Barnes)
+ Bug 628654 - e_calendar_view_get_tooltips memory leak (Matthew Barnes)
+ Bug 628660 - em_format_part_as() memory leak (Matthew Barnes)
+ Bug 580623 - Mishandling of evolution's proxy ignore_hosts key (Milan Crha)
+ Bug 628635 - Crash in alarm-queue.c:display_notification() (Matthew Barnes)
+ Bug 628483 - signature_combo_box_refresh_cb memory leak (Matthew Barnes)
+ Bug 628482 - e_shell_settings_install_property_for_key memory leak (Matthew Barnes)
+ Bug 624021 - Honour weeks shown in a multi week view on print (Milan Crha)
+ Bug 628350 - Allow deletion of a deleted message to advance cursor (Matthew Barnes)
+ Bug 627101 - Not able to attach files in calendar (Milan Crha)
+ Bug 628005 - Russian: evolution Advanced Search dialogs are oversized (hao li)
+
+Miscellaneous Fixes:
+ Use --disable-gtk3 in DISTCHECK_CONFIGURE_FLAGS. (Matthew Barnes)
+ GnomeCalendar: Sink the floating ECalendarView references. (Matthew Barnes)
+ Convert ECell from a GtkObject to a GObject. (Matthew Barnes)
+ Re-work my GtkDialog:has-separator workaround. (Matthew Barnes)
+ Add missing linker flag to composer-autosave module. (Matthew Barnes)
+ No more blinking status icon. (Matthew Barnes)
+ Work around deprecation of gtk_dialog_set_has_separator() (Matthew Barnes)
+ Use the and operator only if there are two conditions (Chenthill Palanisamy)
+ Simplify emu_restore_folder_tree_state(). (Matthew Barnes)
+ Memory leak fix in em_folder_tree_get_selected_folder (Milan Crha)
+ Add composer-autosave to SUBDIRS. (Matthew Barnes)
+
+Translations:
+ Changwoo Ryu (ko)
+ Leonid Kanter (ru)
+ Dirgita (id)
+ Takayuki KUSANO (ja)
+ Kjartan Maraas (nn)
+ Ivar Smolin (et)
+ Christian Kirbach (de)
+ Dr.Tirumurti Vasudevan (ta)
+ Jorge González (es)
+ Fran Diéguez (gl)
+ Daniel Nylander (sv)
+ Philip Withnall (en_GB)
+ Matej UrbanÄiÄ (sl)
+ Claude Paroz (fr)
+ Bruno Brouard (fr)
+ Bruce Cowan (en_GB)
+ Gabor Kelemen (hu)
+
+Evolution 2.31.91 2010-08-29
+----------------------------
+
+Bug Fixes:
+ Bug 573320 - "Encrypt to self" by default on newly created mail
+ accounts (Milan Crha)
+ Bug 627124 - Crash while opening task-page.ui (Matthew Barnes)
+ Bug 627333 - Cannot cancel password dialog for a calendar (Milan Crha)
+ Bug 627598 - Memory leak in emf_format_clone() (David Woodhouse)
+ Bug 627601 - Memory leak in itip_get_comp_attendee() (David Woodhouse)
+ Bug 627601 - Memory leak in itip_get_comp_attendee() (David Woodhouse)
+ Bug 627611 - Memory leak in efh_format_header() (David Woodhouse)
+ Bug 627734 - Double-click a message opens it twice (Milan Crha)
+ Bug 627852 - Memory leak in em_format_push_level() (Matthew Barnes)
+ Bug 628003 - Bundle IM protocol icons dropped from gnome-icon-theme
+ (Matthew Barnes)
+ Bug 628136 - update_query_async() should not free the message struct
+ (Matthew Barnes)
+ Bug 628141 - Duplicate signal connections in EMailReader
+ (Matthew Barnes)
+ Bug 628154 - Ignore paths in MIME part filenames (Matthew Barnes)
+
+Other Changes:
+ * Use the new e_load_book_source_async() where possible.
+ (Matthew Barnes)
+ * Fix more non-removal of signals on user_data object distruction by
+ using g_signal_connect_object in many places (Michael Meeks)
+ * Add encryption and authentication support for autoconfig
+ (Gary Ching-Pang Lin)
+ * Update autoconfig settings for live.com (Gary Ching-Pang Lin)
+ * Add e_load_cal_source_async(). (Matthew Barnes)
+ * Build break with evolution-connman - new parameter in a GDBus
+ function (Milan Crha)
+ * Crash on Startup wizard cancel (Milan Crha)
+ * Convert EAttachmentHandler to an EExtension. (Matthew Barnes)
+ * Contact list editor is not translated (Federico Mena Quintero)
+ * Remove the last traces of dbus-glib. (Matthew Barnes)
+
+Translations:
+ Ask H. Larsen (da)
+ Giannis Katsampirhs (el)
+ Philip Withnall (en_GB)
+ Jorge González (es)
+ Bruno Brouard (fr)
+ Fran Diéguez (gl)
+ Yair Hershkovitz (he)
+ Andika Triwidada (id)
+ Takayuki KUSANO (ja)
+ Kjartan Maraas (nb)
+ A S Alam (pa)
+ Tao Wang (zh_CN)
+ 朱涛 (zh_CN)
+ Chao-Hsiung Liao (zh_HK)
+ Aron Xu (zh_CN)
+
+Evolution 2.31.90 2010-08-16
+----------------------------
+
+Bug Fixes:
+ Bug 624896 - Missing icons in table properties (Matthew Barnes)
+ Bug 605737 - Appointment reminder shows icons on buttons (Matthew Barnes)
+ Bug 624913 - Disallow drag-and-drop within the same attachment bar (Matthew Barnes)
+ Bug 323142 - Signature missing when handling mailto: URI with body part (Matthew Barnes)
+ Bug 626724 - Folder tree mistakes "mark as unread" as new mail (Matthew Barnes)
+ Bug 271691 - Add a way to view all attachments inline (Matthew Barnes)
+ Bug 626453 - Show attachments inline when printing (Matthew Barnes)
+ Bug 626090 - Only set -fno-strict-aliasing for GCC (Matthew Barnes)
+ Bug 626059 - Welcome messages has incorrect links (Christian Kirbach)
+ Bug 625847 - make signatures work again. (Michael Meeks)
+
+Miscellaneous Fixes:
+ ESelectionModel, ECanvas, EMsgComposer, EMfolderTreeModel, EMFormat cleanups. (Matthew Barnes)
+ Pass an EShell to EMsgComposer instances. (Matthew Barnes)
+ Pause timline instead of stop. It hides the search animation texture. (Srinivasa Ragavan)
+ Add keybindings to tab. (Srinivasa Ragavan)
+ remove select-on-focus hack, and replace with new skip-a-parent chaining hack; sub-set this only for when we have a hint visible ie. fix alt-c + type-new-search (Michael Meeks)
+ Ensure widgets are registered, without relying on config dialog setup at startup. (Michael Meeks)
+ build: Add libemformat to LDADD for evolution-settings (Rob Bradford)
+ Add Histogram of mail trend in clutter tab and enable DnD of tabs. (Srinivasa Ragavan)
+ Change em_format_redraw() to em_format_queue_redraw(). (Matthew Barnes)
+ Defer the load / creation of configuration UI with changes to e_preferences_window to take factory callbacks and store a reference to the shell. - This makes start-up substantially faster, particularly on Atom (eg.). (Michael Meeks)
+ docs on where the repo for the web version lives, and how to deal with it (Michael Meeks)
+ Execute calendar search post startup, not (Michael Meeks)
+ Make the intention of /tmp more explicit, and rescue people who happen to have evolution .po files in /tmp from a sad fate ... (Michael Meeks)
+
+Translations:
+ Fran Diéguez (gl)
+ Matej UrbanÄiÄ (sl)
+ Claude Paroz (fr)
+ Kjartan Maraas (nn)
+ drtv (ta)
+ Nils-Christoph Fiedler (de)
+
+Evolution 2.31.6 2010-08-02
+---------------------------
+
+Evolution now complies with the XDG Base Directory Specification [1],
+which means user-specific data is no longer stored under ~/.evolution.
+Instead, data is partitioned into three base directories controlled by
+environment variables:
+
+ $XDG_DATA_HOME/evolution (default: $HOME/.local/share/evolution)
+ $XDG_CACHE_HOME/evolution (default: $HOME/.cache/evolution)
+ $XDG_CONFIG_HOME/evolution (default: $HOME/.config/evolution)
+
+Data which is managed by Evolution will be migrated from $HOME/.evolution
+on startup.
+
+[1] http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+
+
+Express mode now shows mail messages and folders in tabs, using Clutter
+for animation effects if available. (Srinivasa Ragavan)
+
+
+Bug Fixes:
+ Bug 598833 - Do not ship dropped evo_mail_notifier.png (Matthew Barnes)
+ Bug 615049 - Crash in remove_contact at e-addressbook-model.c:202
+ (Milan Crha)
+ Bug 622181 - Backup settings uses unhelpful yes/no dialog
+ (Matthew Barnes)
+ Bug 622912 - Migrate from dbus-glib to glib's GDBus (Milan Crha)
+ Bug 623035 - Crash when printing email with too many recipients
+ (Milan Crha)
+ Bug 624204 - Warn when replying privately to a mailing list message
+ (David Woodhouse)
+ Bug 624216 - Runtime warning in Attachment Reminder plugin
+ (Matthew Barnes)
+ Bug 624235 - CamelPOP3Store missing some methods (Matthew Barnes)
+ Bug 624237 - Fails to start when smartcard is inserted (Matthew Barnes)
+ Bug 624285 - When replying, ignore text selection if preview is hidden
+ (Matthew Barnes)
+ Bug 624335 - Abort after group-by-thread with certain sorting
+ (Milan Crha)
+ Bug 624482 - Monitor /apps/evolution/mail/prompts for changes
+ (David Woodhouse)
+ Bug 624500 - Missing EggSMClient linker flags in shell (Matthew Barnes)
+ Bug 624525 - Variable name collision in gtk-compat macro (Milan Crha)
+ Bug 624534 - Adapt to GTK+ GtkNotebookPage changes (Kjartan Maraas)
+ Bug 624677 - Missing keyboard shortcut for "Save as mbox"
+ (Matthew Barnes)
+ Bug 624891 - Various compiler warnings in git/master (Milan Crha)
+ Bug 625204 - Typo in e_day_view_finish_long_event_resize()
+ (Thomas Mittelstaedt)
+ Bug 625606 - git/master build dies with glib-2.25.12 (Milan Crha)
+ Bug 625624 - Customizations of contacts views forgotten
+ (Matthew Barnes)
+ Bug 625724 - Message filters do no work (Lucian Langa)
+ Bug 625761 - Folder views not preserved after migration (Lucian Langa)
+
+Other Changes:
+ * EMailReader: Remove unused variable (Matthew Barnes)
+ * Warn on reply-to-all with too many recipients (David Woodhouse)
+ * Add support for ignoring mailing list Reply-To: headers
+ (David Woodhouse)
+ * Fix two memory leaks when replying (David Woodhouse)
+ * Don't show the "reply in private?" nag popup for munged Reply-To:
+ list messages (David Woodhouse)
+ * Change 'Reply to All' toolbar button into configurable
+ 'Group Reply' (David Woodhouse)
+ * Add nag popup when mailing list hijacks private reply with
+ Reply-To: header (David Woodhouse)
+ * Clean up "ensure_sources" backend routines. (Matthew Barnes)
+ * Report error to user when fails to open calendar/task/memo list
+ (Milan Crha)
+ * Disable my evil GtkExpander hack in EAttachmentPaned (Matthew Barnes)
+ * Use PVOID instead of gpointer when working with COM+ function
+ pointers (Fridrich Å trba)
+ * Migrate ~/.evolution to XDG base directories. (Matthew Barnes)
+ * Reset BASE_VERSION to 2.32. (Matthew Barnes)
+ * Remove unused 'preview' argument from
+ e_import_assistant_new_simple(). (Matthew Barnes)
+ * Make EImportAssistant extensible. (Matthew Barnes)
+ * addressbook/gui, plugins/groupwise, widgets/misc: Update to new
+ icon theme (Rob Bradford)
+ * build: Update gnome-icon-theme dependency for new default-avatar
+ icon (Rob Bradford)
+ * addressbook: Port to use new _async suffix instead of _ex suffix
+ (Rob Bradford)
+ * mail-reader: e_mail_reader_get_formatter may now return NULL
+ (Rob Bradford)
+ * Prefer gio-2.0 when requiring GLib libraries. (Matthew Barnes)
+ * mail-session: Use the shell's active window as parent for
+ dialog (Rob Bradford)
+ * fix lifecycle nasties bgo#625852 (Michael Meeks)
+
+Translations:
+ Mario Blättermann (de)
+ Christian Kirbach (de)
+ Jorge González (es)
+ Fran Diéguez (gl)
+ Nana Suryana (id)
+ Shankar Prasad (kn)
+ Sandeep Shedmake (mr)
+ Kjartan Maraas (nb)
+ Lucian Adrian Grijincu (ro)
+ krishnababu k (te)
+ Aron Xu (zh_CN)
+ Chao-Hsiung Liao (zh_HK)
+
+Evolution 2.31.5 2010-07-12
+---------------------------
+
+Bug Fixes:
+ Bug 624128 - Folder -> Subscriptions is always enabled (Matthew Barnes)
+ Bug 621839 - Improve auto-selection of messages (take two)
+ (Matthew Barnes)
+ Bug 623702 - SEGV on redirecting message (Matthew Barnes)
+ Bug 623738 - Select All is always enabled for message list
+ (Matthew Barnes)
+ Bug 623947 - Error handling issues in em-format.c (Matthew Barnes)
+ Bug 624011 - EMeetingTimeSelector tries to change mouse cursor
+ before it's realized (Matthew Barnes)
+ Bug 624022 - "stock_mail-import" no longer exists in gnome-icon-theme
+ (Matthew Barnes)
+ Bug 623204 - Be able to report detailed errors from backends
+ (Milan Crha)
+ Bug 623796 - Post Message to List asks for confirmation on close
+ (Milan Crha)
+ Bug 623432 - Use gweather-3.0 when building with gtk3
+ (Maciej Piechotka)
+ Bug 623201 - Set default options automatically while creating a
+ new account (Chenthill Palanisamy)
+
+Other Changes:
+ * Fix places where "~/.evolution" is hard-coded. (Matthew Barnes)
+ * Migrate from CamelException to GError. (Matthew Barnes)
+ * Fix transience problems with ENameSelectorDialogs ... (Michael Meeks)
+ * Allow edit accounts in the capplet to go fwd/back (Srinivasa Ragavan)
+ * Work around sudden disappearance of GdkRegion in GTK+ 2.90.5.
+ (Matthew Barnes)
+
+Translations:
+ Jorge González (es)
+ Fran Diéguez (gl)
+ Kjartan Maraas (nb)
+ Matej Urban¿i¿ (sl)
+ Andrej ¿nidar¿i¿ (sl)
+
+Evolution 2.31.4 2010-06-29
+---------------------------
+
+Bug Fixes:
+ Bug 623029 - Work week days not restored on start (Milan Crha)
+ Bug 622535 - Account assistant loops on first run (Matthew Barnes)
+ Bug 553104 - Ambiguous "for" in calendar translations (Milan Crha)
+ Bug 621770 - Bottom-left calendar too big (Milan Crha)
+ Bug 617854 - Critical warnings in calendar view (Milan Crha)
+ Bug 620815 - Memory leaks with Evolution (Milan Crha)
+ Bug 622633 - Can't launch Evolution from clock applet (Matthew Barnes)
+ Bug 621903 - Crash on HTML message print preview (Milan Crha)
+ Bug 622547 - mail_async_event_destroy() doesn't cancel its idle callback (Matthew Barnes)
+ Bug 604262 - "Copy Email Address" should also copy to primary clipboard (Matthew Barnes)
+ Bug 622559 - Changing search option should focus search entry (Matthew Barnes)
+ Bug 611165 - Use memo start date from a calendar view, if active (Milan Crha)
+ Bug 620246 - Increase size of 'group' combo box in task (Milan Crha)
+ Bug 331305 - Can't drag email addresses to Contact List Editor (Matthew Barnes)
+ Bug 621819 - Can't drag message attachments to folders (Matthew Barnes)
+ Bug 622329 - Help menu points to the wrong FAQ page (Matthew Barnes)
+ Bug 619347 - Contact List Editor calls wrong EDestination function (Matthew Barnes)
+ Bug 620951 - A11y support still thinks GnomeCalendar is a widget (Matthew Barnes)
+ Bug 621759 - EShellSearchbar reference counting errors (Matthew Barnes)
+ Bug 621210 - Can't get the shell back after closing it (Matthew Barnes)
+ Bug 616724 - Initialize message window with threaded state of main window (Matthew Barnes)
+ Bug 621958 - Due date is not displayed in message list (Matthew Barnes)
+ Bug 619098 - mail_shell_backend_sync_store_cb() has wrong signature (Jonathon Jongsma)
+ Bug 621930 - Error when using Assign Color filter action (Lucian Langa)
+ Bug 621839 - Improve auto-selection of messages (Matthew Barnes)
+ Bug 206061 - Allow normal, non-vFolder, Trash and Junk folder (Milan Crha)
+ Bug 585904 - Don't overwrite Date: header when writing Fcc (David Woodhouse)
+ Bug 617557 - Quits without asking user to save unfinished messages (Milan Crha)
+ Bug 534369 - [new-mail-notify] Intermittent notifications (Milan Crha)
+ Bug 603468 - Improve handling of --quit option (Matthew Barnes)
+ Bug 619218 - Should select imported certificate when succeeded (Milan Crha)
+ Bug 585301 - Use camel_init() to initialize NSS consistently (David Woodhouse)
+ Bug 585353 - (part of bug) Use new CAMEL_STORE_REAL_JUNK_FOLDER flag (Milan Crha)
+ Bug 501534 - apply new customized view to all folders (Chenthill Palanisamy)
+ Bug 611100 - Forward-to filter stops at outbox (Milan Crha)
+ Bug 573228 - Make the "This event has alarms" icon clickable (Milan Crha)
+
+Miscellaneous Fixes:
+ Build with gtk3 and have backward compatibility (Chenthill Palanisamy, Matthew Barnes)
+ Add Outlook Express DBX mailbox file importer plugin [patch v2: Don't error on empty mailboxes, build plugin by default] (David Woodhouse)
+ audio-inline: Fix linking order issue. (Matthew Barnes)
+ Composer: Append drag dest targets to the GtkHTML widget. (Matthew Barnes)
+ Various folder tree icon enhancements. (Matthew Barnes)
+ Use an appropriate icon when dragging attachments. (Matthew Barnes)
+ Don't auto-undelete when viewing Trash folder. (Matthew Barnes)
+ Composer: Only hide single From account in express mode. (Matthew Barnes)
+ Left-align text in switcher buttons. (Matthew Barnes)
+ [win32] Don't run evolution when asked to register handlers. (Fridrich ¿¿trba)
+ [win32] add --register-handlers and --unregister-handlers options and don't tamper with registry unless asked for it explicitely. (Fridrich ¿¿trba)
+ Warn the user before marking all messages as read (Chenthill Palanisamy)
+ Remove gnome-pilot integration. (Matthew Barnes)
+ Embed libart_lgpl and libgnomecanvas. (Matthew Barnes)
+
+Translations:
+ Kjartan Maraas (nn)
+ Wouter Bolsterlee (nl)
+ Jorge Gonz¿¿lez (es)
+ Fran Di¿¿guez (gl)
+
+Evolution 2.31.3 2010-06-07
+---------------------------
+Bug Fixes:
+ Bug 620150 - EventEditor: Disconnect signal handlers before disposing model (Matthew Barnes)
+ Bug 620602 - Next/prev shortcuts should focus message list (Matthew Barnes)
+ Bug 620628 - Checkbox in vfolder deletion prompt is saved backwards (Matthew Barnes)
+ Bug 620635 - do not setup proxy if it's not enabled (Lucian Langa)
+ Bug 257776 - Import assistant shows wrong extension for vCalendar files (Matthew Barnes)
+ Bug 620207 - Receiving options are missing in preference window (Chenthill Palanisamy)
+ Bug 617579 - HIG issues in "Save Current View" dialog (Matthew Barnes)
+ Bug 617094 - System timezone label not initialized in preferences (Matthew Barnes)
+ Bug 619345 - GtkHTML color settings not being honored (Matthew Barnes)
+ Bug 620044 - Reply and Forward actions should have "is-important" set (Matthew Barnes)
+ Bug 585301 - Use NSS SQLite database, if available (Craig Ringer)
+ Bug 619417 - system_tz_label is not translated in cal-prefs-dialog (Gert Michael Kulyk)
+ Bug 585577 - Wrong FROM in envelope during SMTP negotiation (Fabien Tassin)
+ Bug 619637 - Inconsistent buttons in delete confirmation dialogs (Matthew Barnes)
+ Bug 619783 - Web Addresses arrow button doesn't change (Matthew Barnes)
+ Bug 613038 - Preview pane size not remembered (Matthew Barnes)
+ Bug 619903 - Event editor is too small in express mode (Matthew Barnes)
+ Bug 619900 - First widget skipped in e_shell_hide_widgets_for_express_mode() (Matthew Barnes)
+ Bug 619904 - Mnemonic issues in express mode (Matthew Barnes)
+ Bug 573510 - Outlook type CSV import broken (Milan Crha)
+ Bug 313791 - Delegator can be repeated when delegating a meeting (Milan Crha)
+ Bug 619781 - Some preference sections don't show the right preferences (Matthew Barnes)
+ Bug 248105 - No warning if you create an appointment in the past (Milan Crha)
+ Bug 613798 - Marcus Bains line is grey (Matthew Barnes)
+ Bug 619811 - Bogus "Cannot update from version 0.0" dialog on start (Matthew Barnes)
+ Bug 478090 - Meeting acceptances for attendees who weren't listed are lost (Milan Crha)
+ Bug 599794 - Reopened drafts shouldn't ask for save without change (Milan Crha)
+ Bug 576165 - SIGSEGV in e_plugin_mono_register_type (bnc) (Chenthill Palanisamy)
+
+Miscellaneous Fixes:
+ Add more missing icons for GtkhtmlEditor. (Matthew Barnes)
+ More GTK3 preparation. (Matthew Barnes)
+ Hook up GNOME's configured SOCKS4 proxy in the mail session (Federico Mena Quintero)
+ Convert "startup-wizard" to an EExtension. (Matthew Barnes)
+ Use the send_port, not the recv_port, when configuring SMTP for an account (Federico Mena Quintero)
+ [win32] Relocate the position of mail-autoconfig directory (Fridrich ¿¿trba)
+ Use EWebView functions whenever possible. (Matthew Barnes)
+ Fix alignment of lblCarset in composer-prefs-dialog (Gert Michael Kulyk)
+ Simplify the Notes tab in Contact Editor. (Matthew Barnes)
+ Install evolution-alarm-notify into bindir for windows (Fridrich ¿¿trba)
+ [win32] Set a path in evolution-alarm-notify binary, so it finds its dependencies even if it is started by a link in StartUp submenu of Program menu. (Fridrich ¿¿trba)
+ Revert "don't bridge to the active-view gconf setting" (Matthew Barnes)
+ Merge branch 'express2' (Matthew Barnes)
+ Add tooltips for print button on CompEditor toolbar. (Matthew Barnes)
+
+Translations:
+ Ivar Smolin (et)
+ Jorge Gonz¿¿lez (es)
+ Fran Di¿¿guez (gl)
+ Theppitak Karoonboonyanan (th)
+ Sira Nokyoongtong (th)
+ Kjartan Maraas (nn)
+
+Evolution 2.31.2 2010-05-24
+---------------------------
+
+Bug Fixes:
+ #220672 - Excessive autosaving uses lots of resources (Milan Crha)
+ #240317 - Allow searching in subscribe dialog (Milan Crha)
+ #304415 - Allow change of signature hash algorithm (Milan Crha)
+ #499320 - Preview before import from command line (Milan Crha)
+ #523775 - Order of Email Addresses in UI is broken (Milan Crha)
+ #531013 - Proxy login window is not in focus. (Vibha Yadav)
+ #531912 - Mail inline parser doesn't always work (Milan Crha)
+ #545462 - Printing of contacts is weird. (Vibha Yadav)
+ #546551 - Dialog for mark-all-read always mentions subfolders
+ (Milan Crha)
+ #593890 - New folder window is not in focus in filter dialog
+ (Milan Crha)
+ #594153 - Allow setting alarms on any meeting (Jim Ramsay)
+ #598833 - Do not ship dropped evo_mail_notifier.png (Yves-Alexis Perez)
+ #603006 - Move All Contacts To enabled for read-only address books
+ (Milan Crha)
+ #604971 - Evolution allows deletion of default views (Milan Crha)
+ #607257 - Add checks for event->comp_data != NULL (Milan Crha)
+ #608855 - Can't drag and drop multiple attachments (Matthew Barnes)
+ #611560 - 'Mark as junk' should be disabled in junk folder (Milan Crha)
+ #615291 - Preview pane's attachment bar accepts drop (Matthew Barnes)
+ #615745 - New task pop up in calendar day view doesn't work
+ (Matthew Barnes)
+ #616640 - Don't display attachment size if it's unknown (Matthew Barnes)
+ #616823 - Evolution allows moving IMAP Inbox to other folders
+ (Milan Crha)
+ #616889 - Force 24h format for locales not supporting 12h format
+ (Gert Michael Kulyk)
+ #617041 - Set translation domain for e-mail-reader actions (Gert Kulyk)
+ #617496 - Critical warnings when open a task (Milan Crha)
+ #617557 - Quits without asking user to save unfinished messages
+ (Milan Crha)
+ #617865 - Various data file cleanups (Matthew Barnes)
+ #618113 - Missing icon in alarm dialog (Matthew Barnes)
+ #618177 - Mobile Phone of imported contact not shown in preview
+ (Milan Crha)
+ #618400 - "Mark All Messages as Read" shortcut missing (Matthew Barnes)
+ #618578 - Require automake >= 1.10 (Matthew Barnes)
+ #618902 - Crash when viewing/closing messages quickly (Matthew Barnes)
+ #619010 - Mailer's crash avoidance features are broken (Matthew Barnes)
+
+Other Changes:
+ * Convert "default-mailer" plugin to an extension. (Matthew Barnes)
+ * Initial implementation of setting evolution as default mail client
+ and mailto handler. (Fridrich Å trba)
+ * Require GtkHtml 3.31.2 for new API in bug #220672. (Matthew Barnes)
+ * Improve attachment bar selection behavior. (Matthew Barnes)
+ * Create the source groups required to ensure local adresssbooks and
+ calendars are created (Chenthill Palanisamy)
+ * Consider full name and also the first part of e-mail address for
+ contact description in the import dialogue. (Fridrich Å trba)
+ * On Windows, some LDIF files can have .ldi extension (Fridrich Å trba)
+ * [win32] Set patch to evolution's bindir because some child
+ processes need it in some situations. (Fridrich Å trba)
+ * [win32] Don't call glib functions before g_thread_init was called
+ and register evolution as capable to handle mailto: protocol on
+ startup (Fridrich Å trba)
+ * [win32] Make Evolution actually appear in "Set Program Access and
+ Defaults" dialogue and use quoted string instead of short path,
+ since this is how the "Hotmail" e-mail provider is doing it
+ (unlike what documentation says) (Fridrich Å trba)
+ * [win32] Implement --reinstall, --show-icons, --hide-icons options
+ to be used by windows default application setting dialogue
+ (Fridrich Å trba)
+ * [win32] Try to get the default application registration right
+ (Fridrich Å trba)
+ * [win32] Register evolution as "Contacts" application and .vcf
+ handler (Fridrich Å trba)
+ * [win32] Register evolution as able to handle ldif files too
+ (Fridrich Å trba)
+
+Translations:
+[be8a061] Updated Galician translations (Fran Diéguez)
+[3a9faf9] Updated Shavian translation (Thomas Thurman)
+[491100b] Updated Spanish translation (Jorge González)
+[c5fa894] Updated Spanish translation (Jorge González)
+[ce37e4c] Estonian translation updated (Ivar Smolin)
+[85ebbc3] Updated Shavian translation (Thomas Thurman)
+[fd151ac] Updated Shavian translation (Thomas Thurman)
+[801c425] Updated Shavian transliteration (Thomas Thurman)
+[933e668] Updated Galician translations (Fran Diéguez)
+[073d7e1] Updated Norwegian bokmål translation (Kjartan Maraas)
+[2f57daa] Updated Oriya Translation (Manoj Kumar Giri)
+[a516af7] Updated Oriya Translation (Manoj Kumar Giri)
+[aa3e354] Updated Oriya Translation (Manoj Kumar Giri)
+[8254cec] [help] Updated German help translation screenshots (Christian Kirbach)
+[e1bae28] Updated Spanish translation (Jorge González)
+[518c616] Estonian translation updated (Mattias Põldaru)
+[27eb820] Added be to LINGUAS (Ihar Hrachyshka)
+[1d4c54e] Updated Galician translations (Fran Diéguez)
+
+Evolution 2.31.1 2010-05-03
+----------------------------
+
+Bug Fixes:
+ Bug #614346 - Use cached table row height rather than recalculate (Michel Dänzer)
+ Bug #545505 - Properly free unused message infos periodically (Milan Crha)
+ Bug #609052 - Crash printing contacts in List View (Bharath Acharya)
+ Bug #569523 - be.po (Ihar Hrachyshka)
+ Bug #609052 - Proper warning should be shown. (Punit Jain)
+ Bug #614900 - Description field in calendar list view. (Punit Jain)
+ Bug #604430 - Calendar view not remembered (Milan Crha)
+ Bug #610495 - Plugins should define e_plugin_lib_enable (Roy Marples)
+ Bug #615384 - Use contact's free/busy URL only when not empty (Holger Mickler)
+ Bug #603418 - Custom headers not displayed in message preview (Milan Crha)
+ Bug #613392 - No copyright/licensing information for geo-utils (Cedric Bosdonnat)
+ Bug #360461 - Avoid markup in translatable messages (Milan Crha)
+ Bug #583742 — Port to external libgdata (Philip Withnall)
+ Bug #494047 - Unescape uris in composer's Post-To (Milan Crha)
+ Bug #615331 - Message list/Folder tree focus policy has changed (Milan Crha)
+ Bug #616097 - Remembers page ranges (Matthew Barnes)
+ Bug #592986 - Preferences window shows some buttons on icons (Matthew Barnes)
+ Bug #610428 - Duplicate mnemonic in itip formatted message (Matthew Barnes)
+ Bug #614041 - Filter's relative date combos aren't set (Matthew Barnes)
+ Bug #615814 - Missing mnemonic in import dialog (Matthew Barnes)
+ Bug #613867 - Minor typo in Evolution documentation (Marios Zindilis)
+ Bug #600861 - Backup utility should use --quit instead of --force-shutdown (Matthew Barnes)
+ Bug #569516 - Updated Indonesian translation to fix bug #569516 (Andika Triwidada)
+ Bug #608766 - Replace pthread with GLib's GThread (Milan Crha)
+ Bug #608203 - Left pane of mailer window is really narrow at startup (Milan Crha)
+ Bug #610229 - Status bar progress goes beyond 100 percentage (punit)
+ Bug #615263 - SIGSEGV on Evolution close in e-tree.c:1990 (Milan Crha)
+ Bug #611646 - Calendar shows recurring birthdays incorrectly (Milan Crha)
+ Bug #589393 - Configure fails to detect pilot-link utf8 capabilities (Dominique Leuenberger)
+ Bug #614325 - Shrink/expand To,Cc header images is missing (Milan Crha)
+ Bug #612236 - Find-As-You-Type in Folder list stops working (Milan Crha)
+ Bug 614644 - Email window's title is blank when subject is blank (Matthew Barnes)
+ Bug #614647 - Don't reset names and colors of default mail labels (Matt McCutchen)
+ Bug #614813 - Crash during e-mail migration (Jürg Billeter)
+ Bug #614889 - Memory leaks in EMailSidebar (Paolo Borelli)
+ Bug #614892 - String leak in the composer (Paolo Borelli)
+ Bug #614918 - GnomeGoal: Correct Desktop Files (Javier Jardón)
+ Bug #614926 - Memos and Tasks accelerators switched since 2.28 (Matt McCutchen 2)
+ Bug #591939 - Use ngettext in e-datetime-format.c (Milan Crha)
+ Bug #574755 - Add translator comments (Milan Crha)
+ Bug #567304 - Add translator comment and remove few strings (Milan Crha)
+ Bug #571714 - Remove obsolete strings (Milan Crha)
+ Bug #567304 - Review strings for translation (Milan Crha)
+ Bug #549971 - "Report Junk Failed", "Check Junk Failed" strings (Milan Crha)
+ Bug #547368 - Messages with unclear meaning (add translator comments) (Milan Crha)
+ Bug #458828 - What is the "Top Posting Option"? (Milan Crha)
+ Bug #458510 - Cannot translate "_Backup Settings..." (Milan Crha)
+ Bug #458499 - 'epoch' in evolution-mail.schemas.in (Milan Crha)
+ Bug #417412 - Improve "display text part of limited size" DoS strings (Milan Crha)
+ Bug #347330 - Mark forgotten strings for translation (Milan Crha)
+ Bug #333039 - Merge some i18n strings (Milan Crha)
+ Bug #329694 - "Visual" needs translator comments (Milan Crha)
+ Bug #325616 - Remove whitespace, add translator comments (Milan Crha)
+ Bug #325609 - Add translator comment for "%s = %s" (Milan Crha)
+ Bug #592117 - Calendar compressed weekend print improvement (pepp)
+ Bug #325121 - Do not translate developer strings in g_param_spec_* (Milan Crha)
+ Bug #302742 - The mail error messages is difficult to understand/translate (Milan Crha)
+ Bug #272567 - Evolution message needs ngettext support (Milan Crha)
+ Bug #261979 - Untranslatable string due to sentence splitting (Ushveen Kaur)
+ Bug #261062 - Do not translate untranslatable texts (Milan Crha)
+ Bug #605745 - Use a few more named constants (Paul Bolle)
+ Bug #613352 - Changed time range not propagated to calendar (Milan Crha)
+ Bug #613356 - Calendar doesn't save Task/Memo table state (Milan Crha)
+ Bug #613354 - Folder->Mark all messages as read does not work (Milan Crha)
+ Bug #613261 - application/mbox not shown properly (Milan Crha)
+ Bug #612916 - Runtime error on console when opening a message window (Milan Crha)
+ Bug #612821 - Uses freed memory when changing task's source (Milan Crha)
+ Bug #602801 - Duplicate mnemonic (Viswanath S)
+ Bug #569945 - Recurrence icon not removed after changing to single event (Milan Crha)
+ Bug #488979 - Disable Edit for card views in contacts (Milan Crha)
+ Bug #374533 - Read window stays open after last email is deleted (Milan Crha)
+ Bug #614049 - Attachment bar causes drawing issues in RTL locales (Matthew Barnes)
+
+Miscellaneous Fixes:
+ Adapt to Camel API changes. (Matthew Barnes)
+ [i18n] Strings not aligned in ui. (bgo #616181) (Mario Carrion)
+ One more fix of the icon installation (Fridrich Å trba)
+ Fix a typo on Makefile.am that prevents installation of a big chunk of the stock icons (Fridrich Å trba)
+ Use default headers when none stored to display in mailer (Milan Crha)
+ Fix linking of face plugin (Fridrich Å trba)
+ Camel is now GObject-based. (Matthew Barnes)
+ Initialize dbus threading to avoid loosing alarms (Michael Meeks)
+ Relocating EVOLUTION_BINDIR which will be used in plugin setting Evolution comme defaut mail application on windows. (Fridrich Å trba)
+ Remove 3 leftover references to non-existing libraries (Fridrich Å trba)
+ Work around another dropped gnome-icon-theme icon. (Matthew Barnes)
+ Fix migration event hook for google-account-setup and calendar-weather plugins (Philip Withnall)
+ fix disappearing e-table headers by realising the (horrible) pet widget we are going to steal the gc from, so it actually has it. (Michael Meeks)
+ Adapt to Camel API changes. (Matthew Barnes)
+ Fix compiler warnings. (Matthew Barnes)
+ Don't bundle 256x256 icon since it does not work anyway (Fridrich Å trba)
+ Give the windows version of evolution-alarm-notify a nice win32 icon (Fridrich Å trba)
+ Adding the stock_people icon needed and absent in gnome-icon-theme (Fridrich Å trba)
+ Add more stock icons dropped from gnome-icon-theme. (Matthew Barnes)
+ Revise legacy stock icon contexts. (Matthew Barnes)
+ Adapt to libedataserverui API changes. (Matthew Barnes)
+ Use newer GTK+ API to manage print settings. (Matthew Barnes)
+ Miscellaneous string fixes (Philip Withnall)
+ Fix usage of "backup" in translatable strings (Philip Withnall)
+ Open and save smime-ui.ui in Glade 3. (Matthew Barnes)
+ Install stock icons in "hicolor" instead of "gnome". (Matthew Barnes)
+ Remove comments that have no point after pthreads dependency disappeared (Fridrich Å trba)
+ Remove duplicate use_system_timezone pref, set default to true (Sandy Armstrong)
+ [win32] Fix a build breakage by adding a proper define for gmtime_r instead of the broken one that used to be pulled by including pthread.h (Fridrich Å trba)
+ Use accessor functions instead direct access (GSEAL work) (Javier Jardón)
+ Adapt to Camel API changes. (Matthew Barnes)
+ Forgot to commit some bits. (Matthew Barnes)
+ Giant leap towards GSEAL compliance. (Matthew Barnes)
+ Replace ESpinner with GtkSpinner. (Matthew Barnes)
+ Remove gtk_notebook_set_tab_label_packing(). (Matthew Barnes)
+ hook out X symbols via g_module to avoid direct X linkage. (Michael Meeks)
+ Do not hide junk mail when vJunk folder not supported by store (Milan Crha)
+ Fix distcheck errors. (Matthew Barnes)
+ Drop the "hula-account-setup" plugin. (Matthew Barnes)
+ Revert "[win32] #undef some conflicting defines" (Fridrich Å trba)
+ [win32] #undef some conflicting defines (Fridrich Å trba)
+ Adapt to Camel API changes. (Matthew Barnes)
+ Generate ChangeLog files for tarball releases. (Matthew Barnes)
+ Remove dead Bonobo-era source files. (Matthew Barnes)
+ Only #include Camel's top-level header. (Matthew Barnes)
+ Miscellaneous cleanup bits from WebKit branch. (Matthew Barnes)
+ Workaround broken build due to direct X function calls (Milan Crha)
+ Add meego detection logic, it needs to be used (next pass) to configure the shell, to name widgets differently, and re-order some menu/toolbar bits. (Michael Meeks)
+ Enable the alarm daemon on MeeGo. (Michael Meeks)
+ camel/camel-i18n.h gone, adapt to it properly (Milan Crha)
+ Stop relying on CamelObject meta-data. (Matthew Barnes)
+ Add gtk-doc tests, but leave them disabled. (Matthew Barnes)
+ Add --name-space to MKDB_OPTIONS. (Matthew Barnes)
+ Move EPoolv back to Evolution from libedataserver. (Matthew Barnes)
+ Post-release version bump. (Matthew Barnes)
+ [win32] Test for eventsys.h and sensevts.h properly (Fridrich Å trba)
+ Fix build settings under capplet. (Matthew Barnes)
+ Disable the status bar for all but the mail view. Not implemented prettily, but cf. mail_shell_backend_window_created_cb getting invoked even for addressbok windows ... (Michael Meeks)
+ If no <> in the email address, the address should be the full email address. Fix for #613564 (caiqm)
+ Build libevolution-mail-settings as dll on windows (Fridrich Å trba)
+ Express: Composer always defaults to HTML mode (Matthew Barnes)
+ Hide searchbar in calendar view in express mode. (Srinivasa Ragavan)
+ Drop support for migrating from Evolution < 2.0. (Matthew Barnes)
+ Reformat code so that it looks ok (Fridrich Å trba)
+ [win32] Don't brew your own macro if glib has one suitable available (Fridrich Å trba)
+ [win32] Windows SENS module cannot be built with C++ compiler (Fridrich Å trba)
+ [win32] Some buildability tweaks for Windows SENS module (Fridrich Å trba)
+ Last scroll-pane, and manual sizing tweak (Michael Meeks)
+ Get the new contact sizing right despite the scrolled regions. Add Claire's calendar popup feedback wrt. express mode (Michael Meeks)
+ Scrolled window for personal bits ... (Michael Meeks)
+ Add a scrolled area to cope if we want to expand mail settigns (Michael Meeks)
+ Add conditionally enabled expanders for 'Other' address and 'Misc' personal items, to fit on a 600 pixel high screen. (Michael Meeks)
+ Fix mismatched quotes. (Matthew Barnes)
+
+Translations:
+ vasudeven (ta)
+ Mattias Põldaru (et)
+ Rodrigo Flores (pt)
+ Christian Kirbach (de)
+ Shankar Prasad (kn)
+ Valencian translation (ca)
+ Francisco Diéguez (gl)
+ Jorge González (es)
+ Fran Diéguez (gl)
+ Nikos Bakaoukas (el)
+ Philip Withnall (en_GB)
+ Bruno Brouard (fr)
+ Theppitak Karoonboonyanan (th)
+ Petr Kovar (cs)
+ Mario Blättermann (de)
+ Kjartan Maraas (nn)
+ Maxim V. Dziumanenko (uk)
+ Jordi Serratosa (ca)
+ Peteris Krisjanis (lv)
+
+Evolution 2.29.92 2010-03-08
+----------------------------
+
+Bug Fixes:
+ #529331 - Deletes appointments when moving to the same calendar
+ (Milan Crha)
+ #594083 - Oversized main window on startup (Milan Crha)
+ #601551 - [PST] evolution crashed with SIGSEGV (Milan Crha)
+ #610327 - Proxy login doesn't show folder list (Bharath Acharya)
+ #610382 - No addressbook selected on account disable (Milan Crha)
+ #610658 - Contact is lost after moving to the same address book
+ (Milan Crha)
+ #610659 - Clear option is disabled after moving to other component
+ (Milan Crha)
+ #610663 - Message receipts combo box is empty (Milan Crha)
+ #610824 - Contacts list view column width doesn't follow header
+ (Milan Crha)
+ #611873 - Make triple-clicking a shortcut for "Show Only This ..."
+ (Matthew Barnes)
+ #611975 - Delivery Notification message not internationalized
+ (Ulrich Schoepp)
+
+Other Changes:
+ Various cleanups for Windows support (Fridrich Strba)
+ Work around recent GTK+ deprecations. (Matthew Barnes)
+ Fix a misspelled icon name. (Matthew Barnes)
+ Save state key file asynchronously. (Matthew Barnes)
+ Allow retrieving multiple messages without cancelling if the store
+ is async (Chenthill Palanisamy)
+ Restore some calendar headers that got dropped. (Matthew Barnes)
+ Do less output on an evolution-alarm-notify console (Milan Crha)
+
+Translations:
+ Alexander Shopov (bg)
+ Mario Blättermann (de)
+ Bruce Cowan (en_GB)
+ Jorge González (es)
+ Claude Paroz (fr)
+ Fran Diéguez (gl)
+ Kjartan Maraas (nb)
+ Nils-Christoph Fiedler (nds)
+ Leonid Kanter (ru)
+
+Evolution 2.29.91 2010-02-22
+---------------------------
+
+Bug Fixes:
+ #610061 - Do not re-run book view on same book with same query (Milan Crha)
+ #588833 - Improve account selection heuristics for replies (Matthew Barnes)
+ #610250 - '[' and ']' keyboard shortcuts are swapped (Milan Crha)
+ #609982 - Avoid unnecessary prompts when marking folders as read (Matthew Barnes)
+ #609042 - Convert quoted-printing to UTF-8 when copying to clipboard (Matthew Barnes)
+ #610124 - Autosave errors dialogues can't be dismissed (Matthew Barnes)
+ #438759 - Fixed German translation, bug #438759 (Mario Blättermann)
+ #609836 - Add translator comments to ambiguous strings (Matthew Barnes)
+ #604306 - Crash in folder_tree_cell_edited_cb (Milan Crha)
+ #610085 - e_alert_get_primary_text() does not escape arguments (Matthew Barnes)
+ #599370 - Crash in e_activity_set_percent (Milan Crha)
+ #554663 - Swap "Save" and "Save as Draft" accelerators in composer (Matthew Barnes)
+ #609638 - Empty warning message on New vFolder (Milan Crha)
+ #604522 - Mouse wheel scroll doesn't work above inline images (Milan Crha)
+ #604542 - Skip non-system rules when building quick search menu (Matthew Barnes)
+ #593700 - Opens folder on top (Milan Crha)
+ #609403 - Doesn't restore window size always (Matthew Barnes)
+ #609404 - Quick search filter should work on current message list view (Matthew Barnes)
+
+Other Changes:
+ Fix a potential crasher in e_charset_add_radio_actions(). (Matthew Barnes)
+ Update API documentation and fixed some warnings. (Matthew Barnes)
+ [itip-formatter] Show reason of failed calendar open (Milan Crha)
+
+Translations:
+ Nils-Christoph Fiedler (ru)
+ Petr Kovar (cs)
+ Mattias Põldaru (et)
+ Mario Blättermann (gl)
+ Fran Diéguez (gl)
+ Mario Blättermann (de)
+ Bruno Brouard (fr)
+ vasudeven (ta)
+ Kjartan Maraas (nb)
+
+Evolution 2.29.90 2010-02-08
+----------------------------
+
+Bug Fixes:
+ #581604 - Permissions on mail/local folders are too open
+ (Chenthill Palanisamy)
+ #602416 - Changing shell views emits many runtime warnings
+ (Matthew Barnes)
+ #605596 - Crash on message change (Milan Crha)
+ #606666 - Cannot move cursor with arrows in preview with caret mode
+ (Milan Crha)
+ #607520 - 'Add to Address Book' fails when address has space
+ (Matthew Barnes)
+ #607566 - Cause calendar view widget to redraw when dates shown
+ changed (Gustavo Noronha Silva)
+ #607595 - Do not auto-sign when replying to a signed message
+ (Milan Crha)
+ #607751 - Double free while copying whole calendar (Milan Crha)
+ #607776 - Crash in image-inline.c:size_allocate_cb (Milan Crha)
+ #608160 - Pasting text from FireFox into composer gives just "[?]"
+ (Matthew Barnes)
+ #608340 - Help text missing --debug parameter (Matthew Barnes)
+
+Other Changes:
+ Implement account-wide search scope in mail. (Matthew Barnes)
+ Move some ESource-plugin common code to e-plugin-util.h/.c (Milan Crha)
+ Updating PunjabiTranslation by A S Alam (A S Alam)
+ Enforce unique-1.0 >= 1.1.2 build requirement. (Matthew Barnes)
+ Disable strict aliasing optimization. (Matthew Barnes)
+ Fix some misspellings of "calendar". (Matthew Barnes)
+ Improve sidebar and ECalModel interaction. (Matthew Barnes)
+ Sidebar cleanups for Memos and Tasks. (Matthew Barnes)
+ Remove a bunch of dead code in GnomeCalendar. (Matthew Barnes)
+ Refactor the autoconfig stuff a bit. (Srinivasa Ragavan)
+ Don't show total attachment size if it's zero. (Matthew Barnes)
+ Add bug-database and XML header. Fixes bug 587974 (Andre Klapper)
+ Changes in mingw.org last w32api/mingw-rt packages. (Fridrich Strba)
+ Level the differences with the alternative runtime/header set
+ (Fridrich Strba)
+ Expose ECalendarSelector (Gustavo Noronha Silva)
+ Make authentication functionality available (Gustavo Noronha Silva)
+ Fix include paths for some files to also work when installed
+ (Gustavo Noronha Silva)
+ Remove a couple silly ECalModel functions. (Matthew Barnes)
+ Fix a issue for anjal while saving/restoring search across multiple
+ folders (Srinivasa Ragavan)
+
+Translations:
+ Krasimir Chonov (bg)
+ Jamil Ahmed (bn)
+ Jiri Eischmann (cs)
+ Jorge González (es)
+ Kjartan Maraas (nb)
+ Åsmund Skjæveland (nn)
+ Matej UrbanÄÂiÄ (sl)
+ Aron Xu (zh_CN)
+
+Evolution 2.29.6 2010-01-25
+---------------------------
+
+Bug Fixes:
+ #607952 - "Hours" used as both singular and plural form(Matthew Barnes)
+ #606342 - PST option not offered in single file import (Matthew Barnes)
+ #607804 - Fallback to missing image, when a stock icon could not be
+ found (Gustavo Noronha Silva)
+ #607087 - Not all inlined text attachments are included in replies
+ (Matthew Barnes)
+ #607741 - Move folder to claims it's copying in status bar
+ (Matthew Barnes)
+ #607591 - Revert commit for bug #516000 (Matthew Barnes)
+ #607572 - Date navigator should be synced with the GnomeCalendar upon
+ setting (Gustavo Noronha)
+ #549558 - "Download Messages for Offline Usage" still sensitive in
+ offline mode (Viswanath Sivakumar)
+ #607608 - Empty Trash does not work unless Trash is selected
+ (Matthew Barnes)
+ #607542 - Sometimes delete in pop up doesn't get displayed
+ (Matthew Barnes)
+ #606301 - Slow sort by subject (Milan Crha)
+ #607409 - ~/.evolution/mail/config not created on demand
+ (Matthew Barnes)
+ #603480 - [bbdb] Traverse lists in destinations properly (Milan Crha)
+ #602827 - Disable broken plugins automatically (Milan Crha)
+ #603480 - [bbdb] Crash on unref of uninitialized memory (Milan Crha)
+ #607360 - [regression] Runtime warnings at exit (Matthew Barnes)
+ #606940 - plugin_lib_loadmodule() always enables the plugin
+ (Matthew Barnes)
+ #607234 - Open received attachments as read-only (Matthew Barnes)
+ #390973 - Changing meeting organizer should also change default
+ attendee (Milan Crha)
+ #606937 - void function should not have a return value. (Wang Xin)
+ #605120 - evolution-exchange requires libcomposer. (Wang Xin)
+ #606874 - mktemp disabled in latest glibc-2.11.90-8 (Milan Crha)
+ #605633 - A little code inconsistency in em_utils_send_receipt
+ (Milan Crha)
+ #604670 - addressbook-export segfaults when specifying addressbook
+ (Milan Crha)
+
+Other Changes:
+ Rearrange composer options. (Matthew Barnes)
+ Coding style and whitespace cleanups. (Matthew Barnes)
+ Add a EShellWindow::shell-view-created signal. (Matthew Barnes)
+ Add focus tracking to EMailBrowser. (Matthew Barnes)
+ Move e-search-bar around. (Kjartan Maraas)
+ A bit less 'camel_exception_get_id called with NULL parameter' on
+ console (Milan Crha)
+ Don't stomp on GConf's identifier namespace. (Jan Holesovsky)
+ Fix mention of CVS in autogen.sh. (Jan Holesovsky)
+ EShellBackend cleanup. (Matthew Barnes)
+ Give all preview panes a search bar. (Matthew Barnes)
+ Improve clipboard behavior. (Matthew Barnes)
+ Add selection utilities for "text/html" targets. (Matthew Barnes)
+ Fix a potential uninitialized variable use in em-composer-utils.c.
+ (Matthew Barnes)
+ Fix a potential uninitialized variable use in emae_authtype_changed().
+ (Matthew Barnes)
+ Fix a potential uninitialized return value in e-timezone-dialog.c.
+ (Matthew Barnes)
+ Fix a potential uninitialized argument in ech_config_section_factory().
+ (Matthew Barnes)
+ Fix a potential uninitialized argument in e_signature_list_find().
+ (Matthew Barnes)
+ Fix a potential uninitialized argument in e-plugin-python.c.
+ (Matthew Barnes)
+ Remove dead assignments found by clang. (Matthew Barnes)
+ Remove unused tooltip support from ECanvas/ETable/EText.
+ (Matthew Barnes)
+ Remove unused ECell::show_tooltip method. (Matthew Barnes)
+ Remove dead ETableItem code. (Matthew Barnes)
+ Remove unused ECanvas functions. (Matthew Barnes)
+ Also ship gnome-cal.h as a public header (Gustavo Noronha Silva)
+ Baby steps toward GSEAL compliance. (Matthew Barnes)
+
+Translations:
+ Chao-Hsiung Liao (zh_HK) (zh_TW)
+ Alexander Shopov (bg)
+ Krasimir Chonov (bg)
+ Jorge González (es)
+ Kjartan Maraas (nb)
+ Milan Crha (nb)
+
+Evolution 2.29.5 2010-01-11
+---------------------------
+
+Bug Fixes:
+ #329693 - Add contexts to translated "None" words (Milan Crha)
+ #342935 - Do not choose disabled accounts for meeting requests
+ (Milan Crha)
+ #361145 - Evolution hangs when formatting message - fixes part of it
+ (Chenthill Palanisamy)
+ #372921 - Meeting invites sent from wrong email account (Milan Crha)
+ #520816 - S/MIME shares "Do not sign meeting requests" with PGP
+ (Milan Crha)
+ #549988 - "Empty Trash" in Trash popup empties all Trash folders
+ (Milan Crha)
+ #592117 - Calendar Day view All Day events print improvements (pepp)
+ #595501 - Crash on a changed mail filter action removal (Milan Crha)
+ #597816 - Read/save search folders with labels properly (Milan Crha)
+ #598305 - Use Exif data to rotate inlined photos (Matthew Barnes)
+ #599794 - Set composer as not changed on reply or forward action
+ (Milan Crha)
+ #600521 - Remove trailing spaces from particular account fields
+ (Milan Crha)
+ #603452 - Increase gnome-pilot version to 2.0.16 (H.Habighorst)
+ #603469 - Crash in contacts-map with no Home address filled
+ (Cedric Bosdonnat)
+ #604520 - Create first account window hidden behind main window
+ (Matthew Barnes)
+ #604994 - Folder state not preserved in Copy/Move Folder dialog
+ (Milan Crha)
+ #605192 - New memo window has start date as None (Milan Crha)
+ #605392 - pkg-config files reference libraries that are not used
+ anymore (Vincent Untz)
+ #605600 - Meeting reminders with wrong times (Milan Crha)
+ #605645 - Crash on exit in calendar_view_dispose (Milan Crha)
+ #606250 - Remove usage of deprecated GTK+ symbols (Matthew Barnes)
+ #606316 - Mail with an attachment in a Junk folder crashes Evo
+ (Milan Crha)
+ #606340 - Crash on non-utf8 letter in mail folder name (Milan Crha)
+ #606344 - Clicking "Reply to All" button causes Evo to dump core
+ (Matthew Barnes)
+ #606449 - empty mail-notification popups (Lucian Langa)
+ #606542 - Broken paste action on to/cc/subject fields (Matthew Barnes)
+
+Other Changes:
+ Various changes to support Anjal. (Srinivasa Ragavan)
+ Introduce ESelectable and EFocusTracker. (Matthew Barnes)
+ Remove dbus-glib-1 from evolution-shell.pc.in. (Matthew Barnes)
+ Rename ECalendarTable to ETaskTable. (Matthew Barnes)
+ Remove useless --enable-nntp configure option. (Matthew Barnes)
+ Hard code "EDS_PACKAGE" since it will never change. (Matthew Barnes)
+ Replace alloca() with g_alloca(). (Matthew Barnes)
+ Hard code "GTKHTML_PACKAGE". (Matthew Barnes)
+ Evolution does not need flex and bison. (Matthew Barnes)
+ Hide "Submit Bug Report" if bug-buddy is not present. (Matthew Barnes)
+ Clarify "Synchronization Options" menu item. (Matthew Barnes)
+ Kill redundant RGB/HSV color conversion utilities. (Matthew Barnes)
+ Kill e_popup_menu(). (Matthew Barnes)
+ Kill widgets/misc/e-colors.[ch]. (Matthew Barnes)
+ Teach ETable to prefer themed icon names over pixbufs. (Matthew Barnes)
+ Do not focus in a search entry when it is not having a focus
+ (Milan Crha)
+ Cleanup delete actions in shell views. (Matthew Barnes)
+
+Translations:
+ Jiri Eischmann (cs)
+ Jorge González (es)
+ Kjartan Maraas (nb)
+ Tomasz Dominikowski (pl)
+ Matej UrbanÄÂiÄ (sl)
+ Daniel Nylander (sv)
+ krishnababu k (te)
+
+Evolution 2.29.4 2009-12-21
+---------------------------
+
+Bug Fixes:
+
+Mailer:
+ #596967 - Per-folder setting for threading and preview panel (Milan Crha)
+ #604884 - Use proper colors in Search bar when is search activated (Milan Crha)
+ #593896 - "Search -> Find now" should not be always enabled (Milan Crha)
+ #593700 - Restore folder's last selected message as expected (Milan Crha)
+ #603184 - Various problems with search box in folders (Milan Crha)
+ #604761 - Select certificate doesn't work (Milan Crha)
+ #553057 - Show signer's information in a message window/preview (Matthew W. S. Bell)
+ #602505 - Incorrect information in message window (Milan Crha)
+ #551464 - Paste files into composer as attachments (Matthew Barnes)
+
+Calendar:
+ #596947 - Calendar view forgets memo pane height (Matthew Barnes)
+ #359755 - Do not fetch content of a CalDAV calendar when given it (Milan Crha)
+ #604512 - Calendar publishing tab misses button label (Milan Crha)
+ #604182 - Do not block UI with publish-calendar messages (Milan Crha)
+ #359755 - Support for CalDAV collections (Milan Crha)
+ #603682 - Duplicate mnemonic in meeting window (Matthew Barnes)
+ #603061 - Use .ics for temp vcalendar files (Paul Bolle)
+
+Contacts:
+ #602998 - Contacts searches are supposed to be per address book (Milan Crha)
+
+Misc:
+ #604838 - Drop unused alert dialog (Paul Bolle)
+ #604822 - Drop more alert titles. Drop all alert titles to be found in *.error.xml.
+ iHIG suggests alerts (Paul Bolle).
+ #603701 - Don't treat 4 byte values as DDWORDs (Paul Bolle)
+ #603342 - Memory leak fixes (Milan Crha)
+ #604562 - Typo in gconf schema (Christophe Fergeau)
+ #604182 - Hide variable used only with HAVE_LIBNOTIFY (Milan Crha)
+ #499322 - Use extension for "Save as" suggested file name (Milan Crha)
+ #603972 - Proper title for dialog (Paul Bolle)
+ #591938 - Update translator's comments (Milan Crha)
+ #604098 - Missing \n in EAlert
+ #603592 - X11 window roles should be set (Matthew Barnes)
+ #602963 - Migrate to new EError Apis (Jonathon Jongsma)
+
+Misc Fixes
+ Punctuation fixes (Jordi Mas)
+ EShellContent cleanups. (Matthew Barnes)
+ Fix distcheck errors. (Matthew Barnes)
+ Fix a small memory leak in EShellBackend (Jonathon Jongsma)
+ Add get_data_dir(), get_config_dir() vfuncs to EShellBackend (Jonathon Jongsma)
+ Merge some composer header changes for Anjal. (Matthew Barnes)
+ Introduce EMailBackend into libevolution-mail. (Matthew Barnes)
+ Use the boxed CamelObject type for signal params in MailFolderCache (Jonathon Jongsma)
+ Remove mail-config, vfolder, and filter deps from mail-folder-cache (Jonathon Jongsma)
+ Kill ETableScrolled. (Matthew Barnes)
+ Bump glib requirement to 2.22.0 (Jonathon Jongsma)
+ Remove libhal requirement from configure (Bastien Nocera)
+
+Translations:
+ Jorge González (es)
+ Daniel Nylander (sv)
+ Matej UrbanÄÂiÄ (sl)
+ Kjartan Maraas (nb)
+ Ray Wang (zh_CN)
+
+Evolution 2.29.3 2009-11-30
+---------------------------
+
+Bug Fixes:
+
+Calendar:
+ #558030 - Convert meeting to appointment popup menu option(Milan Crha)
+ #550025 - Add error dialogs for Meetings (Paul Bolle)
+ #598166 - All Day Meeting String Improvement (Milan Crha)
+ #602907 - Cannot delete meetings or appointments in list view
+ (Matthew Barnes)
+ #602102 - [regression] evolution-alarm-notify segv on login to desktop
+ (Chenthill Palanisamy)
+ #602081 - Runtime warnings when going to Tasks (Milan Crha)
+ #602165 - Meeting window doesn't show status, role fields (Milan Crha)
+ #602098 - No progress notification from GnomeCalendar (Milan Crha)
+ #602081 - Calendar purge doesn't seem to work (Milan Crha)
+ Bug 494394 - No way for the user to refresh a calendar (Milan Crha)
+
+Tasks:
+ #591330 - Do not clear task preview every minute (Milan Crha)
+ #602704 - Actions->Purge in task view doesn't work (Matthew Barnes)
+
+Mailer:
+ #602799 - "Mark for Follow Up" menu item glitches (Matthew Barnes)
+ #602844 - Flags not saved to IMAP account on exit (Matthew Barnes)
+ #563555 - Confirm before forwarding many emails inline
+ (Ritesh Khadgaray)
+ #579599 - Let the Advanced Search work again (Milan Crha)
+ #602178 - Missing widget in Search folder dialog (Milan Crha)
+ #590127 - Define ETable::vertical-spacing style property (Milan Crha)
+ #592294 - Output an error message on system filter rules loading error
+ (Yan Li)
+
+Contacts:
+ #361156 - contacts-map plugin (Cedric Bosdonnat)
+ #602803 - New Contact enabled for read-only address books
+ (Matthew Barnes)
+ #474502 - Don't check for contacts in broken address books (Milan Crha)
+ #364618, solve the chinese character issue. (Jeff Cai)
+
+Plugins:
+ #602177 - Plug leaks. Fix race. (Paul Bolle)
+ #601517 - Accept/decline options are missing on event right click
+ (Milan Crha)
+
+Conduits:
+ #551603 - Special case "positive zero alarms" (Paul Bolle)
+ #554779 - Removal of task due date does not sync from Palm.
+ (Matt McCutchen 2)
+
+Misc:
+ #602920 - In German translation (Mario Blättermann)
+ #602719 - Default /evolution/shell/network_config/proxy_type to 0
+ explicitly(Milan Crha)
+ #602625 - Typos in translation messages (Matthew Barnes)
+ #360461 - Do not hardcode invisible_char in ui files (Claude Paroz)
+ #589153 - Use GtkBuilder instead of libglade (Matthew Barnes)
+
+Other Changes:
+
+Calendar:
+ Fix uninitialized variable from a patch for bug #591330 (Milan Crha)
+ Header file cleanup. (Matthew Barnes)
+ Disallow renaming a non-deletable ESource. (Matthew Barnes)
+
+Contacts:
+ Remove some redundancy from EABContactDisplay. (Matthew Barnes)
+ Don't unref destinations in eab_send_as_to(). (Matthew Barnes)
+
+Plugins:
+ Rewrite champlain-gtk and geoclue detection. (Matthew Barnes)
+ Remove unused files after GtkBuilder merge (Milan Crha)
+
+Shell:
+ Implement a new 'killev' program. (Matthew Barnes)
+ Make EShell more subclassable. (Matthew Barnes)
+ Add a --quit command-line option. (Matthew Barnes)
+ Add a --geometry command-line option. (Matthew Barnes)
+
+Mailer:
+ Fix a build error. (Matthew Barnes)
+
+Misc:
+ Update API documentation. (Matthew Barnes)
+ Coding style and whitespace cleanups. (Matthew Barnes)
+ Fix compile time warnings in filter/e-rule-context.c (Milan Crha)
+ Add Evolution's process ID to ~/.evolution/.running. (Matthew Barnes)
+ Restore some lost characters in filter.ui. (Matthew Barnes)
+ Add gettext/glade prefix before ui files in POTFILES.in (Claude Paroz)
+ Remove the last traces of libglade. (Matthew Barnes)
+ Fix typos in e_cal_shell_content_paste_clipboard(). (Matthew Barnes)
+ Fix some details in our asynchronous functions. (Matthew Barnes)
+ Still tweaking pane position restoration. (Matthew Barnes)
+ Kill e_util_read_file(). (Matthew Barnes)
+ Add e_attachment_store_load_async(). (Matthew Barnes)
+ Kill Evolution's icon cache once and for all. (Matthew Barnes)
+ Assemble HTML code in a GString instead of a GtkHTMLStream.
+ (Matthew Barnes)
+ Prefer EWebView calls over direct GtkHTML calls. (Matthew Barnes)
+ Updated POTFILES.in/skip after GTKBuilder migration (Claude Paroz)
+
+Translations:
+ Jorge González (es)
+ Ivar Smolin (et)
+ Mattias Põldaru (et)
+ Claude Paroz (fr)
+ Bruno Brouard (fr)
+ Matej UrbanÄÂiÄ (sl)
+ Zhang Miao (zh_CN)
+
+Evolution 2.29.2 2009-11-16
+---------------------------
+
+Bug Fixes:
+ Bug 600397 - Delete option enabled for undeletable ESource
+ (Matthew Barnes)
+ Bug 600714 - No label colors in popup menu (Matthew Barnes)
+ Bug 600933 - Empty Trash missing for real trash folders
+ (Matthew Barnes)
+ Bug 601601 - No Create Rule in popup menu (Lucian Langa)
+ Bug 601767 - Delete action in calendar view has glitches
+ (Matthew Barnes)
+ Bug 601769 - Print issues in address book (Matthew Barnes)
+ Bug 601774 - "Send Message to Contact" is always disabled
+ (Matthew Barnes)
+ Bug 601785 - Menu glitches in memo and task view (Matthew Barnes)
+ Bug 600133 - Crash on day view print preview without all day events
+ (Milan Crha)
+ Bug 600217 - Crashes in emfh_multipart_related_check (Bharath Acharya)
+ Bug 601626 - pst-import missing link to libeutil (Travis Reitter)
+ Bug 588093 - Allow import of local files from command line (Milan Crha)
+ Bug 601516 - Calendar views missing from calendar popup menu
+ (Matthew Barnes)
+ Bug 593751 - Show correct context menu in calendar views (Milan Crha)
+ Bug 601218 - Accepted meeting doesn't show attachments in calendar
+ view (Milan Crha)
+ Bug 250046 - Composer addresses reading fixes (Milan Crha)
+ Bug 600926 - Fails to build due to missing dependencies
+ (Jonathon Jongsma)
+ Bug 600926 - Fails to build due to missing dependencies (Yan Li)
+ Bug 601219 - Transient dialogs in composer window blocks main window
+ (Matthew Barnes)
+ Bug 271836 - Incorrect signature for "model_cell_changed" signal
+ handler (Li Yuan)
+ Bug 601229 - Crashes when replying a mail. (Chenthill Palanisamy)
+ Bug 557613 - evolution crashed with SIGSEGV in try_open_e_book_cb()
+ (Chenthill Palanisamy)
+ Bug 482327 - Save attached calendar with multiple items easily
+ (Milan Crha)
+ Bug 599792 - Anjal composer's Send button doesn't work after pressed
+ Save Drafts button (Yan Li)
+ Bug 598877 - Crash while sending mail, in report_status function
+ (Milan Crha)
+ Bug 573304 - Forward an email shouldn't strip signature (Milan Crha)
+ Bug 597582 - Original Date: header should be given precedence
+ (David Woodhouse)
+ Bug 596027: In Anjal, although invalid mail address warning popup,
+ mail's tab closed automatically (Yan Li)
+ Bug 557505 - [bbdb] hangs and is unresponsive (Milan Crha)
+ Bug 596827 - Don't remove meeting attendees after edit (Milan Crha)
+ Bug 600402 - Clear search is always enabled in calendar/contact/task
+ (Matthew Barnes)
+ Bug 599124 - Signature always includes an empty line in front of
+ text (Milan Crha)
+ Bug 599627 - Crash when adding a new task in a table (C de-Avillez)
+ Bug 464400 - New mail notify should display sender and subject
+ (Milan Crha)
+ Bug 583450 - [prefer-plain] Ability to hide html attachments
+ (Milan Crha)
+ Bug 599890 - Search should not be remembered across folders
+ (Matthew Barnes)
+ Bug 570835 - Custom e-mail headers inserted with double column
+ (Milan Crha)
+ Bug 599837 - Junk plugin combo box is invisible (Matthew Barnes)
+ Bug 561843 - Properly check for filename being set, to not crash
+ (Milan Crha)
+ Bug 600019 - Menu glitches when an account name is selected
+ (Matthew Barnes)
+ Bug 600014 - Remove warnings from ech_config_widget_factory()
+ (Matthew Barnes)
+ Bug 268644 - unread mail shortcut collides with gtk tree search
+ (Milan Crha)
+ Bug 599896 - Flush outbox option is missing (Matthew Barnes)
+ Bug 599882 - Crash in em_folder_tree_select_prev_path() when wrapping
+ to bottom (Matthew Barnes)
+ Bug 599842 - EConfig does not respond to disabling/enabling EPlugins
+ (Matthew Barnes)
+ Bug 552727 - Flooded by spam checking errors if bogofilter not
+ installed (Milan Crha)
+ Bug 550049 - Disable Mark messages as read actions when unusable
+ (Milan Crha)
+ Bug 571039 - Shows all selected messages in a preview pane on a slow
+ network (Milan Crha)
+ Bug 599199 - Hangs regularly when synchro with pidgin is activated
+ (Milan Crha)
+ Bug 599740 - Crashing in g_thread_init (Milan Crha)
+ Bug 598519 - Cannot open task/memo by double click in calendar day
+ view (Milan Crha)
+ Bug 204900 - The sort indication arrows cover up the icons in tab
+ header (Milan Crha)
+
+Other Changes:
+ Update API documentation. (Matthew Barnes)
+ Hide actions when lockdown settings are enabled. (Matthew Barnes)
+ EWebView popup menu enhancements. (Matthew Barnes)
+ Fix a typo in a comment block. (Matthew Barnes)
+ Update the OtherBinaries line in our .desktop file. (Matthew Barnes)
+ Simplify clipboard handling in addressbook. (Matthew Barnes)
+ Simplify clipboard handling in calendar. (Matthew Barnes)
+ More build failures due to missing internal lib dependencies
+ (Jonathon Jongsma)
+ Fix Windows build (Tor Lillqvist)
+ Fix a potential crash in the mail migration code. (Matthew Barnes)
+ Ensure "pkcs12.h" is the mozilla-nss one and not the gnutls one
+ (Tor Lillqvist)
+ Enable building without Canberra-GTK (Tor Lillqvist)
+ Fix EPluginLib callback signatures. (Matthew Barnes)
+ Kill e-cursor(s) (both of them). (Matthew Barnes)
+ EMFormat plugins should always be enabled. (Matthew Barnes)
+ Add zooming and drag-and-drop to the plugin. (Matthew Barnes)
+ Prototype an inline image plugin. (Matthew Barnes)
+ Convert some "Save As" actions to run asynchronously. (Matthew Barnes)
+ Prototype EIOActivity, which integrates with GIO. (Matthew Barnes)
+ Move EActivity and subclasses to e-util. (Matthew Barnes)
+ Support other forward types for Anjal. (Srinivasa Ragavan)
+ Remove redundant URI/filename conversion functions. (Matthew Barnes)
+ Build filename using g_build_filename instead of hardcoding
+ forward-slash (Tobias Mueller)
+ Quote filename during restore to prevent user assisted arbitrary
+ code execution (Tobias Mueller)
+ Sync to disk the outbox, since if we crash, we endup sending mail
+ again. (Srinivasa Ragavan)
+ Add support for Googlemail and hotmail/live/msn.com accounts.
+ (Srinivasa Ragavan)
+ Fix a regression caused by EEvent cleanup (Lucian Langa)
+ Don't update the message list when right-clicking on a folder.
+ (Matthew Barnes)
+ Add a menu to the Forward toolbar button. (Matthew Barnes)
+ Cleanup and rename filter classes. (Matthew Barnes)
+ Prefer GQueue (or GNode) over EDList. (Matthew Barnes)
+ EImport cleanup. (Matthew Barnes)
+ EEvent cleanup. (Matthew Barnes)
+ EConfig cleanup. (Matthew Barnes)
+ Remove some unfinished / unwanted bits from mail-mt. (Matthew Barnes)
+ Prefer GLib mutexes over pthread mutexes. (Matthew Barnes)
+
+Translations:
+ Thomas Thurman (en@shaw)
+ Jorge González (es)
+ Matej UrbanÄÂiÄ (sl)
+ vasudeven (ta)
+
+Evolution 2.29.1 2009-10-26
+----------------------------
+
+Bug Fixes:
+ Bug #575208 - Use complete template message with all attachments
+ (Milan Crha)
+ Bug #599131 - Crash on new contact adding with similar values as an old
+ (Milan Crha)
+ Bug #585715 - Skip empty parts in multipart/alternative formatting
+ (Milan Crha)
+ Bug #248745 - Indent single mail in a threaded view too (Milan Crha)
+ Bug #599190 - Unable to drop attachments in the attachment bar
+ (Matthew Barnes)
+ Bug #484839 - Sort, when in threading mode, properly (Milan Crha)
+ Bug #599245 - Use bitwise AND instead of logical AND for checking flags
+ (Thomas Andersen)
+ Bug #480361 - Useful action when clicking on a mail notification
+ (Matthew Barnes)
+ Bug #598567 - Can only insert local image files (Matthew Barnes)
+ Bug #593953 - LDAP SSL option order doesn't match with a backend's
+ (Milan Crha)
+ Bug #598631 - Add tooltip of "Ctrl+click to open a link" in buffer tagger
+ (Milan Crha)
+ Bug #238879 - Use explicit text color in a Welcome message (Milan Crha)
+ Bug #552779 - Sort order of messages by "From" is case sensitive
+ (Milan Crha)
+ Bug #267749 - Week numbers are incorrect when the week starts on Sunday
+ (Milan Crha)
+ Bug #470291 - [prefer-plain] Be able to show HTML only messages
+ (Milan Crha)
+ Bug #596860 - Duplicate event gets shown in calendar view (Milan Crha)
+ Bug #339628 - Non-default Draft folders are Draft folders too
+ (Milan Crha)
+ Bug #555901 - Preserve Start/End/Due timezone when editing in list view
+ (Milan Crha)
+ Bug #522783 - Signature separator for HTML E-mails (Milan Crha)
+ Bug #545851 - Set properly sign type on reply of signed message
+ (Milan Crha)
+ Bug #372435 - Show SMIME cert info from mail, not from cert db
+ (Milan Crha)
+ Bug #597473 - Reply-all composes reply to wrong address (Milan Crha)
+ Bug #322261 - vCalendar replies are sent out using the default account
+ (Milan Crha)
+ Bug #245683 - Use QP encoding when composing message with "\nFrom "
+ (Milan Crha)
+ Bug #565306 - "Edit Full" in "Add to address book" searches first
+ (Milan Crha)
+ Bug #458173 - Date selection window in "Advanced Search" inconsistent
+ (Milan Crha)
+ Bug #411768 - Don't remove column by drag&drop out of a table header
+ (Milan Crha)
+ Bug #404227 - Over-aggressive appointment editor date check (Milan Crha)
+ Bug #449520 - Adding a contact to a contact list fails when using a comma
+ (Milan Crha)
+ Bug #468736 - Prevent recursion in em-format (Milan Crha)
+ Bug #562512 - Make hyperlinks clickable in Memos, Tasks and Calendar
+ (Milan Crha)
+ Bug #516000 - Wrong formatted quoted text (Milan Crha)
+ Bug #329710 - [PublishCal] 'Enable' button should update on change
+ (Milan Crha)
+ Bug #373297 - Option for autocomplete in address book preferences
+ (Milan Crha)
+ Bug #523335 - [mail-to-task] Enhancements (Milan Crha)
+ Bug #336337 - Send & receive dialog shows the default smtp server
+ (Milan Crha)
+ Bug #573878 - [face] Plugin is unusable (Milan Crha)
+ Bug #542361 - Unhelpful error warnings (Milan Crha)
+ Bug #314333 - Decrypt body in reply to an inline-PGP encrypted mail
+ (Milan Crha)
+ Bug #592117 - Calendar Printout Love (pepp)
+ Bug #593753 - Calendar search in list view doesn't work properly
+ (Milan Crha)
+ Bug #597123 - Composer's Send Options doesn't work (Milan Crha)
+ Bug #329100 - Choosing adress book for birthdays (Milan Crha)
+ Bug #594471 - Shouldn't call e_error_new/run with NULL 'parent'
+ (Milan Crha)
+ Bug #498095 - Fixing mnemonics (Milan Crha)
+ Bug #596720 - Account assistance repeats itself after finishing
+ (Milan Crha)
+ Bug #598027 - Use vCard instead of VCard (Matthew Barnes)
+ Bug #597932 - Split out Kerberos 5 check into an macro (H. Habighorst)
+ Bug #552552 - File/Empty Trash does not expunge maildir folders
+ (Milan Crha)
+ Bug #595092 - Remove option to skip offline syncrhonization dialog
+ (Matthew Barnes)
+ Bug #596952 - Offline mode does not stick when set from command line
+ (Matthew Barnes)
+ Bug #596824 - evolution hangs on start up (Milan Crha)
+ Bug #597564 - Invalid g_object_unref call in redo_queries (Milan Crha)
+ Bug #593612 - Pane size restoration does not play nice with maximized
+ windows (Matthew Barnes)
+ Bug #597533 - e_file_dialog_save() does not pass parent window
+ (Matthew Barnes)
+ Bug #594373 - Calendar notifications are not cleared from system tray
+ (Milan Crha)
+ BUG #595803 - Fixes a double free (Bharath Acharya)
+ Bug #587014 - Magic space does not work as expected (Lucian Langa)
+ Bug #597224 - Cannot close preferences window with escape key
+ (Lucian Langa)
+ Bug #597151 - [regression] Folder doesn't get deleted properly
+ (Lucian Langa)
+ Bug #456240 - Move exchange plugin to exchange package (Milan Crha)
+ Bug #597108 - E_CONFIG_SECTION headers not properly escaped
+ (Matthew Barnes)
+ Bug #596972 - Drop support for Kerberos 4 (H.Habighorst)
+ Bug #596848 - Use per-target CPPFLAGS in automake files (H.Habighorst)
+ Bug #596843 - Link to libraries when building API docs (H.Habighorst)
+ Bug #596800 - Hang on contacts merging (Milan Crha)
+ Bug #596712 - Recovered messages not autosaved until modification
+ (Matthew Barnes)
+ Bug #596753 - Autocompletion addressbooks not remembered (Milan Crha)
+ Bug #594015 - Keeps "Loading..." node on the first fetch (Milan Crha)
+ Bug #594005 - Mailer preview pane doesn't update on show (Milan Crha)
+ Bug #582745 - Place signature at bottom when Edit As New Message
+ (Milan Crha)
+ Bug #593700 - Opens folder on top (Matthew Barnes)
+ Bug #594534 - Can't select calendar for a new appointment
+ (Matthew Barnes)
+ Bug #595812 - Crash after finishing account set up (Matthew Barnes)
+ Bug #596186 - New Mail account setup Assistant window is blank
+ (Matthew Barnes)
+ Bug #593609 - Have buildable exchange-operations plugin again
+ (Milan Crha)
+ Bug #596268 - Crash when sidebar was clicked while 'loading'
+ (Matthew Barnes)
+ Bug #596130 - Use correct Name and GenericName in .desktop file
+ (William Jon McCann)
+ Bug #596157 - Use "Message-ID" instead of "Message-Id" (Matthew Barnes)
+ Bug #593633 - Runtime warnings trying to create a recurrence event
+ (Milan Crha)
+ Bug #594543 - Crash on folder/message change (Matthew Barnes)
+ Bug #594864 - "Select Folder" is a too generic title (Paul Bolle)
+ Bug #594864 - "Select Folder" is a too generic title (Paul Bolle)
+ Bug #594989 - Drop some dialog titles (Paul Bolle)
+ Bug #591380 - Optional dependencies must be explicitly disabled
+ (H.Habighorst)
+ Bug #595326 - Bump libtool to 2.2 and remove dolt (H.Habighorst)
+ Bug #594988 - Drop generic dialog titles (Paul Bolle)
+ Bug #595501 - Crash on a changed filter rule removal (Milan Crha)
+ Bug #593747 - Calendar preview dates not indicating events (Milan Crha)
+ Bug #593750 - Month view doesn't update / scroll (Matthew Barnes)
+ Bug #593617 - GroupWise plugins are not built (Milan Crha)
+ Bug #595119 - Crash while trying to add a new category in contact
+ (Matthew Barnes)
+ Bug 595687 - Message list popup menu not activated by menu key
+ (Matthew Barnes)
+ Bug 595668 - Crash on startup (Matthew Barnes)
+ Bug #587011 - Add more requirements to evolution-plugin.pc.in
+ (Milan Crha)
+ Bug #594284 - Missing libraries in composer to link properly (Milan Crha)
+ Bug #594528 - Crash when clicked on File->quit (Matthew Barnes)
+ Bug #594017 - Crash on set preview visible (Milan Crha)
+ Bug #594468 - Revise kill-bonobo hack for non-working plugins
+ (Matt McCutchen)
+ Bug #594863 - Message body doesn't allow right click pop up menu
+ (Matthew Barnes)
+ Bug #217066 - Rename folders directly inside folder list (Matthew Barnes)
+ Bug #595002 - There should not be a space before ? in strings
+ (Matthew Barnes)
+ Bug #593899 - "Create Search Folder from Search" does not work
+ (Matthew Barnes)
+ Followup fix for bug #593905. (Matthew Barnes)
+ Bug #593892 - 'Find in message' issues when clearing search
+ (Matthew Barnes)
+ Bug #593905 - 'Subject or Addresses contains' search criteria missing
+ (Matthew Barnes)
+ Bug #572960 - Ignore and drop invalid signatures on load (Milan Crha)
+ Bug #582780 - Use proxy in Google calendar setup plugin
+ (Alexander Klepikov)
+ Bug #590707 - Initialize DBus threading on start (Milan Crha)
+ Bug #594609 - Date field in message list shows incorrect "x days ago".
+ (Chenthill Palanisamy)
+ Bug #594628 - Switching back from Outgoing filters to Incoming filters
+ does not (Chenthill Palanisamy)
+ Bug #593659 - Missing UI error messages (Matthew Barnes)
+ Bug #593646 - Starting in day view does not restore panels correctly
+ (Matthew Barnes)
+ Bug #594573 - Label dropdown box in the rule editor does not work
+ (Matt McCutchen)
+ Bug #571881 - Make messages inherit labels from collapsed subtree
+ (Matt McCutchen)
+ Bug #594484 - Crashed when tried to open more than one memo (Milan Crha)
+ Bug #594407 - Alarms won't go away (Milan Crha)
+ Bug #581602 - Purge calendar function not working (Milan Crha)
+ Bug #586854 - Crash on File->Quit with empty_junk enabled
+ (Ritesh Khadgaray)
+ Reverted part of bug #594284 (Milan Crha)
+ Bug #594284 - FTBFS: missing links (Diego Escalante Urrelo)
+ Bug #594002 - Stuck mail activities when error occurs (Milan Crha)
+ Bug #593754 - Warnings on evolution terminal when open any task
+ (Milan Crha)
+ Bug #593442 - plugin-manager: HIG-ify main screen (Paul Bolle)
+ Bug #593881 - Category icons do not appear in preview pane
+ (Matthew Barnes)
+ Bug #593762 - Event creation window has start date as Today (Milan Crha)
+ Bug #593940 - No options for google address book available
+ (Matthew Barnes)
+ Bug #593872 - Forgets which signature is assigned to which account
+ (Milan Crha)
+ Bug #593922 - Reply freezes evo (Milan Crha)
+ Bug #593761 - Wrong dir for calendar local sources (Milan Crha)
+ Kill debug messages in default-mailer plugin. (Matthew Barnes)
+ Bug #593778 - Clear search enabled when it shouldn't be (Matthew Barnes)
+ Bug #593783 - Edit contact option in composer doesn't work
+ (Matthew Barnes)
+ Bug #592169 - "Checking for new mail" doesn't show which folder
+ (Milan Crha)
+ Bug #593776 - Fix include of a11y/addressbook and a11y/calendar
+ (H.Habighorst)
+ Bug #593779 - re-committing patch from bug #214238 (Milan Crha)
+ Bug #593627 - Tool bar > new > contact list doesn't work (Matthew Barnes)
+ Bug #593675 - Freeze on startup (Milan Crha)
+ Bug #593614 - efh_format_secure() recurses forever (Matthew Barnes)
+ Bug #579598 - Change in view types (from Menu) is not working
+ (Milan Crha)
+ Bug #593685 - Insensitive actions after start (Matthew Barnes)
+ Bug #593613 - Doesn't differentiate an appointment and meeting button
+ click (Matthew Barnes)
+ Bug #494531 - Use quoted-printable encoding when necessary (David Liang)
+ Bug #593648 - mail-to-task used full path in .eplug file (Milan Crha)
+ Bug #592680 - Remove deprecated Encoding key from desktop file
+ (Frederic Peters)
+ Bug #590687 - Evolution not restoring data from backup archive
+ (Milan Crha)
+ Bug #592873 - Initialize Force Read only check state properly
+ (Milan Crha)
+ Add menu item ellipsis according to bug #324492. (Matthew Barnes)
+ Bug #488409 - Remember size of filter/vfolder editor windows
+ (Matthew Barnes)
+ Bug #592335 - Submit bug-report doesn't work (Matthew Barnes)
+ Bug #511769 - Poor indication of when network is unavailable
+ (Matthew Barnes)
+ Bug #359909 - "New" Button too small (Matthew Barnes)
+ Bug #571488 - Migrate from deprecated gnome_sound to libcanberra
+ (H.Habighorst)
+ Bug #592680 - Remove deprecated Encoding key from desktop file
+ (Frederic Peters)
+ Fixed bug #591916 (Mario Blättermann)
+ Bug #592551 - Build break fix caused by bug #581288 (Milan Crha)
+ Bug #567260 - Migrate from GnomeDruid to GtkAssistant (Milan Crha)
+ Bug #591829 - Dragging mails to folder tree does not work
+ (Matthew Barnes)
+ Bug #591830 - Inline attachments no longer shown (Matthew Barnes)
+ Bug #592032 - Marks message as read when preview is off (Matthew Barnes)
+ Bug #592034 - Reply to List doesn't work (Matthew Barnes)
+ Bug #591755 - Gtk-Doc build failure when NM support disabled
+ (H.Habighorst)
+ Bug #567260 – Migrate from GnomeDruid to GtkAssistant (Milan Crha)
+ Bug #591377 – Fails to detect krb5 in configure with -as-needed
+ (H.Habighorst)
+
+Other Fixes:
+ Coding style and whitespace cleanups. (Matthew Barnes)
+ Put compiler warning flags in AM_CPPFLAGS instead of CFLAGS.
+ (Matthew Barnes)
+ Slightly better error dialog on "Unable to book" (Milan Crha)
+ Check whether message-list is filtered properly (Milan Crha)
+ Enable mail-next-unread and mail-prev-unread for multi-selections.
+ (Matthew Barnes)
+ Clean up includes in main.c. (Matthew Barnes)
+ Gtk-Doc updates. (Matthew Barnes)
+ Shell cleanup. (Matthew Barnes)
+ Enable File->Empty Trash menu item for all folders (Milan Crha)
+ Build with GTK_DISABLE_DEPRECATED and fix resulting breakage.
+ (Matthew Barnes)
+ Various composer autosave fixes. (Matthew Barnes)
+ Code cleanup in e-msg-composer.c (Matthew Barnes)
+ Show import progress directly in the assistant window. (Matthew Barnes)
+ Rename EShellImporter to EImportAssistant and move it to widgets.
+ (Matthew Barnes)
+ Convert the shell importer to a widget class. (Matthew Barnes)
+ Shell importer does not need an EShellWindow. (Matthew Barnes)
+ Trim unused or unnecessary bits from the import framework.
+ (Matthew Barnes)
+ Overlooked compiler warnings from exchange-operations plugin (Milan Crha)
+ Make gweather detection consistent with other optional libraries.
+ (Matthew Barnes)
+ No longer need the X11 configure checks. (Matthew Barnes)
+ Rework optional plugin detection to fix distcheck. (Matthew Barnes)
+ Developer documentation improvements. (Matthew Barnes)
+ Typo fix (Andre Klapper)
+ Disable gdk_event_get_graphics_expose() call in EMap. (Matthew Barnes)
+ Goodbye libgnome and libgnomeui!! (Matthew Barnes)
+ Kill the killev program, and the whole tools directory. (Matthew Barnes)
+ EMFolderTree code cleanup. (Matthew Barnes)
+ Copy folder tree state of 1st window when opening new windows.
+ (Matthew Barnes)
+ Homing in on a reference counting issue in EShellContent.(Matthew Barnes)
+ Introduce an EShellView::execute-search signal. (Matthew Barnes)
+ Relax the EBinding API to reduce GObject casting. (Matthew Barnes)
+ Kill EPopup. (Matthew Barnes)
+ Kill ECalPopup. (Matthew Barnes)
+ Trim more fat off the GnomeCalendar API. (Matthew Barnes)
+ Update GConf when the online/offline button is clicked. (Matthew Barnes)
+ Track the timezone in one place: ECalModel (Matthew Barnes)
+ Remove unnecessary <calendar/gui/e-cal-popup.h> includes. (Matthew Barnes)
+ Kill EMenu. (Matthew Barnes)
+ Fix msgfmt check by setting strings to fuzzy (Andre Klapper)
+ Allow calendar to be written as a external app and split the huge .so
+ (Srinivasa Ragavan)
+ Changes for having a light version of calendar. (Srinivasa Ragavan)
+
+Translations:
+ Ivar Smolin (et)
+ Mattias Põldaru (et)
+ Åsmund Skjæveland (nn)
+ drtvasudevan (ta)
+ Leonid Kanter (ru)
+ Jorge González (es)
+ David Planella (ca)
+ Andrej ŽnidaršiĠ(sl)
+ Matej UrbanÄÂiÄ (sl)
+ Luca Ferretti (it)
+ Daniel Nylander (sv)
+ Khaled Hosny (ar)
+ Adi Roiban (ro)
+ Takayuki KUSANO (ja)
+ Andre Klapper (cs)
+ Yavor Doganov (bg)
+ Kostas Papadimas (el)
+ Chao-Hsiung Liao (zh_HK)
+ Mario Blättermann (de)
+ Christian Kirbach (de)
+ Gabor Kelemen (hu)
+ Sandeep Shedmake (mr)
+ krishnababu k (te)
+ Sweta Kothari (gu)
+ Wadim Dziedzic (pl)
+ Iestyn Pryce (cy)
+ Ask H. Larsen (da)
+ Kenneth Nielsen (da)
+ Ilkka Tuohela (fi)
+ A S Alam (pa)
+ Žygimantas BeruÄÂka (lt)
+ Igor Nestorović (sr)
+ Kjartan Maraas (nb)
+ Denis Arnaud (br)
+
+Evolution 2.27.91 2009-08-24
+----------------------------
+
+Calendar:
+ #591414 - libevolution-cal-shared is linked as a module (Götz Waschk)
+
+Miscellaneous:
+ #591321 - Cosmetic changes and fixes in configure.ac (H.Habighorst)
+ #591326 - Keep m4 macros in their own folder (H.Habighorst)
+ #591377 - Fails to detect krb5 in configure with -as-needed
+ (H.Habighorst)
+
+Other Fixes:
+ Fix msgfmt check by setting strings to fuzzy (Andre Klapper)
+ Update czech screenshots. (Andre Klapper)
+
+Translations:
+ Alexander Shopov (bg)
+ Jamil Ahmed (bn)
+ Gil Forcada (ca)
+ Carles Ferrando (ca@valencia)
+ Jorge González (es)
+ Mattias Põldaru (et)
+ Ivar Smolin (et)
+ Seán de Búrca (ga)
+ Antón Méixome (gl)
+ Mark Krapivner (he)
+ Changwoo Ryu (ko)
+ Kjartan Maraas (nb)
+ Sandeep Shedmake (mr)
+
+Evolution 2.27.90 2009-08-10
+-----------------------------
+
+Bug Fixes:
+
+Calendar:
+ #205137 - Configurable date formats in components (Milan Crha)
+ #587468 - Show meeting icon for component with attendees only (Milan Crha)
+ #320071 - Unclear why you can't edit appointment in calendar (Milan Crha)
+ #314599 - Recurrence Tab Should Not Default To Forever (Milan Crha)
+ #325278 - cannot access parts of "save calendar" without mouse (Milan Crha)
+ #324676 - Print preview displays preview of previous month (Milan Crha)
+ #590392 - Show selected day in day view's second timezone column (Milan Crha)
+ #539334 - Postpone processing event when called recursively (Milan Crha)
+ #328361 - Support for "Fifth Sunday *of the month*" (Marcel Stimberg)
+ #514725 - Critical warnings with appointments (Milan Crha)
+ #273535 - Meeting request with attachments has bogus CID value (Milan Crha)
+ #300567 - Calendar drawing optimizations (Milan Crha)
+ #317290 - [Publish-Calendar] Cancel setup should cancel (Milan Crha)
+ #245829 - Cannot copy (with mouse for pasting) appointment summary (Milan Crha)
+ #203853 - Cut/Copy key bindings don't work in day and week views (Milan Crha)
+ #575581 - All Day Events Should Not Depend On Calendar Scrolling (Milan Crha)
+ #420513 - Be able to notify about meeting only new attendees (Milan Crha)
+ #579646 - Remember alarm's last notified per calendar (Milan Crha)
+
+Mail:
+ #590747 – Composer autosave can easily lose data (Philip Withnall)
+ #562913 – Changed signature format not written to GConf (Matthew Barnes)
+ #401530 - [imap-features] imap-headers.glade issues (Milan Crha)
+ #563795 - Crashed while importing an mbox file in local folder (Milan Crha)
+ #589982 - Fix a critical warning while replying for a mail (Srinivasa Ragavan)
+
+Plugins:
+ #586076 - [external-editor] Pass cursor pos to vim (Milan Crha)
+ #584030 - [Mail-To-Task] improve duplicate handling and such (Milan Crha)
+ #573919 - [Mail-Notification] Check for 'actions' capability (Ken VanDine)
+ #563041 - Template plugin doesn't work; added new variables (Bharath Acharya)
+
+Miscellaneous
+ #551127 - Added translators comment and changed strings slightly (Milan Crha)
+ #580895 - Fix evolution build break (Milan Crha)
+ #580895 - Kill libgnomeui/gnome-thumbnail.h (Milan Crha)
+ #325611 - Rephrased translators comments (Milan Crha)
+ #590260 – Minimum requirement of libpst not checked (Matthew Barnes)
+
+Other Fixes:
+
+Calendar:
+ Allow calendar to be written as a external app and split the huge .so
+ to (Srinivasa Ragavan)
+
+Translations:
+ Jorge González (es)
+ Seán de Búrca (ga)
+ Iestyn Pryce (cy)
+ Ivar Smolin (et)
+ Kjartan Maraas (nb)
+ Mattias Põldaru (et)
+
+
+Evolution 2.27.5 2009-07-27
+---------------------------
+
+Bug Fixes:
+
+Calendar:
+ #266150 - In list view Delete option not working in menu and toolbar
+ (Milan Crha)
+ #572176 - Allow local iCal files to be selected as calendar source
+ (Milan Crha)
+ #583374 - The broken Google calendar import should be replaced by
+ the working CalDAV support (Milan Crha)
+ #583527 - Provide the option of sending an e-mail to meeting attendees
+ irrespective of the calendar backend (Chenthill Palanisamy)
+ #583972 - Resend meeting dialog isn't coming properly
+ (Chenthill Palanisamy)
+ #588856 - Google calendar backend to CalDAV migration code (Milan Crha)
+
+Contacts:
+ #589580 - Crashes when dragging an image to the contact editor
+ (Milan Crha)
+
+Mail:
+ #589494 - Doesn't print full list of recipients (Bharath Acharya)
+ #589412 - Misleading notice in message list when messages are hidden
+ (Milan Crha)
+
+Miscellaneous:
+ #578945 - Adapt to changes in libpst 0.6.41 (Bharath Acharya)
+ #588787 - Crash on search in an active account or all accounts
+ (Milan Crha)
+ #339361 (BNC) - soap threading not working. (Chenthill Palanisamy)
+ #472079 (BNC) - Cannot Edit Account When Proxy (Bharath Acharya)
+ #480095 (BNC) - Alpha Search In Proxy Dialog Crashes Evolution
+ (Bharath Acharya)
+
+Other Fixes:
+ Don't warn when NM support is explicitly disabled. (Matthew Barnes)
+ Make it possible to send/receive without dialog (Srinivasa Ragavan)
+
+Translations:
+ Mario Blättermann (de)
+ Daniel Nylander (sv)
+ Jorge González (es)
+
+Evolution 2.27.4 2009-07-15
+---------------------------
+
+Bug Fixes:
+
+Addressbook:
+ #561300 - Edit contact's Notes on its own tab. (Milan Crha)
+ #586109 - [vcard-inline] Crash while rendering inline vcard (Milan Crha)
+ #555326 - Suppress Del key press in Contacts source selector (Marcel Stimberg)
+
+Calendar:
+ #586251 - Let the SSL checkbox for Google calendar work (Milan Crha)
+ #513451 - Select Today for calendar views on the first showing (Milan Crha)
+ #238058 - Show more from summary for events with icons (Milan Crha)
+ #245723 - Show days with transparent events in italic (Milan Crha)
+ #252296 - Do not preset alarm for all day events (Milan Crha)
+ #525689 - Do not show all days as Sunday in a comp-editor (Milan Crha)
+ #236996 - Calendar display for weekends in month view (Milan Crha)
+ #251694 - Highlight current day in a calendar (Milan Crha)
+ #425582 - Calendar Alarm Display is not noticable enough (Milan Crha)
+ #245723 - Show days with transparent events in italic (Milan Crha)
+ #240605 - auto-select next day at midnight in selected day view (Milan Crha)
+
+Mail:
+ #345775 – Missing blank line between messages in saved mbox (Matthew Barnes)
+ #464131 – Allow inline view of application/mbox attachments (Matthew Barnes)
+ #568302 - Skip "noselect=yes" folders on Send/Receive (Milan Crha)
+ #268644 - unread mail shortcut collides with gtk tree search (Milan Crha)
+ #587699 - Localize only local folder names (Milan Crha)
+ #214238 - Indicate unread emails in closed tree subfolders (Milan Crha)
+ #586958 - Too long texts instartup wizard (Michael Terry)
+
+Plugins:
+ #586332 - Build error (long gint) (Matthew Barnes)
+ #346146 - Appointments in Sent folder should not display actions (Milan Crha)
+ #566369 - backup-restore - recognize broken archive (Milan Crha)
+ #566369 - fix string typo "cancelled" => "canceled" (Milan Crha)
+ #588106 – Makefile.am misuses *_LDFLAGS (Daniel Macks)
+
+Misc:
+ #586378 - Various build cleanups (H.Habighorst)
+ #586478 – Fix quoting in configure.ac (H.Habighorst)
+ #586631 – Rearrange autotool initialization in configure.ac (H.Habighorst)
+ #586632 – Require automake 1.9 (H.Habighorst)
+ #586629 – Fix whitespace in configure.ac (H.Habighorst)
+ #586806 – Fix iconv cflags/libs in configure.ac (H.Habighorst)
+ #586809 – Enable "silent rules" automake 1.11 option (Matthew Barnes)
+ #587138 - Require libxml2 2.7.3 (Yavor Doganov)
+ #587374 - iconv test broken on some gcc (Matthew Barnes)
+ #586991 – Require autoconf 2.58 / various configure cleanups (H.Habighorst)
+ #588277 – Unnecessary special-purpose configure flag (Matthew Barnes)
+ #588018 – NetworkManager & DBUS build check rewrite (H.Habighorst)
+
+Other Fixes:
+
+Mail:
+ Re-arrange attachment bar files for Anjal's and webkit rendering. (Srinivasa Ragavan)
+ Fix properly include paths, since this is one of our public headers (Fridrich Strba)
+ Do not treat edit accounts as new accounts in a case (Srinivasa Ragavan)
+Shell:
+ Check network manager state on startup and set start_offline appropriately (Chenthill Palanisamy)
+
+Misc:
+ Use G_BEGIN_DECLS / G_END_DECLS macros. (Matthew Barnes)
+ Stop abusing forward declarations. (Matthew Barnes)
+ Remove a weak pointer when disposing EAttachmentHandler. (Matthew Barnes)
+ Fix "make check" errors. (Matthew Barnes)
+ Remove INSTALL from source control. (Matthew Barnes)
+ Fixes for anjal (Srinivasa Ragavan)
+ Read entire UI definition in "eplug" files. (Matthew Barnes)
+ Add localized screenshots (Andre Klapper)
+ Hide proper widgets from filter.glade for searches (Milan Crha)
+ Use AM_CPPFLAGS instead of INCLUDE in all Makefile.am. (Matthew Barnes)
+ Fix whitespace issues in em-account-editor.c. (Matthew Barnes)
+ Kill EConfigListener. (Matthew Barnes)
+ Work around deprecation of g_mount_unmount(). (Matthew Barnes)
+
+
+Translations:
+ Manoj Kumar (or)
+ Mark Krapivner (he)
+ Ivar Smolin (et)
+ Jorge Gonzalez (es)
+ drtvasudevan (ta)
+ Runa Bhattacharjee (bn)
+ Andre Klapper (de)
+ Christian Kirbach (de)
+ Daniel Nylander (sv)
+ Maxim V. Dziumanenko (uk)
+
+Evolution 2.27.3 2009-06-15
+---------------------------
+
+Bugs Fixed:
+ #585523 - Don't link against libsoftoken3 explicitly (Jeff Cai)
+ #584902 - Disabled default account hides "From" in composer (Matthew Barnes)
+ #585554 - Opening PDF attachment crashes in e_attachment_open_handle_error()
+ (Matthew Barnes)
+ #584733 - Fixed account setup to work after Anjal merge (Srinivasa Ragavan)
+ #573263 - Crash in reset_layout (text) at e-text.c (Milan Crha)
+ #362907 - Give icons to Drafts/Sent/Templates folders (Milan Crha)
+ #584733 - Cannot create new account (Srinivasa Ragavan)
+ #581780 - Remember passwords in keyring for web calendars too (Milan Crha)
+ #572543 – Doesn't show correct application for pdf attachments (Matthew Barnes)
+ #581280 - Wrong attachment name in event (Matthew Barnes)
+ #582939 - Drop support for CDE (Matthew Barnes)
+ #574940 - Do not use freed memory in EMFolderView/Browser (Milan Crha)
+ #337082 - Do not produce unnamed folders in a folder tree (Milan Crha)
+ #580212 - Report inline parts only when found both tags (Milan Crha)
+ #323037 - Folder emblem to show new mail arrival (Milan Crha)
+ #583446 - refresh folder hook (Lucian Langa)
+ #584154 – custom icon folder hook does not work (Milan Crha)
+ #583991 - "Suggest automatic display of attachment" does not work (Matthew Barnes)
+ #583441 - bbdb plugin is getting information from composer now (Milan Crha)
+ #535516 - Crash in GConf Bridge while replying (Milan Crha)
+ #540269 - Do not crash in em_format_is_attachment (Milan Crha)
+ #540269 - Do not crash in em_format_is_attachment (Milan Crha)
+ #578335 - CalDAV - replace '@' in username to "%40" (Milan Crha)
+ #524497 - Change the order of getting an account (Jeff Cai)
+
+Translations:
+ Manoj Kumar (or)
+ Runa Bhattacharjee (bn_IN)
+ Claude Paroz (fr)
+ Kjartan Maraas (nb)
+ Jorge Gonzalez (es)
+ Gabor Kelemen (hu)
+ Ask H. Larsen (da)
+
+Other Fixes:
+ Added couple of APIS for EAttachmentPaned to hide combo and get the
+ widget's container.(Srinivasa Ragavan)
+ Fix a runtime warning for zero-length attachments. (Matthew Barnes)
+ Fix Compiler warnings. (Matthew Barnes)
+ Fix build on Windows: link with needed libraries. (Tor Lillqvist)
+ (Fridrich Strba)
+ Replace libgnome function with equivalent glib functions. (Fridrich Strba)
+
+Evolution 2.27.2 2009-05-25
---------------------------
-Bugzilla Bugs Fixed (see http://bugzilla.ximian.com/show_bug.cgi):
+Bug Fixed:
+
+ #274117 – Difficult to post a new message to newsgroups
+ (Matthew Barnes)
+ #440919 – Evolution can't attach "zero length" files (Matthew Barnes)
+ #458491 – Remove useless "Call To..." popup menu option
+ (Matthew Barnes)
+ #523216 – User-oriented plugin descriptions (Matthew Barnes)
+ #524497 – Wrong "From" value if multiple accounts configured
+ (Jeff Cai)
+ #559366 – Evolution: Cannot scroll the Calendar view using the
+ arrow keys (Marcel Stimberg)
+ #571496 – Migrate from deprecated gnome_execute to
+ g_spawn/xdg-terminal (Adam Petaccia)
+ #578176 – "Send message to contact" does not honor "always BCC"
+ (Matthew Barnes)
+ #578478 – Composer shows not all "From" information (Matthew Barnes)
+ #579779 – Evolution crashes when updating a repeated (ej, yearly)
+ event for al event instances (Milan Crha)
+ #580163 – alarm notify window does not resize correctly
+ (Ritesh Khadgaray)
+ #580900 – Kill libgnomeui/gnome-dateedit (Adam Petaccia)
+ #580925 – Better search bar for word searches (Matthew Barnes)
+ #581424 – Personal folder tree appears besides Public folder when
+ you go to Folder > Subscription (Johnny Jacob)
+ #581454 – Move nautilus-sendto integration to Evolution
+ (Matthew Barnes)
+ #582144 – Evolution not showing proper attachment filename
+ (Matthew Barnes)
+ #582168 – Remove duplicated shebang and comment from autogen.sh
+ (Damien Lespiau)
+ #582585 – Crash when deleting multiple attachments from composed
+ mail (Matthew Barnes)
+ #582626 – Time zone "select" button is broken (Milan Crha)
+ #582744 – CC field autofill doesn't work for replies (Matthew Barnes)
+ #583360 – Evolution won't set "UTC" as a "second zone" on Calendar
+ and Tasks preferences (Milan Crha)
+ #498712 – (bnc) deleting meetings sometimes does not work properly
+ (Chenthill Palanisamy)
+ #499107 – (bnc) delete all the recurring instances from the folder
+ (Chenthill Palanisamy)
+
+Updated Translations:
+
+ Marios Zindilis (el)
+ Jorge Gonzalez (es)
+ Ivar Smolin (et)
+ Manoj Kumar Giri (or)
+ Kjartan Maraas (nb)
+ Theppitak Karoonboonyanan (th)
+
+Evolution 2.27.1 2009-05-04
+----------------------------
+
+Bug fixes:
+ #504767 - Inherit modality from a parent's window
+ #574680 - Remove all headers except "References" and "In-Reply-To" when composing from an existing message
+ #552583 - Compare only user names, without a domain part, if such exists
+ #576694 - Handle absolute font sizes correctly
+ #576696 - Set mandatory properties
+ #576845 - typo in code.
+ #576921 - Unref GtkListStore right after gtk_tree_view_set_model
+ #576921 - Remove needless GtkListStore objects
+ #577717 - Fill some default values to mandatory properties of ECalComponentAttendee
+ #569765 - Don't keep the selected message in the message list if it is removed from the folder
+ #578034 - Use proper format string
+ #577989 - Use proper format string
+ #537530 - Use g_filename_to_utf8 for attachment filenames
+ #529745 - Add more file types in a file filter for certificates
+ #539002 - Show all other certificates in a contact tab
+ #523802 - Use copy of the preview panel, when focused, and events' copy otherwise
+ #574248 - Compare base URI case insensitively
+ #471083 (bnc) - Do not allow deletion of system folders
+ #561312 - Do not invoke recurrence dialog while modifying detached instances
+ #467659 (bnc) - Set the description for send mail operation
+ #578685 – evolution crashed with SIGSEGV
+ #577929 – Consolidate marshallers
+ #565780 – Message view is tightly packed and hard to read
+ #577898 – Port ExoBinding to Evolution
+ #572348 - Removed deprecated Gtk+ symbols
+ #577615 - Get rid of "Adjust for daylight saving time" option
+ #205804 - Include timezone information in a tooltip when differs from user's
+ #340783 - Show error or success to user with publish-calendar plugin
+ #381132 - Use system timezone in Evolution
+ #552583 - Let the provider compare urls
+ #569652 - Use new ESourceList API (simplifies code)
+ #342296 - Be able to save mail to event, meeting, task or memo
+ #563954 - Sort UIDs before using them
+ #571272 - Possible leak fix
+ #573704 - Calendar - do not close editor after error
+ #579306 - Do not crash on delete folder
+ #561188 - Define .error files correctly and external-editor crash fix
+ #553535 - Do not delete text lines on signature set in composer
+ #575773 - Allow Last Modified and Created columns for event table
+ #491755 - Sanitize values from GConf before using them
+ #579635 - Hide last junked message too from the non-junk folder
+ #516933 – Rewrite attachment UI
+ #579550 - Do not mark newly recognized Junk messages Read
+ #572348 - Fix filter breakage after deprecated Gtk+ symbols removal
+ #578335 - Store username in a source URL in CalDAV
+ #567145 - External Editor rewrite
+ #579774 - Use spamc to learn junk if available
+ #570730 - Get rid of gnome-config in Evolution
+ #273818 - Allow scrolling Month View by a week only
+ #580898 – Kill libgnomeui/gnome-winhints
+ #580894 – Kill libgnome/gnome-util (partial fix)
+ #580896 – Kill libgnome/gnome-program
+ #580892 – Kill libgnomeui/gnome-app and gnome-app-helper
+ #580893 – Kill libgnome/gnome-gconf
+ #575242 – New composer window not autosaved until modification
+ #581032 – Some links can't be opened
+ #542685 – [default-mailer] Leaking GConfValue
+ #572977 – Use g_strerror() instead of strerror()
+ #577482 – Bad strings in plugins/itip-formatter/itip-view.c
+ #325131 – Do not translate ETable property nicknames
+ #574781 – Bad e-send-options.glade strings
+ #575124 – Clarify "S_pecify the mailbox name" string
+ #575122 – "before every anniversary/birthday" is missing translator comment
+ #573170 - Add back support for vfolder of vfolders
+ #569696 – Memory leak in message-list
+ #573830 - g_timeout_add_seconds should be preferred to g_timeout_add
+ #355240 - String errors
+
+Other updates:
+ - Icons for windows binaries.
+
+Updated translations:
+ Djihed Afifi (ar)
+ Jorge Gonzalez Gonzalez (es)
+ Manoj Kumar Giri (or)
+ Takeshi AIHANA (ja)
+ Claude Paroz (fr)
+ Amanpreet Singh Alam (pa)
+ Shankar Prasad (kn)
+ Jen Ockwell (en_GB)
+ Mattias Põldaru (et)
+ Fotis Tsamis (el)
+ Shankar Prasad (kn)
+ Baris Cicek (tr)
+ Miloš Popović (sr)
+ Ivar Smolin (po)
+ Theppitak Karoonboonyanan (th)
+ Khaled Hosny (ar)
+ Ihar Hrachyshka (be)
+ Gil Forcada (ca)
+ Kjartan Maraas (nb)
+ Christian Kirbach (de)
+
+Evolution 2.26.0 2009-03-16
+----------------------------
+
+What is new in 2.26.0?
+
+ Exchange MAPI integration for Exchange 2007 connectivity.
+ PST Import support through plugins.
+ Calendar view performance improvements
+ Loads of stability & bug fixes
+
+Evolution 2.25.92 2009-03-02
+----------------------------
+
+Updated Translations:
+ Andre Gondim (pt)
+ Bruno Brouard and Claude Paroz (fr)
+ Changwoo Ryu (ko)
+ Chao-Hsiung Liao (zh)
+ Clytie Siddall (vi)
+ Daniel Nylander (sv)
+ David Planella (ca)
+ Gabor Kelemen (hu)
+ Ihar (be)
+ Ilkka Tuohela (fi)
+ Inaki Larranaga Murgoitio (eu)
+ Ivar Smolin (et)
+ Jiri Eischmann (cs)
+ Jorge Gonzalez (es)
+ Kenneth Nielsen (da)
+ Kjartan Maraas (nb)
+ Manoj Kumar Giri (or)
+ Mattias Põldaru (et)
+ Philip Withnall (en)
+ Simos Xenitellis (el)
+ Sweta Kothari (gu)
+ Takeshi AIHANA (ja)
+ Theppitak Karoonboonyanan (th)
+ Wouter Bolsterlee (nl)
+
+Bug Fixes:
+ #238346 : Set timezones from component to the calendar first, then add events (Milan Crha)
+ #333716 : Do not store incomplete or broken files in a cache (Milan Crha)
+ #404232 : Rebuild view immediately for an advanced search too (Milan Crha)
+ #404232 : search bar text is set, thus the text will not be empty, which is considered as "no search" these days. (Milan Crha)
+ #529037 : Disconnect signals on ESource-s too, not only on ECal-s (Milan Crha)
+ #548623 : No auto-proxy at the moment (Milan Crha)
+ #550114 : Replaced 'compute_mouse_over' with 'get_mouse_over', now works with cached values 'motion_row', 'motion_col' (Milan Crha)
+ #550114 : Show proper tooltip in table with grouping columns (Milan Crha)
+ #551470 : Do not force adding "--
+ #554458 : Make content type from a mime type first (Milan Crha)
+ #555888 : Do not overwrite user settings with system proxy settings (Milan Crha)
+ #558366 : Set default timezone to resolve floating DATE-TIME properly (Milan Crha)
+ #559027 : Do not set date for 'None' value (Milan Crha)
+ #559719 : Use it's own/unique name for the property on the 'epl' and free the widget only if it wasn't freed yet (Milan Crha)
+ #561465 : Expand 'Attendee' column instead of the last (Milan Crha)
+ #563212 : Ensure empty GError before filling it (Milan Crha)
+ #564229 : Do not use uninitialized variable (Milan Crha)
+ #564229 : Initialize the EPluginUI registry during class initialization, so that it's sure to be there when we need it (Matthew Barnes)
+ #567089 : Do not crash when no From set yet (Milan Crha)
+ #567949 : Do not free memory before done with it (Milan Crha)
+ #568176 : Make the migration dialog look better (Gilles Dartiguelongue)
+ #569700 : Stop reading from a network when operation was canceled (Milan Crha)
+ #569986 : (Srinivasa Ragavan)
+ #570364 : (Gabor Kelemen)
+ #571625 : Use black/white for foreground instead of active/inactive text color (Chow Loong Jin)
+ #571721 : (Milan Crha)
+ #572268 : Do not duplicate "Loading..." node when adding to existing node (Milan Crha)
+ #572348 : Call gtk_status_icon_set_tooltip_text() instead of gtk_status_icon_set_tooltip() (decprecated) (Matthew Barnes)
+ #572399 : Do not read from invalid iterator after call of row changed (Milan Crha)
+ #572543 : Always look for alternative apps for application/octet-stream (Milan Crha)
+ #572903 : (Philip Withnall)
+ #572950 : Fix ordering of -I compiler directives (Daniel Macks)
+ #572962 : Pass e_shell_dbus_initialise() the right type of object, and fix the incorrect function declaration. Go offline when we see NM_STATE_ASLEEP from NetworkManager (Matthew Barnes)
+ #572975 : Destroy file chooser dialog early enough to not have hidden any other windows below it (Milan Crha)
+ #573198 : (Chenthill Palanisamy)
+ $566556 : Make it use the proper action. (Paweł Zembrzuski)
+
+Other contributions:
+ Build a "GUI" executable. (Tor Lillqvist)
+ Do not use non-zero page size in an adjustment, it's deprecated now. (Milan Crha)
+ Format signature/encryption information nicer. (Milan Crha)
+ Function-declaration compiler warning. (Suman Manjunath)
+ Migrate from deprecated gtk_window_set_policy to gtk_window_set_resizable (Andre Klapper)
+ Remove deprecated gtk_combo_set_case_sensitive() call. (Andre Klapper)
+ Remove useless and deprecated gtk_layout_freeze and gtk_layout_thaw calls. (Andre Klapper)
+ Substitute some deprecated gtk functions. (Andre Klapper)
+
+Evolution 2.25.90 2009-02-02
+----------------------------
+
+Updated Translations:
+ Andre Klapper (de)
+ Bharath Acharya (PO)
+ Changwoo Ryu (ko)
+ Daniel Nylander (sv)
+ Funda Wang (zh)
+ Gabor Kelemen (hu)
+ Hendrik Richter (de)
+ I. Felix (ta)
+ Ilkka Tuohela (fi)
+ Jonh Wendell (pt)
+ Jorge Gonzalez (es)
+ Jovan Naumovski (mk)
+ Kjartan Maraas (nb)
+ Miloš Popović) (sr)
+ Nguyễn Thái Ngá»Âc Duy (vi)
+ Raivis Dejus (lv)
+ Wadim Dziedzic (pl)
+
+Bug Fixes:
+ #318003 : Support move of the event in day view when dropped over the source list. Use the same function for events/tasks/memos. Encode string data same as memos and tasks do, with a source UID. Removed inappropriate comments. (Milan Crha)
+ #342446 : Use localized digits in the calendar widget. (behnam esfahbod)
+ #362754 : Ensure to show default groups and sources with actual localized name, not the one it was stored last time. (Milan Crha)
+ #442869 : Delete attendee only if we have enough rights for it. (Milan Crha)
+ #450554 (BNC) : Remove all attendees from the list-view and name-selector before populating it on 'event_changed' callback. (Suman Manjunath)
+ #470474 (BNC) : fix unused strings. (Bharath Acharya)
+ #539467 : Find group by its base uri, not by a localized name. (Milan Crha)
+ #546637 : Partial fix for unread vfolders (Srinivasa Ragavan)
+ #559604 : Additional Information On Calendar Tooltip (Milan Crha)
+ #561628 : Initialize 'parent_class' with its parent, not with itself. (Milan Crha)
+ #562449 : regression in vfolder functionality with read/deleted messages (Srinivasa Ragavan)
+ #567654 : Crash in vfolders (Srinivasa Ragavan)
+ #567824 : Fix all header related bugs in calendar printing. (Bharath Acharya)
+ #347287 : MVC for calendar. (Chenthill Palanisamy)
+ #450535 (BNC): Monthly Calendar Highlighted Days Does Not Pass To Meeting/Appointment (Chenthill Palanisamy)
+ #463602 (bnc) In Calendar View, Meeting/Recur/Alarm Icons Obscure Time Of Meeting. (Chenthill Palanisamy)
+
+ Other contributions:
+
+ Cross-compilation from Linux to Windows support by Fridrich Strba. on Windows.
+ Added hooks for Seek plugin which is under development. (Johnny Jacob)
+ Show attachment bar at all times. Seems like the contents are missing at times. (Srinivasa Ragavan)
+ Fix compiler warnings. (Matthew Barnes)
+ function-declaration compiler warning. (Suman Manjunath)
+ Migrate the test programs off libgnomeui/libbonobo. (Matthew Barnes)
+
+Evolution 2.25.5 2009-01-19
+---------------------------
+
+Updated Translations:
+ Andre Klapper (de)
+ David Planella (ca)
+ Hendrik Richter (de)
+ Jorge Gonzalez (es)
+ Kjartan Maraas (nb)
+ Luca Ferretti (it)
+ Wadim Dziedzic (pl)
+
+Bug Fixes:
+ #208426 : Added support for importing .pst files into Evolution (Bharath Acharya )
+ #245156 : Helper functions to make it easier. (Milan Crha)
+ #246313 : Added ability to show all event in one-day view, but show only up to 6 columns in a multi-day view. (Milan Crha)
+ #303738 : Forget password on AuthFailed or AuthRequired and try to reopen on AuthFailed status, which will ask for a password again. Show "Authentication Required" on such status returned. Do not free memory which hold ECal. Also always forget password for calendar with the URL key. (Milan Crha)
+ #310844 : Transfer master object instead of the instance for recurring events. (Milan Crha)
+ #339879 : Have two types of code expression, one "code", which adds also a "match-all" into the expression, and a "rawcode" without it. (Milan Crha)
+ #360813 : RFC 2445 - CREATED/DTSTAMP/LAST-MODIFIED always in UTC. (Milan Crha)
+ #443544 (bugzilla.novell.com) : Handle E_MEETING_FREE_BUSY_FREE. (Suman Manjunath)
+ #458968 (bugzilla.novell.com) : Don't warn the user about changes being lost if he is trying to delegate the meeting. (Suman Manjunath)
+ #462372 (bnc) : Add supported URI format. (Ashish Shrivastava)
+ #489437 : Check whether the 'until' date is in the future, and report error if not. (Milan Crha)
+ #554454 : Do not crash when received 'modified' event for something not in a model. And a leak fix. (Milan Crha)
+ #555310 : Localize strings properly. (Milan Crha)
+ #563364 : Manage the second day zone in a Preferences dialog. (Milan Crha)
+ #563867 : Unescape "&amp;" when passing the link to browsers. (Felix Riemann)
+ #565376 : Support storing folder uri in a camel's way. Compiler warning fix. (Milan Crha)
+ #565376 : Bump eds requirement to 2.25.5 because of new functionality. (Milan Crha)
+ #565681 : EPlugins must be loaded after Bonobo init, else variables like `session` are not available for plugin's initialization functions (Philip Van hoof)
+ #566011 : Include <glib/gi18n-lib.h> instead of <glib/gi18n.h> and add bindtextdomain(). (Takao Fujiwara)
+ #566572 : Fix typos. (Andre Klapper)
+ #566599 : Add translator comments and gettext context for meeting mail subject prefixes. (Matthew Barnes)
+ #566653 : Fix a leaked info (Srinivasa Ragavan)
+ #567031 : Hide also label of the combo. (Milan Crha)
+ #567045 : Escalate scroll event's to a scrolled window, to let mouse wheel work over data too. (Milan Crha)
+ #567129 : Add <default> tag in C locale to localize the value. Add gettext. (Takao Fujiwara)
+ #567148 : Use a labelled button to bring up the timezone selector widget. (Matthew Barnes)
+ #567270 : Remove already-disabled use of gnome_about_new(). (Matthew Barnes)
+ #567276 : Remove unneeded #include <libgnomeui/gnome-dialog-util.h>. Removed unused function calendar_config_check_timezone_set(). (Matthew Barnes)
+ #567280 : Remove unneeded #include <libgnomeui/gnome-pixmap.h>. (Matthew Barnes)
+ #567281 : Remove unneeded #include <libgnomeui/gnome-messagebox.h>. (Matthew Barnes)
+ #567282 : Remove unrequired #include of <libgnomeui/gnome-href.h>. (Andre Klapper)
+ #567285 : Remove unneeded #include <libgnomeui/gnome-popup-menu.h>. (Matthew Barnes)
+ #567409 : Remove redundancy; split up strings (Andre Klapper)
+ #567687 : Force text/html part only when choosing between text/plain and it. (Milan Crha)
+ #567744 : Comment attribute in property tag should be plural. e.g. <property comments="..."> (Matthew Barnes)
+
+Other contributions:
+ Call e_show_uri() instead of gnome_url_show(). (Matthew Barnes)
+ <gmodule.h> API instead of <dlfcn.h> API. (Tor Lillqvist)
+ Add support for category syncing. Also, retain an existing given/first name split if it exists in the pilot record. (Matt Davey)
+ B & W version of our new logo to replace the old Ximian logo. Regenerate the Quick Reference PDFs with the new logo. (Matthew Barnes)
+ Call e_display_help() instead of gnome_url_show(). New convenience function calls gtk_show_uri() and displays an error dialog if the URI cannot be shown. (Matthew Barnes)
+ Now that we require GTK 2.14, use gtk_show_uri() instead of gnome_help_display(). (Matthew Barnes)
+ Updated screenshots. ( pc radhika )
+ Remove explicit mentioning of some translators. (Andre Klapper)
+ Add cast to avoid warning. (Tor Lillqvist)
+
+Evolution 2.25.4 2009-01-05
+---------------------------
+
+Bug Fixes:
+ #435694: (Novell Bugzilla) Since we now add a bar, lets set the popup items right (Bharath Acharya)
+ #439998: (Novell Bugzilla) Ask the user if he wants to remove the delegated events or keep a copy (Bharath Acharya)
+ #446285: (Novell Bugzilla) Traverse all the entries in the added list (Bharath Acharya)
+ #546437: Fix various typos and poor wording in chapters 1-4 (Matthew Barnes)
+ #546860: Don't craash on malformed label strings (Matthew Barnes)
+ #558337: Fix a crash while managing IMAP folder subscriptions (Norman Wang)
+ #559153: Migration improvements (Sankar P)
+ #559604: Show additional status information for the meeting only when user is an organizer (Milan Crha)
+ #562091: Fix the problem of normal memo window popup when trying to create a shared memo (Matthew Barnes)
+ #562155: Fix a warning shown in the terminal output (Matthew Barnes)
+ #564248: Bump minimum version required for gtkhtml because of new html editor functions (Milan Crha)
+ #565628: Fix memory leak (Ignacio Casal Quinteiro)
+ #565857: Fixes a memory leak (Matthew Barnes)
+ #566206: Remove unlocalized screenshots (Andre Klapper)
+
+Updated Translations:
+ Jorge Gonzalez (es)
+ Yannig Marchegay (oc)
+ Marcel Telka (sk)
+ Leonardo Ferreira Fontenelle (pt_BR)
+ Andre Klapper (de)
+
+Evolution 2.25.3 2008-12-15
+---------------------------
+
+Bug Fixes:
+ #332629: New helper function to be used in FilterOption (Milan Crha)
+ #332629: Use dynamically created list of categories in the option's widget (Milan Crha)
+ #333224: Fix a crash when changing the time of an exchange appointment (Milan Crha)
+ #337082: Do not set we finished with loading until we are really done with it. The previous behavior can cause duplicate nodes in tree for subscribed folders (Milan Crha)
+ #348299: Use category completion in the Categories field. Fix some reference count leaks (Matthew Barnes)
+ #350725: Copy/Paste support in day/week views (Hiroyuki Ikezoe)
+ #352287: Draw top icons in full detail/color depth (Milan Crha)
+ #549964: Fix for an errorneous string (Jennifer Newman)
+ #551599: Do not fallback to default 15 minutes alarm offset if alarm is triggered at start (or end) of appointment (Paul Bolle)
+ #552357: Function prototype (Milan Crha)
+ #552583: Extending Sankar's fix of account checking logic a bit, to be more consistent (Milan Crha)
+ #552583: For the purpose of matching a URL to an EAccount, only compare the protocol, user, host and port and disregard the rest. Fix the errors in the account checking logic (Matthew Barnes,Sankar P)
+ #555371: Added print menu option to task, memo and event editors (Jennifer Newman)
+ #555663: Do not overwrite signal id (Milan Crha)
+ #556303: Check whether attachment has a body already before accessing it (Milan Crha)
+ #558498: Check for the offline status before setting up the Exchange settings (Bharath Acharya)
+ #560420: spamc and spamassassin use error codes >= 64 to denote execution errors. Positive error codes < 64 means the message was identified as Spam (hp@syntomax.com)
+ #562228: Make it clearer then mailbox entry is optional (Milan Crha)
+ #562990: Use 'username' property to read/write user name, not the url (Milan Crha)
+ #563077: Fixes a crash if the gnome-settings-daemon is not running. Observed on SUN Solaris (Jeff Cai)
+ #563250: Load on startup and save on shutdown, custom keyboard accelerators (Matthew Barnes)
+ #563369: Translate "Templates" folder name (Milan Crha)
+ #563633: SUN compiler doesn't understand an empty structure (Jeff Cai)
+ #563669: Use zero GtkSpinButton's Pagesize, as Gtk+ requires (Milan Crha)
+ #563870: Drop unused header include (Milan Crha)
+ #564351: Fix single header include issue for GdkPixbuf (Tal Benavidor)
+
+Updated Translations:
+ Ilkka Tuohela (fi)
+ Leonardo Ferreira Fontenelle (pt_BR)
+
+Evolution 2.25.2 2008-12-01
+---------------------------
+
+New in 2.25.2:
+ Added a "Dismiss" button to the alarm notification dialog to be able to dismiss only some of the alarms shown in the dialog (Milan Crha)
+ Show attendees' status in the tooltip if available (Milan Crha)
+ Support for evolution-mapi support (Suman Manjunath)
+
+Bug Fixes:
+ #332729: Disconnect handlers on the widget before freeing the structure it is using (Milan Crha)
+ #359745: Show CalDAV options under all the other standard options (Milan Crha)
+ #386036: Added new option "Sender or Recipients" which filters on From/To/Cc/Bcc headers (Milan Crha)
+ #434320: (Novell Bugzilla) When the popup is clicked close the status icon (Srinivasa Ragavan)
+ #437226: (Novell Bugzilla) Proper message to hint the mail is being sent by delegatee (Bharath Acharya)
+ #440007: (Novell Bugzilla) Print Preview of Calendar Event Shows Blank Page Before Data fixed (Bharath Acharya)
+ #440646: (Novell Bugzilla) Set the ESource color-spec for proxy accounts in the correct format (Suman Manjunath)
+ #443190: (Novell Bugzilla) Block signals from attachment-bar while still filling the widgets (Suman Manjunath)
+ #446286: (Novell Bugzilla) Remove the header check as we do a e_gw_connection_get_item for tracking the status (Bharath Acharya)
+ #490503: Show summary of unaccepted meetings as bold in calendar views (Suman Manjunath)
+ #503662: Set NULL properly to protect against using already freed memory (Milan Crha)
+ #524377: Declare, be able to change and listen to changes on new key, '/apps/evolution/mail/composer/outlook_filenames' to encode file names header in camel based on the RFC 2047, instead of the correct RFC 2231 (Milan Crha)
+ #541121: Itip-formatter: don't allow sending a response to meeting invitation replies (Patrick Ohly)
+ #552583: Strip the attributes out of both URLs and just do a simple string comparison. Try to match a URL to an account (Matthew Barnes)
+ #552850: Prefer the term "side bar" over "folder tree" (Matthew Barnes)
+ #554450: Get drag-and-drop to the attachment bar working again (Matthew Barnes)
+ #554464: Bump gtk+ minimum version to 2.14.0 which pulls in a recent enough Pango version (Felix Riemann)
+ #555276: Don't load vfolder as subfolder (Srinivasa Ragavan)
+ #556224: Run always 'update_todo_view' in a separate thread and guard its body with a mutex (Milan Crha)
+ #557246: Pop up the "Unsubscribe Folder" option only for the subscribed folders and not to the Other's folder hierarchy (Bharath Acharya)
+ #557581: Break up the version definitions such that we can calculate the latest stable version and pass a STABLE_VERSION definition (Matthew Barnes)
+ #557726: Destroy the widgets created by the google contacts group (Bharath Acharya)
+ #557818: ESourceSelector now handles most of the drag-and-drop signals. We just have to listen for the new "data-dropped" signal and deal with it (Matthew Barnes)
+ #558322: New "Rename" item in the source selector pop-up menu calls the recently added e_source_selector_edit_primary_selection (Matthew Barnes)
+ #558354: Changed "Close" button to "Dismiss all" and added a "Dismiss" button to the alarm notification dialog to be able to dismiss only some of the alarms shown in the dialog (Milan Crha)
+ #559371: Opening _either_ Preferences or a new composer window with no spell checking language chosen will pick a default language for you (Matthew Barnes)
+ #559518: Desensitizes the button when the username field is blank for the google source (Matthew Barnes)
+ #559604: Show attendees' status in the tooltip if available (Milan Crha)
+ #559701: Edit Preferences crashes when there are no spell checking dictionaries added. Don't save when its NULL (Srinivasa Ragavan)
+ #559810: Do not localize empty label names, also localize them only first time (Milan Crha)
+ #560138: Let wrap description text in a tooltip (Milan Crha)
+ #560329: Fix the signature of the 'children-changed' signal emission (Li Yuan)
+ #560882: Left-align header labels instead of centering them, and adjust the header padding so they look purdy (Matthew Barnes)
+ #561467: some changes in the core code needed for evolution-mapi (Suman Manjunath)
+
+Updated Translations:
+ Jorge Gonzalez (es)
+ Petr Kovar (cs)
+ Nickolay V. Shmyrev (ru)
+
+Evolution 2.25.1 2008-11-03
+---------------------------
+
+New in 2.25.1:
+ New UI for Edit->Preferences->Autocompletion, to be able to setup whether show mail address for the autocompleted contact (Milan Crha)
+
+Bug Fixes:
+ #272391: New UI for Edit->Preferences->Autocompletion, with the checkbox for the key "/apps/evolution/addressbook/completion/show_address" to be able to setup whether show mail address for the autocompleted contact (Milan Crha)
+ #311479: Rephrasing the heading in Evolution Import Assistant (Kandepu Prasad)
+ #313225: Show meeting icon in 'Attachment' column on messages with '$has_cal' user flag set (Milan Crha)
+ #364542: Stop when camel operation has been canceled. Also check for cancellation when opening EBook, thus the UI (preview) will not freeze with slow address books. (Milan Crha)
+ #424818: (Novell Bugzilla) Integrate the mark-calendar-offline plugin into the main code as we already have a similar per-calendar option which does the same thing (Suman Manjunath)
+ #438155: Guard access to the 'regen' list with a lock (Milan Crha)
+ #497928: Set URI to empty string when user deletes previously selected source (Milan Crha)
+ #503898: Replace all occurences of the word "criteria" with "condition" (Matthew Barnes)
+ #511918: Use TRUE/FALSE texts for boolean values and do not free returned value for them, otherwise it crashes (Milan Crha)
+ #511947: Check for NULL values to prevent runtime warnings. (Milan Crha)
+ #514989: Calculate tomorrow from current time, not from the date to convert (Milan Crha)
+ #519491: Convert texts to valid UTF-8 texts before passing them to Gtk+ functions which requires that (Milan Crha)
+ #528816: We do not support vCalendar importer when we can parse the iCalendar from the file, because the latter holds more information, like timezones (Milan Crha)
+ #530606: Check validity of returned pointer before using it (Milan Crha)
+ #530691: Remove folders in its own thread, not in main thread (Milan Crha)
+ #530716: Differentiate between response with valid message pointer and with one already freed (Milan Crha)
+ #530872: Check for NULL soon enough to not crash (Milan Crha)
+ #535248: Check if log file has been opened successfully before using it (Milan Crha)
+ #541121: Improved itip formatter: allow replying to forwarded and already imported invitations; honor RVSP flag in invitation (Patrick Ohly)
+ #545045: Don't show SMTP in the Send/Receive dialogue if there are no unsent mails (Philip Withnall)
+ #548469: Drop support for deprecated libnm-glib (Matthew Barnes)
+ #549025: Restrict libmono linkage to the mono plugin, so that downstream packagers can isolate the mono dependency to a subpackage. Add configuration summary lines indicating whether the Mono and Python bindings are enabled (Matthew Barnes)
+ #550441: Use the proper functions to traverse messages in a folder's summary. Ignore if summary not there. (Milan Crha, Srinivasa Ragavan)
+ #551121: Standardise use of "SpamAssassin" vs. "spamassassin" or "Spamassassin". (Philip Withnall)
+ #552551: Add a NULL check for search_word before calling strcmp (Philip Withnall)
+ #552575: Register default callbacks to composer to be able to send/save draft (Milan Crha)
+ #552583: Do not hide auth_mech from the URL. (Sebastian Keller)
+ #552851: Add translator comments to the accept/decline strings, and improve some other strings in the file (Philip Withnall)
+ #553067, #553070, #553105, #553106: Mark some forgotten strings for translation (Gabor Kelemen)
+ #553148: Standardise "GroupWise" usage in translatable strings (Philip Withnall)
+ #553273: Always end e_error_run/e_error_new calls with NULL parameter (Milan Crha)
+ #553297: Do not try to access uninitialized variables (Milan Crha)
+ #553461, #553389: Rename the "SSH" option to "Secure FTP (SSH)" and update the code accordingly. Also, change a related string to use better terminology. (Philip Withnall)
+ #553479: String capitalisation improvements (Philip Withnall)
+ #553527: Do the EBook work in a separate thread to have better performance on reply with slow address books (Milan Crha)
+ #553609: Do not do any changes when the view has not been shown yet (Milan Crha)
+ #553715: Set end time for the event properly, not same as start time (Milan Crha)
+ #554107: Add "Subject - Trimmed" column which enables to read mailing list mails in a better way (Hans Petter Jansson)
+ #554297: Add translator comment to the occurrences of the Proxy term (Gabor Kelemen)
+ #554349: Expand threads and select messages, if user has given select-all (Sankar P)
+ #554418: Guess mime_type based on the filename only (Milan Crha)
+ #554458: Use content-type to call of g_app_info_get_all_for_type (Milan Crha)
+ #554548: French translation update (Hanka Zalska)
+ #554566: New function to update current selected rule (Lucian Langa)
+ #554664: Call attach_remote_file when knows the URI points to it. (Milan Crha)
+ #554832: Updated Spanish translation (Jorge Gonzalez)
+ #555203: Use the url value in cases where the account goes NULL. Fixes the issue of Exchange not sending mails, because it does not have a valid transport url to use (Bharath Acharya)
+ #555276: Don't load a vfolder as a sub folder (Srinivasa Ragavan)
+ #555494: Category icons are not themed. Load by file, not by icon name (Matthew Barnes)
+ #555775: Include e-util-private.h for Win32 redefinition of EVOLUTION_UIDIR and build the filename using it (Bharath Acharya)
+ #555958: Add the UI manager's accelerator group to the editor window so that menu shortcut keys work (Anis Elleuch)
+ #556059: Allow building outside the source tree (Matt Davey)
+ #556191: Remove org-gnome-mark-calendar-offline.eplug.xml (Matthew Barnes)
+ #556284: Fixes for fetching the store using mail_component_peek_local_store. Fixes the right-click crash issues caused on OS_WIN32 by Templates plugin (Bharath Acharya)
+ #557563: Updated German translation (Ronny Standke)
+ #558726: Fix a potential format string crash. (Frederic van Starbmann)
+
+Updated Translations:
+ Gabor Kelemen (hu)
+ Kenneth Nielsen (da)
+ Ivar Smolin (et)
+ Daniel Nylander (sv)
+ Mikel González (ast)
+ Ronny Standke (de)
+ Theppitak Karoonboonyanan (th)
+ Marcel Telka (sk)
+ Jorge Gonzalez (es)
+ Leonardo Ferreira Fontenelle (pt_BR)
+ Ignacio Casal Quinteiro (gl)
+ Ilkka Tuohela (fi)
+ Og Maciel (pt_BR)
+ Kjartan Maraas (nb)
+ Alexander Shopov (bg)
+ Wouter Bolsterlee (nl)
+ Goran Raki (sr, sr@latin)
+ Hari Vishnu (ml)
+
+Evolution 2.24.0 2008-09-22
+---------------------------
+
+New in 2.24.0:
+
+ * Message Templates
+ * WebDAV Contacts Plugin
+ * Google Contacts Plugin
+ * Custom header support while sending mails
+ * Single Model view for Calendar
+ * Sqlite Based message summary
+ * New Bonobo-less composer for Evolution
+ * Quota support to IMAP/POP accounts
+ * Gtk+ Recent manager integration in Composer
+
+Bug Fixes:
+ #504767: Expand also parent nodes, if necessary (Milan Crha)
+ #505016: Check for NULL to prevent crash when error occurred. (Milan Crha)
+ #514299: Connect to signals only once, when creating new status icon (Milan Crha)
+ #534039: Dropped unnecessary and offending code causing infinite loops when deleting search folder. (Milan Crha)
+ #539536: Add "Face" header to default headers and allow it to be hidden (Paul Bolle)
+ #551548: Enable selection of S/MIME for individual messages (Matthew Barnes)
+ #551628: Remove old events from the view when objects are modified. (Chenthill Palanisamy)
+ #551895: Fix a warning message (Paul Bolle)
+ #551915: Manage error on idle, to call gtk functions in the main thread (Milan Crha)
+ #552911: Do not use spaces in file names (Milan Crha)
+
+Updated Translations:
+ Wadim Dziedzic (pl)
+ Osama Khalid, Usama Akkad, Abou Manal (ar)
+ Gabor Kelemen (hu)
+ Kenneth Nielsen (da)
+ Luca Ferretti (it)
+ Fabrício Godoy, Vladimir Melo and Leonardo Ferreira Fontenelle (pt_BR)
+ Laurent Dhima (sq)
+ Igor Nestorović(sr, sr@latin)
+ Pierros Papadeas (el)
+ Žygimantas BeruÄÂka (lt)
+ Tirumurthi Vasudevan (ta)
+ Inaki Larrañaga Murgoitio (eu)
+ Shankar Prasad (kn)
+ Chao-Hsiung Liao (zh_HK, zh_TW)
+ Jiri Eischmann (cs)
+ Jorge Gonzalez (es)
+ Ivar Smolin (et)
+ David Planella (ca)
+ Tino Meinen (nl)
+ Ilkka Tuohela (fi)
+ Sandeep Shedmake (mr)
+ Daniel Nylander (sv)
+ Baris Cicek (tr)
+ Hendrik Richter (de)
+ Philip Withnall (en_GB)
+ Duarte Loreto (pt)
+ Runa Bhattacharjee (bn_IN)
+ Luca Ferretti (it)
+ Rajesh Ranjan (hi)
+ Robert Sedak (hr)
+ David Planella (ca)
+ Yavor Doganov (bg)
+ Theppitak Karoonboonyanan (th)
+
+Evolution 2.23.92 2008-09-08
+----------------------------
+
+New in 2.23.92:
+ Evolution source code license changed to LGPLv2 & LGPLV3 (Sankar P)
+
+Bug Fixes:
+ #549968: Use the same mnemonic for "Recent Documents" as composer (Matthew Barnes)
+
+Updated Translations:
+ Philip Withnall (en_GB)
+ Andre Klapper (de)
+ Claude Paroz (fr)
+ Alexander Shopov (bg)
+ Theppitak Karoonboonyanan (th)
+ Changwoo Ryu (ko)
+
+Evolution 2.23.91 2008-09-01
+----------------------------
+
+Bug Fixes:
+ #458512: Delete the accessibility tag from the User button (Matthew Barnes)
+ #509647: Do not expunge folder when something goes wrong (Milan Crha)
+ #523327: Show description in monospace font and wrap lines too. (Milan Crha)
+ #525555: Evolution forgets Google Calendar credentials (Milan Crha)
+ #534762: Change "addressbook" to "address book" in translatable strings (Philip Withnall)
+ #544430: Better formed translatable strings for quota usage (Matthew Barnes)
+ #546926: New function to simply call camel_shutdown() (Matthew Barnes)
+ #547822: Make it show "Tasks" for printing tasks list and "Calendar" for printing a calendar (Rouslan Solomakhin)
+ #547822: Use g_malloc() and g_free() instead of malloc() and free() (Matthew Barnes)
+ #548348: Add a libecontactprint_la_LIBADD stanza so we link to the correct libemiscwidgets and libeutil (Matthew Barnes)
+ #549554: Drop sentence about an "Automatic" option (Paul Bolle)
+
+Updated Translations:
+ Andre Klapper (de)
+ Yannick Tailliez and Bruno Brouard (fr)
+ Mark Krapivner(he)
+ Ignacio Casal Quinteiro (gl)
+ Jorge Gonzalez (es)
+ Inaki Larranaga Murgoitio (eu)
+ Ivar Smolin (et)
+ Hendrik Richter (de)
+ Kjartan Maraas (nb)
+ Ilkka Tuohela (fi)
+ Daniel Nylander (sv)
+ Goran Rakić(sr, sr@Latin)
+ Shankar Prasad (kn)
+ Chao-Hsiung Liao (zh_HK, zh_TW)
+ Åsmund Skjæveland (nn)
+ Jovan Naumovski (mk)
+
+Evolution 2.23.90 2008-08-18
+----------------------------
+
+Bug Fixes:
+ #249844: Fix compiler warnings (Milan Crha)
+ #324203: New check box to be able to set LDAP address books browseable until reaches given limits (Milan Crha)
+ #347287: Use a single model for all the views (Chenthill Palanisamy)
+ #352695: Search and clear action, looses the expanded state of threads (Milan Crha)
+ #416258: Make evolution respect GTK_ICON_SIZE changes (Gilles Dartiguelongue)
+ #435969: Show authentication section in an account druid too (Milan Crha)
+ #467115: Fix missing icons in different modules (Matthew Barnes)
+ #498095: Set proper mnemonic widget for description label (Dmitrijs Ledkovs)
+ #508732 Removed 'Crash detection' startup dialog box. (Mathew Barnes)
+ #513363: Removed the outdated "New Features" list and the incorrect "Evolution team" email address. (Mathew Barnes)
+ #519292: Better thread expand and collapse handling (Milan Crha)
+ #529743: Support Subject or Recipients contain search (Srinivasa Ragavan)
+ #530402: Improve dialog wording, and don't use a window title (HIG) (Matthew Barnes)(
+ #531288: Use proxy icon from tango-icon-theme and fall back to the icon shipped by gnome-control-center (Josef Vybíral)
+ #535745: Require and link calendar libs with libgdata and libgdata-google (Milan Crha)
+ #544117: Initialize variables to NULL, to not free uninitialized memory in the cleanup part on the error (Milan Crha)
+ #546263: Editing contact list messes minicard view fixed (Milan Crha)
+ #546668: Drop one unused define (Paul Bolle)
+ #546744: Use address-book-new icon instead of contacts-new (Michael Monreal)
+ #546748: Change "_Properties..." to "_Properties" to match HIG and other components. (Michael Monreal)
+ #546785: Make bbdb plugin just as polite as google-account-setup (Paul Bolle)
+ #546788: Drop unused "ViewNormal" cmd entry (Paul Bolle)
+ #546788: Remove unused formatting style option (Paul Bolle)
+ #546892: Prefer themed icon names (Matthew Barnes)
+ #547308: Do not try to authenticate to the server more than twice with correct credentials (Milan Crha)
+ #547369: Fix a typo. (Matthew Barnes)
+ #547372: Fix TeX-style quotes (Matthew Barnes)
+ #547411: New, Tangoized versions of images now live in data/icons (Matthew Barnes)
+ #547805: Do not filter list of applications to open attachments (Sebastien Bacher)
+
+Other fixes:
+ Lots of disk summary related stability fixes (Srinivasa Ragavan)
+
+Updated Translations:
+ Ignacio Casal Quinteiro (gl)
+ Kjartan Maraas (nb)
+ Shankar Prasad (kn)
+ Ilkka Tuohela (fi)
+ Jorge Gonzalez (es)
+ Duarte Loreto (pt)
+ Chao-Hsiung Liao (zh_HK)
+ Chao-Hsiung Liao (zh_TW)
+ Ivar Smolin (et)
+ Abou Manal (ar)
+
+Evolution 2.23.6 2008-08-04
+---------------------------
+
+New in 2.23.6:
+ WebDAV contacts plugin (Matthias Braun)
+
+Bug Fixes:
+ #211267: Report correct number of pages to print and print them as requested (Milan Crha)
+ #249844: Use fully qualified names for "New" submenu entries (Matthew Barnes)
+ #256540: Do not use GtkNotebook with only one tab (Milan Crha)
+ #329821: Recalculate returned row to the model row, if we are sorting (Milan Crha)
+ #353927: Do not blink the icon more than 15 seconds (Milan Crha)
+ #428384: Improve buttons in the "exit-unsaved" dialog by replacing "Cancel" with "Continue Editing" and "Save Message" with "Save Draft". (Matthew Barnes)
+ #491176: Word-wrap the summary if necessary; keep the text and action buttons aligned on the left (Milan Crha)
+ #500389: New ability to define Options (ComboBox) in provider's options (Milan Crha)
+ #504417: Preferences windows cut off (Lucian Langa)
+ #514006: Quote literal values (Matthew Barnes)
+ #517151: Give a mnemonic to "Composer in External Editor" (Matthew Barnes)
+ #517825: Fix duplicate mnemonic. "_Work Offline" -> "Work _Offline" (Matthew Barnes)
+ #529460: Change "Startup Wizard" to "Setup Assistant". Also make the plugin description less lame (Matthew Barnes)
+ #530388: Fix a crash when editing labels (Milan Crha)
+ #537088: Fix empty headers if FROM/Sender is NULL (Paul Bolle)
+ #539268: Fix attachment description (Paul Bolle)
+ #543058: Properly capitalize INBOX (Paul Bolle)
+ #543411: Don't load known folders (Srinivasa Ragavan)
+ #543532: Let free memory when we are done with it, not before. (Milan Crha)
+ #543754: Reword "insufficient-permissions" error message (Matthew Barnes)
+ #543755: Fix a typo (Matthew Barnes)
+ #543756: Make question better translatable (Milan Crha)
+ #543943: Fix a memory leak (Milan Crha)
+ #544252: Use consistent naming to the GUI for different components (Paul Bolle)
+ #544157: Sort View / Window (sub)menu in shortcut order. (Paul Bolle)
+ #544383: Put contact list members in reverse order (Milan Crha)
+ #544857: Fix a typo (Matthew Barnes)
+ #544859: Clarify description of "sync_interval" key. (Matthew Barnes)
+ #544860: Add translator comments for split "update every" sentence (Matthew Barnes)
+ #544861: Reword "invalid-user" error message (Matthew Barnes)
+ #544862: Clarify description of "use_authentication" key (Matthew Barnes)
+ #544958: Use email, not e-mail (per documentation guidelines) (Matthew Barnes)
+ #544969: Added the hook for folder custom icon (Lucian Langa)
+ #544994: Typos/Syntax improvements (Claude Paroz)
+ #545300: Add a translatable tag in "_Merge" string (Takao Fujiwara)
+ #545303: Add gettext in the xml string (Takao Fujiwara)
+ #545436: Check the info before accessing it (Srinivasa Ragavan)
+ #545558: Hula support is disabled by default now, so remove any mention of it from the User Guide (Matthew Barnes)
+ #545568: Make sure system plugins are enabled on startup (Matthew Barnes)
+ #545820: Fix a typo. (Nicolas Kaiser)
+ #546057: Use "x-office-calendar" icon name instead of "stock_calendar" (Matthew Barnes)
+
+Updated Translations:
+ Ignacio Casal Quinteiro (gl)
+ Frco. Javier Rial Rodríguez (gl)
+ Kjartan Maraas (nb)
+ Changwoo Ryu (ko)
+ Abou Manal (ar)
+ Petr Kovar (cs)
+ Fabrício Godoy (pt_BR)
+ Jorge Gonzalez (es)
+ Bruno Brouard and Claude Paroz (fr)
+ Zabeeh Khan (ps)
+ Pavel Sefranek (cs)
+
+
+Evolution 2.23.5 2008-07-21
+---------------------------
+New in 2.23.5
+ Camel DB Summary support. (Srinivasa Ragavan & Sankar P)
+ New EPlugin for message templates. (Bharath Acharya & Diego Escalante Urrelo)
+ Google Contacts support (Jörgen Scheibengruber)
+
+Bug Fixes:
+ #543753: Addressbook error string fixes (Andre Klapper)
+ #228725: Contacts view should not say "no items in this view" until the backend is done responding (Milan Crha)
+ #543134: Mail notification plugin should provide a right-click menu for preferences (Milan Crha)
+ #269152: Work-around for MS Outlook/Lookout that use X-MimeOLE (Milan Crha)
+ #200147: Added basic Template support (Bharath Acharya)
+ #206592: Action to invoke New Message window from the composer itself (Milan Crha)
+ #207802: Do not allow drop messages to the same message list as is the source. (Milan Crha)
+ #243201: Escape rule title so that can contain also XML entities in the file (Milan Crha)
+ #310988: Don't even show the "send-options" action unless an Exchange or GroupWise account appears in the From combo box (Matthew Barnes)
+ #318089: Ask for destination source only when have more than one writable source defined (Milan Crha)
+ #329821: Show tooltips over task's table (Milan Crha)
+ #368038: Ensure only one Birthdays & Anniversaries source (Milan Crha)
+ #370731: (Novell Bugzilla) Use MAX to determine the minimal size for each cell. This prevents the numbers and day-names from getting fuzzy when using large font-sizes (Suman Manjunath)
+ #382783: Grab focus of new rule part on adding and scroll to the bottom too (Milan Crha)
+ #395636: Added accel key Ctrl+Shift+B for collapsing all threads and Ctrl+/ for marking all messages as read (Roshan Kumar Singh)
+ #423395: Put the anchor where the message body begins and let GtkHTML know the anchor name to place the cursor there in caret mode on the first focus (Milan Crha)
+ #440818: Convert line to UTF-8 if not a valid one. Pretend it to be an ISO-8859-1 line (Rodrigo Castro)
+ #477082,#438479: Fixed documentation (Andre Klapper)
+ #478469: Changed the progress dialog to be more HIG compliant (Milan Crha)
+ #519536: Handle freeing of data safely. (Srinivasa Ragavan)
+ #524130: Pass description text through 'camel_text_to_html' to have links clickable in a preview (Milan Crha)
+ #526262: Handle _title element in analogical way as title (Maciej Piechotka)
+ #530069: Don't show the configuration tab unless the selected plugin actually has configuration options (Matthew Barnes)
+ #532472: Strip the account URL (via CAMEL_URL_HIDE_ALL) before comparing it to the already-stripped 'transport_url', to avoid unnecessary password prompts (Matthew Barnes)
+ #532597: Do not leave selected more than one item if somebody else took care or reposition of the cursor row before the delete (Milan Crha)
+ #534039: Track folders even when Search Folders disabled, to have them known when enabling Search Folders on demand (Milan Crha)
+ #536488: Remove '~/.evolution/.running' file before backup/after restore, thus Evolution will not claim next start it was closed incorrectly (Milan Crha)
+ #537275: Do not pass data to the child structure if we were canceled (Milan Crha)
+ #537725: Set the autosaved flag so we don't get pestered with a save dialog if the user then decides to close the composer window (Matthew Barnes)
+ #538741: Strip preceding tabs from Date headers too (Paul Bolle)
+ #538908: Desensitize the "send-options" action unless we've selected as Exchange or GroupWise account. (Paul Bolle)
+ #539268: Do not use both filename and description if these are identical (Paul Bolle)
+ #539755: Do not access memory beyond the columns array (Milan Crha)
+ #540152: Fix some memory leaks (Milan Crha)
+ #540160: Remember whether we come from none/multi select to single select and properly update the preview. (Milan Crha)
+ #540274: After restore walk through all account, addressbook, calendar, task and memo sources and fix the base uri if required (Milan Crha)
+ #540282: Remove the "printing" GConf key. We use a key file now (Matthew Barnes)
+ #540282: Store printer and page settings in a key file rather than GConf (Matthew Barnes)
+ #540400: Make Evolution Backup follow symbolic links (Roger Zauner)
+ #540516: Sanitize user input while accepting path/filename of the backup (Tobias Mueller)
+ #540972: Small memory leak fix. (Milan Crha)
+ #541355: Removes any freed objects from the 'locals' list in each conduit which otherwise frees them again when the conduit is closed (Keith Packard)
+ #541365: Do not call 'camel_folder_sort_uids' when we do not have folder or uid (Milan Crha)
+ #542101: Escape PlaceOfTheMeeting in the Location: line of the tooltip (Paul Bolle)
+ #542125: Remove unnecessary files from source control (Matthew Barnes)
+ #542149: Display an error message to restart if user tries to subscribe to other's mailbox (Bharath Acharya)
+ #542587: New widget implements the online/offline button used in the main window. (Matthew Barnes)
+ #542631: Use g_format_size_for_display instead of cut and pasted code (Paolo Borelli)
+ #542889: Port to the new gtk tooltip api (Paolo Borelli)
+ #543758: Never mark empty strings for translations (Tor Lillqvist)
+
+Other Contributors:
+ Sort the uids so that moving/copying messages preserves mailbox ordering rather than jumbled randomness. (Jeffrey Stedfast)
+ Add dolt revision 5e9eef10 to the autotools build system. Speeds up the build, otherwise falls back to libtool (Alp Toker)
+ Configure email-custom-header plugin within the plugin-manager. (Ashish Shrivastava)
+
+Updated Translations:
+ Andre Klapper (de)
+ Jorge Gonzalez (es)
+ Kjartan Maraas (nb)
+ Jorge Gonzalez (es)
+ Ivar Smolin (et)
+ Yannig Marchegay (oc)
+ Leonardo Ferreira Fontenelle (pt_BR)
+ Timo Jyrinki (fi)
+ Lucas Lommer (cs)
+
+Evolution 2.23.4 2008-06-16
+---------------------------
+New in 2.23.4
+ Python support for EPlugins. (Johnny Jacob)
+
+Bug Fixes:
+ #201011: Ability to disable filter rules (Milan Crha)
+ #201011: Show Enabled column in the editor, because we support it here (Milan Crha)
+ #314467: Reset port when setting host name without it (Milan Crha)
+ #330597: Add all text/* parts which has a filename set and also attach all submessages (Milan Crha)
+ #337160: Do not pretend the row with a cursor is selected when it isn't (Milan Crha)
+ #509595: Do not crash if file does not exists. Also be able to read lines more than 249 characters long (Milan Crha)
+ #535204: The tasks objects had been destroyed before the call of destroy_component (Shuai Liu)
+ #535791: New UI option to let uset choose whether start typing at the bottomof the document or not on replying (Milan Crha)
+ #536772: Disable Folder menu items consistently with a popup menu over folder (Milan Crha)
+ #536813: Do not start to edit the event on the double click if the event is not on the server yet (Milan Crha)
+ #538002: Do not allow dropping messages on folders with CAMEL_FOLDER_NOSELECT flag set (Milan Crha)
+ #304029: changed description of default search filter from "Name begins with" to "Name contains" (Milan Crha)
+
+Other Contributors:
+ Fix for security vulnerabilities CVE-2008-1108 and CVE-2008-1109 (Matthew Barnes)
+
+Updated Translations:
+ Jorge Gonzalez (es)
+ Abou Manal (ar)
+ Kjartan Maraas (nb)
+ Yair Hershkovitz (he)
+
+Evolution 2.23.3 2008-06-02
+---------------------------
+
+New in 2.23.3
+ New plugin for setting headers while sending email (Ashish)
+
+Bug Fixes:
+ #311042: Allocate size for location and info labels differently (Milan Crha)
+ #317755: Do not quit until we are done with mail sync (Milan Crha)
+ #322553: Do not run signature script when disabled in /desktop/gnome/lockdown/disable_command_line (Milan Crha)
+ #394441: (Novell Bugzilla) Fixes a double free (Bharath Acharya)
+ #463040: Forget former selected uid as soon as we know we moved to other (Milan Crha)
+ #473198: Ignore signature (Johnny Jacob)
+ #496476: Removed GtkTables and added simple HBoxes (Johnny Jacob)
+ #514383: Remove the "ask-mark-read" error (Matthew Barnes)
+ #523402: Do not leak. Reassign back the old values before freeing (Milan Crha)
+ #525966: Don't mark composer as dirty (Milan Crha)
+ #529464: Don't use the string handle (jeblinux)
+ #529995: Disable the "attachment reminder" plugin instead of disabling the check for missing attachment (Johnny Jacob)
+ #530392: Pressing Enter in the entry activates the default response (Matthew Barnes)
+ #531592: Do not escape window titles and status bar messages (Matthew Barnes)
+ #531836: Don't block on deleted message (Srinivasa Ragavan)
+ #532384: Choose the text/html part in normal mode only if the alrenative multipart contains also a text/plain part (Milan Crha)
+ #532597: Fix random selection of contacts (Milan Crha)
+ #533465: Strip whitespace from user-entered hostname (Ritesh Khadgaray)
+ #533820: Fix for a crash on double-clicking the border of meetings in day-view (Chenthill Palanisamy)
+ #534012: Indicate error if backup folder chosen lacks permissions (Sankar P)
+ #534312: Show icons for forwarded mails (Milan Crha)
+ #534360: Migrate from deprecated GtkObject symbols to GObject equivalents. (Matthew Barnes)
+ #534476: Remove the special check for "winmail.dat". GIO correctly identifies it as "application/ms-tnef" (Matthew Barnes)
+ #535273: Link e-util and econduit libraries with gnome-pilot (Frederic Crozat)
+ #535459: Crash while opening a mail (Milan Crha)
+ #535670: Prevent evolution-rss articles being formatted as attachments (Lucian Langa)
+ #535749: Don't leave deleted messages strike through (Milan Crha)
+
+Updated Translations:
+ Ignacio Casal Quinteiro (gl)
+ Jorge Gonzalez (es)
+ Philip Withnall (en_GB)
+ Clytie Siddall (vi)
+ Ivar Smolin (et)
+ Tino Meinen (nl)
+ Nikos Charonitakis (el)
+ Kjartan Maraas (nb)
+ Abou Manal (ar)
+ Theppitak Karoonboonyanan (th)
+ Gil Forcada (ca)
+ Reinout van Schouwen (nl)
+
+Evolution 2.23.2 2008-05-12
+---------------------------
+
+Bug Fixes:
+ #240823: Send notification only to individuals and groups (Milan Crha)
+ #273041: Allow propagation of the error from the plugin in the hook target (Milan Crha)
+ #316390: Listen for changes in categories setup and propagate them to UI (Milan Crha)
+ #338330: Internet based calendar events are declined by Evolution/GroupWise (Chenthill Palanisamy)
+ #358644: (Novell Bugzilla) Retracted groupwise appointments should disappear as soon as they are retracted. (Chenthill Palanisamy)
+ #363908: Evolution crashed during exit (Srinivasa Ragavan)
+ #368277: (Novell Bugzilla) Cannot copy and paste email addresses from an appointment to a mail message (Ashish Shrivastava)
+ #382687: Don't download contents in main thread, which causes deadlock (Srinivasa Ragavan)
+ #424744: Remove Camel's dependency on libedataserver (Matthew Barnes)
+ #467892: "Unread Messages" causes mail that you read to disappear (Milan Crha)
+ #511337: Fix a crash when simultaneously pressing the "show" preview/arrow button on several very large image attachments in an e-mail (Milan Crha)
+ #518103: Check online status from NetworkManager at startup instead of using the last-used-state. (James Westby)
+ #524121: Fixing typo from patch for bug #516408 (Milan Crha)
+ #525241: Extend EPlugin to support GtkUIManager (Matthew Barnes)
+ #528288: Display warning when starting in search view & no messages displayed (Milan Crha)
+ #529179: Rebuild search menu rather on idle, then immediately after the change in gconf, because other parts may not have this change propagated yet (Milan Crha)
+ #529247: Fix theming issue with HTML mail display (Johan Euphrosine)
+ #529254: Handle either URI or filename. Return success or failure, not gint (Milan Crha)
+ #529375: Add new option to determine whether check for address in a local address book only (Milan Crha)
+ #529660: Change stable version to 2.22.1 (Akhil Laddha)
+ #529768: Setup default callbacks for the newly created EMsgComposer widget (Matthew Barnes)
+ #529855: Use proper label element name, these are localized by default (Milan Crha)
+ #529893: Properly set type hint on tooltip window (Danny Baumann)
+ #530245: Let searches work with labels again (Milan Crha)
+ #530576: Link with libebackend (Rob Bradford)
+ #530672: Evolution crashes when viewing pgp-signed message (Shuai Liu)
+ #531426: Display face header images at 48x48 instead of 64x64 (Roland Clobus)
+ #531519: Evolution crashes on print-preview (Srinivasa Ragavan)
+
+Other Contributors:
+ Fix up the Debug Logs window a bit (Matthew Barnes)
+ Fix include path for e-dbhash.h, now in libebackend (Johan Euphrosine)
+
+Updated Translations:
+ Tino Meinen (nl)
+ Yair Hershkovitz (he)
+ Kjartan Maraas (nb)
+ Jorge Gonzalez (es)
+ Yannig Marchegay (oc)
+
+Evolution 2.23.1 2008-04-21
+---------------------------
+
+New in 2.23.1:
+ Quota support to IMAP/POP accounts (Milan Crha)
+ Configurable Proxy settings for Evolution (Veerapuram Varadhan)
+ Gtk+ Recent manager integration in Composer (Suman)
+ New bonobo-less message composer (Matthew Barnes)
+
+Bug Fixes:
+ #232594: Set status to Needs Action when attendee's address have been changed. (Milan Crha)
+ #264456: Do not count deleted junk messages when doesn't show deleted messages. (Milan Crha)
+ #270406: Add quota support to IMAP/POP accounts (Milan Crha)
+ #271863: Do not count deleted junked messages to total number of messages with unchecked "Hide Deleted Messages" option (Milan Crha)
+ #273177: New function to add whole vCard to addressbook. (Milan Crha)
+ #316572: Do not translate unused text. (Milan Crha)
+ #328146: Fix missing and conflicting mnemonics. (Matthew Barnes)
+ #334444: Fix for mails with huge attachments (Srinivasa Ragavan)
+ #335891: Desensitize the signature editing interface if the "signatures" GConf key is not writable. (Matthew Barnes)
+ #346555: Fixed a mnemonic conflict (Qinkuangyu)
+ #350308: Make colors only darker, not lighter. Use black in case someone has too dark theme. (Milan Crha)
+ #378203: Don't crash if path is corrupted (Bharath)
+ #404241: Never return NULL, rather return "Other" as default. (Milan Crha)
+ #408579: Changed '&quot;' to '\"' to work with intltool. (Takao Fujiwara)
+ #437539: Use DocBook tags instead of UTF-8 characters for things like copyright and trademark symbols, quotes, etc. (Matthew Barnes)
+ #438613: Use different read-only message when checking from contact editor and from calendar UI. (Milan Crha)
+ #451976: Try to find text/html part in multipart/alternative when in normal mode. (Milan Crha)
+ #460204: Check whether found mime type is valid before returning it. (Milan Crha)
+ #476918: Fix a minor typo (Matthew Barnes)
+ #482148: Allow clear search when some search is active and text is empty. (Milan Crha)
+ #484793: String change: "Continue Editing" -> "Edit Message" (Ambuj Chitranshi)
+ #488175: Colorize follow-up messages same as with due-by flag. (Milan Crha)
+ #496839: Implement Plugin Load Levels. You can decide on which load-level you want your plugin to be loaded. (Sankar P)
+ #501885: Specify locale directory correctly (Frederic Crozat)
+ #502826: Reword and reorder Reply Style items in the Preferences. (nickspoon0, Milan Crha)
+ #506347: Inherit background colors from actual theme, do not use hardcoded one. (Milan Crha)
+ #506359: Add Translators' comments. (Milan Crha)
+ #507372: Done language edits on newly added sections. (PC Radhika)
+ #507526: Add translators' comment. (Milan Crha)
+ #509672: Clarify an error message (Matthew Barnes)
+ #509923: Evolution does not show recurrence of accepted meeting invites (Milan Crha)
+ #511950: Do not force button/label sizes. (Milan Crha)
+ #511952: Marking text for translation. (Milan Crha)
+ #511953: Create dialog properly. (Milan Crha)
+ #511956: Mark text for translation. Make dialog nicer (Milan Crha)
+ #511957: Mark messages for translation. (Milan Crha)
+ #511978: Resolve mnemonics clash on Junk tab (Milan Crha)
+ #512543: Get rid of ENABLE_CAIRO define (Milan Crha)
+ #513951: Centralize where Evolution's user data directory is defined (Matthew Barnes)
+ #514744: Check also for proper root node and use default if not the right one. (Milan Crha)
+ #515786: Fix misspelled SpamAssassin word. (Milan Crha)
+ #517134: Added a placeholder to dock the "Recent Documents" menu. (Suman Manjunath)
+ #517168: "compose in external editor" not working (Sankar P)
+ #517492: Set proper dialog caption with New or Properties (Milan Crha)
+ #519154: Do not localize folder name used in window title (Milan Crha)
+ #519292: Use numbers instead of gboolean value (Milan Crha)
+ #519304: Mark plugin name for translation (Sankar P)
+ #519421: also use <libytnef/ytnef.h> to check for TNEF support (Paul Bolle)
+ #521562: Small typo fix. (Milan Crha)
+ #522178: New mail notification in switcher appears for each mail activity (Milan Crha)
+ #522631: Fix build failure when --enable-profiling is enabled (Alex Rostovtsev)
+ #522764: Remove unused include (Ross Burton)
+ #523271: MIME types should not be case sensitive (Matthew Barnes)
+ #523402: Fix a Crash on paste event in calendar (Milan Crha)
+ #523413: Evolution should just save the messages when quitting rather than asking about each one (Matthew Barnes)
+ #523541: Plug a memory leak (Milan Crha)
+ #524310: Don't double-free server messages (Dan Williams)
+ #524434: Fixed build break (PC Radhika)
+ #525234: Install more include files that are useful to the out of tree evolution plugins. (Ondrej Jirman)
+ #525238: Add new "component.activated" event. Event is emitted whenever component is activated. (Ondrej Jirman)
+ #525508: Fix a leak (Matthew Barnes)
+ #525510: Mark "On This Computer" for translation. (Matthew Barnes)
+ #525966: Fix a boolean error in detecting unsaved changes (Matthew Barnes)
+ #526152: Fix New composer spell check warning (Matthew Barnes)
+ #526739: Ported gnome-vfs to gvfs (Milan Crha)
+ #527327: Change the name of the variable we look for in the glade file. Also add some if conditions to avoid certain crash. (Sankar P)
+ #528358: Use message subject as default filename when attempting to 'save message' (Shuai Liu)
+ #528817: Fix a typo in logic (Matthew Barnes)
+
+Other Contributors:
+ Add icons for Edit->Select All, Folder->New, Folder->Delete and Folder->Refresh (Matthew Barnes)
+
+Updated Translations:
+ Jorge Gonzalez (es)
+ Kjartan Maraas (nb)
+ Leonardo Ferreira Fontenelle (pt_BR)
+ Mark Krapivner (he)
+ Yair Hershkovitz (he)
+ Ivar Smolin (et)
+ Philipp Kerling (de)
+ Dominik Sandjaja (de)
+ Daniel Nylander (sv)
+ Philip Withnall (en_GB)
+ Simos Xenitellis (el)
+ Kenneth Nielsen (da)
+ Gintautas Miliauskas (lt)
+ Åsmund Skjæveland (nn)
+ Krishna Babu K (te)
+ Yavor Doganov (bg)
+ Sandeep Shedmake (mr)
+ Runa Bhattacharjee (bn_IN)
+
+Evolution 2.21.93 2008-03-10
+----------------------------
+
+Bug Fixes:
+ #282466: (Novell Bugzilla) Handle CIDs of broken cases too (Srinivasa Ragavan)
+ #351672: Dragging imap message when another is copying locks X (Matthew Barnes)
+ #520745: Fix format-string vulnerability (Tor Lillqvist/Srinivasa Ragavan)
+
+Other Contributors:
+ Changes for Windows. Misc simplification and cleanup. (Tor Lillqvist)
+ Updated contributors list (Johnny Jacob)
+
+Updated Translations:
+ Luca Ferretti (it)
+ Ivar Smolin (et)
+ Ankit Patel (gu)
+ Stéphane Raimbault (fr)
+ Gabor Kelemen (hu)
+ Åsmund Skjæveland (nn)
+ Hendrik Richter (de)
+ Takeshi AIHANA (ja)
+ Tino Meinen (nl)
+ Sandeep Shedmake (mr)
+ Ihar Hrachyshka, AleśNavicki (be@latin)
+ Changwoo Ryu (ko)
+ Chao-Hsiung Liao (zh_HK,zh_TW)
+ Maxim Dziumanenko (uk)
+ Kenneth Nielsen (da)
+ Kostas Papadimas (el)
+ Guntupalli Karunakar (hi)
+ Runa Bhattacharjee (bn_IN)
+ Gintautas Miliauskas (lt)
+ Petr Kovar (cs)
+ Vasiliy Faronov (ru)
+
+Evolution 2.21.92 2008-02-25
+----------------------------
+
+Bug Fixes:
+ #153807: (Novell Bugzilla) Patch from OpenSUSE (Srinivasa Ragavan)
+ #159736: (Novell Bugzilla) Fix a crash when dbus daemon restarts (Jeffrey Stedfast)
+ #167638: Quit evolution quickly (Jeffrey Stedfast)
+ #173186: (Novell Bugzilla) Fix a crash while quitting (Jeffrey Stedfast)
+ #178778: (Novell Bugzilla) Fix a crash when creating an appointment (Michael Meeks)
+ #209353: Allow paste text on mouse middle button click (Milan Crha)
+ #209353: Pass Home/End keys to cell when editing (Milan Crha)
+ #294999: (Novell Bugzilla) Fix subscribing to other user's exchange folder (Srinivasa Ragavan)
+ #339266: Do not show folder size in offline mode (Sushma Rai)
+ #358697: (Novell Bugzilla) Make sure the default search filter for sent/draft/outbox is "Recipients Contain" (Srinivasa Ragavan)
+ #383438: Report "mouse over" even with no text entered (Milan Crha)
+ #440426: Unset also default_client if removing it (Milan Crha)
+ #469292: Add empty line only when top posting is enabled (Srinivasa Ragavan)
+ #471779: Sort timezone entries alphabetically (Suman)
+ #512776: Fix a startup issue (Milan Crha)
+ #516408: Free memory returned my libical (Chenthill)
+ #514836: Fix importing contact lists into a attendee lists for a meeting (Milan Crha)
+ #514987: New sorting by Status based on the index in popup, not on the text (Milan Crha)
+ #515659: "Highlight quotations with" checkbox doesn't do anything (Paul Bolle)
+ #515744: Memory leak fix (Milan Crha)
+ #516234: Removed a stray printf() statement (Aidan Delaney)
+ #516279: Don't allow newlines in the password dialog title. Use a fixed string instead (Matthew Barnes)
+ #516349: Do not force black text in quotation part of the message (Milan Crha)
+ #516453: Change Not Started status back to Canceled when Canceled requested (Milan Crha)
+ #516648: Use "pkill -x" to kill processes on Solaris (Jeff Cai)
+ #516648: Use $HOME instead of "~" (Jeff Cai)
+ #517072: Properly escape text (Paul Bolle)
+ #517082: Fix small leak (Paul Bolle)
+ #517129: Fix build break of pl translation (Akhil Laddha)
+ #517458: Handle broken UIDs (Srinivasa Ragavan)
+
+Updated Translations:
+ Reinout van Schouwen (nl)
+ Arangel Angov (mk)
+ Changwoo Ryu (ko)
+ Daniel Nylander (sv)
+ Jorge Gonzalez (es)
+ Ignacio Casal Quinteiro (gl)
+ Nguyễn Thái Ngá»Âc Duy (vi)
+ Wadim Dziedzic (pl)
+ Kjartan Maraas (nb)
+ Djihed Afifi (ar)
+ David Lodge (en_GB)
+ Inaki Larranaga Murgoitio (eu)
+ Baris Cicek (tr)
+ David Planella (ca)
+ Pawan Chitrakar (ne)
+ Duarte Loreto (pt)
+ Andre Klapper (de)
+ Yannig Marchegay (oc)
+ Theppitak Karoonboonyanan (th)
+ Ilkka Tuohela (fi)
+ Abou Manal (ar)
+ Ivar Smolin (et)
+ Luca Ferretti (it)
+ Takeshi AIHANA (ja)
+
+Evolution 2.21.91 2008-02-11
+----------------------------
+
+New in 2.21.91
+ Documentation update for 2.22. (PC Radhika)
+
+Bug Fixes:
+ #240073 - Fix regression in strike out completed task (Milan Crha)
+ #249501 - Fix for attachments with '%' in the filename to be handled well (Milan Crha)
+ #395939 - Free alarms (Milan Crha)
+ #411576 - Give gconf option to have same fonts in vertical view column. (Srinivasa Ragavan)
+ #468427 - Fixes lots of crashes around itip-formatter (Srinivasa Ragavan)
+ #502571 - Name change to Crash Detection (Srinivasa Ragavan)
+ #506948 - Unescape while copying urls (Srinivasa Ragavan)
+ #509741 - Crash while asking certificate popup (Matthew Barnes)
+ #510642 - Improved error messages (Suman Manjunath)
+ #514736 - Added application/ms-tnef to supported mime type. (Paul Bolle)
+ #514771 - Fixes a crash while decoding attachments (Paul Bolle)
+ #511600 - Doc fixes (PC Radhika)
+ #511602 - Doc fixes (PC Radhila)
+ #512623 - Fix keystates for thread expand (Milan Crha)
+ #513285 - Do not use entities in doc (Wouter Bolsterlee)
+ #513395 - Make sure that camel url isn't null (Jeff Cai)
+ #515054 - Better spam support - Upsync SPAM flags (Milan Crha)
+
+Other Contributors:
+ Windows build fixes (Tor Lillqvist)
+ G_STRFUNC build fixes (Matthew Barnes)
+ Fix for Google Calendar Alarm (Srinivasa Ragavan)
+
+Updated Translations:
+ Kjartan Maraas (nb)
+ Jorge Gonzalez (es)
+ Daniel Nylander (sv)
+ Inaki Larranaga Murgoitio (eu)
+ Stéphane Raimbault (fr)
+ Claude Paroz (fr)
+ Duarte Loreto (pt)
+ Chao-Hsiung Liao (zh_HK)
+ Chao-Hsiung Liao (zh_TW)
+ Andre Klapper (de)
+ Yannig Marchegay (oc)
+ Shankar Prasad (kn)
+ Djihed Afifi (ar)
+ Sandeep Shedmake (mr)
+ Washington Lins (pt_BR)
+
+Evolution 2.21.90 2008-01-28
+----------------------------
+
+New in 2.21.90:
+ Improved spam filtering and new preferences UI for configuring spam filtering (Srinivasa Ragavan)
+
+Bug Fixes:
+ #324604: Ensure the print of the email is transformed from RFC822 or RFC2047 (Milan Crha)
+ #329712: Add a new state to maintian forced offline (Srinivasa Ragavan)
+ #333695: Print attendee name instead of email address if available (Milan Crha)
+ #337046: Have a ticking filename for attachment, if the mime doesn't carry it (Srinivasa Ragavan)
+ #339156: Translation issues (Andre Klapper)
+ #355864: Critical Crash warning while unchecking web calendar (Milan Crha)
+ #371011: Insert a new paragraph for signature (Johnny Jacob)
+ #391408: Fix contact minicards for RTL languages (Djihed Afifi)
+ #395939: Memory leak fix (Milan Crha)
+ #402487: Memory leak fix (Milan Crha)
+ #405777: Fix a crash when previewing mails (Srinivasa Ragavan)
+ #426159: Allow users to snooze for 1+ hour 0 minutes (Suman Manjunath)
+ #467581: Don't cancel all threads for a vfolder based search (all/account search) (Johnny Jacob)
+ #475781: Fix memory leaks (Milan Crha)
+ #503327,503678: Return GByteArray instead of gchar* (Johnny Jacob)
+ #503551: Fix a crash when trying to delete unselected contact (Milan Crha)
+ #504062: Fix message list sorting (Milan Crha)
+ #507564: Fix contact view for RTL languages. (Djihed Afifi)
+ #509124: Check result of build_message() for NULL before proceeding (Matthew Barnes)
+ #509509: Make the status bar height as large as the task bar to eliminate "bouncing" when navigating the main menu (Jean-Christophe)
+ #509697: Ensure search folders are running before calling anything from this (Milan Crha)
+ #509741: Fix a crash that occurs when prompted to accept a certificate (Matthew Barnes)
+ #509879: Drop code to clear memo preview every 60 seconds (Milan Crha)
+ #510409: Free memory before assigning NULL (Milan Crha)
+ #511094: Set proper foreground color based on focused/non-focused canvas (Milan Crha)
+ #511105: Free allocated memory properly (Milan Crha)
+ #511232: Fixed typo Uknown -> Unknown (Jan Tichavsky)
+ #511488: Ensure vfolder is running (Milan Crha)
+ #512020: Imposible to remove categories of weather (Milan Crha)
+
+Other Contributors:
+ Windows build fixes (Tor Lillqvist)
+ Message list cairo drawing (Srinivasa Ragavan)
+ Added localized screenshots (Andre Klapper)
+ libsoup updates (Dan Winship)
+
+Updated Translations:
+ Žygimantas BeruÄÂka (lt)
+ Jovan Naumovski (mk)
+ Jorge Gonzalez (es)
+ Andre Klapper (de)
+ Kjartan Maraas (nb)
+ Yair Hershkovitz (he)
+ Inaki Larranaga Murgoitio (eu)
+ Sandeep Shedmake (mr)
+ Shankar Prasad (kn)
+ Ignacio Casal Quinteiro (gl)
+
+Evolution 2.21.5 2008-01-14
+---------------------------
+
+New in 2.21.5:
+ Mail errors are now non-intrusive (Srinivasa Ragavan)
+ RTL fixes - Mail and Addressbook (Djihed Afifi)
+
+Bug fixes:
+ #211353: Allow categories to be assigned to emails (Milan Crha)
+ #219197: Quit application when session dies (Milan Crha)
+ #270605: Skip disabled accounts. (Suman Manjunath)
+ #300336: Added checkbox for "Enable Search Folders" option (Milan Crha)
+ #300336: Ensure vfolder is running. (Milan Crha)
+ #309432: Fix message headers for RTL languages. (Djihed Afifi)
+ #317823: Bump GtkHTML requirement to 3.17.5 (Matthew Barnes)
+ #317823: Save inline pictures embedded into HTML Mails (Milan Crha)
+ #327965: Fixed multiple password prompts in an exchange account (Sushma Rai)
+ #329692: Get the content size of the MIME part (Jean-Christophe BEGUE)
+ #333695: Print attenddes/roles in the print view (Milan Crha)
+ #339813: Setting new option 'e_date_edit_set_twodigit_year_can_future' to FALSE (Milan Crha)
+ #348638: Remove pre-edit buffer cleanly in day view (Mayank Jain)
+ #350932: Enable the use of scrollable tabs in the mail-preferences dialog. (Gert Kulyk)
+ #362638: Overhaul the message passing API (Matthew Barnes)
+ #364642: New option in Composer tab to preset Request Read Receipt in composer (Milan Crha)
+ #375580: Use ISO-8859-1 encoding to store contacts in iPod (João Vale)
+ #448441: Disable "OK" and "Edit Full" buttons if no source is selected. Also set always book from combo, do not use the new created (Milan Crha)
+ #457842: Do not call edit/start editing of the event when double clicked on the same component as is actually editing (Milan Crha)
+ #474118: Check for the right type of store and invoke appropriate functions (Bharath Acharya)
+ #476264: Add mnemonic_widget for default junk plugin (Andre Klapper)
+ #488213: Fix locks when displaying e-mail with large tiff drawing attached (Milan Crha)
+ #492188: Use the new Tangoized icons instead of deprecated icons from gnome-icon-theme. (Michael Monreal)
+ #492702: Just disable the dbus message part of mail notification if dbus isn't there. Also remove new-mail-notify plugin (Srinivasa Ragavan)
+ #496301: Clean up the schema (Martin Meyer)
+ #496402: Do not synchronize blocked bodies from pidgin (Milan Crha)
+ #497914: backport changes from the copy/pasted code in imap-headers plugin (Gilles Dartiguelongue)
+ #498095: Fix mnemonic issues (David Turner)
+ #499145: Follow RFC 3798 to send return receipts. (Colin Leroy)
+ #502303: Plugins configure widgets are not freed correctly in plugin-mamager (Milan Crha)
+ #502783: Restore message states (read receipt/priority) when opening from a draft (nickspoon0@gmail.com)
+ #502914: Do not write NULL into gconf (Milan Crha)
+ #503954: Accept custom domain names while setting up account (Nyall Dawson)
+ #504480: Increases the height of the ETaskBar to eliminate the constant resizing (Milan Crha)
+ #504541: Add --with[out]-help option to make it possible to skip building and installing user documentation (Matthew Barnes)
+ #506772: Not-NULL check for a string array before finding its length (Christian Krause)
+ #506814: Add the signal only if the view is present (Srinivasa Ragavan)
+ #507067: Can't save pictures embedded in HTML Mail when picture = link (Milan Crha)
+ #507311: Submit bugs to the "BugBuddyBugs" Bugzilla component (Matthew Barnes)
+ #507359:
+ #507363: Also check if toplevel widget has non-NULL window property (Milan Crha)
+ #508282: Mark the window title for translation. (Changwoo Ryu)
+ #508678: Included missing header glib/gi18n.h (Bharath Acharya)
+ #508731: Have a safe default, if the values from gconf isn't so nice. (Srinivasa Ragavan)
+
+Updated Translations:
+ Amitakhya Phukan (as)
+ Espen Stefansen (nb)
+ Jorge Gonzalez (es)
+ Luca Ferretti (it)
+ Changwoo Ryu (ko)
+ Inaki Larranaga Murgoitio (eu)
+ Erdal Ronahi (ku)
+ Clytie Siddall (vi)
+ Kjartan Maraas (nb)
+ Yannig Marchegay (oc)
+ Wadim Dziedzic (pl)
+ Daniel Nylander (sv)
+ Seán de Búrca (ga)
+ Djihed Afifi (ar)
+
+Evolution 2.21.4 2007-12-17
+---------------------------
+
+New in 2.21.4:
+ Basic support for non-intrusive error reporting and error logging in Mailer (Srinivasa Ragavan)
+ Add basic support for crash detection (Srinivasa Ragavan)
+ Basic Message tagging support (aka Custom labels) (Sankar P / Milan Crha)
+
+Bug fixes:
+ #220846: New option to accept meeting request as free time (Milan Crha)
+ #263236: Look for "Do not ask me again" check in alignment, so let it works properly (Milan Crha)
+ #329578: Add mnemonic for "minutes" widget (Alex Kloss)
+ #329706: Confirmation dialog for HTML Message needs some improvements (Alex Kloss)
+ #336074: Check for mail only in active folders (Milan Crha)
+ #340267: Show description in preview as preformatted text, so tabulators are kept instead of treated as white spaces (Milan Crha)
+ #347328: Fix mnemonic clash over 'c', add mnemonic for 'Name' entry (Alex Kloss)
+ #347329: Added a mnemonic to the 'Create' button of the 'New Folder' dialog (David Turner)
+ #354265: Fixed mnemonic clash between print and paste mnemonics (David Turner)
+ #392747: Abbreviated day names are in english for month view, while they appear in indic lang chars when seen in print-preview/actual-print (Matthew Barnes)
+ #408170: Added mnemonics to the "Custom" and "Sort By" menu options (David Turner)
+ #409121: Corrected misspelled instances of vCard (Lucky Wankhede)
+ #430369: Crash in ea_setting_setup() (Srinivasa Ragavan)
+ #437579: Fix all "entity not defined" warnings (Matthew Barnes)
+ #438769: Changed label from 'Search name' to 'Rule name' in edit -> message filters -> add (Bob Mauchin)
+ #444227: Make string for PrepareForOffline more descriptive. Add mnemonic to PrepareForOffline menu item (Alex Kloss)
+ #446029: Fix for a mnemonic conflict in 'Find in Message' feature (David Turner)
+ #458824: Added mnemonics to the "Group" dialog (David Turner)
+ #466241: Added a mnemonic to "Authentication type" in the recieving mail section of configuration (David Turner)
+ #466497: Changed some mnemonics to stop l being used as a mnemonic key (David Turner)
+ #466499: Added support for mnemonics in config options from camel (David Turner)
+ #466503: Fix for a mnemonic conflict in Preferences -> Mail Preferences -> Junk tab (Alex Kloss)
+ #468277: Added a mnemonic to "Copy book content locally for offline operation" (David Turner)
+ #474043: Prevent buffer overflows, by introducing a max size to copy (Evil Ninja Squirrel)
+ #474651: Use format strings in gtk_message_dialog_new (Tobias Mueller)
+ #475508: Changed the string for search folder and filter creation from message list to make it understandable (Akhil Laddha)
+ #492702: Moved bits of sound notification on new messages to mail-notification plugin. (Milan Crha)
+ #500210: Show plugin configuration in a tab of plugin manager (Milan Crha)
+ #500561: Added icon for mark all messages as read menu item. (Denis Washington)
+ #501474: Fix wrong expression from bug #359267 (Milan Crha)
+ #501677: If it is not FolderBrowser object, the pane size signal is not sent (Jeff Cai)
+ #501969: Passwords should not be forgotten on all errors (Sankar P)
+ #502188: Initialize "remember" variable to FALSE. (nickspoon0@gmail.com)
+ #502312: A little cleanup of configuration part of the plugin to not use global variables and free memory properly (Milan Crha)
+ #502318: Critical warnings fixed when closing message window (Milan Crha)
+ #502501: Re use the existing string (Srinivasa Ragavan)
+ #503111: Suppress "Loading %s as the default junk plugin" message (Alex "weej" Jones)
+
+Other Contributors:
+ Fixes some CPU usage issue whenever (un)read count is updated (Sankar P/Michael Meeks)
+ Added a preference to disable Magic Spacebar (Srinivasa Ragavan)
+ Fix an implicit function declaration. (Matthew Barnes)
+ Bump libgtkhtml requirement to 3.17.3 due to bug #271551 (Matthew Barnes)
+ Cleanup of attachment reminder over Milan Crha's work (Johnny Jacob)
+ Move preferences of attachment reminder plugin to the configure tab (Sankar P)
+ Fix capitalization of "Download Messages..." & "Switcher Appearance" menu (Matthew Barnes)
+
+Updated Translations:
+ Kjartan Maraas (nb)
+ Kostas Papadimas (el)
+ Jorge Gonzalez (es)
+ Matej UrbanÄÂiÄÂ(sl)
+ Andre Klapper (de)
+ Rodrigo Flores (pt_BR)
+ Daniel Nylander (sv)
+ Seán de Búrca (ga)
+
+Evolution 2.21.3 2007-12-03
+---------------------------
+
+Bug fixes:
+ #214645: Collapses non-working days to occupy one row and expand other days if possible (Milan Crha)
+ #216485: Add Select Message Subthread (Nicholas Miell)
+ #216485: Edit->Select thread menu fix and improvement (Nicholas Miell)
+ #256899: Remove "Disable/Enable" button from Mail Accounts preferences (Chaya)
+ #271551: File manager used during composer should remember last directory (Milan Crha)
+ #325730: Tasks preview pane not refreshed on delete event (Milan Crha)
+ #335931: Disappearing of the bottom-most mail leaves invalid selection (Milan Crha)
+ #346693: Ensure new event in top canvas will be visible. (Milan Crha)
+ #353807: Notice user if any error occur during opening calendar, calendar is readonly or when add fails. (Milan Crha)
+ #380644: "Required Participants" dialog does not show meeting participants (Milan Crha, Matthew Barnes)
+ #391062: Automatic contacts are now added only if enabled (Srinivasa Ragavan)
+ #400213: Do not use pixmaps and masks, load images from file, instead (Milan Crha)
+ #401337: Use other mnemonic for Organizer and let it work properly (Milan Crha)
+ #401523: Selectable text in imap headers page. (Lucky)
+ #458237: Check for non-NULL source before using it to prevent a crash (Milan Crha)
+ #479081: Check for input validity immediately after creating setup widgets (Milan Crha)
+ #480514: Let "Last 5 Days' Messages" and "Recent messages" filters work in Sent folder too (Milan Crha)
+ #484603: Do not forget for organizer icon when counting used icons. (Milan Crha)
+ #489652: Migrate the contact list editor from ETable to GtkTreeView and fix some HIG issues (Matthew Barnes)
+ #493783: Do not erase old content when re-formatting same mail, so keep scroll position (Milan Crha)
+ #494414: If used uri points to an account, then prepend account's name to folder name (Milan Crha)
+ #494425: 'Save All' handles duplicate attachement names incorrectly (Milan Crha)
+ #495123: Refactor composer headers (Matthew Barnes)
+ #495711: Keep track of previously created Full Name dialog and reuse it (Milan Crha)
+ #495872: Add memo support (Gilles Dartiguelongue)
+ #495875: Right click menu reordering (Gilles Dartiguelongue)
+ #495951: Use GtkTreeView in place of ETable (Gilles Dartiguelongue)
+ #497810: Add "Evolution FAQ" help menu item (Andre Klapper)
+ #498173: Plugin configure dialog pops up automatically (Sankar P)
+ #498551: Forgotten "Loading..." node under nntp server (Milan Crha)
+ #499644: The behavior of the "Include remote tests" check button was swapped with respect to its state. (Matthew Barnes)
+ #499920: Missing header files has to be shipped (Matthew Barnes)
+ #500024: Set number of pages first (Milan Crha)
+
+Updated Translations:
+ Jorge Gonzalez (es)
+ Ivar Smolin (et)
+ Matej UrbanÄÂiÄÂ(sl)
+ Yannig Marchegay (oc)
+ Daniel Nylander (sv)
+
+Evolution 2.21.2 2007-11-12
+---------------------------
+
+Bug fixes:
+ #231166: Do not start appointment time drop-down at midnight (Milan Crha)
+ #255051: No way to abort creation of new task (Milan Crha)
+ #315101: Receiving list of components, so made changes here to reflect it (Milan Crha)
+ #318592: Allow UI notification of links inserted in composer (Milan Crha)
+ #318604: Automatically enable view of the task list you add a task to (Milan Crha)
+ #334675: When only one message is selected, try to use selected text in preview as description, instead of whole message body (Milan Crha)
+ #341085: Use 'x_offset' instead of changing event size when has icons (Milan Crha)
+ #343011: restore collapse state of selected folder after start (Milan Crha)
+ #346693: Too Many All Day Events force Calendar to grow beyond screen-height (Milan Crha)
+ #351932: Ensure due date is not before start date (Milan Crha)
+ #353779: Allow convert more than one mail to meeting with one click (Milan Crha)
+ #353780: Stop processing immediately when page is filled incorrectly (Milan Crha)
+ #359267: Not all memos are showed in calendar view (Milan Crha)
+ #463946: Fix of critical warning and misused variable (Milan Crha)
+ #478704: Remove dead files from source control (Matthew Barnes)
+ #483785, #209425: Get rid of deprecated icons from gnome-icon-theme (Michael Monreal)
+ #484064: Use mail-message-new instead of mail-send for composing mail to contact, contacts or group (Michael Monreal)
+ #487318: Fix typo in D-Bus (Gilles Dartiguelongue)
+ #488298: Disable marking of Drafts as junk (Milan Crha)
+ #491345: Hide completed tasks option requires evo's restart (Milan Crha)
+ #492058: Name the anonymous unions to build with the Sun Studio compiler. (Damien Carbery)
+ #492102: Use mail-mark-read icon (Michael Monreal)
+ #492106: Use the about icon from the freedesktop spec, not the deprecated gnomeui icon (Michael Monreal)
+ #492170: Replace the old color definitions with very similar colors from the Tango color palette (Michael Monreal)
+ #492692: Plug memory leak (Milan Crha)
+ #493646: Fixed a crash at startup (Sankar P)
+
+Updated Translations:
+ Ignacio Casal Quinteiro (gl)
+ Washington Lins (pt_BR)
+ Jorge Gonzalez (es)
+ David Planella (ca)
+ Kjartan Maraas (nb)
+
+Evolution 2.21.1 2007-10-29
+---------------------------
+
+New in 2.21.1:
+ New plugin: external-editor, which will make it possible to use an external editor as the mail composer (Sankar P)
+ Support for Google Calendar (Ebby Wiselyn)
+ New Tango look icons (Michael Monreal)
+
+Bug fixes:
+ #228832: Show tasks in calendar (Milan Crha)
+ #230339: Print also location, if present. (Milan Crha)
+ #261165: Added search on CC and BCC (Andre Klapper)
+ #271734: Show description of operation, if available (Milan Crha)
+ #300693: Removed obsolete code and references to "task-sort" virtual column (Milan Crha)
+ #311179: Avoid selection of label text by Tab (Milan Crha)
+ #323977: Filters Editor Needs UI Modifications (Milan Crha)
+ #324472: Tasks marked as complete using multiple selection are now saved (Milan Crha)
+ #329823: Added support to change component's button icon (Milan Crha)
+ #329823: Icon change to reflect new mail (Milan Crha)
+ #331421: Make contact list name clickable (Milan Crha)
+ #331578: Run command line in other thread rather than in main thread (Milan Crha)
+ #337539: Omit left column when showing list of contacts (Milan Crha)
+ #340748: Notifies others about change (Milan Crha)
+ #342283: Behave consistently when printing (Milan Crha)
+ #346146: Appointments in "Sent Items" should not display Accept/Decline buttons (Milan Crha)
+ #346686: Uses new helper function to determine if row is editable (Milan Crha)
+ #351333: Added more descriptive hint over search bar's option button (Milan Crha)
+ #353656: Rename "Phone List" to "List View" (Anand V M)
+ #360134: Plug memory leaks (Tobias Mueller)
+ #395272: Minor code cleanups and value checking (Tobias Mueller)
+ #412360: Show tooltip for all email addresses (Milan Crha)
+ #413420: Change mimetype if knows the extension and if the content of file is valid. (Milan Crha)
+ #417999: Don't use deprecated GTK+ symbols (Milan Crha)
+ #423401: Better error handling when attaching remote file (Milan Crha)
+ #428402: Fix a crash in calendar (Milan Crha)
+ #428402: Really go through every component when removing one (Milan Crha)
+ #437579: Fix various compiler warnings (Milan Crha)
+ #461195: Remove needless marshalers (Hiroyuki Ikezoe)
+ #461272: Configure button should not be enabled for all (Sankar P)
+ #467364: Evolution uses "Emoticon" instead of "Smiley" (Christian Kintner)
+ #468736: Fixed high memory consumption (Srinivasa Ragavan)
+ #469657: Use destroy functions in GHashTables to simplify memory management (Matthew Barnes)
+ #470837: Improved "Sort by" submenu behavior (Milan Crha)
+ #473903: Fix compile time warnings (Milan Crha)
+ #474000: Use GLib's Base64 API instead of Camel's (Matthew Barnes)
+ #474557: Choose right widget and use PANGO_PIXELS to calculate height (Milan Crha)
+ #476389: Maintain UI consistency (Diego Escalante Urrelo)
+ #476926: Remove the --enable-gtk-doc configure option since we don't ship any Gtk-Doc content (Matthew Barnes)
+ #477045: Require gnome-icon-theme 2.19.91 (Matthew Barnes)
+ #477045: Use standard icon names where applicable (Matthew Barnes)
+ #478871: Shows proper 'Fields shown' description for all tables (Milan Crha)
+ #479257: Change icon references (Michael Monreal)
+ #479257: Migration of theme icons (Michael Monreal)
+ #479716: Maintain UI consistency (Milan Crha)
+ #480621: Use consistent terminology for mail messages (Matthew Barnes)
+ #480804: use EVOLUTION_GLADEDIR instead of EVOLUTION_PLUGINDIR (Pedro Villavicencio Garrido)
+ #481235: Display Face header value if contacts doesn't have any image associated with them. (Sankar P)
+ #481325: Fix capitalization of program name in About dialog (Matthew Barnes)
+ #481325: Require GTK+ 2.12 (Matthew Barnes)
+ #482575: Don't use "insert_image" icon (Michael Monreal)
+ #482603: Use document-properties icon instead of stock_folder-properties (Michael Monreal)
+ #483301: Remove an unused variable (Matthew Barnes)
+ #483989: Require libbonobo 2.16.0 or later (Matthew Barnes)
+ #484635: Plugged memory corruption (Bharath Acharya)
+ #484814: Change name and comment in .desktop file (Matthew Barnes)
+ #486406: Use addressbook-new icon instead of stock_addressbook (Michael Monreal)
+ #489027: Thread sorting for new mails fixed (Milan Crha)
+ #489661: Remove dead, unshipped code from addressbook/gui/widgets (Matthew Barnes)
+
+Updated Translations:
+ Jorge Gonzalez (es)
+ Matej UrbanÄÂi (sl)
+ Anas Husseini (ar)
+ Daniel Nylander (sv)
+ David Planella (ca)
+ Yavor Doganov (bg)
+ Ivar Smolin (et)
+ Gintautas Miliauskas (lt)
+ Ignacio Casal Quinteiro (gl)
+ Stéphane Raimbault (fr)
+
+Evolution 2.12.0 2007-09-17
+----------------------------
+
+Bug fixes:
+ #270605: Skip disabled accounts and choose first available address as organizer. (Chenthill Palanisamy, Milan Crha)
+ #274047: (Novell Bugzilla) Pick the glade file from install area (Chenthill Palanisamy)
+ #274048: (Novell Bugzilla) Prompt for a password if required (Chenthill Palanisamy)
+ #277159: (Novell Bugzilla) Listen to the changes made in publish frequency (Chenthill Palanisamy)
+ #300284: (Novell Bugzilla) Do not allow the user to set a 'no-date' for start/end of appointments in list view (Suman Manjunath)
+ #301044: (Novell Bugzilla) Dont append the comma from the Nameselector (Srinivasa Ragavan)
+ #304993: (Novell Bugzilla) Allow folder selection of created folders and expand only if selection is not asked for (Srinivasa Ragavan)
+ #329629: audio-inline plugin has been ported to gstreamer 0.10 (Frederic Crozat)
+ #330223: More than one memo list was getting marked as default (Milan Crha)
+ #332026: Filter the input context key events (Chenthill Palanisamy)
+ #363645: Don't translate empty label names. (Bastien Nocera)
+ #368033: Assign default color for B&A when no color is set (Milan Crha)
+ #467581: Get the right URIs for selected and current folders. (Johnny Jacob)
+ #468366: Avoid empty keywords getting added and other small fixes and improvements. (B S Srinidhi)
+ #471791: Move away from g_assert to g_critical (Srinivasa Ragavan)
+ #473903: Fixes serious compiler warning (Milan Crha)
+
+Other Contributors:
+ Fix weak references which fixes one issue of the patch from bug #439122 (Gilles Dartiguelongue)
+ Code cleanup (Suman Manjunath)
+
+Updated Translations:
+ Yannig Marchegay (oc)
+ Nickolay V. Shmyrev (ru)
+ Gabor Kelemen (hu)
+ Iestyn Pryce (cy)
+ Ahmad Farghal (ar)
+ Jamil Ahmed (bn)
+ Hendrik Richter (de)
+ Danishka Navin (si)
+ Igor Nestorovi (sr)
+ Ani Peter (ml)
+ Amitakhya Phukan (as)
+ Ilkka Tuohela (fi)
+ Jorge Gonzalez (es)
+ Kenneth Nielsen (da)
+ Daniel Nylander (sv)
+ Jovan Naumovski (mk)
+ Ankit Patel (gu)
+ Luca Ferretti (it)
+ Inaki Larranaga Murgoitio (eu)
+ Clytie Siddall (vi)
+ Priit Laes (et)
+
+Evolution 2.11.92 2007-09-03
+----------------------------
+
+Bug fixes:
+ #201167: Complete implementation of Categories synching and lots of bug fixes (Nathan Owens and Tom Billiet)
+ #351672: Dragging imap message when another is copying locks X (Gavin Scott)
+ #377763: Do not scale under 1x1 pixel (Milan Crha)
+ #378759: Fixed a crash when entering S/MIME password for signing email (Milan Crha)
+ #431459: Avoid reentrancy of prefer-plain plugin (Srinivasa Ragavan)
+ #466051: When memo start date is set to 'None', do not store DTSTART property. (Suman Manjunath)
+ #469886: Update FSF address in header comments (Tobias Mueller)
+ #471791: Move away from g_assert to g_critical (Srinivasa Ragavan)
+
+Other Contributors:
+ - Add mail/default/pl/Makefile to AC_OUTPUT (Matthew Barnes)
+ - Add Evolution contributors names to credits page (Gilbert Dartiguelongue)
+
+Updated Translations:
+ Kjartan Maraas (nb)
+ Ivar Smolin (et)
+ Takeshi AIHANA (ja)
+ Washington Lins (pt_BR)
+ Jovan Naumovski (mk)
+ Ankit Patel (gu)
+ Tirumurthi Vasudevan (ta)
+ Ilkka Tuohela (fi)
+ GNOME PL Team (pl)
+ Daniel Nylander (sv)
+ Jorge Gonzalez (es)
+ Theppitak Karoonboonyanan (th)
+ Clytie Siddall (vi)
+ Funda Wang (zh_CN)
+ Duarte Loreto (pt)
+
+Evolution 2.11.91 2007-08-27
+----------------------------
+
+Bug fixes:
+ #201201: Double-click on selected range in week view empty area should bring up event editor (Milan Crha)
+ #201202: Double-click on selected range in day view should bring up event editor (Milan Crha)
+ #239441: Fixed a crash when sorting imap mailbox by date (Milan Crha)
+ #256878: Set the message for valid signatures (Vincent Untz)
+ #262226: Inconsistent "all day" behaviour of appointment editor (Milan Crha)
+ #262682: Add labelled-by relation between labels and entry. (Li Yuan)
+ #272167: 'Mark calendar for offline option' is available for local calendars (Milan Crha)
+ #274070: (BNC) download of freebusy not working (Chenthill Palanisamy)
+ #301835: (BNC) Fixed a crash when clicking on mail with a calendar appointment (Suman Manjunath)
+ #303877: candidate window position at 0,0 in Evolution Task (Hiroyuki Ikezone)
+ #303878: candidate window position at 0,0 in calendar (Hiroyuki Ikezoe and Mayank Jain)
+ #308636: User can delete grouwpise 'Calendar' (Milan Crha)
+ #309166: Fix incorrect cusor movement and delete for indic charcters in evolution calendar (Mayank Jain)
+ #328405: A signature will be attached when redirecting an email (Raghavendran)
+ #329746: Renamed 'Journal' to 'Memo'. (Milan Crha)
+ #330628: In day view Meeting icon should be displayed in All day meeting (Hiroyuki Ikezoe)
+ #331174: Rename KRBx_LDFLAGS to KRBx_LIBS (Matthew Barnes)
+ #337616, #352346, #467364, #468309: Documentation fixes (PC Radhika)
+ #338803: Free/Busy Loses Meeting Duration When Click To Another Time. (Milan Crha)
+ #347770: Improved description text parsing (Milan Crha)
+ #350539: Check for NULL MIME part (Milan Crha)
+ #352358: Harmonized some error messages (Ushveen Kaur)
+ #353462: Changing the labels of buttons from "Yes/No" to make them HIG compliant. (Anand V M)
+ #355766: Multi-lang text in Body is not printed when composing in ASCII mode (Mayank Jain)
+ #355864: Fixed a critical warning when unchecking a webcal (Milan Crha)
+ #364431: Fix a crash while refreshing IMAP subscriptions (Johnny Jacob)
+ #364700: Load/Enable junk plugins while loading only (Srinivasa Ragavan)
+ #367760: Fix multiple issues with Save / Save All attachment button (Milan Crha)
+ #385414: Fix multi language text display in message source (Mayank Jain)
+ #385517: Evolution Preferences for Task now allows to change field values (Milan Crha)
+ #411619: Fixed build failures with -z defs (Matthew Barnes)
+ #412732: Fixed a crash when adding contact (Milan Crha)
+ #414420: Fix a crasher on repeated destroy (Ed Catmur)
+ #420492: new all day event does not record "show as busy" status (Ebby Wiselyn)
+ #428110: Dragging memo onto the same memo list used to delete the memo (Milan Crha)
+ #431459: Enable format plugins while loading only (Srinivasa Ragavan)
+ #435942: Documentation fixes (PC Radhika)
+ #440328: Added missing mnemonic for merge button (Suman Manjunath)
+ #440807: Sync now with Pidgin IM (Suman Manjunath)
+ #458715: Fixed a crash in GW proxy setting (Johnny Jacob)
+ #464106: GoTo Date dialog does not honor settings (Milan Crha)
+ #464338: Show popup when creating new folder (Bharath Acharya)
+ #465573: Optimize pixbuf behaviour (Tim Yamin)
+ #466548: Fixed a crash when editing calendar event when none of the accounts are enabled (Milan Crha)
+ #466796: Fixed a crash at start up (Rouslan Solomakhin)
+ #467165: Fixed a crash at start up(Srinivasa Ragavan)
+ #467198: Initialize the camel exception (Srinivasa Ragavan)
+ #467382: Compilation with "-pedantic" fails due to missing array size (Tobias Mueller)
+ #467559, 467883: Fix a crash on startup (Matthew Barnes)
+ #467635: String changes (Johnny Jacob)
+ #468159: Removed usage of BASE_VERSION (Gilles Dartiguelongue)
+ #468294: Add a few strings for translation. (Srinivasa Ragavan)
+ #468303: Add strings for i18n (Srinivasa Ragavan)
+ #468303: Add strings for i18n (Srinivasa Ragavan)
+ #468303: Enable strings for i18n. (Srinivasa Ragavan)
+ #468411: Fixed a crash while editing a newly typed event in week view (Srinivasa Ragavan)
+ #468440: Fixed a crash in calendar week-view (while editing a new event with empty text) (Srinivasa Ragavan)
+ #468734: Fix a crash when trying to change label color in preferences (Srinivasa Ragavan)
+ #468804: Fixed a crash when converting a mail with attachment to task (Wang Xin)
+ #468869: Mark strings for Translation. (Sankar P)
+
+Other Contributors:
+ Set the free/busy info of events entered directly on the canvas,
+ with the editor defaults. (Suman Manjunath)
+
+Updated Translations:
+ Jorge Gonzalez (es)
+ Daniel Nylander (sv)
+ Washington Lins, Raul Pereira (pt_BR)
+ Ivar Smolin (et)
+ Ankit Patel (gu)
+ Ilkka Tuohela (fi)
+ Andre Klapper, Hendrik Richter (de)
+ Kjartan Maraas (nb)
+ Stéphane Raimbault (fr)
+ Theppitak Karoonboonyanan (th)
+ Takeshi AIHANA (ja)
+ Reinout van Schouwen (nl)
+ Jakub Friedl (cs)
+ Tirumurthi Vasudevan (ta)
+ GNOME PL Team (pl)
+
+Evolution 2.11.90 2007-08-13
+---------------------------
+
+New in 2.11.90:
+ - A new command line option (--disable-preview) to disable loading crash-on-selected last mails,
+ tasks, contacts (Srinivasa Ragavan)
+
+Bug fixes:
+ #287394: (BNC) When exitting, close after the message was saved. (Srinivasa Ragavan)
+ #313221: Improve parsing of VCARD file with multiple TYPE information (Milan Crha)
+ #322624: Don't add alarms for types with unknown/none notification method (Milan Crha)
+ #327977: Fix a crash when setting password in preferences window (Milan Crha)
+ #331729: Fixed a crash when using cursor keys after expunging selected mail (Milan Crha)
+ #335566: Fix a crash when scaling an image in preview pane (Milan Crha)
+ #351552: Fixed critical warning with e_passwords for calendars without 'auth-domain' property (Milan Crha)
+ #352346: Cannot create Maildir account (Milan Crha)
+ #377173: Show category icon correctly (Hiroyuki Ikezoe)
+ #377309: "Synchronize now" should work even if periodic checking is not enabled (Diego Escalante Urrelo)
+ #383684: Do not load pending hooks if the corresponding plugin is disabled (Sankar P)
+ #387312: Auto-collapse of expanded threads has been fixed (Tobias Mueller)
+ #401533: Text marked for localization in memos (Milan Crha)
+ #419690: Fixed a crash during startup after a unclean shutdown (Srinivasa Ragavan)
+ #427469: When importing VCARD, if HOME or WORK isn't specified for EMAIL, add TYPE=OTHER (Milan Crha)
+ #428125: Added mnemonic for "Plain Text Mode" in preferences (Anand V M)
+ #429234: Fixed a crash when opening an attachment (Srinivasa Ragavan)
+ #444882: Fixed configure options beautification (Gilles Dartiguelongue)
+ #451599: Timing of setting the attachment is downloaded has to be after creating the attachment (Srinivasa Ragavan)
+ #454253: Fixed a crash during alarm notify (Srinivasa Ragavan)
+ #455799: Remove all .cvsignore and update svn:ignore porperty in all directories. (Hiroyuki Ikezoe)
+ #458508: String issues resolved in backup-restore plugin (Anand V M)
+ #458822: Description string fixed for mail-notification plugin (Anand V M)
+ #460326: If the vcalendar isn't there don't crash but report invalid. (Srinivasa Ragavan)
+ #460821: The second argument of g_utf8_strdown() expects the length of string in bytes or -1 (Hiroyuki Ikezoe)
+ #462007: Plugged memory leak. (Hiroyuki Ikezoe)
+ #462010: Plugged memory leak. (Hiroyuki Ikezoe)
+ #462138: Signature on top does not work if no signature is set as default (Sankar P)
+ #462332: Avoid duplicate attachments when DnD image (Hiroyuki Ikezoe)
+ #463061: Fixed a crash while launching preferences window (Srinivasa Ragavan)
+ #463129: Fix glibc free crash when changing components (Milan Crha)
+ #463946: Calling "Add Column" more than once now works (Milan Crha)
+ #464312: Do not connect to server if the account is disabled. (Srinivasa Ragavan)
+
+Other Contributors:
+ - Fix for expanding newly created folders (Lucky)
+ - Documentation updates (Radhika)
+ - Exchange Calendar delegation bug fixes (Suman)
+
+Updated Translations:
+ Claude Paroz and Stéphane Raimbault (fr)
+ Jorge Gonzalez (es)
+ Andre Klapper (de)
+ Daniel Nylander (sv)
+ Theppitak Karoonboonyanan (th)
+ Takeshi AIHANA (ja)
+ Tirumurthi Vasudevan (ta)
+ Ankit Patel (gu)
+ Ilkka Tuohela (fi)
+ Kostas Papadimas (el)
+ Danishka Navin (si)
+ Kjartan Maraas (nb)
+
+Evolution 2.11.6.1 2007-07-31
+-----------------------------
+Changes:
+ Handle mails from delegates appropriately, rather than showing the
+ pretty-on-behalf-of band for all mails containing a Sender field
+ (Veerapuram Varadhan)
+
+Evolution 2.11.6 2007-07-30
+---------------------------
+
+New in 2.11.6:
+ New Face plugin - Helps in attaching Face header to outgoing mails
+ (Sankar P)
+ Plugins are now configurable within the plugin-manager itself
+ (Sankar P)
+ Provide support for keeping your signature on top while replying
+ (Sankar P)
+
+Bug fixes:
+ #200977: Ensure that selected day is visible when changed (Milan
+ Crha)
+ #237989: Included support for backspace in magic space bar feature
+ (Johnny Jacob)
+ #268162: Add username and password options to webcal dialog (Milan
+ Crha)
+ #273386: Fixed a crash while viewing an attached image (Milan Crha)
+ #273699: Fixed a crash when starting evolution-alarm-notify if it is
+ already running (Milan Crha)
+ #303937: Fixed a crash on receiving a drag-n-drop event at startup
+ (Milan Crha)
+ #323522: Fixed a crash when switching components (Srinivasa Ragavan)
+ #326388: Delete button is disabled for 'Birthdays & Anniversaries'
+ calendar (Milan Crha)
+ #332112: Fixed inconsistent punctuation in send/receive dialog
+ (Lucky Wankhede)
+ #335881: Fixed pasting of raw text in task list (Hiroyuki Ikezoe)
+ #380534: Collect all the required package versions in one place and
+ explicitly require GTK+ 2.10 or higher (Matthew Barnes)
+ #410287: Removed whitespaces in front of punctuation marks (Lucky
+ Wankhede)
+ #428123: Fixed mnemonic conflicts (Lucky Wankhede)
+ #444433: Fix spelling and grammar errors in "Advanced Search
+ options" (Lucky Wankhede)
+ #445248: Fixed a crash when changing default drafts / sent folder in
+ IMAP (Johnny Jacob)
+ #451211: Fixed a crash (Lucky Wankhede, Hiroyuki Ikezoe)
+ #453544: Fixed switched actions of "Do not mark as read" and "Mark
+ as read" buttons (hggdh)
+ #453668: Fixed a random crash (Rob Bradford)
+ #453860: Fix a crash when creating new meeting (Xiurong Simon Zheng)
+ #457394: Fixed a crash in tasks (Milan Crha)
+ #457523: Fixed parse error in quick search bar (Johnny Jacob)
+ #458275: Fixed malformed body part headers for a MDN (Atos Origin
+ Communication Systems <support-syscom@atosorigin.com>)
+ #458511: Fix display of exchange delegate emails (Hiroyuki Ikezoe)
+ #458820: Grey out local photos search if sender photo display is
+ disabled (Cosimo Cecchi)
+ #458894: Fixed a crash when deleting an IMAP account (Johnny Jacob)
+ #459030: Shrink To / Cc / Bcc headers now work in non-english
+ locales too (Srinivasa Ragavan)
+ #459251: Added new files with translatable strings (Johnny Jacob)
+ #459413: Fixed a crash when connecting to a wcap calendar account
+ (Li Yuan)
+ #459522: Plugins should be configurable within the plugin-manager
+ itself. (Sankar P)
+ #460825: Removed needless EFilterBarClass (Hiroyuki Ikezoe)
+ #461474: Remove redundant code in calendar (Rob Bradford)
+
+Updated Translations:
+ Jorge Gonzalez (es)
+ Matic Žgur (sl)
+ Bharat Kumar (te)
+ Claude Paroz, Myriam Malga and Stéphane Raimbault (fr)
+ Danilo Å egan (sr)
+ Vincent van Adrighem (nl)
+ Raivis Dejus (lv)
+ Daniel Nylander (sv)
+ Ilkka Tuohela (fi)
+ Priit Laes (et)
+ Changwoo Ryu (ko)
+ Ankit Patel (gu)
+
+Evolution 2.11.5 2007-07-09
+---------------------------
+
+New in 2.11.5:
+ Hook for plugging into Send/Receive dialog for the Evolution RSS plugin. (Srinivasa Ragavan)
+ Attachment reminder plugin (Johhny Jacob)
+ Tnef attachment plugin (Lucky Wankhede)
+ Exchange Delegation support (Bharath and Suman)
+ Improved email printing with support of most of the Gtk+ print options (Matthew Barnes)
+
+Bug fixes:
+ #271864: Junk and Trash folders now list number of selected emails
+ correctly (Hiroyuki Ikezoe)
+ #307410: Fix prompting for IMAP password a second time after
+ canceling first request (Milan Crha)
+ #312370: When loading images from an html message, the download
+ status is shown correctly (B S Srinidhi)
+ #317281: Allow vFolder to search on the different states of a flag
+ (Michael P. Lepore)
+ #321741: Default date for appointment or meeting is now set to
+ current date (Milan Crha)
+ #328484: Changing the color of a calendar wasn't getting reflected
+ correctly (Milan Crha)
+ #334118: Add EPlugin hook for checking just written mail (Johnny
+ Jacob)
+ #334140: Fixed a crash when replying to a mail with "Automatic
+ Contacts" are enabled (Milan Crha)
+ #337787: Fixed copy behavior in the Contact Preview Pane (Hiroyuki
+ Ikezoe)
+ #347782: Fixed display of gpg/pgp encrypted error message as S/MIME
+ (hggdh)
+ #352947: Fixed a crash when selecting a default S/MIME certificate
+ (Milan Crha)
+ #387844: Fix invalid time and date values (Mayank Jain)
+ #433732: Location of perl binaries are now configurable (Laszlo
+ (Laca) Peter)
+ #437892: Improve display of IMAP headers plugin's configuration
+ window (Gilles Dartiguelongue)
+ #444882: Fixed configure options beautification (Gilles
+ Dartiguelongue)
+ #445526: Sensitivity of alarm dialog widgets has been fixed (Milan
+ Crha)
+ #446894: Clean up printing in Evolution's Mailer (Matthew Barnes)
+ #448568: Fixed alignment issue in the contact editor (Gilles
+ Dartiguelongue & Vinod)
+ #448970: Fixed a crash during startup (Srinivasa Ragavan)
+ #449811: Fixed magic spacebar break when using caret mode (Srinivasa
+ Ragavan)
+ #450820: Add an empty line at the beginning of the mail body when
+ relpying a mail (Wang Xin)
+ #452900: Fixed the alignment of mail notification popup with tray
+ icon (Cosimo Cecchi)
+ #453294: Fixed attachment name garble on locale 8859-1 (simon.zheng)
+
+Updated Translations:
+ Jorge Gonzalez (es)
+ Nguyễn Thái Ngá»Âc Duy (vi)
+ Priit Laes (et)
+ Clytie Siddall (vi)
+ Kjartan Maraas (nb)
+ Guilherme de S. Pastore (pt_BR)
+ I. Felix (si)
+ Daniel Nylander (sv)
+ Funda Wang (zh_CN)
+
+
+Evolution 2.11.4 2007-06-18
+---------------------------
+
+New in 2.11.4:
+ Portugese help files (Duarte Loreto)
+ Add initial support for the Magic Space Bar (Mutt) to read unread emails in
+ all folders. (Srinivasa Ragavan)
+
+Bug fixes:
+ #257118: Clear button is now getting disabled after clearing the
+ search (Milan Crha)
+ #263207: Advanced Search "Remove" button is now inactive (Milan
+ Crha)
+ #325882: Fix some of the window /dialog positions (Milan Crha)
+ #330175: Added helper function which test selection for non-space
+ characters. (Milan Crha)
+ #344728: Add configuration option for Sun Kerberos v5 (Irene Huang)
+ #386503: Fix a minor typo in Makefile.am (Gilles Dartiguelongue)
+ #428328: Move away from popt to GOptions (Ghislain MARY)
+ #437584, 437935: More compilation warnings cleanup (Gilles
+ Dartiguelongue)
+ #439186: fix some bad mnemonics, mark string for translation. (Andre
+ Klapper)
+ #440075: Enable customized alarms to work correctly (Matthew Barnes)
+ #442631: Added support for multimedia keys (Bastien Nocera)
+ #443659: Fix size and alignment mis-match in the evolution
+ preferences window (Vinod)
+ #444107: Allow adding of image attachments to HTML composer
+ (Srinivasa Ragavan)
+ #444248: Fix a crash in solaris (Wang Xin)
+ #444289: Allow the "test" component to build (Tobias Mueller)
+ #444548: Included files for translating strings for "Advanced search
+ options" (Andre Klapper)
+ #444747: Fix a build break (Daniel Gryniewicz)
+ #445793: Addressbook conduit now loads correctly (Gilles
+ Dartiguelongue)
+ #445812: Included missing icons in popups (Gilles Dartiguelongue)
+ #446015: Improved "Define views" dialog (Gilles Dartiguelongue)
+ #446870: Set the correct size of the duplicate contact warning
+ window (Srinivasa Ragavan)
+ #447727: Improve display of label text (Matthew Barnes)
+ #447742: Plug a memory leak (Matthew Barnes)
+ #448201: Add translation domain (Gabor Kelemen)
+ #448223: Remove duplicated function string_without_underscores
+ (Gilles Dartiguelongue)
+
+Updated Translations:
+ Priit Laes (et)
+ Jorge Gonzalez (es)
+ Daniel Nylander (sv)
+ Pema Geyleg (dz)
+ Kjartan Maraas (nb)
+
+Evolution 2.11.3 2007-06-04
+---------------------------
+
+New in 2.11.3:
+ Improved search and show options for Calendar/Memo/Tasks.
+ (Chenthill, Abhishek and Keshav)
+ Included support for Contact Image in the preview pane
+ (Srinivasa Ragavan)
+ Improved thread sorting. Even expanded threads are
+ promoted up the list. (Srinivasa Ragavan)
+ Improved options for offline support. (Srinivasa Ragavan)
+ Added Swedish Welcome mail. (Daniel Nylander)
+ Version less binary for Evolution. (Gilles Dartiguelongue)
+
+Bug fixes:
+ #311512: New message notification is not triggered even by
+ identified spam. (Karl Relton)
+ #315012: Fixed crash when reopening an encrypted sent email (Pascal
+ Terjan)
+ #321741: Default date for appointment or meeting is now set to
+ current date (Milan Crha)
+ #326388: Delete button is disabled for 'Birthdays & Anniversaries'
+ calendar (Raghavendaran)
+ #333707: Thread message selection improvements, while deleting
+ messages in thread. (David Moore)
+ #333858: Fixed popping of multiple categories dialog in contact
+ editor (Milan Crha)
+ #335241: Send/Receive Messages window size fixed (Matthew Barnes)
+ #335396: Account Editor's "Sent / Draft Folder" dialogs now has
+ proper title (Muktha)
+ #347767: A confirmation dialog will come up if a memo is saved
+ without a summary (Ushveen Kaur)
+ #351729: Fixed unnecessary/broken windows (Milan Crha)
+ #386503: Help Menu or F1 now works (Matthew Barnes, Götz Waschk)
+ #415770: Outlook style reply option (Christian Kellner)
+ #424562: Dropped support for GTK+ < 2.10 (Matthew Barnes)
+ #427232: Fixed a crash during startup due to missing relative-URI
+ (Matthew Barnes)
+ #436985: Move files that have translations but are not shipped to
+ POTFILES.skip (Philip Withnall)
+ #438461: Mail preferences buttons now has a consistent look (Gilles
+ Dartiguelongue)
+ #438467, #439118, #437584, #441055, #441014: Compilation warning
+ cleanups (Gilles Dartiguelongue)
+ #439049: Setting time for an appointment in "ja" locale now works
+ correctly (Wang Xin)
+ #439122: Compilation warnings cleanup (Gilles Dartiguelongue)
+ #439146, #438711: Improvements for the new mail-notification plugin
+ (Ross Burton and Daniel Gryniewicz)
+ #439316: Fixed translation issues and some fixes around broken gtk.
+ (Srinivasa Ragavan)
+ #439512: Mark strings for translation. (Srinivasa Ragavan)
+ #439957: Fix camel warnings (Ross Burton)
+ #440741: Added apps-evolution-mail-notification.schemas.in.in to
+ translation. (Srinivasa Ragavan)
+ #441010: Fixed dropdowns in mailer's view editor (Matthew Barnes)
+ #441992: Fixed a crash when selecting a mail (Jeff Cai)
+ #443140: Added a missing mnemonic in Preferences window (Vinod)
+
+Updated Translations:
+ Jorge Gonzalez (es)
+ Theppitak Karoonboonyanan (th)
+ Ivar Smolin (et)
+ Hendrik Richter (de)
+ Daniel Nylander (sv)
+ Stéphane Raimbault (fr)
+ Rhys Jones (cy)
+ Yair Hershkoviz (he)
+ Jakub Friedl (cs)
+ David Lodge (en_GB)
+
+Other Contributors:
+ Fixed casts and other compilation warnings (Gilles Dartiguelongue)
+ Added German translations for help files (Andre Klapper)
+ Fix file descriptor leak (Jules Colding)
+ Do not fetch folder-info from backend - just use the data from the
+ current folder tree. (Veerapuram Varadhan)
+
+Evolution 2.11.2 2007-05-14
+---------------------------
+
+New in 2.11.2:
+ Mail notification plugin with libnotify and panel
+ tray support (Srinivasa Ragavan)
+
+Bug fixes:
+ #407104: Makes the GNOME Clock applet able to correctly start
+ Evolution. (Matthew Barnes)
+ #355919: Fixes evolution crash when display depth set to 8 on
+ sparc machine (Xiurong Simon Zheng)
+ #427789: Allow cut/copy and paste an appointment/meeting/task
+ with localized characters (Xiurong Simon Zheng)
+ #337616: Fix "make distcheck" errors. (Matthew Barnes)
+ #334966: Fix for crash on close. (Srinivasa Ragavan)
+ #325966: Clicking folder tree submenu title now opens/closes the
+ tree (Christian Neumair)
+ #435610: Run gtk-update-icon-cache in uninstall-hook (David Farning)
+ #330098: Selecting Copy on Right-clicking any memo list now works
+ (Naresh)
+ #424055: Fixed resizing of contact list dialog. (Øystein Gisnås)
+ #417797: Copy and move of contacts between address books now works
+ correctly (Øystein Gisnås)
+ #404239: Included a missing row columns in contacts minicard view
+ (Øystein Gisnås)
+ #358250: Change field Organization to Company in AddressBook (Javier
+ F. Serrador)
+ #325118: Add translator comments for a string (Andre Klapper)
+ #378441: Mnemonics added for FROM/SUBJECT/TO headers in message pane
+ (Ebby Wiselyn)
+ #380750: Make force-shutdown work in Solaris (Wang Xin)
+ #414195: Fix build break (Loïc Minier)
+ #425506: Fix a crash when clicking the Edit button (Xiurong Simon
+ Zheng)
+ #324982: Fix warnings at program startup (Hiroyuki Ikezoe)
+ #375234: Fix a crash when syncing with iPod (Vitaliy Ischenko)
+ #325965: Fix a crash when selecting "mark messages as read" on a
+ Maildir subfolder (Ilkka Tuohela)
+ #432867: Changed default attribute for file from 0755 to 0644 (Milan Crha)
+
+Updated Translations:
+ Jorge Gonzalez (es)
+
+
+Evolution 2.11.1 2007-04-23
+---------------------------
+
+New in 2.11.1:
+ Improved SPAM support (Srinivasa Ragavan)
+ Bogofilter plugin (Mikhail Zabaluev)
+ Spinner for progress indication (Srinivasa Ragavan)
+ Improved Backup/restore plugin (Srinivasa Ragavan)
+ Improved Groupwise status tracking (Sankar)
+ Improved GtkPrint support (Matthew Barnes)
+
+Bug fixes:
+ #211082: Contact merging support on creation (Ebby Wiselyn)
+ #429422 and #419469: Code cleanups (Matthew Barnes)
+ #415985 and #416028: Fix crash in calendar (Wang Xin)
+ #419524: Fix incorrect includes (Matthew Barnes)
+ #426812: Refactor the printing infrastructure (Matthew Barnes)
+ #353662: Signature list now scrollable using keyboard (Baris Cicek)
+ #423766: Fix saving of mail attachments (Matthew Barnes)
+ #343195: Get total number of mails with CAMEL_FOLDER_TOTAL if the folder
+ is junk folder. (Hiroyuki Ikezoe)
+ #383953: Fix message count display (Matthew Barnes)
+ #332765: More intelligent message selection (Christof Krüger)
+ #424795: Fix system beep (Karl Relton)
+ #352713: Update parent rows when a child row changes (René Stadler)
+ #400241: Don't #include <composer/e-msg-composer.h> since we don't
+ install that file (Matthew Barnes)
+ #411331: Fix the message selection (Srinivasa Ragavan)
+ #375577: Correctly capitalize SpamAssassin (Priit Laes)
+ #387619: Remove use of deprecated icon names (Rodney Dawes)
+ #373116: Migrate from GnomeColorPicker to GtkColorButton (Matthew
+ Barnes)
+ #373837: Migrate from GnomeFontPicker to GtkFontButton (Matthew Barnes)
+ #271851: fix startup notification problem (Stephen Cook)
+ #259606: Added support for middle click to open the component in new
+ window (Michael Meeks)
+ #396645: Show only cert files in filechooser (Gilles Dartiguelongue)
+ #426816: Refactor the printing infrastructure (Matthew Barnes)
+ #329168: Add missing mnemonic widgets (Andre Klapper)
+ #408423: Code cleanups and several memory leaks (Daniel Gryniewicz)
+ #353922: Fix a duplicate keyboard shortcut (Diego Escalante Urrelo)
+ #401539: Fix a crasher (Matthew Barnes)
+ #356523: Copies the file uri and decodes it before trying to attach the
+ image (Martin Olsson)
+ #243241: Show only enabled accounts on composer (Paul Iadonisi)
+ #430559: Added mnemonics. (Vinod)
+ #426743: Corrected typo "asychronous" (Elizabeth Greene)
+ #404233: change "E-Mail" to "Email" (Andre Klapper)
+ #426487: Date is garbled in contacts preview pane on locale "ja_JP.PCK"
+ (Xiurong Simon Zheng)
+ #426829: Code cleanups (Xiurong Simon Zheng)
+ #406933: Call gettext() on the EConfigItem labels (Jeff Cai)
+ #380843: Fix time format translations (Jeff Cai & takao.fujiwara)
+ #426481: Fix Typo Assitant (Elizabeth Greene)
+ #404764: Fix typos and reword a string (Andre Klapper)
+
+
+Updated Translations:
+ David Lodge (en_GB)
+ Yair Hershkovitz (he)
+ Daniel Nylander (sv)
+ Djihed Afifi (ar)
+ Jakub Friedl (cs)
+ Duarte Loreto (pt)
+ Laurent Dhima (sq)
+ Hendrik Richter (de)
+
+Evolution 2.10.0 2007-03-12
+---------------------------
+
+Fixes since 2.9.92 :
+
+ Harish Krishnaswamy (Welcome mail update,
+ GtkHTML version required update)
+
+Updated Translations:
+
+ Igor Nestorović (sr)
+ Jakub Friedl (cs)
+ Christian Kintner (de)
+ Theppitak Karoonboonyanan (th)
+ Takeshi AIHANA (ja)
+ Mugurel Tudor (ro)
+ Gintautas Miliauskas (lt)
+ Gabor Kelemen (hu)
+ Daniel Nylander (sv)
+ Tino Meinen (nl)
+ Josep Puigdemont i Casamajó (ca)
+ Alexander Shopov (bg)
+ Ilkka Tuohela (fi)
+ Maxim Dziumanenko (uk)
+ Duarte Loreto (pt)
+ Chao-Hsiung Liao (zh_HK, zh_TW)
+ Artur Flinta and GNOME PL Team (pl)
+ Changwoo Ryu (ko)
+ Jovan Naumovski (mk)
+ David Lodge (en_GB)
+ Ankit Patel (gu)
+ Jonathan Ernst (fr)
+ Djihed Afifi (ar)
+ Kjartan Maraas (nb)
+ Washington Lins (pt_BR)
+ Daniel Nylander (sv)
+ Leonid Kanter (ru)
+ Luca Ferretti (it)
+
+Evolution 2.9.92 2007-02-26
+---------------------------
+
+Major Updates:
+ Documentation updates from PC Radhika.
+
+Updated Translations:
+ Luca Ferretti (it)
+ Ivar Smolin (et)
+ Changwoo Ryu (ko)
+ Gabor Kelemen (hu)
+ Kjartan Maraas (nb)
+ Gintautas Miliauskas (lt)
+ Jordi Mas (ca)
+ Daniel Nylander (sv)
+ Leonid Kanter (ru)
+ Funda Wang (zh_CN)
+ Artur Flinta (pl)
+ Leonardo Ferreira Fontenelle, Washington Lins (pt_BR)
+ Stéphane Raimbault (fr)
+ Nguyễn Thái Ngá»Âc Duy (vi)
+ Alexander Shopov (bg)
+ David Lodge (en_GB)
+ Djihed Afifi (ar)
+ Leonid Kanter (ru)
+ Duarte Loreto (pt)
+ Ilkka Tuohela (fi)
+ Theppitak Karoonboonyanan (th)
+
+Contributors:
+ Matthew Barnes, Raghavendran R, Srinivasa Ragavan, Ebby Wiselyn,
+ Harish Krishnaswamy, Chenthill Palanisamy, Sankar P
+
+Evolution 2.9.91 2007-02-12
+--------------------------
+
+Updated Translations:
+ Djihed Afifi (ar)
+ Theppitak Karoonboonyanan (th)
+ Stéphane Raimbault, Robert-André Mauchin and Stéphane Raimbault (fr)
+ Duarte Loreto (pt)
+ Hendrik Richter (de)
+ David Lodge (eb_GB)
+ Pema Geyleg (dz)
+ Changwoo Ryu (ko)
+ Daniel Nylander (sv)
+ Andre Klapper (de)
+ Chao-Hsiung Liao (zh_HK)
+ Chao-Hsiung Liao (Zh_TW)
+ Ivar Smolin (et)
+ Gabor Kelemen (hu)
+ Ilkka Tuohela (fi)
+ Kjartan Maraas (nb)
+
+
+
+Contributors:
+ Nickolay V. Shmyrev, Wang Xin, Ebby Wiselyn, Duarte Loreto, Matthew Barnes,
+ Ushveen Kaur, William Jon McCann, Andre Klapper, Raghavendran, Srinivasa Ragavan,
+ Sankar P, Kjartan Maraas, Wang Xin, Matthias Clasen
+
+Evolution 2.9.6 2007-01-22
+--------------------------
+Updated Translations:
+Ilkka Tuohela (fi), Daniel Nylander(sv)
+
+Contributors:
+Raghavendran R, Srinivasa Ragavan, Sankar P
+
+
+Evolution 2.9.5 2007-01-08
+--------------------------
+
+Updated Translations:
+Djihed Afifi (ar), Danilo Å egan (sr), David Lodge (en_GB), Kjartan Maraas
+(nb), Gintautas Miliauskas (lt), Jordi Mas (ca), Bernat Tallaferro (ca),
+Clytie Siddall (vi), Priit Laes (et)
+
+Contributors:
+Daniel Nylander (Updated translation for documentation)
+Veerapuram Varadhan (346728, 268412)
+Simon Zheng (352108)
+Nickolay V. Shmyrev (340165)
+Nathan Owens (389664)
+Jerry Yu (389664)
+Matthew Barnes (383027, 377511)
+Wang Xin (389966, 389961)
+Harish Krishnaswamy (382860)
+
+Evolution 2.9.4 2006-12-18
+--------------------------
+
+Updated Translations:
+Kjartan Maraas(nb), Djihed Afifi (ar), Francisco Javier F. Serrador (es),
+Ilkka Tuohela (fi), Hendrik Richter (de), Jakub Friedl (cs), Ivar Smolin (et)
+
+Contributors:
+Sankar P (Evolution exchange shouldnt check mail in all folders by default)
+Srinivasa Ragavan (Icons in Quick Show)
+Matthew Barnes (382431)
+Hendrik Richter (358310)
+Francisco Javier F. Serrador (Updated translation for documentation)
+Veerapuram Varadhan (bugzilla.novell.com - 208395)
+
+Evolution 2.9.3 2006-12-04
+--------------------------
+
+Updated Translations:
+Ivar Smolin (et), Jakub Friedl (cs),
+Karsten Bräckelmann (nb), Francisco Javier F. Serrador (es),
+Christophe Merlet (fr)
+
+Contributors :
+Francisco Javier F. Serrador (gnome-doc-tools integration, 358249)
+Harish Krishnaswamy (evolution.desktop install fixes, GW proxy pruning,
+memory leak fixes, 381642 (b.g.0), bug #208959 at bugzilla.novell.com)
+Nickolay V. Shmyrev (support for commandline uri in tasks),
+Daniel Gryniewicz (349966), Srinivasa Ragavan (Fix DoS by large emails)
+Sankar, Chris Halls (372528), Wang Xin (380064), Carlos Garcia (367183),
+Chenthill (208318 - b.n.c), Parthasarathi Susarla (348679).
+Matthew Barnes (357970).
+
+Evolution 2.9.2 2006-11-07
+--------------------------
+
+Updated Translations:
+Christophe Merlet (fr), Alexander Shopov (bg),
+Francisco Javier F. Serrador (es), Ivar Smolin (et),
+Ilkka Tuohela (fi), Pawan Chitrakar (ne), Gabor Kelemen (hu),
+Josep Puigdemont i Casamajó (ca).
+
+Contributors :
+Jules Colding, Harish Krishnaswamy, Ben Gamari, Priit Laes.
+
+
+Evolution 2.9.1 2006-10-16
+--------------------------
+
+Updated Translations:
+
+Ivar Smolin (et)
+Jovan Naumovski (mk)
+Ilkka Tuohela (fi)
+Francisco Javier F. Serrador (es)
+Johan Dahlin (sv)
+Satoru SATOH (ja)
+Alexander Shopov (bg)
+Luca Ferretti (it)
+Zygimantas BeruÄÂka (lt)
+Cyprien Le Pannérer (fr)
+Jordi Mas (ca)
+Tino Meinen (nl)
+Ankit Patel (gu)
+Daniel Nylander (sv)
+Ignacio Casal Quinteiro (gl)
+Pema Geyleg (dz)
+Åsmund Skjæveland (nn)
+Hendrik Richter (de)
+Nickolay V. Shmyrev (ru)
+Changwoo Ryu (ko)
+Wouter Bolsterlee (nl)
+Luca Ferretti (it)
+Gabor Kelemen (hu)
+Subhransu Behera (or)
+Pawan Chitrakar (ne)
+David Lodge (en_GB)
+Vladimer Sichinava (ka)
+Kostas Papadimas (el)
+Jamil Ahmed (bn)
+Alessio Frusciante (it)
+
+Contributors:
+
+Mathew Barnes, Harish Krishnaswamy, Radhika Nair,
+Tor Lillqvist, Chris Heath, Sankar P, Ushveen Kaur,
+Srinivasa Ragavan, Daniel Gryniewicz, Nick Sukharev,
+Roozbeh Pournader, Wouter Bolsterlee, Andre Klapper,
+Kjartan Maraas, Chenthill Palanisamy, Devashish Sharma,
+Hiroyuki Ikezoe.
+
+Evolution 2.8.1 2006-10-02
+--------------------------
+
+Updated Translations:
+
+Ignacio Casal Quinteiro (gl), Ilkka Tuohela (fi),
+Francisco Javier Fernandez Serrador (es),
+Daniel Nylander (sv), Jovan Naumovski (mk),
+Pema Geyleg (dz), Ivar Smolin (et),
+Åsmund Skjæveland (nn), Hendrik Richter (de),
+Nickolay V. Shmyrev (ru), Daniel Nylander (sv),
+Changwoo Ryu (ko), Wouter Bolsterlee (nl),
+Luca Ferretti (it), Gabor Kelemen (hu),
+Cyprien Le Pannérer (fr), Subhransu Behera (or),
+Pawan Chitrakar (ne), Alexander Shopov (bg),
+David Lodge (en_GB), Ankit Patel (gu),
+Vladimer Sichinava (ka), Kostas Papadimas (el),
+Jamil Ahmed (bn), Alessio Frusciante (it)
+
+
+Bug fixes :
+356811, 351332, 353472, 357422, 354650, 352767, 341932, 353920,
+355294, 343331, 332101, 352450, 348419, 343369, 261082, 261980,
+325611, 325613, 334692, 354775, 352450, 344276, 343409, 261062,
+342882, 332101, 357811, 352353, 329694, 335814, 341474, 341099.
+351332, 352450, 343686.
+
+Contributors:
+Matthew Barnes, Harish Krishnaswamy, Daniel Gryniewicz, Nick Sukharev,
+Roozbeh Pournader, Srinivasa Ragavan, Wouter Bolsterlee, Kjartan Maraas,
+Tor Lillqvist, Chenthill, Ushveen Kaur, Arvind, Hiroyuki Ikezoe.
+Andre Klapper, Radhika Nair.
+
+Evolution 2.8.0 2006-09-04
+--------------------------
+Evolution 2.8 Stable Release for GNOME 2.16.0.
+
+Evolution 2.7.92 2006-08-21
+---------------------------
+
+Updated Translations
+
+Hendrik Richter (de), Wouter Bolsterlee (nl), Daniel Nylander (sv),
+Priit Laes (et), Francisco Javier F. Serrador (es), Satoru SATOH (ja),
+Subhransu Behera (or), Matic Žgu (sl), Jovan Naumovski (mk),
+Ankit Patel (gu), Žygimantas BeruÄÂÂka (lt), Gabor Kelemen (hu),
+Ilkka Tuohela (fi), Ahmad Riza H Nst (id), Rahul Bhalerao (mr),
+Clytie Siddall (vi), Changwoo Ryu (ko), Chao-Hsiung Liao (zh_HK) (zh_TW),
+Tino Meinen (nl), Ani Peter (ml), Xavier Conde Rueda (ca),
+Maxim Dziumanenko (uk), Guntupalli Karunakar (dz), Leonid Kanter (ru),
+Daniel van Eeden (nl), Kjartan Maraas (nb)
+
+Bug Fixes
+
+Pavel Roskin, Kjartan Maraas, Srinivasa Ragavan, Laurent Goujon,
+Matthew Barnes, Chenthill Palanisamy, Li Yuan, Harish Krishnaswamy,
+Mubeen Jukaku, Ushveen Kaur, Jeff Cai, Johannes Berg, Hiroyuki Ikezoe,
+Øystein Gisnås
+
+Evolution 2.7.91 2006-08-07
+---------------------------
+
+Updated Translations
+
+Jordi Mas (ca), Rhys Jones (cy), Francisco Javier F. Serrador (es),
+Inaki Larranag (eu), Priit Laes (et), Ilkka Tuohela (fi),
+Christophe Merlet (fr), Ankit Patel (gu), Jovan Naumovski (mk),
+Rahul Bhalera (mr), Kjartan Maraas (nb), Vincent van Adrighem (nl),
+Daniel Nylander (sv), Theppitak Karoonboonyanan (th), Maxim Dziumanenko (uk),
+Funda Wang (zh_CN), Chao-Hsiung Liao (zh_HK) (zh_TW)
+
+Bug Fixes
+
+Johnny Jacob, Srinivasa Ragavan, Alessandro Decina, Sankar P,
+Veerapuram Varadhan, Arvind, Andre Klapper, Bastien Nocera,
+Chenthill Palanisamy, Rajeev ramanathan, Devashish Sharma,
+Roozbeh Pournader, Sushma Rai
+
+Evolution 2.7.90 2006-07-24
+---------------------------
+
+Updated Translations:
+
+Zygimantas Berucka (lt),
+Christophe Merlet (fr),
+Francisco Javier F. Serrador (es),
+Changwoo Ryu (ko), Jonathan Ernst (fr),
+Nikos Charonitakis (el), Funda Wang (zh_CN),
+Ankit Patel (gu), Ilkka Tuohela (fi),
+Raivis Dejus (lv), Kostas Papadimas (el),
+Dzongkhalinux team, DIT (dz), Hendrik Richter (de),
+Daniel Nylander (sv), Ivar Smolin (et),
+Theppitak Karoonboonyanan (th), Simos Xenitellis (el),
+Chao-Hsuing Liao (zh_HK, zh_TW)
+
+Bug fixes and features :
+
+Arvind, Andre Klapper, Boby Wang, Yuri Pankov,
+Harish Krishnaswamy, Srinivasa Ragavan, Johnny Jacob,
+Raghavendran, Shree Krishnan, Ushveen Kaur, Karsten
+Brackelmann, Michael Zucchi, Hiroyuki Ikezoe,
+Rajeev Ramanathan, Chenthill Palanisamy, Li Yuan,
+Devashish Sharma, Mikhail Zabaluev, Ross Burton,
+Sankar, Benoît Dejean, Vandana Shenoy, Julio M. Merino
+Vidal, Luca Ferretti.
+
+Evolution 2.7.4 2006-07-10
+--------------------------
+Updated Translations:
+
+Francisco Javier F. Serrador, Jovan Naumovski,
+Changwoo Ryu, Nikos Charonitakis, Rostislav
+Raykov, Ilkka Tuohela, Ivar Smolin, Ahmad Riza
+H Nst, Inaki Larranaga, Ankit Patel, Vincent
+van Adrighem, Runa Bhattacharjee, Benoît Dejean,
+Theppitak Karoonboonyanan, Pawan Chitrakar, I.Felix,
+Rajesh Ranjan, Kjartan Maraas, Chao-Hsiung Liao,
+Clytie Siddall, Hendrik Richter, Daniel Nylander.
+
+Bug fixes :
+
+Andreas Köhler, Harish Krishnaswamy, Ushveen Kaur,
+Andre Klapper, Johnny Jacob, Mathew Barnes, Arvind_evo,
+Srinivasa Ragavan, Tor Lillqvist, Li Yuan, Chenthill,
+Wang Xin, Rajeev Ramanathan, Aishwarya K, Hiroyuki Ikezoe,
+Simon Zheng, Devashish Sharma, Oswald Rodrigues, Harry Lu,
+Oswald, Sushma Rai, Mathew Barnes, Karsten Bräckelmann,
+Sankar P, Frederic Peters.
+
+Evolution 2.7.3 2006-06-12
+--------------------------
+
+Updated Translations contributed by
+Ilkka Tuohela, Ignacio Casal Quinteiro, Kjartan Maraas,
+Ankit Patel, Francisco Javier F. Serrador,
+Funda Wang, Pema Geyleg, Vincent van Adrighem,
+Clytie Siddall, Stanislav Brabec, Priit Laes,
+Alexander Shopov.
+
+Bug fixes and other changes :
+Srinivasa Ragavan, Li Yuan, Harish Krishnaswamy,
+Chris Heath, Jeffrey Stedfast, Gary Coady, Tor Lillqvist,
+Frederic Peters, Wang Xin, Hiroyuki Ikezoe, Li Yuan,
+Parthasarathi Susarla, Simon Zheng, Devashish Sharma,
+Roozbeh Pournader, Johnny Jacob, Federico Mena Quintero
+Ed Catmur, Carlos Garcia Campos, Sushma Rai, Sankar P,
+David Richards, Chenthill Palanisamy,
+
+Evolution 2.7.1 2006-04-24
+---------------------------
+
+First release of 2.7 development series.
+
+What is new ?
+-------------
+
+* Integration of Evolution Calendar with Cairo
+
+Evolution 2.5.92 2006-02-27
+---------------------------
+
+Bug fixes since last release :
+http://go-evolution.org/Evo2.5.92#Evolution
+
+Updated Translations:
+
+ - ca (Jordi Mas)
+ - cs (Miloslav Trmac)
+ - el (Kostas Papadimas)
+ - es (Francisco Javier F. Serrador)
+ - et (Priit Laes)
+ - fi (Ilkka Tuohela)
+ - gl (Ignacio Casal Quinteiro)
+ - gu (Ankit Patel)
+ - ja (Takeshi AIHaNA)
+ - ka (Clytie Siddall)
+ - lt (Žygimantas BeruÄÂÂka)
+ - nb (Kjartan Maraas)
+ - nl (Vincent van Adrighem)
+ - no (Kjartan Maraas)
+ - ru (Leonid Kanter)
+ - sr (Slobodan D. Sredojevic)
+ - th (Theppitak Karoonboonyanan)
+ - vi (Clytie Siddall)
+ - zh_CN (Funda Wang)
+ - zh_HK (Chao-Hsiung Liao)
+ - zh_TW (Chao-Hsiung Liao)
+
+
+Evolution 2.5.91 2006-01-13
+---------------------------
+
+Bug fixes since last release :
+http://go-evolution.org/Evo2.5.91#Evolution
+
+Updated Translations:
+
+ - bg (Vladimir Petkov)
+ - ca (Xavier Conde, Jordi Mas)
+ - cs (Lukas Novotny)
+ - cy (Rhys Jones)
+ - en_CA (Adam Weinberger)
+ - es (Francisco Javier F. Serrador)
+ - et (Ivar Smolin)
+ - fi (Ilkka Tuohela)
+ - gl (Ignacio Casal Quinteiro)
+ - gu (Ankit Patel)
+ - lt (Žygimantas BeruÄÂka)
+ - nb, no (Kjartan Maraas)
+ - nl (Tino Meinen)
+ - pt_BR (Raphael Higino)
+ - sq (Laurent Dhima)
+ - sr, sr@Latn (Slobodan Sredojevic)
+ - th (Theppitak Karoonboonyanan)
+ - vi (Clytie Siddall)
+ - zh_CN (Funda Wang)
+ - zh_TW, zh_HK (Chao-Hsiung Liao)
+
+Evolution 2.5.90 2006-01-30
+---------------------------
+
+What's new :
+
+Bug fixes since 2.5.5 :
+http://bugzilla.gnome.org/buglist.cgi?query_format=advanced&short_desc_type=allwordssubstr&short_desc=&classification=Desktop&product=Evolution&long_desc_type=substring&long_desc=&status_whiteboard_type=allwordssubstr&status_whiteboard=&keywords_type=allwords&keywords=&bug_status=RESOLVED&resolution=FIXED&resolution=WONTFIX&resolution=DUPLICATE&resolution=NOTABUG&resolution=NOTGNOME&resolution=INCOMPLETE&resolution=INVALID&resolution=GNOME1.x&resolution=MOVED&resolution=OBSOLETE&resolution=NOTXIMIAN&emailassigned_to1=1&emailtype1=substring&email1=&emailassigned_to2=1&emailreporter2=1&emailqa_contact2=1&emailcc2=1&emailtype2=substring&email2=&bugidtype=include&bug_id=&chfieldfrom=2006-01-17&chfieldto=Now&chfield=bug_status&chfieldvalue=RESOLVED&cmdtype=doit&order=Reuse+same+sort+as+last+time&field0-0-0=noop&type0-0-0=noop&value0-0-0=
+
+Updated Translations:
+
+ - bg (Vladimir Petkov)
+ - el (Kostas Papadimas)
+ - en_CA (Adam Weinberger)
+ - es (Francisco Javier F. Serrador)
+ - et (Ivar Smolin)
+ - fi (Ilkka Tuohela)
+ - gl (Ignacio Casal Quinteiro)
+ - gu (Ankit Patel)
+ - ko (Changwoo Ryu)
+ - nb, no (Kjartan Maraas)
+ - nl (Vincent van Adrighem)
+ - pt_BR (Evandro Fernandes Giovanini)
+ - sr, sr@Latn (Slobodan D. Sredojevic)
+ - vi (Clytie Siddall)
+ - zh_CN (Funda Wang)
+ - zh_TW, zh_HK (Chao-Hsuing Liao)
+ - POTFILES.in (Adam Weinberger)
+ - POTFILES.in (Harish)
+
+Evolution 2.5.5 2006-01-16
+--------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.gnome.org/show_bug.cgi):
+
+ #326458 – New Meeting/Task UI: remove useless seperators (Srini)
+ #326265 – "Message Source", "Character Encoding" miss mnemonics (Srini)
+ #326266 – avoid using "i" as mnemonic (Srini)
+ #326381 – change "_Insert" mnemonic in Signature Editor Menu (Srini)
+ #325110 – Compose Message Controls Not Working (Shreyas)
+ #326877 – UI: Menu Bar Changes Number Of Items When No Email Highlighted (Srini)
+ #218570 – "Collapse all" and "expand all" threads feature missing (Srini)
+ #221270 – Send & Receive -dialog should show also account name for usability (Rohini)
+ #246257 – Find in Message dialog - UI suggestions (Rohini)
+ #239929 – Zoom with mousewheel broken (Rajeev)
+ #255303 – changing folders strangeness (Srini)
+ #325334 – "Canceled" spelling errors (Andre Klapper)
+ #325618 – Exchange operations plugin doesn't get loaded on startup. (Srini)
+ #313095 – gw: Disable a account which has done proxy login to other account error message is wrong (Shreyas)
+ #325568 – Spaces disappeared from strings (Andre Klapper)
+ #325748 – Add a new mozila built-in cert module's path for compatible reason (Simon Zheng)
+ #273076 – Cryptic short messages in Evolution certificate manager (Andre Klapper)
+ #324739 – Crash moving from mail to calendar (Srini)
+ #325629 – port to the new libnotify API (Sebastien Bacher)
+ #324816 – Alarm Tray eats CPU (Chakravarthi)
+ #324889 – Selecting calendar from event-notification drop-down from notification-area crashes EDS (Chakravarthi)
+ #213660 – Set default alarm type and sound file in preferences (Johnny Jacob)
+ #320101 – When Scheduling Meeting, [Invitations] Tab Accepts Multiple Names (Chenthill)
+ #311888 – On Recurrence Meeting Screen, Calendar Doesn't Display Correct View (Chenthill)
+ #313112 – Make this occurence movable does not delete moved recurring instance (Chenthill)
+ #259505 – In Calendar List View, switching months changes View (Chenthill)
+ #271810 – Calendar not enabled if editor adds event (Chenthill)
+ #274234 – jump to today pretty useless (Srini)
+ #271541 – Read Only Calendars shouldn't present Read Only "New" Screen (Chenthill)
+ #326735 – Meeting editor shows a wrong organizer (Chenthill)
+ #325446 – Alarm Editor Window width changes as typing custom message (Srini)
+ #325502 – resizing task editor window does not resize description input field (Srini)
+ #325612 – strings in e-alarm-list.c need translator comments (Andre Klapper)
+ #261071 – "RSVP" in evolution addressbook probably needs a translator comment (Andre Klapper)
+ #216535 – changing start time should keep appointment's time length (Johnny Jacob)
+ #258786 – 'Mark Selected Tasks as Complete' active even after tasks are marked complete (Johnny Jacob)
+ #303193 – Changing reminder snooze time doesn't work after pressing ALT-S (Johnny Jacob)
+ #325416 – tooltip of *earlier* appointment displayed in day view (Srini)
+ #325414 – calendar tooltip never disappearing when aborting appointment creation (Srini)
+ #323127 – Attachments pane gone wild (Johnny Jacob)
+ #326378 – missing mnemonics for mail recover dialog buttons (Srini)
+ #246237 – Compose a message dialog - label suggestions (Rohini)
+ #317283 – Contact Categories dialog should have a default response (Devashish)
+ #317282 – Contact Full Name dialog should have a default response (Default)
+ #326268 – "search > advanced" misses mnemonic (Srini)
+ #307513 – Please update some of the commandline tools. (Ali Akcaagac)
+ #325334 – "Canceled" spelling errors (Andre Klapper)
+ #326265 – "Message Source", "Character Encoding" miss mnemonics (Srini)
+ #220286 – Hints are not gone after a folder switch (Srini)
+ #326264 – "Current View" and "Caret Mode" have same mnemonic (Srini)
+ #325132 – change "Sa junk-plugin" to "Spamassassin plugin" (Andre Klapper)
+ #325210 – Plugin Spam learn can not work correctly (Shi Pu)
+ #327053 – One typo in the .po file (Harish)
+ #327155 – New grammar error (Harish)
+ #326842 – Save password not working (Sushma)
+ #271546 – Can't subscribe to other user's calendar with non-english Exchange server (Chenthill)
+ #326060 – Exchange password expiry handling is broken (Sushma)
+ #316100 – there is an empty menu after the help menu (Srini)
+ #314748 – modal dialog issue (Sushma)
+ #267402 – can not specify https URL for a remote calendar location (Tony Tsui)
+ #326265 – "Message Source", "Character Encoding" miss mnemonics (Srini)
+ #323011 – UI: options available on right click should be in menus as well (Srini)
+ #325926 – Menu bar has entry with no text (Chenthill)
+
+New features and other fixes :
+ - Merge caldav eplugin from evolution-caldav into Evolution (Harish)
+ - Calendar EText Wrapping (Johnny Jacob)
+ - CSV and Tab import support for addressbook (Devashish)
+ - Edit menu implementation in Event/Task Editor (Johnny Jacob)
+ - Keyboard Accelerator Fixes across Evolution (Srini & Harish)
+ - Code cleanup (Simon Zheng, Johnny Jacob, Boby Wang, Harish )
+ - Win32 Fixes (Tor Lillqvist)
+ - import-ics-attachments plugin (Johnny Jacob)
+
+Updated Translations:
+
+ - bg (Alexander Shopov)
+ - en_CA (Adam Weinberger)
+ - es (Francisco Javier F. Serrador)
+ - et (Priit Laes)
+ - fi (Ilkka Tuohela)
+ - gu (Ankit Patel)
+ - ja (Takeshi AIHANA)
+ - lt (Žygimantas BeruÄÂka)
+ - nl (Vincent van Adrighem)
+ - nb, no (Kjartan Maraas)
+ - nn (Åsmund Skjæveland)
+ - vi (Clytie Siddall)
+ - zh_TW (Zhe Su, Chao-Hsiung Liao)
+
+Evolution 2.5.4 2006-01-02
+--------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.gnome.org/show_bug.cgi):
+
+ #301149 - Translated plugin names, descriptions and labels. (Funda Wang)
+ #323151 - Seperator in toolbar between Send/Receive and component buttons (Karsten Bräckelmann)
+ #325120 - Remove ui/evolution-executive-summary.xml from CVS
+ #306117 - Partially fixes typos and harmonizing capital/small letters (Andre Klapper)
+ #319946 - Shortcut keys for Send/Receive and Save Message are same when invoked through Alt-F (Andre Klapper)
+ #324677 - Mark as Menu does provide Clear/Completed (Srinivasa Ragavan)
+ #313293 - Added shortcut for Preferences window (M Victor Aloysius J)
+ #321734 - Added tooltips for Alarms and Attachment in the event editor.
+ #322499 - Removed clashing tooltip for show/hide status bar (Srinivasa Ragavan)
+ #227853 - Modifed Control + M to be the accelerator for show/hide preview across Evolution. (Srinivasa Ragavan)
+ #316897 - Removed Copy To and Move To from the Evolution toolbar. (Rajeev Ramanathan)
+ #323108 - ReOrdered Reply in the right click menu (Karsten Brackelmann)
+ #325375 - Critical warning fix (Harish)
+ #325276 - Modified usage of ""don't"" to "Do not" string (Harish)
+ #306117 - Fixed few typos in po file (Andre Klapper)
+ #325116 - Modified Cancelled to Canceled (Andre Klapper)
+ #272772 - Added quotes to literal values (Andre Klapper)
+ #311472 - Removed wrong singular string (Andre Klapper)
+ #313801 - Changed duplicate mnemonic (Andre Klapper)
+ #324173 - Changed title in selecting sound in Preferences page (Andre Klapper)
+ #256913 - Fixed 3 HIG violations in Preferences page (Andre Klapper)
+ #228040 - Setting up Follow-up flag to update preview (Srinivasa Ragavan)
+ #324677 - Added menu for flag complete and clear menu (Srinivasa Ragavan)
+ #60354 - Added the functionality to show folder name, mail and unread count in window title (NotZed)
+ #324473 - Add-delete signature cause evolution crash (Jeff Cai)
+ #324670 - Fixed evolution to change the pane size when changed in gconf (Sam Yang)
+ #246256 - Changed "Case _Sensitive" to "Case _sensitive" (Varadhan)
+ #324319 - Added accessible name for the attachment bar (Boby Wang)
+ #234008 - Highlight drafts folder (Felix Ortega)
+ #325364 - G_CRITICAL warning in shell (Harish)
+ #325119 - Removed a duplicate word in the shell error dialog (Andre Klapper)
+ #315866 - Made FAQ to point to go-evolution.org (Andre Klapper)
+ #322001 - Fixed the display of menu item in ja locale (David Malcom)
+ #325472 - G_CRITICAL warnings fix in certificates page (Harish)
+ #325489 - G_CRITICAL warnings fix in tasks (Harish)
+ #325468 - G_CRITICAL warnings fix in calendar preferences (Harish)
+ #325123 - Removed duplication exclamation mark in iCalendar importer (Andre)
+ #325125 - Strings Url and url are modified to URL (Andre Klapper)
+ #313144 - Added punctuation to calendar error messages (Andre Klapper)
+ #308851 - Fixed some grammatical errors in Calendar (Andre Klapper)
+ #306150 - Fixed a confusing string in calendar schema (Chenthill)
+ #248133 - Peculiar popup menu in Scheduling tab (Chakravarthi)
+ #324525 - Delete Calendar events should default to Cancel (Chenthill)
+ #323125 - Default search bar in calendar is not same after pressing clear (Varadhan)
+ #323955 - Fixed Evolution hang when trying to invoke alarm daemon (Chakravarthi)
+ #324196 - Empty summary check in event editor (Johnny Jacob)
+ #323984 - Task / Assigned task shows part of timezone widgets in task editor (Sam Yang)
+ #324195 - Evolution Not Pulling Down Webcal Content (Chenthill)
+ #324094 - Added translatable strings in calendar tooltips (Srinivasa Ragavan)
+ #324058 - Fixed a crash, while creating a calendar in exchange (Chenthill)
+ #321739 - Synchronize between the attendees and the name selector dialog (Chenthill)
+ #246245 - Changed the file selector title to "Insert Attachment" (Johnny Jacob)
+ #205616 - Added new top/bottom buttons to filter dialog (Mathew Hall)
+ #246225 - Changed strings in Advanced Search dialog (Arulanandan)
+ #246227 - Changed strings in Save Search dialog (Arulanandan)
+ #258048 - Modified categories menu to option (Srinivasa Ragavan)
+ #266003 - Fixed a false status message in import popup (Sushma)
+ #309618 - G_CRITICAL warnings fix (Harish)
+ #246233 - Modified Search Editor to Searches (Johnny Jacob)
+ #303876 - Fix for input strings committed in the wrong order in Evolution Task (Akira TAGOH)
+ #306118 - Fixed a typo in e-table (Andre Klapper)
+ #240762 - Make only user creatable views editable (Srinivasa Ragavan)
+ #306117 - Fixed typos in bbdb plugin (Andre Klapper)
+ #325491 - Fix to allow to right click if exchange account is configured (Sushma)
+ #306117 - Fixed typos in exchange errors (Andre Klapper)
+ #324678 - Creating the contacts folder and accessing it from Evolution is not working (Sushma)
+ #324580 - Set the folder subscription dialog title correctly (Sushma)
+ #313545 - Added translator comments for Exchange Delegate dialog (Sushma)
+ #324485 - Fix to stop asking password twice during account creation (Sushma)
+ #324483 - Fixed a memory leak in connector (Sushma)
+ #325127 - Changed string Uid to UID (Andre Klapper)
+ #320119 - Fix to avoid Novell Address Book Showing Up Twice In Lists (Sushma)
+ #274433 - Fixed encoding conversion problem when converting email to task (Chenthill)
+ #325128 - Added a missed word in itip formatter (Andre Klapper)
+ #313554 - Marked missing strings translatable in itip-formatter (Andre Klapper)
+
+
+New features and other fixes :
+
+ - Added visual cue to the present of search filter (Srinivasa Ragavan)
+ - G_CRITICAL warnings (Harish)
+ - Network Manager support in Evolution (Shreyas)
+ - Publish Calendar plugin (David Trowbridge)
+ - Using gstdio wrappers and code cleanup (Tor Lillqvist)
+ - Win32 Fixes (Tor Lillqvist)
+
+Updated Translations:
+
+ - be (Ales Nyakhaychyk)
+ - en_CA (Adam Weinberger)
+ - es (Francisco Javier F. Serrador)
+ - el (Kostas Papadimas)
+ - fi (Ilkka Tuohela)
+ - gl (Ignacio Casal Quinteiro)
+ - gu (Ankit Patel)
+ - ja (Takeshi AIHANA)
+ - lt (Žygimantas BeruÄÂka)
+ - nb, no (Kjartan Maraas)
+ - nn (Åsmund Skjæveland)
+ - vi (Clytie Siddall)
+ - zh_CN (Funda Wang)
+
+Evolution 2.5.3 2005-12-12
+--------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.gnome.org/show_bug.cgi):
+
+ #321639 - order of Reply methods confusing in the menu (Karsten Brackelmann)
+ #321640 - Forward As menu missing (Karsten Brackelmann)
+ #323140 - Mail Contex Menu ordered incorrectly (Karsten Brackelmann)
+ #323253 - Evolution fails to show mailbox in send & receive dialog (Shi Pu)
+ #322414 - Evolution doesn't respect to a key's change in gconf (Sam Yang)
+ #315987 - Evolution 2.4 crashes EVERY time i sent an email (Parthasarathi)
+ #316315 - Evolution exchange storage crashes on ECalendar sync (Varadhan)
+ #322616 - End time in list view is displayed in UTC timezone (Chenthill)
+ #317322 - crash when delete a imported recurrent event (Chenthill)
+ #314639 - Evolution crashed on right click and select new appointment (Chenthill)
+ #318777 - recurrence editing ... (Chenthill)
+ #321237 - The categories' name cannot be displayed in braille monitor (Boby Wang)
+ #314550 - When description of meeting is lengthy alarm notify popup should
+ have scrollbar (Chakravarthi)
+ #322863 - crashes on redirect (Parthasarathi)
+ #300300 - Evolution, EAddress-conduit extra newline breaks PalmOS (Sushma)
+ #303856 - Appointment Editor's OK button still greyed out after changing
+ value (Johnny Jacob)
+ #322740 - Screen Reader can't read the subject or date (Boby Wang)
+ #322776 - Unable to keyboard navigate into message headers pane, if no
+ message selected. (Li Yuan)
+ #313219 - gal_view_new_dialog_set_property() does GTK_IS_ENTRY(random)
+ (Veerapuram Varadhan)
+ #322311 - New defined viewname with non-ASCII characters is not displayed
+ in the View menu on some Non Ascii locale (Simon Zheng)
+ #272514 - Don't include URL in translateable evolution-exchange message (Sushma)
+ #314583 - Incorrect error messages (Sushma)
+ #314576 - hang when using "Type: None" for a mail account (Partha)
+
+New features and other fixes :
+
+Evolution Editor UI and tooltip enhancements (Srinivasa Ragavan and Chenthill)
+Resolve duplicate symbols in e-util wrt libedataserver (Irene)
+Fix make-clean issues in Evolution plugins (Harish)
+e-attachment-bar crasher and Misc. code clean-up (Harish)
+Win32 related fixes and code clean-up (Tor Lillqvist)
+
+Updated Translations:
+
+ - be (Vital Khilko)
+ - bg (Rostislav Raykov)
+ - cs (Miloslav Trmac)
+ - en_CA (Adam Weinberger)
+ - es (Francisco Javier F. Serrador)
+ - et (Ivar Smolin)
+ - fi (Ilkka Tuohela)
+ - gl (Ignacio Casal Quinteiro)
+ - ja (Takeshi AIHANA)
+ - lt (Zygimantas BeruÄÂka)
+ - nb, no (Kjartan Maraas)
+ - th (Theppitak Karoonboonyanan)
+ - zh_CN (Funda Wang)
+ - zh_TW (Abel Cheung)
+ - zh_TW (Chao-Hsuing Liao)
+
+Evolution 2.5.2 2005-10-25
+--------------------------
+
+New Features:
+ - New Event / Meeting Editor dialog (Srinivasa Ragavan &
+ Chenthill)
+ - Hula Account setup plugin (Harish)
+
+Bugzilla bugs fixed (see http://bugzilla.gnome.org/show_bug.cgi):
+
+ #302974 - Added accelerators for Next and Previous message
+ (Sankar)
+ #314638 - Fixes a memory build-up, while creating a new meeting
+ with new category (Chakravarthi)
+ #313538 - Fix to show Free/Busy information for organiser
+ (Chenthil)
+ #321088 - Fix to reduce the size of time window in free/busy to
+ avoid the scroll of widget in the wrong direction.
+ It Shows only 35 days in the canvas. (Chenthill)
+ #273322 - Fixed a crash in evolution, when calendar is removed,
+ remove it from publishing. (Dinesh)
+ #316710 - Fixed a alarm issue to popup for exchange, by
+ obtaining correct key for a authenticated calendar (Chakravarthi)
+ #319217 - Show only alarms starting from today for missed alarms
+ (Chakravarthi)
+ #316280 - Fix to addressbook print to use specified page size
+ (Evan Yan)
+ #229972 - In contact editor, move focus automatically to next
+ field, after setting phone from the menus (Devashish)
+ #301081 - Fix to rememberpublishing recipents in converting mail
+ to task plugin (Mubeen)
+ #308752 - Renamed 'Meetings and Tasks' to 'Calendar and Tasks'
+ in Preferences (Dinesh)
+
+Other Fixes:
+
+ - Category syncing in todo-conduits (Nathen Owens)
+ - Adjust the Date/Time widgets to take actual size in
+ meeting/event page (Chenthill)
+ - Automatic file extention filling in saving a calendar (Dinesh)
+ - Code Cleanup (Harish)
+
+Update Translations:
+
+ - bg (Alexander Shopov)
+ - ca (Adam Weinberger)
+ - es (Francisco Javier F. Serrador)
+ - et (Priit Laes)
+ - fi (Ilkka Tuohela)
+ - gl (Ignacio Casal Quinteiro)
+ - ku (Erdal Ronahi)
+ - lt (Žygimantas BeruÄÂka)
+
+Evolution 2.5.1 2005-10-25
+--------------------------
+New !! Evolution Memos component (Nathan Owens)
+and plenty of bug fixes as usual.
+
+Evolution 2.4.0 2005-09-05
+--------------------------
+What is new ?
+
+- A new menu layout (More HIG compliant)
+- Inline PGP Signature/Encryption support.
+- Performance enhancements on Camel/GroupWise Backends.
+- Auto-fit Image Attachments
+- Support for GroupWise proxy accounts
+- Extended EPlugin support, importers as an EPlugin.
+- Thunderbird-compatible storage of labels on IMAP.
+- Support for delegation of meetings (Calendar)
+- Marcus Baines Line (calendar)
+
+Evolution 2.3.8 2005-08-23
+---------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.gnome.org/show_bug.cgi):
+
+ #312225 - Cannot post message to NNTP easily (Rodney)
+ #306878 - CTRL + H, does not select all mails of thread (Rodney)
+ #310136 - Unable to get number of mails in a folder using
+ accessibility interface (Li Yuan)
+ #312668 - Unable to go back to Online mode after
+ clicking offline button... (Michael Zucchi)
+ #271894 - PGP-encrypted attached messages not displayed
+ (Michael Zucchi)
+ #312224 - New attachment UI is weird (Srinivasa)
+ #312033 - new attachment widget no polished (Srinivasa)
+ #307375 - Serious fd usage error 16 (Kaushal)
+ #313440 - installed header includes non-existant file
+ (Michael Zucchi)
+ #313582 - Add scalix to send and receive check_all
+ (Christian Kellner)
+ #273842 - click 'Back' & 'Forward' to proceed in last but
+ one page (Vivek)
+ #232499 - renamed IMAP folder loses custom view settings
+ (Michael Zucchi)
+ #313057 - Evolution sends a GetFolderListRequest instead of
+ a LogoutRequest when disabling an account (Vivek)
+ #271985 - More Command Line Spew (Michael Zucchi)
+ #312715 - Evolution crashes moving IMAP folder to local folder
+ (Michael Zucchi)
+ #304938 - Crash after posting to newsgroup (Michael Zucchi)
+ #313585 - Install missing e-plugin header (Christian Kellner)
+ #271984 - Command Line Spew From Plugins (Michael Zucchi)
+ #311904 - unable to create new task b/w 00:00-03:00 (Chenthill)
+ #312739 - Double click on the meeting in day view,
+ opens as appointment (Viren)
+ #310338 - Click on 'Edit' on 'Alarm notification nothing
+ happens (Viren)
+ #310438 - drag-n-drop a task from a task list to the
+ same task list makes the task disappear (Dinesh)
+ #314152 - Contact renderer incorrectly uses
+ e_contact_get_const() (Sushma)
+ #241219 - "Edit Categories" shouldn't be modal (Devashish)
+ #269870 - evolution-addressbook-export --format=csv
+ does not work (Sushma)
+ #312554 - Unable to rename contact list - Contact list
+ copy of existing contact list (Devashish)
+ #313063 - scrollbar doesn't work at all (Michael Zucchi)
+ #308117 - mono plugin fails to load (Michael Zucchi)
+ #312621 - un-subscribe to list from mail that no
+ longer exists crashed evo (Michael Zucchi)
+ #312313 - Cannot remove and then provide proxy access
+ immedietly to same id (Sankar)
+ #312352 - Evolution crashes always while providing proxy
+ access to more then one user (Sankar)
+ #312309 - gw: Evolution crashed when proxy access
+ modified (Sankar)
+ #311555 - sharing tab missing for user-created folders
+ with names like Mailbox, Trash... (Vivek)
+ #305627 - Inconsistent behaviour while accepting meeting
+ (Dinesh)
+ #307841 - When accepting appointment into a groupwise
+ calendar, they are being marked as "free"
+ not "busy" (Chenthill)
+ Win32 support fixes (Tor Lillqvist)
+ Misc. build fixes (Harish)
+
+Updated Translations:
+
+ - bg (Alexander Shopov)
+ - bg (Rostislav Raykov)
+ - ca (Josep Puigdemont i Casamajó)
+ - ca (Xavi Conde Rueda)
+ - cy (Rhys Jones)
+ - de (Frank Arnold)
+ - el (Kostas Papadimas)
+ - en_CA (Adam Weinberger)
+ - es (Francisco Javier F Serrador)
+ - et (Ivar Smolin)
+ - fi (Ilkka Tuohela)
+ - hu (Gabor Kelemen)
+ - id (Mohammad DAMT)
+ - ja (Takeshi AIHANA)
+ - lt (Zygimantas BeruÄÂka)
+ - nb, no (Kjartan Maraas)
+ - nb, no (Terance Sola)
+ - nl (Tino Meinen)
+ - nn (Sigurd Gartmann)
+ - pt_BR (Raphael Higino)
+ - ru (Nickolay V. Shmyrev)
+ - sq (Laurent Dhima)
+ - sr, sr@Latn (Igor Nestorović)
+ - sv (Christian Rose)
+ - th (Theppitak Karoonboonyanan)
+ - th (Supranee Thirawatthanasuk)
+ - vi (Clytie Siddall)
+ - zh_CN (Funda Wang)
+ - zh_TW (Chao-Hsuing Liao)
+
+Evolution 2.3.7 2005-08-08
+---------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.gnome.org/show_bug.cgi):
+
+ #261971 - Bad plural form: foo(s) in evolution-addressbook.xml (Devashish)
+ #302843 - Replying to news posting from vFolder (Michael Zucchi)
+ #300881 - crash adding signature (Michael Zucchi)
+ #312397 - Forward Of Message Displays Wrong Names In Comments (Michael Zucchi)
+ #273885 - Many english messages in a translated version of evolution (Michael Zucchi)
+ #310840 - Resizing evolution mail window which contains an image attachment crashes it. (Michael Zucchi)
+ #308512 - Key /apps/evolution/lock/mail/accounts/save_password does not work correctly (Michael Zucchi)
+ #312410 - new attachment ui disappears (Srinivasa Ragavan)
+ #309647 - contents of copy/paster buffer can corrupt initial contents of a reply message (Michael Zucchi)
+ #231968 - Ability to access Permissions dialog from menus (Michael Zucchi)
+ #300607 - "virtual vfolders" aren't moved properly (Michael Zucchi)
+ #311223 - saving a message crashes evolution (Shreyas)
+ #307538 - If receiving mail-tab is set to NONE (Shreyas)
+ #311440 - Crashes on particular e-mail (Michael Zucchi)
+ #311686 - Evolution crashes when adding an attendee in the event editor (Chenthill)
+ #312460 - Evolution crashed on creating recurring meeting with attachment in GW calendar (Chenthill)
+ #302460 - Double clicking in open text field in calendar crashes (Viren)
+ #312447 - [Gnopernicus]Brlmoniter doesn't show the time changes if using keyboard shortcut to change date (Harry Lu)
+ #309601 - GroupWise Calendar Events Can Be Moved By Attendees (Chenthill)
+ #306017 - 'Delete this occurence' removes all day event on day *before* (Chakravarthi)
+ #309247 - Error loading address book dialog seizes the desktop (Srinivasa Ragavan)
+ #254923 - The image in a contact could be scaled to a sane size (Frank Arnold)
+ #258257 - Evolution allows to save the contact without the contact name (Devashish)
+ #309416 - crash on close (Srinivasa Ragavan)
+ #269870 - evolution-addressbook-export --format=csv does not work (Michael Meeks)
+ #311324 - Unsubscribe folder should not work in offline (Shakti Sen)
+ #310353 - password prompt appears twice even after entering the correct password the first time (Sankar)
+ #304461 - clicking on 'edit message' from the 'subscribe to list' pop-up dialog hangs evolution (Michael Zucchi)
+ #312365 - Proxy access to self should be disabled (Sankar)
+ #302817 - "Sent items" status tracking does not appear properly (Vivek)
+ #311721 - 'Track message status' option present for messages other than in sent items folder also (Vivek)
+
+Updated Translations:
+
+ - cs (Miloslav Trmac)
+ - cy (Rhys Jones)
+ - en_CA (Adam Weinberger)
+ - el (Kostas Papadimas)
+ - es (Francisco Javier F. Serrador)
+ - et (Ivar Smolin)
+ - fi (Ilkka Tuohela)
+ - gu (Ankit Patel)
+ - ja (Takeshi AIHANA)
+ - nb,no (Kjartan Maraas)
+ - nb,no (Terance Sola)
+ - nl (Vincent van Adrighem)
+ - POTFILES (Adam Weinberger)
+ - pt_BR (Raphael Higino)
+ - sk (Marcel Telka)
+ - te (Prajasakti Localisation Team)
+ - vi (Clytie Siddall)
+ - zh_CN (Funda Wang)
+ - zh_TW (Chao-Hsuing Liao)
+
+Evolution 2.3.6 2005-07-26
+---------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.gnome.org/show_bug.cgi):
+
+ #248126 - Missing options from Task menubar (Viren)
+ #219242 - Save draft shortcut and button (Devashish)
+ #310136 - number of mails in a folder using accessibility interface
+ (Li Yuan)
+ #310138 - locate first mail in a message list tree using
+ accessibility interface (Li Yuan)
+ #310330 - forwarding a mail as inline/quoted makes evolution
+ disappear (Vivek)
+ #216021 - Add confirmation dialog to Forget Password (Sankar)
+ #309991 - PROXY: Appointments not shown in proper time-zone (Chenthill)
+ #310985 - "Subscribe to other user's Folder" option should be moved
+ to File menu (Shakti)
+ #309602 - Un-accepted GroupWise Appointments Should Give
+ Cue On Calendar (Chenthill)
+ #245331 - Keybindings for switching b/w calendar views (Harish)
+ #310340 - 'Delete This Occurence' does not delete that occurence
+ in GW calendar (Chenthill)
+ #309680 - "Make this Occurence Movable" for a recurring appointment
+ crashes evolution (Chenthill)
+ #309869 - Clicking on buttons in composer doesnt change focus
+ to the corresponding fields (Antony)
+ #257329 - autocompletion in the settings uses wrong icon (Sushma)
+ #235830 - Contacts name not displayed during edits (Arunprakash)
+ #311090 - Cut contact asking for confirmation (Sushma)
+ #310343 - Copying contact to same folder - Evolution crashes (Arunprakash)
+ #311096 - Not able to add any user to give permissions (Shakti)
+ #310433 - Renaming a user created Tasks List under exchange account
+ creates one more Tasks List (Praveen)
+ #310837 - Folder Permissions' doesn't show the 'Custom' label in the
+ 'Role' combo box (Shakti)
+ #310699 - Evolution crashes after viewing the all folders' size (Sarfraaz)
+ #310479 - For exchange calendar 'Permission' option is missing (Shakti)
+ #310493 - Checking any Mail folder permission crashes evolution (Shakti)
+ #310369 - No dialog pops up when you click on Folder->Subscribe (Shakti)
+ #310233 - Evolution crashes when no exchange-account is configured (Shakti)
+ #310854 - settings message receipts in send options does not send any message (Vivek)
+ #310347 - trying to enable/disable filters for a mail account when the
+ account is disabled hangs/crashes evolution (Vivek)
+ #309992 - PROXY: Contacts button not disabled in edit-proxy-access-rights (Vivek)
+
+Other fixes and changes :
+
+ - fix make distcheck woes all over the module (Harish)
+ - refactor mail refresh code (Michael)
+ - revert broken view->hide menu (Michael)
+ - attachment bar cleanup (Srinivasa)
+ - mailer memory leak fixes (Kjartan Maraas, Shreyas)
+ - do not enter sidebar button in shell window when there
+ is no label (Sarfraaz)
+ - Build fixes for Windows support and use of NO_UNDEFINED
+ (Tor Lillqvist)
+ - Image resize in contact-editor (Srinivasa)
+ - enhance ESendOptionsDialog ui (Vivek)
+ - allow user added categories to be edited and disable
+ editing on builtin views on etable (Srinivasa)
+ - calendar/contact/task hooks for exchange-operations plugin
+ (Shakti)
+ - fix error calls in exchange (Arunprakash)
+ - exchange folder size display (Sarfraaz)
+ - mark GW System Addressbook for offline usage by default (Sushma)
+ - consolidate proxy plugins into groupwise features (Sankar)
+ - fix memory leak in itip-formatter (Chenthill)
+
+
+Updated Translations:
+
+ - bg (Vladimir Petkov)
+ - el (Nikos Charonitakis)
+ - en_CA (Adam Weinberger)
+ - es (Francisco Javier F. Serrador)
+ - et (Ivar Smolin)
+ - fi (Ilkka Tuohela)
+ - ja (Takeshi AIHANA)
+ - lt (Žygimantas BeruÄÂka)
+ - nb, no (Kjartan Maraas)
+ - nl (Tino Meinen)
+ - POTFILES (Adam Weinberger)
+ - POTFILES (Sankar P)
+ - POTFILES (Sarfraaz Ahmed)
+ - POTFILES (Shakti Sen)
+ - POTFILES (Vivek Jain)
+ - pt_BR (Raphael Higino)
+ - sk (Marcel Telka)
+ - sr, sr@Latn (Igor Nestorović)
+ - vi (Clytie Siddall)
+ - zh_CN (Funda Wang)
+
+Evolution 2.3.5 2005-07-12
+---------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.gnome.org/show_bug.cgi):
+
+ #309624 - An addressbook error tells me to check a filesystem path, but doesn't tell me what it is (Sushma)
+ #237844 - Create a appointment with all blank properties (Sankar)
+ #307794 - Evolution crashs in Mail Account creation druid (Vivek)
+ #274329 - Evolution crashes on load, with notification to d-bus enabled. (Vivek)
+ #242165 - "search in any field" produces wrong results
+ #309245 - Unnecessary confirmation popup dialog while copying contacts (Srinivasa Ragavan)
+ #206774 - Context menu should be different for Lists and Individuals (Srinivasa Ragavan)
+ #242154 - "Open" should be first menu entry when right-clicking on a contact (Srinivasa Ragavan)
+
+New plugins :
+
+ sa-junk - junk filtering through spam assassin (Vivek)
+ Groupwise proxy - proxy support for GW (Sankar, Shreyas)
+
+Other fixes and changes :
+
+ - Importers refactoring (Michael Zucchi)
+ - Unify mail and calendar attachment bar (Srinivasa Ragavan)
+ - Handle contact:// and calendar:// uris (Veerapuram Varadhan)
+ - Enable autocompletion on personal addressbook on creation (Frederic Crozat)
+ - Miscellaneous recurrence fixes (Chenthill)
+ - Enable alarms for non-organizers (Chenthill)
+ - Set vertical scrollbar to always in meeting page (Srinivasa Ragavan)
+ - Show progress information in calendar (Chenthill)
+ - Add forward command line option to uri handling in mail (Veerapuram Varadhan)
+ - Exit evolution when closing wizard using wm control (Frederic Crozat)
+ - GW Junk mail handling (Vivek)
+ - Attachment UI fixes and refactoring (Michael Zucchi)
+ - Exchange Folder size support (Sarfraaz)
+ - Exchange Subscribe/Unsubscribe support (Shakti Sen)
+ - Exchange Folder Permissions support (Shakti Sen)
+ - Exchange Delegation support (Praveen Kumar) -
+ - Improved error handling in Exchange operations plugin (Arun Prakash)
+
+
+Updated Translations:
+
+ - bg (Rostislav Raykov)
+ - de (Hendrik Richter)
+ - de (Jens Seidel)
+ - el (Nikos Charonitakis)
+ - en_CA (Adam Weinberger)
+ - es (Francisco Javier F. Serrador)
+ - et (Ivar Smolin)
+ - nb, no (Terance Sola)
+ - sr, sr@Latn (Igor Nestorović)
+ - vi (Clytie Siddall)
+ - zh_TW (Chao-Hsiung Liao)
+ - POTFILES (Sankar P, Vivek Jain)
+
+Evolution 2.3.4 2005-07-02
+---------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.gnome.org/show_bug.cgi):
+
+Mail :
+ #307398 - blank IMAP warning messages (Michael Zucchi)
+ #301466 - Could not able to create a vFolder with Match all condition (Brian Mury)
+
+New plugins - exchange-operations (Sarfraaz Ahmed, Praveen Kumar)
+ - default-mailer (Jonathan Dieter, Michael Zucchi)
+
+Other fixes and changes :
+
+ - Get around circular dependencies using fake bootstrap libraries
+ and updates for Win32 support (Tor Lillqvist)
+ - Inline-pgp signature/encryption support (Matt Brown)
+ - gal clean up (Kaushal Kumar)
+ - Do not pass data to gtkhtml that it cannot handle (Michael Zucchi)
+ - Copyright year update (Andre Klapper)
+ - utility function to display the busy cursor (Srinivasa Ragavan)
+ - fix memory leaks in conduits (Mark G Adams)
+ - add source type to ECalConfigTargetSource (Praveen Kumar)
+ - fix attachment desensitization and fixes for delegation support (Chenthill)
+ - compare backends for long events in the day view (Jedy Wang)
+ - disable widgets appropriately for non-organizers in Event editor
+ (viren l)
+ - Fix free/busy query updates from the GW backend (viren l)
+ - Fix circular dependancies in the contact-list-editor (Harish)
+ - set default parameter to email attribute. (Sushma)
+
+Updated Translations:
+
+ - bg (Alexander Shopov)
+ - cs (Miloslav Trmac)
+ - cy (Rhys Jones)
+ - da (Martin Willemoes Hansen)
+ - de (Andre Klapper)
+ - de (Hendrik Richter)
+ - en_AU (Not Zed)
+ - en_CA (Adam Weinberger)
+ - es (Francisco Javier F. Serrador)
+ - et (Ivar Smolin)
+ - et (Priit Laes)
+ - fi (Ilkka Tuohela)
+ - nb, no (Terance Sola)
+ - sk (Marcel Telka)
+ - zh_CN (Funda Wang)
+ - zh_TW (Abel Cheung)
+ - zh_TW (Chao-Hsiung Liao)
+ - POTFILES.in (Kaushal Kumar)
+ - POTFILES.in (Not Zed)
+ - POTFILES.in (Sarfraaz Ahmed)
+
+Evolution 2.3.3.1 2005-06-15
+-----------------------------
+
+ #307176 - Remove X-GNOME-Bugzilla-Bugzilla=Ximian (Andre Klapper)
+ Fix build issues related to the mono plugin (Harish)
+
+Evolution 2.3.3, 2005-06-07
+---------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.gnome.org/show_bug.cgi):
+
+UI:
+ #306153 Two mnemonics in same string (Andre Klapper)
+ #305376 Hide/unhide read messages missing from new menu layout (Rodney Dawes)
+
+Mail:
+ #306151 Extra space in string (Andre Klapper)
+
+Calendar:
+ #272114 Beside 'Task' & 'Calender' folders, color boxs get displayed
+ when properties are changed (Chenthill)
+ #302267 Date button should have a detailed name (Li Yuan)
+
+
+Other fixes and new features :
+
+ - subclass mail-component from evolution-component and
+ not a bonobo object (Michael Zucchi)
+ - plugin type loader registration, using a plugin itself.
+ remove e-plugin-mono. (Michael Zucchi )
+ - Delegation of meetings for GW backend (Chenthill)
+ - Marcus Bains line for Calendar (Thouis Jones)
+ - Folder browser listeners for filtering message list (Rodney Dawes)
+ - helper for plugins to get mail session. (Michael Zucchi)
+ - pseudo mime type to find message formatter (Michael Zucchi)
+ - missing bits of e-cert-db from branch merge (JP)
+ - delete/unload old nssckbi root certs module (Jeffrey Stedfast)
+ - initial commits for importer plugin hooks (Michael Zucchi)
+ - DnD support for remote URLs to the attachment window. (Srinivasa
+ Ragavan)
+ - exchange plugin UI changes (Sarfraaz Ahmed)
+ - mail-remote plugin (Michael Zucchi)
+
+Updated translation :
+
+ - zh_CN (Funda Wang)
+ - bg (Vladimir Petkov)
+ - en_CA (Adam Weinberger)
+ - es (Francisco Javier F. Serrador)
+ - nb (Kjartan Maraas)
+ - no (Kjartan Maraas)
+ - vi (Clytie Siddall)
+ - de (Hendrik Richter)
+ - cs (Miloslav Trmac)
+ - bg (Yavor Doganov, Ivelina Karcheva)
+ - el (Kostas Papadimas)
+ - da (Martin Willemoes Hansen)
+
+Evolution 2.3.2, 2005-05-18
+---------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.gnome.org/show_bug.cgi):
+
+#269129 replying to a newsgroup post from a vfolder gets group wrong (Jeffrey Stedfast)
+#271679 "make this occurrence movable" unusable (Rodrigo Moya)
+#274406 alarm notify crasher (Chenthill)
+#209416 Mini-card view for mailing list is wrong (Srinivasa Ragavan)
+
+
+i18n :
+272242 action "Print" doesn't have dots at the end of name (Vivek)
+Fixes #301459 - A collection of typos from the Evolution .po file (Chenthill)
+"all the deleted message" typo in Evolution mail-errors.xml (Sarfraaz)
+273075 - "cert" slang in Evolution certificate manager" (Sarfraaz)
+#300477 - Evolution account assistent does not have label (Mengjie Yu)
+#268906 - improve date selection for recurring appointments (Sushma)
+#229794 - When creating a recurrent appointment, current weekday can't be deselected (Harish)
+ Patch from jack jia.
+#269416 - Drag/drop between task lists copies instead of moving (Srinivasa Ragavan)
+#301350 - alarms totally unreliable . (Rodrigo Moya)
+#261079 - Please add translator comments for "%s %s" messages in evolution (Vivek)
+#272464 - Error message on GW server needs to be clarified (Chenthill)
+#261969 - Bad plural form: foo(s) in addressbook-errors.xml (Sushma)
+#272005 - Click on 'Help' in 'Send Options' popup, this popup closes (Shreyas)
+#273096 - Double spacing in Evolution widget message (Harish)
+#273097 - Unnecessary trailing spaces in Evolution widget messages (Harish)
+
+Other fixes and features :
+
+ New menu layout - Rodney Dawes
+ Attachment Expander changes - Srinivas
+ Remove wizard related code and use eplugin (JP)
+ Evolution Force shutdown fixes (Harish)
+ Pkg config fixes for evolution exchange (Amish)
+ Move e-error to e-util (Michael Zucchi)
+ Prevent crash if D-BUS session bus is not running (Timo Hoenig)
+ Fixes for Bug #73099 and Bug #73098 - rdf, csv formats (Philip Van Hoof)
+ moved widgets/misc/e-system-errors to e-util/e-system.error (Michael Zucchi)
+ Memory leak fixes (Ross burton)
+ Miscellaneous config fixes (Harish)
+ Potfiles - remove dead files (JP)
+
+New plugins :
+
+- mono, mail-remote, profiler (Michael Zucchi)
+
+Updated Translations:
+
+ - bg (Rostislav Raykov)
+ - el (Kostas Papadimas)
+ - ne (Pawan Chitrakar)
+ - fa (Meelad Zakaria and Roozbeh Pournader)
+ - es (Francisco Javier F. Serrador)
+
+Evolution 2.3.1, 2005-04-26
+---------------------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.gnome.org/show_bug.cgi):
+
+* Calendar
+
+ - #301885 - Evolution crash when shifting locale in calendar view
+ several times (Li Yuan)
+ - #274476 - File ->Open Appointments, opens meeting as appointment
+ (Chenthill)
+ - #273508 - status of organizer of a meeting getting changed
+ (Chenthill)
+ - #41740 - No error trying to edit Exchange appointments from alarm
+ (Rodrigo)
+ - #73879 - Attach a file to 'Calendar' in offline, 'OK' button gets enabled
+ (JPR)
+ - #73969 - 'Cancel' meeting doesnt delete all instances of recurring
+ meeting in 'attendee's calendar (Chenthill)
+ - #44719 - Alarm Notify window is not sticky any more (Rodrigo)
+ - #69272 - doesn't accept new date & crashes while retrying (JP)
+ - #73508 - evolution crash on startup (Chenthill)
+ - #44579 appointment location / description does not get printed(Li Yuan)
+ - #73031 - crash when closing event editor (Chenthill)
+ - #268525 - crash when evo is in background (Chenthill)
+ - #272983 - 'List' view has one entry for recurring appointment
+ (Rodrigo)
+ -#74265 incorrect start date display (Chenthill)
+
+* Mail
+ - #273752 - Dragging folder from Maildir spool account to 'On This Computer'
+ account crashes Evolution (Michael)
+ - #273192 - Mark as (un)read missing from context popup menu (Rodney)
+ - #273914 - Some of the tables do not have a11y names (Li Yuan)
+ - #74002 - create shared-to me folder from the wizard offline (Partha, Vivek)
+
+* Shell/GUI
+ - #273066 - buutons" typo in Evolution schemas message (JP)
+ - #300968 - (Mengjie Yu)
+ - #300970 - (Mengjie Yu)
+ - #73270 - (Mengjie Yu)
+
+* a11y
+ - #73914 -add a11y name to Certificates Table (Li Yuan)
+
+* Addressbook
+ - #74366 (Sushma)
+
+
+Other Bugs
+
+* Mail
+ - asynchronously load message if no receipt is supplied (Michael)
+ - New function to send an RFC2298-compliant message delivery notification
+ (ERDI Gergo)
+ - make the 'select all' work in all conditions (Mengjie Yu)
+ - use gnome-vfs API to launch external applications (Marco Pesenti Gritti)
+ - add new receipt_policy field to services (ERDI Gergo)
+
+* Shell
+ - return the localized name of the supported file type (Yong Sun)
+ - fix offline state event (Michael)
+
+* Calendar
+ - display error messages when we can't load the component in the editor
+ (Harry Lu)
+
+
+Updated Translations :
+
+ * et - Ivar Smolin
+ * bg - Vladimir Petkov
+ * cs - Miloslav Trmac
+ * en_CA - Adam Weinberger
+ * en_GB - Gareth Owen
+ * es - Francisco Javier F. Serrador
+ * de - Frank Arnold
+ * id - Ahmad Riza H Nst
+ * ne - Pawan Chitrakar
+ * nl - Tino Meinen
+ * da - Martin Willemoes Hansen
+ * gu - Ankit Patel
+ * pt - Duarte Loreto
+ * pt_BR - Guilherme de S. Pastore
+ * cs - Stanislav Brabec
+ * fi - Ilkka Tuohela
+ * sq - Laurent Dhima
+
+Evolution 2.2.0, 2005-03-07
+---------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
+
+ * Addressbook
+ #73152 - Assigning Color To Default Personal Contacts, Creates Duplicate (Siva)
+
+ * Calendar
+ #72835 - Alarm notify crashes always (Rodrigo)
+ #73152 - Assigning Color To Default Personal Calendar, Creates Duplicate (Siva)
+
+Other bugs
+
+ * Plugins
+ - Fix exchange plugin description for OOF (Sushma)
+
+Updated translations:
+ - pt_BR (Raphael Higino)
+ - hu (Laszlo Dvornik)
+ - sr (Danilo Segan, Igor Nestorovic)
+ - sr@Latn (Danilo Segan, Igor Nestorovic)
+ - nl (Tino Meinen)
+ - lt (Zygimantas Berucka)
+ - sq (Gintautas Miliauskas, Laurent Dhima)
+ - ja (Takeshi AIHANA)
+ - bg (Iassen Pramataro)
+
+Evolution 2.1.6, 2005-02-28
+---------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
+
+ * Addressbook
+ #73005 - Cannot cancel 'Contact List Editor' (Siva)
+ #73005 - offline - setting/unsetting folder offline property is not working (Sushma)
+ #70371 - Evolution crashes when adding contact list (Siva)
+ #67724 - When unix user name, callendar points to old username (Siva)
+ #54825 - Freeze on .vcf import from MacOS X AddressBook (Christophe Fergeau)
+ #73013 - 'Right' click on a 'Contact' cannot select 'Cut' (Siva)
+
+ * Calendar
+ #72958 - Unable to send delayed meeting (Chen)
+ #72006 - Opened existing appointments with attachment - press cancel - popup info with save / discard / cancel changes (Chen)
+ #63866 - Same name can be entered twice in invitations tab (JP)
+ #67714 - Invitations Tab Allows Entry Of Empty Line (JP)
+ #62089 - adding contact lists to meetings impossible (JP)
+ #47747 - Changes to attendee not updated until click on different row (JP)
+ #61495 - Existing text is placed off screen when editing attendee field (JP)
+ #28947 - adding contact list to attendee list should expand it (JP)
+ #67724 - When unix user name, callendar points to old username (Siva)
+ #72038 - Changes meeting to appoinment after throwing warning invalid mail id (Rodrigo)
+ #69556 - Crash attaching mime parts to calendar events (Harish)
+
+ * Mail
+ #66126 - attach File Chooser is modal (Michael)
+ #68549 - Answering to Usenet article doesn't consider the "Followup-To:" field (Michael)
+ #71003 - threads still running at exit (Michael)
+ #62109 - Inconsistent ways of determining 8-bit Subject: and From: header charsets (Jeff)
+ #34153 - Confusing Outbox semantics for deleted outgoing messages (Michael)
+ #71528 - Search Selection Widget Has Repeated Items (Michael)
+ #71967 - Evolution delete mail from POP3 server even is checked the option "leave the mail on server (Michael)
+ #40515 - Signature scripts do not allow switches (Michael)
+ #68866 - Forward button doesn't put newline between headers and body (Michael)
+ #35219 - flag-for-followup crufting (Michael)
+ #64987 - Go to next unread message doesn't work when multiple messages are selected (Michael)
+ #72337 - Evolution crashes if I click OK/Cancel on the password dialog after disabling the IMAP account (Michael)
+ #70718 - Next and previous buttons don't realize there's new mail (Michael)
+ #61363 - Setup wizard, IMAP for receiving server, sending default GW (Michael)
+ #70795 - Next/Previous Message Should Only Display Listed Emails (Michael)
+ #23822 - no copy text option when right-clicking on marked mail text (Rodney)
+ #72266 - You shouldn't be able to open more than one 'Select Folder' dialog in the mail filters (Michael)
+ #71429 - on NLD, menus in wrong order (Michae)l
+ #72228 - cannot store into groupwise sent folder (Michael)
+ #72209 - Evolution is crashing when you move a VFolder to a folder 'on this computer' (Michael)
+ #72275 - Can't use Shift+F10 to popup context menu for link in message (Harry Lu)
+ #54503 - "New" dropdown menu on toolbar has wrong widget style (Rodney)
+ #72676 - Saved filter rule can't be modified if it is selected with GOK. (Harry Lu)
+
+ * SMIME
+ #68592 - "Backup" buttons in certificate settings does nothing - work around (Michael)
+
+ * Shell
+ #33287 - "send/receive" button not greyed out when starting offline (JP)
+ #48868 - Status bar changes its height when fonts are large (William Jon McCann)
+
+ * Plugins
+ #71527 - Save Calendar widget mixup between directory and file (Rodrigo)
+
+Other bugs
+
+ * Addressbook
+ - Use new categories dialog in contact editor (Rodrigo)
+ - HIG spacing fixes (Rodney)
+ - Display warning dialog when GW server is old (Vivek)
+
+ * Calendar
+ - Always ensure default sources are available (Siva)
+ - Don't look up free/busy unless we need to (Harish)
+ - Make sure new events don't display twice (Chen)
+ - Make sure double click opens attachments (Chen)
+
+ * Mail
+ - a11y fixes for composer (Harry Lu)
+ - Use gnome-vfs API to launch external applications (Marco Pesenti Gritti)
+ - New mailer context menus for messages (Rodney)
+
+ * Shell
+ - Fix leak (JP)
+ - Use gnome-vfs API to open quick reference (Marco Pesenti Gritti)
+
+ * Plugins
+ - Make e-popup more robust (Michael)
+ - Cleanup authors/descriptions (Björn Torkelsson)
+ - out of office exchange fixes (Sushma)
+ - retry send options if invalid session string (Chen)
+ - set proper default port for shared folders (Vivek)
+
+ * Miscellaneous
+ - BSD runtime linking fixes (Hans)
+ - distclean fixes (Björn Torkelsson)
+
+Updated translations:
+ - et (Priit Laes)
+ - el (Kostas Papadimas, Nikos Charonitakis)
+ - sv (Christian Rose)
+ - es (Francisco Javier F. Serrador)
+ - it (Luca Ferretti, Marco Ciampa)
+ - da (Martin Willemoes Hansen)
+ - ca (Josep Puigdemont, Xavi Conde)
+ - nb (Kjartan Maraas)
+ - no (Kjartan Maraas)
+ - ru (Leonid Kanter)
+ - gu (Ankit Patel)
+ - cs (Miloslav Trmac)
+ - nl (Vincent van Adrighem)
+ - fi (Ilkka Tuohela)
+ - pt (Duarte Loreto)
+ - uk (Maxim Dziumanenko)
+ - ko (Changwoo Ryu)
+ - de (Frank Arnold)
+ - fr (Vincent Carriere)
+ - en_CA (Adam Weinberger)
+ - cs (Miloslav Trmac)
+ - pl (Artur Flinta)
+ - bg (Vladimir Petkov)
+ - ja (Takeshi AIHANA)
+ - en_GB (David Lodge)
+ - en_CA (Adam Weinberger)
+ - lt (Zygimantas Berucka)
+
+Evolution 2.1.5, 2005-02-07
+---------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
+
+ * Addressbook
+ #36137 - Leading %s in addressbook message totally non-obvious (Siva)
+ #57819 - Evolution allows to create several contact lists with same name
+ (Partha)
+ #61060 - Don't split sentences in Evolution (Siva)
+ #61067 - Use translator comment for evolution addressbook message (Siva)
+ #67411 - Crash: create new address book (Hans Petter)
+ #68799 - Evolution doesn't store IM info on the LDAP server (Siva)
+ #70339 - vcard preview doesn't appear to work (Siva)
+
+ * Calendar
+ #33078 - No category list for Category searches in Calendar & Tasks (Rodrigo)
+ #56901 - Only one line gets printed when printing Tasks and Appointments (Yong)
+ #61078 - Please avoid using different styles of markup in translateable
+ evolution messages (Priit)
+ #64682 - Moving a appts from one calendar to another sends update (Chenthill)
+ #71265 - Deletion Of Weather Calendar Crashes Evo (Rodrigo)
+ #71452 - Pressing 2 times escape - edited meeting window disappear (JP)
+ #71485 - String issues (JP)
+ #71729 - Gnopernicus should report the full name of week day (Li)
+ #71929 - Whitespace before colons in Evolution calendar a11y messages
+ (Rodrigo)
+ #71924, 71926, 71932 - Don't split sentences (Harry)
+ #71944 - Failed to compile (JP)
+ #72088 - Some calendar a11y functions don't work (Harry)
+ #72090 - Evolution crashed when clicking on 'open calender' in sent items (Rodrigo)
+
+ * Mail
+ #65329 - Regression in default folder name localisation (Michael)
+ #67083 - CJK-translated mail header names are line-wrapped with long lined headers
+ (Michael)
+ #68137 - Inconsistent VFolder vs vFolder (Rodney)
+ #68696 - RFE: Simplifications to the "Account Management" page of the Account
+ setup druid (Rodney)
+ #68743 - Button jumps when you click it (Rodney)
+ #69815 - Cannot quit while updating vfolders (Michael)
+ #69850 - Crash: attempting to create a Vfolder based on a message without a Sender
+ (Michael)
+ #70454 - Folder shows unsubscribed, but is subscribed (Jeff)
+ #71310 - Always loses my signature script settings (Michael)
+ #71312 - Double-clicking vFolder of Draft folder doesn't allow editing (Michael)
+ #71520 - Changing server type not displayed immediately in 'Account settings'
+ (Michael)
+ #71521 - 'Account Editor' does not allow to change hostname (Michael)
+ #71774 - Evolution crashes when cancel 'Rename Folder' dialog (Mengjie)
+ #71937 - Spamasssassin typo in Evolution mail schemas (JP)
+
+ * Plugins
+ #41235 - Spacing/padding of itip control (Rodney)
+ #71460 - Clicking accept button in appointment - Unable to send item to calender
+ 'Calender'. Invalid object (Chenthill)
+ #71512 - Crash: AMD64 Unable to add or import contacts (Siva)
+ #71644 - Empty string marked for translation (Sushma)
+
+Other bugs
+
+ * Addressbook
+ - Use new categories dialog in contact editor (Rodrigo)
+ - HIG spacing fixes (Rodney)
+ - Display warning dialog when GW server is old (Vivek)
+
+ * Calendar
+ - Fixed sensitation of widgets in recurrence page (Rodrigo)
+ - Fixed IDL duplications (Hans Petter)
+ - Don't build private libraries as modules (Hans Petter)
+ - Fixed popup menu for detached recurrences (Rodrigo)
+ - HIG spacing/padding fixes (Rodney)
+ - Display warning dialog when GW server is old (Vivek)
+ - Clear component preview when updating (Rodrigo)
+ - Added help button to editors (Rodney)
+ - Fix DND issues with calendar attachments (Harish)
+
+ * Mail
+ - HIG fixes (Rodney)
+
+ * Plugins
+ - Use icon factory in audio-inline plugin (JP)
+ - Fix order of menus in calendar-http plugin (David)
+ - Added missing ID's (JP)
+ - Set weather categories as not searchable (Rodrigo)
+ - Added auth type section in exchange-account-setup plugin (Sushma)
+ - Fixed crash in groupwise-send-options dialog (Chenthill)
+
+ * All
+ - Added 'pt' default setup to build (Rodney)
+ - Fixed druid lock on startup (Jeff)
+ - a11y improvements (Mengjie, Li, Harry)
+ - HIG fixes to e-passwords dialogs (Rodney)
+
+Updated translations:
+ - bg (Alexander Shopov)
+ - cs (Miloslav Trmac)
+ - de (Hendrik Richter, Frank Arnold)
+ - el (Kostas Papadimas)
+ - en_CA (Adam Weinberger)
+ - es (Francisco Javier F. Serrador)
+ - et (Priit Laes)
+ - it (Marco Ciampa)
+ - ja (Takeshi AIHANA)
+ - lt (Zygimantas Beruska)
+ - nb (Kjartan Maraas)
+ - no (Kjartan Maraas)
+ - ru (Leonid Kanter)
+ - sk (Marcel Telka)
+ - sv (Christian Rose)
+ - zh_CN (Funda Wang)
+
+Evolution 2.1.4, 2005-01-24
+----------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
+
+ * Mail
+
+ #46287 - Space key should work for checkbox (JP)
+ #57090 - Junk Button Sensitivity needs changes (Radek)
+ #69122 - Make subject || sender contains the default search (Michael)
+ #60664 - message view does not follow theme change (Michael)
+ #55831 - missing warning dialog about opening a lot of selected mails (Michael)
+ #66943 - Crash when saving draft (Michael)
+ #70768 - 'Mark All as Read' marks all the mails which are not in current query as read (Michael)
+ #71105 - When trying to rename a folder containing a slash "/" and spaces, evil stuff happens (Michael)
+ #65178 - newly created folder on local maildir doesn't show until evolution restart (Michael)
+ #71029 - receiving settings not stored (Michael)
+ #70990 - NNTP without username broken (Michael)
+ #70018 - Signatures don't work (Michael)
+ #68352 - Add post message keybinding (Rodney)
+
+ * Calendar
+
+ #71407 - Input Protect Read-Only Calendars (Rodrigo)
+ #65820 - Evolution Calendar weekday names message needs translator comment (JP)
+
+ * Addressbook
+
+ #70622 - crash (JP)
+ #71448 - Deleting many contacts is incredibly slow (Siva)
+ #41210 - spacing/padding of "Contact Quick Add" dialog (Rodney)
+ #60852 - "Add address" popup dialog UI is ugly/wrong size, and button is resizable (Rodney)
+ #41228 - spacing/padding of "duplicate contact detected" dialog (Rodney)
+ #70922 - Email address types should show "Other" when importing vcards (Siva)
+ #61973 - add TTYTDD translator comment (JP)
+
+ * Plugins
+
+ #71384 - 'Forward' button is disabled while configuring mail id (Sushma)
+ #29985 - Accepted meetings should have a replied-to icon (JP)
+
+ * Miscellaneous
+
+ #46404 - not remembering printer definition (JP)
+
+Other bugs
+
+ * Address Book
+
+ - set full name appropriately when quick adding (Hans)
+ - fix creation of local addressbooks (Siva)
+ - a11y fixes (Hao Sheng)
+
+ * Mail
+
+ - Add items to folder properties correctly (Jeff)
+ - Add async descriptions (Jeff)
+
+ * Calendar
+
+ - for detached instances, disable recurrence UI (Rodrigo)
+ - use receive_objects for importing (Rodrigo)
+ - change free/busy prefs title (Nat)
+ - handle attachment errors better (Harish)
+ - fix possible day view resize crash (Michael)
+
+ * Shell
+
+ - fix offline handler crash (JP)
+ - close import wizard on Esc (Mengjie Yu)
+
+ * S/MIME
+
+ - don't remove tree node if deleting cert failed (Michael)
+
+ * Plugins
+
+ - Add addressbook file config plugin so local calendar get set up right (Siva)
+ - In BBDB check the buddy account name not alias (Nat)
+ - In weather calendar fix units spelling (David Trowbridge)
+ - In weather calendar use single metric/imperial specification (David Trowbridge)
+ - Add default source plugin so its easy to set for the user (Siva)
+ - Make exchange account setup simpler (Sushma)
+ - In groupwise account setup simplify the settings for soap only (Siva)
+ - Add groupwise status tracking plugin so the user can see the information they requested (Chen)
+ - In itip-formatter extract the decoded text so non-ascii works (JP)
+ - In itip-formatter handle utc dtstart/dtend correctly (JP)
+ - In new-mail-notify fix DBUS event handling (Miguel Angel Lopez Hernandez)
+ - In groupwise sendoptions, make sure the global send options actually work (Chen)
+ - In groupwise shared folder, improve UI (Vivek)
+ - In groupwise shared folder, add a wizard for shared folder notifications (Vivek)
+
+Updated translations:
+ - es (Francisco Javier F. Serrador)
+ - de (Hendrik Richter, Frank Arnold)
+ - it (Marco Ciampa)
+ - nl (Vincent van Adrighem)
+ - lt (Zygimantas Berucka)
+ - nb (Kjartan Maraas)
+ - no (Kjartan Maraas)
+ - et (Priit Laes)
+ - el (Nikos Charonitakis)
+ - ja (Takeshi AIHANA)
+ - en_CA (Adam Weinberger)
+
+Evolution 2.1.3, 2004-01-10
+----------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
+
+ * Calendar
+
+ #69663 - Task list on the web does not mark tasks as finished (JP)
+ #61076 - Evolution calendar messages unnecessarily marked for translation (JP)
+ #41624 - only the last exception is deleted on palm device (JP)
+
+ * Addressbook
+
+ #61068 - Extraneous space in evolution message (Andre Klapper)
+ #61975 - Can't translate string "Reflow test" (JP)
+
+ * Plugins
+
+ #30992 - Preferences dialog greys out OK button after Apply (JP)
+
+Other bugs
+
+ * Address Book
+
+ - set read only state better for contact editor (Hans)
+ - add UI for marking calendars offline (Siva)
+ - use new name selector api (Hans)
+
+ * Mail
+
+ - Display icon for shared folder (Vivek)
+ - New offline folder/store classes (Jeff)
+ - Handle reply in mailto: (Michael)
+ - a11y fixes (Mengjie Yu)
+ - (Mengjie Yu)
+
+ * Calendar
+
+ - detached instance recurrence handling (Rodrigo)
+ - calendar attachments (Harish)
+ - send options for meeting (Chen)
+ - handle calendar:// uris (JP)
+ - handle different calendars having the same uid (Rodrigo)
+ - add UI for marking calendars offline (Chen)
+ - use new name selector API (Hans)
+ - prevent crash when searching for f/b info (JP)
+ - a11y fixes (Harry)
+ - calendar config cleanup (JP)
+
+ * Shell
+
+ - Make component buttons configurable (JP)
+ - Set offline with gconf key (Siva)
+
+ * Plugins
+
+ - add component.migration event for calendar (David Trowbridge)
+ - fix translations of popup menus (Michael)
+ - HIG config dialog fixes (Rodney)
+ - Add calendar file config plugin so local calendar get set up right (JP)
+ - Add calendar weather config plugin (David Trowbridge)
+ - Add exchange account config plugin (Sushma)
+ - Add groupwise send options plugin (Partha)
+ - Add itip formatter plugin (JP)
+ - Add new-mail-notify plugin that uses DBUS (Miguel Angel Lopez Hernandez)
+ - Use standard error messages in save-calendar plugin (Philip Van Hoof)
+ - Add send options plugin for account editor (Chen)
+ - Add shared folder notification plugin (vivek)
+
+Updated translations:
+ - lt (Zygimantas Berucka)
+ - ja (Takeshi AIHANA)
+ - bg (Vladimir Petkov, Alexander Shopov)
+ - et (Priit Laes, Ivar Smolin)
+
+Evolution 2.1.2, 2004-12-20
+----------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
+
+ * Mail
+
+ #68759 - Evolution Shell can't load modules (JP)
+ #69579 - Moving a message from an IMAP INBOX to an IMAP folder caused crash (Michael)
+ #69339 - postscript and some other attachments not visable (Michael)
+ #69579 - vFolders#UNMATCHED generates errors (Michael)
+ #68958 - current message forgotten in vfolders (Michael)
+ #69446 - Mail shown as attachment if some headers are upper case (Michael)
+ #46229 - Filters dialog - label suggestions (Diego Sevilla Ruiz)
+
+ * Calendar
+
+ #47535 - Snooze Time "minutes" string Improperly marked for translation
+ (Rodney)
+ #67403 - wrong alarm time displayed (Rodrigo)
+
+ * Shell
+
+ #61065 - Evolution should be spelled with uppercase E in evolution message (Joan Sanfeliu)
+
+Other bugs
+
+ * Address Book
+
+ - Turkish locale fixes (S. Caglar Onur)
+ - Set proper window title for editing addressbook properties (Vivek)
+ - Prevent null UID from causing weird saving problems (Siva)
+ - a11y fixes (Harry Lu, Hao Sheng)
+
+ * Mail
+
+ - Add mnemonics everywhere (Mengjie Yu)
+ - Moving a message from an IMAP INBOX to an IMAP folder caused crash (Radek)
+
+ * Calendar
+
+ - let users set a template for fetching free/busy information (James
+ Bowes)
+ - Set proper window title for editing calendar/task properties (Vivek)
+ - Leak fixes (Harish)
+ - Fix 64 bit problem (David Mosberger)
+ - UI Fixes for meetings and assigned tasks (Chen)
+
+ * Shell
+
+ - fix 64 bit problem (David Mosberger)
+ - use new window icon (Rodney)
+
+ * Plugins
+
+ - make plugin hooks available for mail even when the mailer is not
+ activated (Michael)
+ - move groupwise config code to a plugin (Siva)
+ - support csv and rdf calendar saving (Philip Van Hoof)
+
+Updated translations:
+
+ - nl (Vincent van Adrighem)
+ - sv (Christian Rose)
+ - ca (Jordi Mallach)
+ - zh_CN (Funda Wang)
+ - bg (Alexander Shopov)
+ - fi (Ilkka Tuohela)
+ - da (Martin Willemoes Hansen)
+ - tr (Baris Cicek)
+ - lt (Zygimantas Berucka)
+ - cy (Dafydd Harries)
+
+Evolution 2.1.1, 2004-11-28
+----------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
+
+ * Addressbook
+
+ #28725 - should not say "no items in this view" until the backend is done responding (Sushma)
+ #61065 - Evolution should be spelled with uppercase E in evolution message (Joan Sanfeliu)
+ #61976 - Near-identical strings, should be made identical (Rodney)
+ #67656 - almost the same email address are considrered identical (Siva)
+ #61966 - Typo in string: Word "be" missing (Andre Klapper)
+ #69079 - Data repeated after save with bad date format (Siva)
+ #66854 - Some strings are missed to translation (partial, Rodney)
+
+ * Mail
+
+ #68787 - Crash when migrating 1.4 data to 2.0.2 (Michael)
+ #69109 - EHLO or HELO with ip addresses does not conform rfc 821 (Michael)
+ #69408 - Evolution hang in message fetching with ima4rev1 (Jeff)
+ #69145 - toplevel message/rfc822 parts are broken for IMAP (Michael)
+ #69241 - base64 attachement holding PGP block (Jeff)
+ #69160 - IMAP4 dont freez on scaning imap folders (Jeff)
+ #67496 - html email not rendered in preview pane (Michael)
+
+ * Calendar
+
+ #68624 - Requires URL to have http:// or webcal:// at beginning (Diego Sevilla Ruiz)
+ #47529 - Date in reminder window appears in UTF-8 in non-UTF-8 locale (Rodney)
+ #6767 - Fix hardcode colors in day, week, month views (Li Yuan)
+ #68707 - Events ending at 12:00 AM show as ending at 12:00 pm (JP)
+
+ * Shell
+
+ #61065 - Evolution should be spelled with uppercase E in evolution message (Joan Sanfeliu)
+
+Other bugs
+
+ * Address Book
+
+ - Handle required fields (Siva)
+ - a11y fixes (Hao Sheng)
+ - make shift-F10 popup menu (Hao Sheng)
+ - don't show error dialog when cancelling operation (Siva)
+
+ * Mail
+
+ - Reduce memory for vfolder operations (Michael)
+ - Use unix sockets for spam checking (Radek)
+
+ * Calendar
+
+ - warn is summary is blank (Chen)
+ - allow creating new calendar with right click on a group (Harish)
+ - EConfigize new calendar and calendar properties (David Trowbridge)
+ - make sure switch between 12/24h time shows immediately (JP)
+
+ * Plugins
+
+ - set "base" plugin target (Michael)
+ - add webcal config plugin (David Trowbridge)
+ - mailing list actions plugin (Meilof Venningen)
+ - plugin manager plugin (Michael)
+
+Updated translations:
+
+ - da (Martin Willemoes Hansen)
+ - lt (Žygimantas BeruÄÂka)
+ - nl (Vincent van Adrighem)
+ - de (Hendrik Richter)
+ - it (Marco Ciampa)
+ - ca (Jordi Mallach)
+ - fa (Meelad Zakaria)
+ - sq (Laurent Dhima)
+ - fr (Sebastien Bacher)
+ - cs (Juraj Kubelka)
+
+Evolution 2.1.0, 2004-11-01
+----------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
+
+ * Addressbook
+
+ #61069 - Missing space in evolution addressbook message (Andre Klapper)
+ #61972 - Typo in country name: Is "Grena-dines", should be "Grenadines" (Andre Klapper)
+
+ * Mail
+
+ #68894 - IMAP4 rev1, error on selecting INBOX (Jeff)
+ #68814 - evo crash while fetching mail using IMAP4 rev1 (Jeff)
+ #44876 - Missing keyboard navigation in the e-mail recipient section (Mengjie Yu)
+
+Other bugs
+
+ * Address Book
+
+ - Display multi value attributes in the preview (Nat)
+
+ * Mail
+
+ - Enable IMAP4 camel provider by default (Jeff)
+ - IMAP4 offline folder info caching (Jeff)
+
+ * Calendar
+
+ - a11y fixes (Li Yuan)
+ - make free/busy information gathering more efficient (Harish)
+
+ * Shell
+
+ - remove deprecated calls (Kjartan Maraas)
+
+ * Plugins
+
+ - convert mail, address book to econfig (Zucchi)
+ - convert all components to e-menu (Zucchi)
+ - add new mail event (Zucchi)
+ - add message replied event (Nat/Zucchi)
+ - add online/offline event (Zucchi)
+ - inline audio via gstreamer (Radek)
+ - big brother database (Nat)
+ - copy address tool (Zucchi)
+ - folder unsubscribe (Jeff)
+ - mail to task (Rodrigo)
+ - mark calendar for offline (Harish)
+ - prefer plain text for messages (Zucchi)
+ - save attachments (Zucchi)
+ - save calendar (Rodrigo)
+ - select one calendar/task (JP)
+ - subject threading (JP/Zucchi)
+
+Updated translations:
+
+ - da (Martin Willemoes Hansen)
+ - it (Marco Ciampa)
+ - sq (Laurent Dhima)
+ - el (Nikos Charonitakis)
+ - ms (Hasbullah Bin Pit)
+ - bg (Vladimir Petkov)
+
+Evolution 2.0.2, 2004-10-11
+----------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
+
+ * Addressbook
+
+ #66520 - Crash deleting addressbooks (Michael)
+ #66369 - VCard import requires blank lines between contacts (Hans)
+ #65537 - Updating Contacts Causes Crash (Hans)
+
+ * Calendar
+
+ #65932 - Crash when accessing the details of an appointment notification (Rodrigo)
+ #64683 - meeting invite expands to larger than workspace (Rodrigo and JP)
+ #66736 - crash clicking Search Clear button twice (Michael)
+ #61766 - select personal calendar/tasks by default when migrating (JP)
+ #65599 - 'Evolution 1.5' crash in 'Free/Busy' editor (Rodrigo)
+ #62053 - select GroupWise calendar by default (Siva)
+ #66164 - popup date edit drop down in correct place (JP)
+ #45951 - Scroll properly in task description (Rodrigo)
+
+ * Mail
+
+ #67170 - Unable to subscribe to the alt hierarchy (Michael)
+ #67028 - 2.0.1 compilation fails on camel-service.c: In function `camel_getaddrinfo' (Jeff)
+ #67257 - evolution busy waits looking up hostname if network down (Michael)
+ #66509 - Evolution Crashes when deleteing a news group (Michael)
+ #65828 - Fix typo in error message (Jeff)
+ #63881 - "Cannot copy or move messages into a Virtual Folder" when
+ dragging from UNMATCHED vfolder into real folder (Ed Catmur)
+ #63521 - stale / bogus pop cache file (Michael)
+ #66991 - crash creating folders (Michael)
+ #66706 - Evolution Crashes while refreshing Folder Subscriptions (Michael)
+ #67408 - Seg Fault on exit (Michael)
+ #67211 - Evolution crashes when getting summary from folder (Michael)
+ #66703 - S/MIME signing fails randomly (Jeff)
+
+ * Shell
+
+ #61285 - use better query for config pages (Michael)
+ #66216 - don't show translator-credits directly in about box (Malcolm Treddinnick)
+
+Other bugs
+
+ * Address Book
+
+ - Crash when exiting (Hans)
+
+ * Mail
+
+ - Provide error dialogs if host/name lookups fail (Jeff)
+ - Improve NNTP locking (Michael)
+ - Work with complete MBox hierarchy (Michael)
+ - Forward as inline sends attachments (Michael)
+ - Fix possible migration bug from 1.2 (Dave Malcolm)
+
+ * Other
+
+ - Updated documentation (Rodney and Novell Doc Team)
+ - Don't dereference NULL nickname or emailAddr on certificate (Michael)
+
+Updated translations:
+
+ - el (ta panta rei, Nikos Charonitakis)
+ - ja (Takeshi AIHANA)
+ - hu (Laszlo Dvornik)
+ - pt (Duarte Loreto)
+ - sq (Laurent Dhima)
+ - es (Francisco Javier F. Serrador)
+ - nl (Vincent van Adrighem, Michel Klijmij)
+ - en_CA (Adam Weinberger)
+ - zh_CN (Funda Wang)
+ - cs (Miloslav Trmac)
+ - pl (GNOME PL Team)
+ - pt_BR (Raphael Higino)
+ - sr (Danilo Segan)
+ - sr@Latn (Danilo Segan)
+ - en_GB (David Lodge)
+ - ca (Xavier Conde Rueda)
+ - ko (Changwoo Ryu)
+ - ro (Mugurel Tudor)
+ - fr (Christophe Merlet)
+ - nb (Kjartan Maraas)
+ - no (Kjartan Maraas)
+ - da (Martin Willemoes Hansen)
+ - ru (Leonid Kanter)
+ - fa (Meelad Zakaria)
+
+Evolution 2.0.1, 2004-09-24
+----------------------------
+
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
+
+ * Addressbook
+
+ #61070 - Fix improper grammar (hannah rebekah & fazlu huq)
+ #59725 - Conduit syncing to wrong desktop record (JP)
+ #63191 - Fix contact list editor title (JP)
+ #64080 - addressbook gui component needs to be linked with libcamel (Michael)
+ #64024 - Lower pane doesn't go away when you uncheck "Preview Pane" in Contacts (Siva)
+ #64011 - Remove C99-ism (Vicent Noel)
+ #62856 - in --offline mode, still get prompted for gw addressbook password, work around (Michael)
+
+ * Calendar
+
+ #66344 - Evolution crashes added start time column to tasks (JP)
+ #63513 - G/W appointment acceptance fails ('invalid object') (Chen)
+ #60904 - Show all appointments when work week longer than 5 days (JP)
+ #66158 - Completion status is not displayed immediately (JP)
+ #59194 - Crash editing location field in event list (JP)
+ #65682 - get error deleting appointments (Chen)
+ #55172 - sync montly recurrences properly (JP)
+ #62374 - alarms no function if run over night (Rodrigo)
+ #62728 - week day heading in month view does not update after changing week start day in settings (JP)
+ #62392 - Crash on close alarm notification (Rodrigo)
+
+ * Mail
+
+ #65329 - translate standar folder names (Michael)
+ #65058 - Specific mails don't display picture but picture data (Michael)
+ #64972 - signature auto-selection in composer with Maildir account is broken (Michael)
+ #65448 - Opening a mail does not mark it read (Jeff)
+ #64974 - Allow selecting of file or folder for maildir and mh accounts (Jeff)
+ #65703 - Display reply to all icon (JP)
+ #59717 - crash checking supported authentication types (Michael)
+ #47821 - try all host names available when connecting (Michael)
+ #66199 - Image loading fails with authenticated proxy (Michael)
+ #64023 - Forget NNTP password if it was wrong (Michael)
+ #64092 - Ambiguity in nomenclature of GW Tasks in Evolution (Siva)
+
+ * Shell
+
+ #61285 - use better query for config pages (Michael)
+ #66216 - don't show translator-credits directly in about box (Malcolm Treddinnick)
+
+Other bugs
* Addressbook
- #17336 -- Evolution mixes up First and Last names sometimes.
- (Toshok)
- #27521 -- Crash: exiting from evolution after adding to address
- book. (Toshok)
- #28165 -- Contacts crashed when selecting offline IMAP folders.
- (Toshok)
- #28392 -- Crash when adding a new contact. (Toshok)
- #30208 -- LDAP authentication issues. (Toshok)
- #30481 -- Select contacts dialog not using default contact folder.
- (Toshok)
- #30483 -- LDAP folders do not work as an autocompletion folder.
- (Toshok)
- #31321 -- Missing VERSION property in exported vCards. (Toshok)
- #31434 -- Only sends email to first three addresses on contact
- list. (Toshok)
- #29171 -- Crash after selecting other user's folder for Offline.
- (Toshok)
- #30250 -- Addressbook crashes or hangs after selecting LDAP
- folder. (Toshok)
+ - point to correct documentation file (Rodney)
+ - check for LABEL supported (Siva)
* Calendar
- #14111 -- Gives "are you sure you want to" prompt when no such
- action has occurred. (JP)
- #15710 -- Automatically-created reminder always says "Untitled
- Appointment". (Rodrigo)
- #15892 -- Running out of disk space can cause loss of calender
- entries and tasks. (Rodrigo)
- #18162 -- Double-click on calendar week/month view shouldn't do
- all-day event. (JP)
- #19159 -- evolution-alarm-notify crash. (Rodrigo)
- #24210 -- Calendar is slow. (Rodrigo)
- #27961 -- vcalendar LAST-MODIFIED field not updated on change.
- (Rodrigo)
- #28310 -- Calendar re-runs alarms. (Rodrigo)
- #28853 -- Crash when deleting tasks in task editor. (Mike)
- #29983 -- New appointments use 25 hour day. (JP)
- #30057 -- Calendar GUI does not allow for read-only folders.
- (Rodrigo)
- #30290 -- Importer Not Ready when importing .ics Ical file.
- (Rodrigo)
- #30381 -- Calendar recurrences "off-by-one". (JP)
- #31774 -- Reselecting options for remider crashes calendar.
- (Rodrigo)
-
- * Conduits
-
- #21631 -- Palm calendar event with no time should appear as "All
- day event". (JP)
- #23763 -- Problem with appointments that cross a day boundary and
- pilot sync. (JP)
+ - Don't allow deletion of system calendar or tasks (JP)
+ - Don't allow a task to be changed to an assigned task if the backend doesn't support it (Chen)
* Mail
- #236 -- Composer attachment bar wraps lines annoyingly. (Ettore)
- #4224 -- camel-imap-cache needs better error checking. (Jeff)
- #20849 -- Folder Properties should be on right click menu.
- (Michael)
- #21027 -- Accept broken content-ids. (Jeff)
- #22496 -- Evolution does not appear to support ALERT messages.
- (Michael)
- #24179 -- Character set conversion problem under tr_TR
- locale. (Radek)
- #24732 -- Importing mailman mbox files doesn't work. (Ettore)
- #27391 -- New Message Count not updated in vFolders. (Michael)
- #28453 -- Forwarding PGP-signed message inline should discard
- signature. (Jeff)
- #28209 -- Error messages for Offline folder operations
- misleading. (Michael)
- #28834 -- Threaded + hide deleted messes up clear search.
- (Michael)
- #29293 -- Back button on final page of new account doesn't work.
- (Michael)
- #29625 -- Cannot clear a saved search. (Michael)
- #29731 -- Crash in libsoup. (Michael)
- #29808 -- Control-K to mark read broken when preview not shown.
- (Michael)
- #29933 -- Mail component forgets pane size sometimes. (Dan)
- #29965 -- Crash. (Jeff)
- #30183 -- Advanced search broken. (Jeff)
- #30269 -- Crash appending to an mbox that is too large (>2GB).
- (Jeff)
- #30399 -- Vfolders of imap do not update. (Michael)
- #30580 -- Closing drafts message asks to save again. (Jeff)
- #30731 -- "automatically detect links" checkbox doesn't work.
- (Jeff)
- #30827 -- Delete on Deleted Message Does not move to next.
- (Jeff)
- #30877 -- Improper IMAP folder behavior. (Michael)
- #30873 -- Cannot display many mails in zh_CN.GB2312. (Jeff)
- #30876 -- Drag and drop a mail from Trash duplicates it. (Jeff)
- #30915 -- Crash when upgrading from 1.0.x to 1.1.1. (Jeff)
- #31000 -- evolution-mail random core dumps. (Michael)
- #31031 -- Random crashes -- possible memory corruption bug on
- SMP box. (Michael)
- #31060 -- Advanced Search no longer works. (Michael)
- #31087 -- Mailing list filters fail for yahoogroups.com. (Michael)
- #31331 -- Crash upon opening a mail message. (Michael)
- #31365 -- Enter password dialog not displaying extended ASCII
- chars correctly. (Michael)
- #31379 -- Can't see encrypted mail to myself (and maybe others?)
- (Jeff)
- #31456 -- Evolution does not see IMAP mailboxes. (Jeff)
- #31547 -- Quote the decrypted text when replying to encrypted
- messages. (Jeff)
- #31553 -- Next button disabled in Identity window of setup
- assistant. (Jeff)
- #31554 -- Cannot run evolution if Reply-to: is set to an invalid
- address. (Jeff)
- #31555 -- Account editor mangling reply-to: extended ASCII
- characters. (Jeff)
- #31559 -- Evolution crashes when going to Tools -> Preferences.
- (Jeff)
- #31655 -- Do not strip 8bit characters from text attachments.
- (Jeff)
- #31681 -- Mail filter problem in 1.1.1.99. (Jeff)
- #31693 -- Try harder to pick the correct From-account to use
- when replying. (Jeff)
- #31572 -- valgrind detects a deadlock. (Michael)
- #31752 -- No EHLO to re-check AUTH capabilities after a STARTTLS
- has been issued. (Jeff)
+ - Fix typo setting the root node in folder tree (Dave Malcolm)
+ - Handle 0 length token read for summary (Michael)
+ - Make SSL connections async and cancellable (Michael)
- * Shell
+Updated translations:
+ - fr (Christophe Merlet, Craig Jeffares)
+ - pl (Artur Flinta)
+ - sq (Laurent Dhima)
+ - cs (Miloslav Trmac)
+ - es (Francisco Javier F. Serrador)
+ - nl (Vincent van Adrighem)
+ - zh_CN (Funda Wang)
+ - en_CA (Adam Weinberger)
+ - it (Craig Jeffares)
+ - zh_TW (Craig Jeffares)
+ - en_GB (Gareth Owen)
+ - fa (Roozbeh Pournader)
+ - el (Nikos Charonitakis)
+ - ja (Takeshi AIHANA)
+ - pt_BR (Raphael Higino)
+ - da (Martin Willemoes Hansen)
+ - ko (Changwoo Ryu)
+ - nn (Åsmund Skjæveland)
+ - sr (Danilo Segan)
+ - hu (Laszlo Dvornik)
+ - bs Danilo Segan
+ - id (Mohammad DAMT)
+ - nb (Sigurd Gartmann)
+ - no (Sigurd Gartmann)
+ - ar (Arafat Medini))
- #11645 -- Shortcuts are not updated when a folder is moved.
- (Ettore)
- #14019 -- Cannot access the conduit settings directly from
- Evolution. (Ettore)
- #16556 -- Start-up wizard doesn't propmpt for IMAP password.
- (Ettore)
- #19899 -- First-run code uses free() instead of g_free().
- (Ettore)
- #24062 -- When removing a folder with unread messages, sometimes
- its parent folder stays highlighted even when it
- shouldn't be. (Ettore)
- #27662 -- Unread count in shortcut bar doesn't update properly.
- (Ettore)
- #27855 -- Send/Receive should be disabled when offline.
- (Ettore)
- #24879 -- Crash on folder change. (Mike)
- #28232 -- Default type for the folder creation dialog is
- sometimes "Contacts" instead of "mail". (Ettore)
- #28317 -- File->Close doesn't work. (Ettore)
- #28451 -- Renaming causes incorrect sorting in the folder tree.
- (Ettore)
- #28495 -- Settings dialog resizes when you switch pages.
- (Ettore)
- #28591 -- Crash on startup w/ connector installed. (Mike)
- #29293 -- Back button on final page of new account doesn't work.
- (Michael)
- #30248 -- Folder selection dialog crash. (Mike)
- #30533 -- The folder creation dialog changes the parent folder
- selection if you specify a name that already exists.
- (Ettore)
- #31360 -- Crash when using the folder selection button. (Dan)
- #31690 -- Importer crash. (Ettore)
+Evolution 2.0.0, 2004-09-13
+----------------------------
- * Summary
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
- #15101 -- "My Weather" section shows up when it shouldn't.
- (Ettore)
- #20737 -- Israel missing from the weather station list.
- (Sam Popper)
- #28481 -- Crash during start-up. (Ettore)
- #28903 -- Unread message counts not reported correctly.
- (Ettore)
+ * Addressbook
-Other fixes:
+ #59582 - Contact incompletely updated to LDAP store, address information lost/not editable (Siva)
+ #64084 - addressbook gui component needs to be linked with libcamel (Michael)
+
+ * Calendar
+
+ #65454 - Evolution crashes while opening newly received e-mail (JP)
+ #62392 - Crash on close alarm notification (Rodrigo)
+ #64800 - broken timezone selector (Rodney)
+
+ * Mail
+
+ #60515 - signature setting is not preserved changing "Autogenerated" to "None" (Michael)
+ #63377 - Crash when replying to a (specific) message (Jeff)
+ #62665 - Wrong Folder is deleted (Jeff)
+ #64377 - crash creating new folder (Michael)
+ #63456 - crash replying to E-mail (Michael)
+
+Other bugs
* Addressbook
- - Fixed some memory leaks. (Toshok)
+ - Confirmation dialog was showing up on contact-editor close,
+ even if there were no changes (Hans Petter)
* Calendar
- - Do not allow empty attendee addresses for meetings. (JP)
- - Better alarm daemon activation. (Rodrigo)
- - Notification of calendar query errors. (Rodrigo)
- - Added status messages for all operations. (Rodrigo)
+ - 64 bit build fix (Rodrigo)
+
+ * Misc
+
+ - new documentation (Rodney)
- * Conduits
+Updated translations:
- - Fixed linking issues. (JP)
+ - ar (Arafat Medini)
+ - bn (Runa Bhattacharjee)
+ - cs (Miloslav Trmac)
+ - cy (Dafydd Harries, Telsa Gwynne)
+ - da (Martin Willemoes Hansen)
+ - de (Hendrik Richter)
+ - el (Nikos Charonitakis)
+ - en_CA (Adam Weinberger)
+ - en_GB (David Lodge)
+ - es (Francisco Javier F. Serrador)
+ - et (Priit Laes)
+ - fi (Ilkka Tuohela)
+ - hi (Rajesh Ranjan)
+ - hu (Laszlo Dvornik)
+ - id (Mohammad DAMT)
+ - ja (Takeshi AIHANA)
+ - ko (Changwoo Ryu)
+ - ms (Hasbullah Bin Pit)
+ - nb (Sigurd Gartmann)
+ - nl (Vincent van Adrighem)
+ - nn (Åsmund Skjæveland)
+ - no (Kjartan Maraas)
+ - pl (Artur Flinta)
+ - pt (Duarte Loreto)
+ - pt_BR (Raphael Higino)
+ - ro (Mugurel Tudor)
+ - ru (Leonid Kanter)
+ - sq (Laurent Dhima)
+ - sr (Danilo Segan)
+ - sv (Christian Rose)
+ - tr (Baris Cicek)
+ - uk (Maxim Dziumanenko)
+ - zh_CN (Funda Wang)
+ - zh_TW (Abel Cheung)
- * Shell
+Evolution 1.5.94, 2004-08-27
+----------------------------
- - Some strings that were not translated properly before now are.
- (Kjartan Maraas)
- - Sensitivity problem when using the folder selector. (Toshok)
- - Changed the way shared folders work with Connector. (Dan)
- - Allow accessing local folders even if some folders with
- unknown/corrupted metadata type are found in ~/evolution/local.
- (Ettore)
- - Importer dialog browse entry now has history dropdown. (Rodrigo)
- - We no longer allow selecting a folder of a non-allowed type with
- a double-click in the folder selection dialog. (Dan)
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
-Updated translations:
+ * Addressbook
+
+ #61833 - Blank names in name selector (Hans Petter)
+ #62715 - Free-form addresses not loading in contact editor (Hans Petter)
- - ko (Young-Ho Cha, Changwoo Ryu)
- - nn (Roy-Magne Mo)
- - no (Kjartan Maraas)
- - pl (Zbigniew Chyla)
- - vi (Pablo Saratxaga)
- - tr (Gorkem)
+ * Calendar
+ #62869 - Crash: attempt to access GW tasks from evolution (Siva)
+ #62706 - Changing time-zone doesn't refresh calendar correctly (JP)
+ #62063 - Meeting description does not wrap (Jeff)
+ #58824 - Stray message or failing to open tasks? (Rodrigo)
+ #62911 - ITIP control blocks mailer opening calendar (JP)
+ #54101 - In itip control had "Birthdays & Anniversaries" as calendar (JP)
+
+ * Mail
+
+ #63189 - Deleting IMAP folders is too aggressive (Michael)
+ #63504 - Don't send IMAP commands to a disconnected socket (Jeff)
+ #63177 - Can't drag folder to "On This Computer" (Jeff)
+ #62812 - Crash when parent of search window is closed (Jeff)
+ #62963 - C99-isms in smime/gui/cert-trust-dialog.c (Michael)
+
+Other bugs
+
+ * Addressbook
+
+ - Confirmation dialog was showing up on contact-editor close,
+ even if there were no changes (Hans Petter)
+
+ * Calendar
-Evolution 1.1.1, 2002-09-09
+ - Fixed problems in alarm daemon (JP, Siva, Rodrigo)
+ - Clean up of stray status messages for tasks (Chen)
+ - Don't remove GtkDialog's separator if using GTK >= 2.4.0 (Frederic)
+ - Fix copy/move problems when pilot syncing (JP)
+ - Don't mark menu accels for translation (Christian)
+
+ * Mail
+
+ - Crash in em-utils on GtkFileChooser with no name selected (Hans Petter)
+
+ * Misc
+
+ - avoid warnings on dialogs with GTK 2.4 (Frederic)
+ - upgrade egg tray icon (Rodrigo)
+ - fix memory corruption when pilot syncing tasks/events (JP)
+
+
+Evolution 1.4.1, 2003-06-25
---------------------------
-New features:
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
+
+ * Addressbook
+
+ #41826 - Focus the first minicard when focusing the view for the
+ first time (gilbert.fang@sun.com)
+ #43841 - Contact editor will not save Web Page address (Toshok)
+ #44477 - Make sure the master category list is upgraded (Toshok)
+
+ * Calendar
+
+ #41582 - Display incorrect after switching between week and day
+ view (Rodrigo)
+ #43585 - Ugly tasks printout (Hans Petter)
+ #45273 - Tab through events in day view (Bolian Yin)
+ #45275 - Shift+F10 to activate Popup menu in ToDo List (Bolian Yin)
+ #45423 - Provide shortcus for "Go to today" and "Go to date" (Bolian Yin)
+
+ * Mail
+
+ #22542 - Creating a folder in the vFolder store fails with a
+ meaningless message (Michael)
+ #31745 - Cannot view mails under '#mh' namespace. Temporary
+ workaround, strip #'s (Michael)
+ #33593 - Message remains displayed after last message removed from
+ list (Michael)
+ #40788 - Broken POP3 server causing evolution to hang/crash (Jeff)
+ #42630 - collapsed thread always shows as unread (Jeff)
+ #43917 - ECharsetPicker doesn't save user-specified charset strings
+ properly (Jeff)
+ #43972 - Invert selection doesn't work (Jeff)
+ #43974 - Cannot retrieve "Local Delivery" mail (Michael)
+ #44121 - Invalid multipart/signed message showing empty (Michael)
+ #44139 - Composer spacing is not HIG compliant (Jeff)
+ #44322 - Evolution crash with weird IMAP foldername (Michael)
+ #44344 - Dont use quoted-printable encoding on anything but text/*
+ parts, interoperation with Lookout and others (Jeff)
+ #44457 - Crash viewing video content as inline-text (Jeff)
+ #44519 - Popup message view redraws when new mail arrives (Michael)
+ #44609 - HIG issue with vFolder properties editor (Michael)
+ #44991 - Cannot send mail in GB-2312 (Jeff)
+ #45082 - GB18030 BIG5HKSCS and EUC-TW charsets not supported in
+ evolution mail (suresh.chandrasekharan@sun.com)
+ #45063 - Message display refreshes when new mail arrives,
+ introducted by #33593 (Michael)
+ #45386 - Warnings when sending mail (Michael)
+ #45368 - Crash when closing the folder browser
+
+ * Summary
- * General
+ #44111 - Crash on exit (Ettore)
+ #44798 - Crash when closing print preview dialog (Ettore)
- - The toolbar now includes a "New" dropdown menu/button from which
- you can create messages, appointments, etc. from within any
- folder.
+ * All
- - A new, integrated configuration dialog for all of Evolution is
- now provided.
+ #42691 - Build, make clean doesn't rebuild bonobo-activation
+ .server files (Michael)
+ #44717 - Tarball cointains generated files (Frederic Crozat)
- - When you use the folder selection dialog, you can now jump to a
- folder just by typing its name and hitting Enter (instead of
- using the arrows or the mouse).
+Other bugs
- - You can now specify your default mail, calendar, tasks and
- contacts folders. The shortcuts in the shortcut bar will always
- point to the default folder; so for example if you have an IMAP
- account you can specify that the INBOX on the IMAP account is
- default and clicking on the Inbox icon on the shortcut bar will
- take you to the INBOX on the IMAP account.
+ * Calendar
- - Fonts for displaying of HTML mail can now be configured from
- within Evolution (instead of having to use GNOME Control
- Center).
+ - Fix invalid shared use of list of calendar factories (Rodrigo)
+ - Make the calendar editor window title reflect the summary contents (Rodrigo)
- - You can now make Evolution play a sound, beep, or display a
- message when new mail arrives. It is also possible to trigger
- these actions based on a filter rule.
+ * Mail
- - The behavior of the search bar has been improved, and the UI has
- been integrated better with the menu bar and the rest of the
- system.
+ - Fix bug in indexer string normalisation (they weren't) (Larry)
+ - Major memory leak in message-threading (Larry)
+ - Only try to snoop a content-type if its application/octet-stream
+ when displaying mail parts (Jeff)
+ - Major memory leak in filter-file based filters (Jeff)
+ - Try to make asynchronous dns lookup more asynchronously
+ cancellable (Michael)
+ - Fix a degenerate algorithm case in vFolder shutdown which could
+ cause excessive exit cpu usage (Michael)
+
+ * Shell
- - For the table-based views, you can now define, save and reuse
- view settings using the "View" menu.
+ - Wrong version number used for configuration upgrade (Michael)
+
+ * All
+
+ - Lots of miscellaneous memory leaks
+
+Updated translations:
- - The Send/Receive button is now always accessible from any
- folder.
+ - cs (Miloslav Trmac, Stanislav Brabec)
+ - el (Kostas Papadimas)
+ - es (Francisco Javier F. Serrador)
+ - hu (Andras Timar)
+ - it (Marco Ciampa)
+ - ko (Kan Jeong-Hee)
+ - mk (Ivan Stojmirov)
+ - nl (Vincent van Adrighem)
+ - pt_BR (Gustavo Maciel Dias Vieira)
+ - sr, sr@Latn (prevod.org)
+ - sv (Christian Rose)
+ - tr (Gorkem Cetin)
+ - zh_CN (Wang Li, Funda Wang)
- - Easier to build on non-GNU, and non-GCC systems (e.g. MacOS/X,
- HP/UX, Solaris).
- - Now installs some libraries and headers required for external
- module development.
+Evolution 1.4, 2003-06-02
+-------------------------
- - You now can drop objects (eg. mail messages, appointments)
- directly to the folders on the shortcut bar (in 1.0.x, you could
- only drop them in the folder folder bar).
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
* Calendar
+
+ #43388 - Problems importing appointments (Rodrigo)
+ #43455 - Crash on exit (Rodrigo)
+ #43763 - 2 right mouse menus appear in Week & Month views (Rodrigo)
+ #43775 - Crash under Chinese locale (JP)
- - Loading speed has been improved.
+ * Mail
+
+ #42854 - Copying files from one IMAP folder to another makes
+ multiple copies of file (Jeff)
+ #43862 - First run imap account won't load folders until account
+ is disabled and re-enabled (Jeff, Michael)
+ #42691 - Server files not regenerated after distclean (Michael)
+ #43805 - Evolution locked while editing reply to an mail (Jeff)
+ #43410 - Flag for Followup dialog opens up too small in Evo (Michael)
+ #43688 - Can't save signatures (Michael)
+
+ * Summary
- - When you receive an appointment through email, you can choose
- which calendar to update, and if its for an existing appointment
- the folder is automatically detected
+ #43506 - Spontaneous crash (Ettore)
- - Calendar importer now supports importing to remote folders.
+ * Misc
- - Calendar GUI and alarm daemon now use listeners for the
- configuration.
+ #43596 - Symlink icon file so it doesn't break existing panel
+ setups (Ettore)
- - Reaction to calendar backends crashing has been improved.
+Other bugs fixed:
- - Show status messages for all long calendar operations.
+ * Addressbook
- - Fixed default reminders description (was 'Untitled
- appointment').
+ - Removed conflicting shortcut for the Print Preview menu item
+ (Rodney)
- - Included timezone information on VCALENDAR's used in copy/paste.
+ * Misc
- - Removed extra space that was displayed for categories without
- icons.
+ - Corrected some problems in the pkgconfig files (Rodney)
+ - Fixed an issue with GConf schema file installation (Joe Marcus
+ Clarke)
- - Fixed crashes in the alarm daemon.
+Updated translations:
- - Fixed crashes in calendar related to creating new evolution
- windows.
+ - nl (Vincent van Adrighem)
+ - ru (GNOME Russian Team)
+ - be (GNOME Belarusian Team)
+ - es (Francisco Javier F. Serrador)
- - When right clicking, correctly select the underlying date/time.
- - Meeting scheduling improvements; sends replies when you update
- your attendance status, warnings if the user changes a meeting
- they didn't create.
+Evolution 1.3.92, 2003-05-22
+----------------------------
- - Deleting a meeting with a right click will now offer to send a
- cancellation notice.
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
- - Can accept meeting replies from non-attendees (they become
- attendees).
+ * Addressbook
- - Fixed work day so start can't be before end, its minimum 1 hour
- and the unshaded zone is not rounded to the nearest time
- division (allowing the work hours to be 0:00 to 23:59).
+ #38084 - Rename local folder issue in contacts (sean.gao@sun.com)
+ #41130 - HIG compliance (Anna)
+ #41137 - HIG compliance (Anna)
+ #41140 - HIG compliance (Anna)
+ #41144 - Use stock buttons in the ldap config page (Toshok)
+ #41211 - Add icon to "Add" button in "Add to Contacts" dialog (Toshok)
+ #41229 - HIG compliance (Anna)
+ #41231 - HIG compliance (Anna)
+ #41232 - HIG compliance (Anna)
+ #41245 - HIG compliance (Toshok)
+ #41248 - HIG compliance (Anna)
+ #41249 - HIG compliance (Anna)
+ #41250 - HIG compliance (Anna)
+ #41251 - HIG compliance (Anna)
+ #41254 - HIG compliance (Anna)
+ #41255 - Use stock Add/Remove icons in the contact list editor (Toshok)
+ #41910 - Crash when deleting addresses from long contact lists (Toshok)
+ #42048 - "Print" not hooked up in etable view (Toshok)
+ #42177 - Cannot tab out of date edit widgets in contact editor (Toshok)
+ #42472 - Selecting a field in a contact highlights entire row (Toshok)
+ #42596 - Selecting text in a contact address field selects all
+ rows of text (Toshok)
+ #42604 - Display not shifted when cursor moved to next address
+ line (Toshok)
+ #42606 - Not saving information entered in Notes field of Contact
+ editor (Toshok)
+ #42620 - Crash related to mailing address checkbox (Toshok)
+ #42625 - Clicking in white space of contact brings up empty
+ contact editor (Toshok)
+ #42780 - Crash on solaris due to missing NULL in g_guild_filename.
+ (sean.gao@sun.com)
+ #42825 - clicking on letters in LDAP address card view does not
+ load selected letter (Dan, Toshok)
+ #43005 - Crash on reply (Toshok)
+ #43016 - Crash when adding duplicate contact (Toshok)
+ #43023 - All contacts have disappeared (Toshok)
+ #43090 - GalView menu missing from the addressbook (Toshok)
+ #43175 - Evolution crashed pasting large amount of text into
+ address field (Toshok)
+ #43213 - auto-completion folder list wasn't populated correctly on
+ fresh install (Toshok)
- - Fixed task view to update completion status the same as the
- editor.
+ * Calendar
- - Fixed leap year problem with day of week.
-
- - Handle "last day of the month" and "last Tuesday of the month"
- type recurrences.
+ #40972 - connector crashed while evolution was idle (Rodrigo)
+ #41234 - button order of "Enter Delegate" dialog (Rodrigo)
+ #41329 - Changing Options in scheduling tab causes display time to shift
+ #41579 - Double clicked on meeting in Exchange calendar, Evo
+ crashed (Rodrigo)
+ #41760 - Alarm dialog does not reappear after snoozing Exchange
+ alarm (Rodrigo)
+ #41811 - Calendar update failing and crashing (JP)
+ #41930 - Warning while running gdb includes: "Some clown returned
+ undeclared exception" (JP)
+ #41935 - day view ignores scroll wheel (JP)
+ #42056 - Accelerators in meeting selector not working/looks bad
+ (Hans Petter)
+ #42220 - calendar not refreshing correctly after changing meeting
+ times (Rodrigo)
+ #43029 - When running under valgrind Evolution crashed while
+ exiting (JP)
+ #43308 - scheduling page alignment (JP)
- * Contacts
+ * Mail
- - It is now possible to specify which folders are used for
- autocompletion globally.
+ #40074 - Thread expansion state not remembered (Jeff)
+ #41748 - Send/Recv not sending mail in connector Outbox (Michael)
+ #42000 - Crash selecting a non-selectable folder (Michael)
+ #42045 - Another workaround for mailers sending out invalid date
+ formats (Jeff)
+ #42118 - Edit->Mark as unread doesn't behave the same as right
+ click->mark as unread (Jeff)
+ #42170 - Thread expansion state lost on deleting messages (Jeff)
+ #42212 - Crash entering address in composer (Rodrigo)
+ #42294 - Custom fixed font setting not applying to composer
+ (Michael)
+ #42333 - Crash opening a mail again that was still being opened
+ (Jeff)
+ #42356 - Adding colour from not working properly (Jeff)
+ #42456 - Spelling preferences Enable/Disable button inconsisency
+ (Michael)
+ #42540 - Crash when pressing send/recv too quickly (Michael)
+ #42710 - Invalid 8 bit header data getting to the UI layer
+ generating warnings (Michael)
+ #42763 - Crash deleting local folder with indexing turned off
+ (Jeff)
+ #42838 - Crash setting up local mail account (Michael)
+ #42854 - Copying many messages between IMAP folders results in
+ several duplicates (Jeff)
+ #43214 - changing server settings enables the account (Jeff)
+ #43234 - crash reading mail (Michael)
+ #42748 - Check spelling while I type - broken (Larry)
+ #42749 - Composer ignores color for misspelled words (Larry)
+ #43392 - Reproducible crash after searching mail w/ attachment and
+ closing (Jeff)
+ #43406 - Evo crashed during POP download/filtering (Jeff)
- - Improved address selection dialog (for sending mail and meeting
- requests).
+ * Shell
- - Improved feedback for search results for all backends and the
- UI.
+ #36956 - Window title too long (Ettore)
+ #40391 - Updated contributor list in the about box (Michael)
+ #42038 - Crash hitting escape or closing window on rename box
+ (Michael, Ettore)
+ #42342 - Send/receive sensitive when startedi in offline mode
+ (Ettore)
+ #42465 - Unread count problem in the shortcut bar (Ettore)
+ #42491 - Compilation problems on Forte (Antonio Xu)
+ #42518 - Folder bar selection lost on folder delete (Ettore)
+ #43079 - Don't crash when an invalid "default:" URI is given on
+ the command-line (Ettore)
+ #43119 - Memory corruption problem in settings dialog (Ettore)
+ #43216 - Crash on exit (Ettore)
+ #43322 - Crash on exit (Ettore)
- - SSL/STARTTLS suport for LDAP has been added.
+ * Summary
- - Caches are built for local addressbooks to speed up
- autocompletion.
+ #41131 - HIG compliance (Anna)
+ #41133 - HIG compliance (Anna)
+ #41849 - Charsets not respected in news feed display (Michael)
+ #43101 - Crash on exit (JP)
+ #43117 - Crash on exit (Ettore)
- - Fixed wombat/addressbook crashes dealing with autocompletion, it
- should be much more stable now.
+Other bugs:
- - Categories on LDAP are now stored using a multivalued attribute
- (category) instead of a comma separated list (categories), so
- searches on categories in ldap actually work. The old attribute
- is deprecated and should not be used.
+ * Addressbook
- - Standardized some of the static properties of addressbooks, and
- removed some local addressbook logic from the frontend.
+ - 64bit cleanup and warning fixes (Jeremy Katz)
+ - Fixed some probable memory corruption (Toshok, Sean Gao)
- - When editing contacts from the composer entries (To:, CC:), pop
- up the right kind of editor based on the contact type.
+ * Calendar
- - Much improved LDAP backend responsiveness and performance.
+ - Fixed crash in cal_client_discard_alarm (Rodrigo)
+ - Fixed Bonobo unrefing problems on components (JP)
+ - Fixed multiple initialization in calendar factory (Rodrigo)
* Mail
- - New, much faster indexing engine. This results in faster mail
- incorporation, faster mail display, and faster searches.
- Overall, the new engine should work much better for larger
- folders, and take considerably less space on the disk.
+ - Crash on exit if password dialog was open (Ettore)
+ - Make Ok the default response on the password dialog (Ettore)
+ - Crash in SMTP if unable to resolve the remote host name (Jeff)
+ - Fix an automake 1.6 issues with camel-lock-helper (Dan)
+ - Reload page if citation color changes (Larry)
+ - Made all the composer preferences work (Larry)
+ - Made newly created HTML signatures work again (Radek)
- - Faster POP3 download, using the server's pipeline extensions if
- available.
+ * Shell
- - If you type multiple words in the search bar for the
- "... Contains" rules, Evolution will search messages that
- contain all of the words you specified, in any order.
+ - HIGified config settings dialog a bit more (Anna)
+ - Fixed a bunch of reference count problems (JP)
+ - Improved the look of the "open other user's folder" dialog
+ (Dan)
- - More consistent search results for indexed, non-indexed and
- remote folders.
+ * Summary
- - UTF8 (Unicode) used for all searches, even with IMAP servers.
+ - Fixed a typo that caused the summary to not see the default
+ calendar folder (Ettore)
+ - Made the print dialog close properly (Ettore)
+ - Reference count fixes (JP)
- - It is now possible to mark messages for follow-up and other
- flags. It is also possible to change the color in which a
- specific message is displayed in the mail list.
+ * All
- - When the message list is sorted by a certain field, it is possible
- to jump to the first item in the list that matches a certain
- string by just typing the first few characters.
-
- - Filters are now updated automatically when the destination folder
- gets moved or removed.
+ - Various container referencing issues (JPR)
+ - 64 bit and portability fixups (Jeremy Katz)
+ - Cleaned up lots of compile time warnings and run-time debugging
+ output (everyone)
- - A new filter rule allows you to pipe mail through an external
- process to find out whether or not to filter it.
+Updated translations:
- - You can now specify which folders get synced when switching to
- offline mode.
+ - cs (Miloslav Trmac)
+ - da (Kenneth Rode Christiansen)
+ - de (Christian Neumair)
+ - es (Francisco Javier Fernandez)
+ - fr (Christophe Fergeau)
+ - it (Marco Ciampa)
+ - ja (Takuo Kitame)
+ - no (Kjartan Maraas)
+ - pt (Duarte Loreto)
+ - pt_BR (Gustavo Maciel Das Vieira)
+ - ru (GNOME Russian Team)
+ - sv (Christian Rose, Anders Carlsson)
- - All previously read messages are automatically downloaded for
- offline use.
+ - Fixed encoding of the ca, en_AU, en_CB, et, eu, ro catalogs (Abel
+ Cheung)
- - Offline state is preserved between sessions. Generally, offline
- mode is more stable and complete.
- - STARTTLS support for POP, SMTP and IMAP has been added.
+Evolution 1.3.3, 2003-04-29
+---------------------------
- - IMAP can now handle folder names containing &, -, and UTF-8
- characters.
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
- - You can have all of your mail Auto-Cc:ed or auto-Bcc:ed to a
- specified set of recipients.
+ * Addressbook
- - SMTP error reporting has been improved.
+ #37351 - Contact List drag-n-drop broken from sorted list view (Toshok)
+ #40954 - Wombat crashes when opening an appointment (Toshok)
+ #41843 - Don't use localized field names in the csv exporter (Gilbert Fang)
+ #41779 - Fix crash when adding emails to existing contacts (Toshok)
- - Much improved GnuPG support. Better pgp/mime interoperability.
+ * Calendar
- - Improved support for external Maildir, MH, and mailbox folders,
- and trees of folders. Internally they share more code now and
- are easier to maintain.
+ #21499 - No docs in snaps (Rodney)
+ #22444 - Deleting recurring meetings menu option (Rodrigo)
+ #34498 - alarm-notify not noticing meetings canceled by organizer (Rodrigo)
+ #35814 - same mnemonic for File:New:Mail Message and :Meeting (Rodney)
+ #37552 - GUI doesn't notice Connector failed to delete task (JP)
+ #39735 - Calendar View settings not persistent between sessions (JP)
+ #40257 - selecting day from calendar control causes window resize (JP)
+ #41129, #41215, #41221, #41256, #41148, #41216, #41235 - gui spacing (Rodrigo, Anna)
+ #41230 - forwarded tasks blank when viewed in a separate window (JP)
+ #41458 - Crash sending meeting invite (Dan)
+ #41459 - remove "Delegate to..." from right click menu in meeting dialog (JP)
+ #41641 - crash opening calendar for the first time (Hans)
+ #41661 - Only one popup dialog for repeated message alarm (Rodrigo)
+ #41671 - audio alarms pop up message dialog instead of playing tune (Rodrigo)
- - External mailbox folders can interoperate with pine/mutt/elm
- status flags directly (at slightly performance penalty). See
- options on the "spool" provider.
+ * Mail
- - Many IMAP related bugs fixed. IMAP now passes current folder
- regression tests.
+ #21499 - No docs in snaps (Rodney)
+ #38927 - Signature editor help brings up composer help
+ #40694 - Focus not in To field of new message when From field is
+ visible. (Toshok)
+ #40989 - Deleted sub-folders hang around (Michael)
+ #41043 - Send/receive accelerators broken (Michael)
+ #41142 - Message search dialog has questionable button order (Jeff)
+ #41149 - Spacing/padding of "Filters" dialog (Jeff)
+ #41150 - Use stock buttons in "Filters" dialog (Jeff)
+ #41151 - Spacing/padding of "Add/Edit Filters" window (Jeff)
+ #41152 - Spacing/padding of "Vfolders" dialog (Jeff)
+ #41153 - Use stock buttons in "VFolders" window (Jeff)
+ #41155 - Spacing/padding in "Add/Edit Vfolders" dialog (Jeff)
+ #41156 - Use stock** buttons in "add/edit vfolders" dialog (Jeff)
+ #41163 - Forwarding HTML mail with inline images results in
+ misformatted mail (Michael)
+ #41164 - Can't import mails at all (Michael)
+ #41190 - Crash cursor navigating Inbox (Michael)
+ #41199 - Subscribe dialog's toolbar -- why? :) (Michael)
+ #41205 - Use icons on Add/Edit/Delete buttons in "Search Editor" (Jeff)
+ #41208 - Spacing/padding in "advanced search" dialog (Jeff)
+ #41209 - Spacing/padding of "Create VFolder from Search" dialog (Jeff)
+ #41238 - Crash when opening "attachment properties" (Jeff)
+ #41239 - Spacing/padding of "attachment properties" (Jeff)
+ #41241 - Title capitalisation of "Attachment Properties" (Jeff)
+ #41244 - Spacing/padding of "Reformat Mailbox" dialog (Jeff)
+ #41389 - Crash creating new Exchange acct (Jeff)
+ #41398 - vFolder Sources IMAP folder names not being unencoded
+ correctly (Michael)
+ #41419 - Variable font key has trailing slash (katzj@redhat.com)
+ #41448 - Crash on startup (Michael)
+ #41461 - camel_text_to_html doesn't do as good a job with URLs as
+ e_text_to_html (Jeff)
+ #41513 - Plain text attachments not showing up in the composer (Jeff)
+ #41578 - Up/down buttons broken in vfolder list (Jeff)
+ #41648 - 1.2 -> 1.3 vfolder conversion (Michael)
+ #41730 - Empty "Organization" headers (Jeff)
+ #41789 - Bonobo components can pause/freeze the gui (Jeff)
+ #41972 - Searching on labels is broken (Michael)
+ #42024 - Improper use of Error dialog (Jeff)
- - IMAP body search results are now cached. Vastly improving
- body search vFolder performance with IMAP sources.
+ * Shell
- - Optional IPv6 support.
+ #21499 - Documentation not working in the snapshots (Rodney)
+ #33919 - Crash when opening other user's folder (Dan)
+ #41002 - Default folder bar size too narrow (Ettore)
+ #41008 - HIG compliance (Anna)
+ #41010 - HIG compliance (Anna)
+ #41022 - HIG compliance (Anna)
+ #41024 - HIG compliance (Anna)
+ #41025 - HIG compliance (Anna)
+ #41036 - HIG compliance (Anna)
+ #41059 - Crash connecting to other user's folder (Ettore)
+ #41013 - Startup wizard display problems (Michael)
+ #41128 - HIG compliance (Anna)
+ #41145 - HIG compliance (Anna)
+ #41146 - HIG compliance (Anna)
+ #41147 - HIG compliance (Anna)
+ #41225 - HIG compliance (Anna)
+ #41227 - HIG compliance (Anna)
+ #41242 - HIG compliance (Anna)
+ #41304 - Missing dialog title (Michael)
+ #41392 - HIG compliance (Anna)
+ #41413 - Creating folder needs to make sure parent folder is
+ expanded (Dan)
+ #41468 - New Exchange public folders do not follow type of parent
+ folder (Dan)
+ #41469 - Upgrade routine crashing on Solaris (Jeff)
+ #41484 - Make proxies work (Sanshao Jiang)
+ #41567 - HIG compliance (Anna)
+ #41569 - HIG compliance (Anna)
+ #41648 - Vfolder upgrade problem (Michael)
+ #41916 - Memory corruption in Storage interface (Rodrigo)
- - Progress bar added to subscribe dialogue.
+ * Summary
- - Camel's multithread safe object system streamlined and
- improved. Many other internal cleanups inside Camel.
+ #39693 - Summary weather settings annoyances (Ettore)
+ #40902 - HIG compliance (Ettore)
- - vFolders can now have an additional column which shows the
- original location of the message. Particularly useful for Trash
- folder.
+Other bugs:
- - New messages dont "upset" the thread view as much, if no sorting
- is used.
+ * Addressbook
- - Various vFolder tweaks and fixes.
+ - Mostly, if not completely, fixed 33708 (Dan, Toshok)
+ - Fix duplicate entry in exported CSV (Gilbert Fang)
+ - Use stock buttons (Rodney)
- - Remote inline HTML images are now downloaded incrementally using
- libsoup and are fully cancellable.
+ * Misc
- - Improved quotation display for format=flowed messages.
+ - Made Solaris/CDE integration work again (Rodney)
+ - Removed some debugging spewage (everyone)
+ - Don't crash on malformed GConf folder settings (Toshok)
+ - Don't error out if the directory already exists when creating a
+ new folder (Ettore)
+ - Fixed various memory leaks all over the place (Hans)
- * Mail Composer
+Updated translations:
- - You can now edit a set of signatures within Evolution, and pick
- which signature you want when composing a message.
+ - cs (Miloslav Trmac)
+ - de (Christian Neumair)
+ - es (Francisco Javier Fernandez)
+ - it (Marco Ciampa)
+ - nl (Vincent van Adrighem)
+ - no (Kjartan Maraas)
+ - pt (Duarte Loreto)
+ - sv (Christian Rose)
+ - zh_CN (Wang Jian)
- - Handling of replies has been improved; in particular, you can
- now paste any text as a quotation, and quotation formatting is
- preserved when switching between HTML and non-HTML mode.
- - Evolution can now generate graphical smileys automatically as
- you type.
+Evolution 1.3.2, 2003-04-11
+---------------------------
- - Quotation logic has been improved, rewrapping long lines in
- replies now preserves quotation marks.
+Bugzilla bugs fixed (see http://bugzilla.ximian.com/show_bug.cgi):
- - Multiple simulataneous language support in the spell checker.
+ * Addressbook
+
+ #7103 - Addressbook doesn't play nice with dark themes. (Toshok)
+ #19178 - importers only target default contact folder. (Toshok)
+ #20210 - Cannot save changes when invoked from mailer. (Toshok)
+ #23036 - Export Contact Data to CSV, XLS, etc. (for mail merge,
+ etc.) (Gilbert Fang)
+ #25148 - Selected contacts fields are not scrolling properly.
+ (Toshok)
+ #31786 - LDAP config dialog not properly internationalized.
+ (Toshok)
+ #32113 - Problem with UTF8 and contact list. (Toshok)
+ #34085 - drag+drop not finalizing. (Toshok)
+ #34651 - Searches with 8bit ascii char. not working in Select
+ Contacts. (Toshok)
+ #37204 - Ximian, Inc. contact info update. (Michael)
+ #38202 - Evolution crashed when I clicked the send button. (Michael)
+ #39170 - void function should not has a 'return' keyword. (Philip
+ Zhao)
+ #39256 - "Forward Contact", "Send Message to Contact" don't
+ work. (Michael)
+ #39381 - crash when adding an address from an email to addressbook.
+ (Toshok)
+ #39507 - Select-names search broken. (Toshok)
+ #39730 - Search Base Callback Not Working. (Toshok).
+ #39763 - Pasting text into "To:" field doesn't work. (Toshok)
+ #39788 - Can't add email address to contact. (Toshok)
+ #40026 - Using pulldown to view multiple emails changes email to
+ random characters. (Toshok)
+ #40046 - To: and Cc: fields not accepting accented letters.
+ (Toshok)
+ #40403 - can't edit contact lists. (Toshok)
+ #40715 - Merge email address dialog non functional when adding
+ contact that already exists. . (Toshok)
+ #40727 - email autocompletion not listing all names. (Toshok)
+ #40841 - Ctrl-v was being used for both "Save As VCard" and
+ "Paste". (Toshok)
+ #40901 - HIG-ify the LDAP server editor dialog's button
+ layout. (Toshok)
- - Cut & Paste support for html between netscape/mozilla/evolution.
+ * Calendar
- - Optimized rendering of long messages.
+ #17231 - Private settings not retained. (JP)
+ #31382 - Free/busy retrieval didn't work for http source. (Rodrigo)
+ #31660 - Appointments with "for" recurrence synced with no end date.
+ (JP)
+ #32248 - Todo items imported from pilot have time set to 00:00. (JP)
+ #34095 - Memory leaks. (Hans Petter)
+ #34505 - Duplicate alarm dialogs for appts in exchange calendar.
+ (Rodrigo)
+ #35926 - Contacts entry in appointment editor to be removed.
+ (Hans Petter, Dan)
+ #37935 - Drawing problems in mini-calendar. (Hans Petter)
+ #39262 - Crash when importing an ics file to local calendar. (Rodrigo)
+ #39356 - New evo users didn't get calendar. (Rodrigo)
+ #39692 - File type names should not be OAF component types. (Ettore)
+ #39735 - View settings not persistent between sessions. (Jeff)
+ #39736 - Times in day view too large. (Hans Petter)
+ #39740 - Crash clicking in Attendees field when creating new
+ meeting. (Rodrigo)
+ #39757 - Couldn't delete reminder for appointment. (Hans Petter)
+ #39770 - Not meeting request sent. (Rodrigo)
+ #39803 - Bottom part of text cut off in month view. (Hans Petter)
+ #39895 - Selection vanishes when day view loses focus. (Michael/Hans)
+ #39954 - Crash when setting recurrence rule for an appointment.
+ (Hans Petter)
+ #39955 - Crash when forwarding an appointment as icalendar. (JP)
+ #39961 - Appointment schedule autopick menu displays under File.
+ (Rodrigo)
+ #40133 - wombat startup error. (Toshok)
+ #40195 - Cannot create new calendar folders (JP)
+ #40252 - LOG(e...) syntax error (Michael)
+ #40258 - Recurring event displayed truncated description. (Hans Petter)
+ #40578 - Event summaries cut off in month view. (Hans Petter)
+ #40655 - Mini-calendar always showed January 1970. (Hans Petter)
+ #40661 - Missing header for Forte compilation. (Rodrigo)
+ #40722 - Crash when closing a meeting. (JP)
+ #40789 - Didn't remember reminder text. (JP)
+ #40790 - Didn't launch programs added as reminders. (JP)
+ #40792 - Buttons in Select File dialog for sound reminder didn't
+ work. (Ettore)
+ #40876 - Cannot create a meeting with a resource in Exchange
+ calendar (JP)
+ #40894 - calendar switching weeks selected in small right subcalendars
+ (JP)
+ #41127 - Evolution crashed when sending new meeting invitation (JP)
- - Improved html rendering, including support for the clear
- attribute in <br> elements.
+ * Mail
+
+ #29564 - Message list loses focus when you expunge. (Michael)
+ #33786 - Crash when invalid expression fed to vFolder. (Michael)
+ #36245 - Translation string context problem. (Dan)
+ #37084 - Mailer forgets message list pane size on startup.
+ (Michael)
+ #38227 - Button spacing issues. (Ettore)
+ #38461 - Mail importers cannot import to non-local folders.
+ (Michael)
+ #38659 - RFC2047 word encoding errors. (Jeff)
+ #38926 - Configuration dialogs overlap each other. (Ettore, Jeff)
+ #39165 - Losing all vFolder rules after editing them, until
+ restart. (Michael)
+ #39168 - compiler compatability, empty structs. (Jeff)
+ #39170 - Compiler compatibility, returning a void return value.
+ (Jeff)
+ #39173 - prototype mismatch. (Jeff)
+ #39204 - Charset handling problems with broken mails. (Jeff)
+ #39256 - Send message to contact/forward contact doesn't work.
+ (Michael)
+ #39325 - Allow user to enable/disable account from account list.
+ (Jeff)
+ #39382 - Signature editor dialog buttons messed up. (Jeff)
+ #39464 - Trying to remove a duplicate vfolder crashes. (Michael)
+ #39486 - Cancelling send/receive could cause a crash. (Michael)
+ #39654 - vFolder source remove button doesn't work. (Jeff)
+ #39696 - Default composer window title is meaningless. (Jeff)
+ #39741 - Configuration dialogs overlap each other. (Ettore, Jeff)
+ #39744 - Sending 8 bit mime to a smtp server which doesn't say it
+ supports it. (Jeff)
+ #39759 - Crash using search dialog. (Michael)
+ #39800 - Make To: have focus on a new message. (Jeff)
+ #39809 - Dialog's don't match gnome 2 layout. (Jeff)
+ #39813 - Crash/noop adding signature script. (Jeff)
+ #39870 - Message browser button sensitivity not correct. (Jeff)
+ #39914 - Configuration dialogs overlap each other. (Ettore, Jeff)
+ #39924, and many others - Subject entry box didn't work
+ properly/support i18n very well. (Jeff)
+ #40043 - A warning dialog wont go away. (Jeff)
+ #40074 - Threads always open expanded. (Jeff)
+ #40083 - Search box doesn't work on subscription dialog - it was
+ removed. (Jeff)
+ #40103 - Deadlock at startup. (Michael)
+ #40124 - Cannot unsubscribe from folders that aren't selectable.
+ (Jeff)
+ #40188 - Context menu on addresses crashes. (Michael)
+ #40300 - Files are only detected for recovery when you start an
+ editor. (Michael)
+ #40314 - Some folders not expandable in subscriptions dialog.
+ (Jeff)
+ #40472 - Crash after entering password. (Michael)
+ #40522 - Two passphrase dialogues viewing encrypted mail. (Michael)
+ #40536 - Send/receive dialogue should transient for parent.
+ (Michael)
+ #40608 - Crash saving attachment. (Jeff)
+ #40679 - Composer crash browsing files to attach. (Jeff)
+ #40728 - Crash while scrolling. (Jeff)
+ #40764 - Composer backs up drafts too often. (Jeff)
+ #40778 - incorrect IMAP BODY parsing/display (Jeff)
+ #40900 - vfolder creation dialog has wrong button order. (Michael)
+ #40904 - Spontaneous crash. (Jeff)
+ #40921 - Cancel subscription dialogue while busy -> crash. (Michael)
+ #41004 - HIG compliance. (Jeff)
+
+ * Shell
+
+ #17034 - Use UTF-8 in about box. (Michael)
+ #34371 - Tries to open other user's folder with blank user field.
+ (Ettore)
+ #38775 - Version number hardcoded in warning dialog text. (Michael)
+ #38974 - Xlib dependency causing linking error on Solaris. (Ettore)
+ #39096 - Start-up crash on Solaris. (Ettore)
+ #39467 - Crash when splash image not found. (Michael)
+ #39599 - Crash when folder icons missing. (Ettore)
+ #39692 - OAFIIDs being shown in the importer dialog. (Ettore)
+ #39706 - Settings window too big. (Michael)
+ #40377 - Old stale wombat servers not being killed. (Ettore)
+ #40413 - Problem with closing the folder selector dialog. (Ettore)
+ #40474 - Summary settings not imported from 1.2. (Michael)
+ #40590 - Signature settings upgrade problem. (Michael)
+ #40652 - Folder bar not resizing after resizing Evolution window.
+ (Michael)
+ #40748 - Cannot resize icons in the shortcut bar. (Ettore)
+ #40854 - Problem with selecting other user's folder. (Dan)
+ #40888 - Crash when selecting other user's folder. (Dan)
* Summary
- - Can have non-local mail folders displayed on the summary.
+ #5344 - Missing weather locations. (Marten Woxberg)
+ #7153 - Stock folder names not translated. (Ettore)
+ #12066 - Missing weather locations. (Dan)
+ #15740 - Missing weather locations. (Dan)
+ #18015 - Missing weather locations. (Dan)
+ #19957 - AM/PM setting not being honoured. (Ettore)
+ #40358 - Summary page not showing properly in non-C locales.
+ (Ettore)
+ #40141 - Preferences settings inconsistency when clicking "Close".
+ (Michael)
+ #32027 - Missing locations. (Dan)
- - Improved Calendar and Tasks displayed. Displays overdue and todays
- tasks in colours.
+Other bugs:
- - Uses Soup for HTTP downloading news feeds and weather info.
+ * Addressbook
- - Better folder selector.
+ - HIG'ify the e-address-popup's buttons layout. (Toshok)
+ - Add input method support to the minicard view. (Toshok)
+ - Make the minicard view listen for style changes. (Toshok)
+ - Fix the select names component to be more friendly to non-shlib
+ components. (Dan)
+ - Fix various errors in the contact editor caused by parsing
+ addresses when we don't need to - especially after the user has
+ explicitly entered the elements of the address
+ themselves. (Toshok)
+ - Replace GtkImage based arrow buttons in the contact editor with
+ GtkArrow. (Toshok)
- - Better Weather/News Feed selector.
+ * Calendar
+
+ - Replaced all references to GdkFont deprecatedness with Pango.
+ (Hans Petter)
+ - Alarm notification fixes. (Rodrigo)
+ - Timezone dialog fix. (Dan)
+ - Use weak refs instead of destroy signal. (Rodrigo, Hans Petter)
+ - Use GtkMessageDialogs for meeting-related questions. (Rodrigo)
+ - GtkObject -> GObject fixes. (Everyone)
+ - Connector-related fixes. (Dan)
+ - Made meeting/scheduling work correctly. (JP)
+ - Only remove alarms for backends that request it (Rodrigo)
+ - HIG'ify dialogs (Ettore)
+
+ * Mail
+
+ - Clear passwords didn't work. (Michael)
+ - Show preview and view threaded were made per-folder, as in
+ 1.2.x, 1.3.1 had them global. (Michael)
+ - Make the printing dialog, and account editor transient for the
+ parent. (Larry, Jeff)
+ - Check for unique filter/vFolder names in all cases. (Michael)
+ - Most warnings removed. (Jeff, Michael)
+ - some text/plain mails detected as text/html, re-do the fix for
+ #16817 to make it pickier. (Michael)
+ - Imap buffer overflow potential. (Timo Sirainen)
+ - GSSAPI SASL support. (Jeff)
+ - Handle broken header charset checking similarly to badly
+ labelled/broken body content. (Dan)
+ - Various glib deprecation issues, and use non-locale specific
+ string compares in various places. (Jeff, Michael)
+ - Mail piped to the sendmail transport is canoncalised into Un*x
+ format, using network format (CRLF) confuses some versions of
+ postfix. (Jeff)
+ - Some work on fixing cut and paste shortcuts in composer. (Jeff)
+ - Made the EvolutionComposer corba interfaces work again/port to
+ GNOME 2. (Michael)
+
+ * Shell
+
+ - Fixed some problems with the folder dialogs. (Dan)
+ - Fixed shell .server files. (Dan)
+ - Added --force-shutdown to the shell as a killev replacement.
+ (Dan)
+ - Make Evolution use large WM icons. (Ettore)
+ - Made the offline dialog work again. (Ettore)
+ - Fixed importer framework to support non-local folders. (Ettore)
+
+ * Summary
+
+ - Make creation of the summary settings page faster. (Dan)
+
+ * All
+
+ - A number of compiler portability fixes, varadic macro's,
+ __FUNCTION__ -> G_GNUC_FUNCTION, inline usage, void returns, etc
+ (Everyone)
+ - Fixed druid colors. (Dan)
+
+
+
+Evolution 1.3.1, 2003-03-05
+---------------------------
- - Can delete user added news feeds.
+First release based on GNOME 2.
diff --git a/README b/README
index ee9b5800ff..d26b0f7c45 100644
--- a/README
+++ b/README
@@ -1,267 +1,148 @@
-Evolution is the integrated mail, calendar and address book
-distributed suite from Ximian, Inc.
+Evolution is the integrated mail, calendar and address book suite from
+the Evolution Team.
-See http://www.ximian.com/products/evolution for more information.
+See http://www.gnome.org/projects/evolution for more information.
If you are using Evolution, you may wish to subscribe to the Evolution
-users mailing list. If you are interested in contributing to
+users mailing list. If you are interested in contributing to
development on it, you should certainly subscribe to the Evolution
-Hackers mailing list. Visit
-http://developer.ximian.com/community/lists.html to subscribe to
-Ximian mailing lists. If you are planning to work on any part of
-Evolution, please send mail to the mailing list first, to avoid
-duplicated effort (and to make sure that you aren't basing your work
-on interfaces that are expected to change).
+Hackers mailing list. Visit
-There are mailing list archives available at
-http://lists.ximian.com/archives/public/evolution/ and
-http://lists.ximian.com/archives/public/evolution-hackers/
+ http://lists.ximian.com
-There is also an #evolution IRC channel on irc.gnome.org.
+to subscribe or view archives of the Ximian mailing lists.
+
+If you are planning to work on any part of Evolution, please send mail
+to the mailing list first, to avoid duplicated effort (and to make
+sure that you aren't basing your work on interfaces that are expected
+to change).
+
+There is also a #evolution IRC channel on irc.gnome.org.
Help for Evolution is available in the user manual (select "Help" from
-the menu after running the application), at the Ximian knowledge base
-(http://support.ximian.com), in the Evolution man page (run "man
+the menu after running the application), at the Novell knowledge base
+(http://support.novell.com), in the Evolution man page (run "man
evolution" at the command line), and in the --help strings (run
"evolution --help" at the command line).
The rest of this file is dedicated to building Evolution.
-PROBLEMS BUILDING EVOLUTION
----------------------------
-
-Did you read the "How to build" section below?
-
-If the configure script complains that you don't have a library that
-you know you have installed, it usually means either that you've
-installed things into multiple prefixes (see the bits on GNOME_PATH
-below) or (if you're on Linux) that you installed the "foo" package
-but forgot the "foo-devel" or "foo-dev" packages.
-
-
-HOW TO BUILD EVOLUTION
-----------------------
-
- *** READ THIS BEFORE YOU START BUILDING ANYTHING! ***
-
-Evolution depends on a large number of unreleased and rapidly-changing
-libraries. Some of these libraries in turn depend on other unreleased
-and rapidly-changing libraries.
-
-Building Evolution is HARD, and it's going to stay hard until all of
-the libraries it depends on stabilize, and there's nothing we can do
-to make it any easier until then.
-
-
-GENERAL PRINCIPLES
-------------------
-
-First you have to decide whether you want to install Evolution (and
-its dependencies) into the same prefix as the rest of your GNOME
-install, or into a new prefix. Installing everything into the same
-prefix as the rest of your GNOME install will make it much easier to
-build and run programs, and easier to switch between using packages
-and building it yourself, but it may also make it harder to uninstall
-later.
-
-If you want to install into the same prefix as the rest of GNOME,
-type:
-
- gnome-config --prefix
- gnome-config --sysconfdir
-
-and remember the answers, and pass them to "configure" or "autogen.sh"
-when building the other packages you need. For example:
-
- ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var/lib
-
- --localstatedir is needed to make the docs integrate with scrollkeeper
- and needs to point to the directory containing the scrollkeeper indices
- which are in: gnome-config --localstatedir
-
-If you build in another prefix instead, you will need to set the
-GNOME_PATH environment variable (and ACLOCAL_FLAGS as well if building
-from CVS) to include the prefix you install into. For example:
-
- export GNOME_PATH=/usr/local
- export ACLOCAL_FLAGS="-I /usr/local/share/aclocal"
-
-(Assuming your shell is bash, and you installed into /usr/local.) You
-need to set GNOME_PATH both during compiling AND when you run
-evolution. Remember also that if you're installing into an odd prefix
-such as /evolution, that you also need to make sure to put
-${prefix}/bin in your PATH and ${prefix}/lib in your LD_LIBRARY_PATH.
-
DEPENDENCIES
------------
-The following required libraries are available in GNOME CVS, under the
-given names. Most (but not all) of them are also available as
-tarballs on ftp.gnome.org or one of the Ximian mirrors listed at
-http://ximian.com/mirrors.html.
-
-If installing from packages, remember that you need both the runtime
-and -devel packages for each library.
-
- - GNU intltool 0.18
-
- - scrollkeeper - 0.1.4 or later
-
- - gnome-xml - 1.8.17 or later in the 1.0 series, but not from the 2.0
- series (If you get this from GNOME CVS, use the tag "LIB_XML_1_BRANCH".)
-
-
- - gnome-print - 0.35 or later
-
- - gdk-pixbuf - 0.18.0 or later
-
- - ORBit - 0.5.8 or later (If you get this from GNOME CVS, use the
- tag "orbit-stable-0-5".)
-
- - oaf - 0.6.10 or later (If you get this from GNOME CVS, use the tag
- "oaf-stable-0-6")
+In order to build Evolution you need to have the full set of GNOME 2.6
+(or greater) development libraries installed.
- *** If you are using oaf from CVS, you should use the flag
- *** "--disable-more-warnings" when you configure, or it may fail to
- *** build.
+GNOME 2.6 or greater comes with most of the modern distributions, so
+in most cases it should be enough to just install all the devel
+packages from your distribution.
- - gnome-vfs - 1.0.5 or later (If you get this from GNOME CVS, use
- the tag "gnome-vfs-1-0")
+Please make sure you have the most recent versions of the libraries
+installed, since bugs in the libraries can cause bugs in Evolution.
- *** If you are using gnome-vfs from CVS, you should use the flag
- *** "--disable-more-warnings" when configuring, or it may fail to
- *** build.
+Additional dependencies, besides the stock GNOME libraries (the
+dependencies should be compiled in the order they are listed here):
- - libglade - 0.14 or later
+ * gnome-icon-theme 1.2.0 or later
- - bonobo - 1.0.3 or later
+ * ORBit 2.9.8 or later
- *** Note that bonobo must be installed with the same --prefix as
- *** either gnome-libs or evolution for the Makefiles to work
- *** properly.
+ ftp://ftp.gnome.org/pub/gnome/sources/libsoup
+
+ * libsoup 2.2.1 or later
- - bonobo-conf - 1.0.16 or later
+ ftp://ftp.gnome.org/pub/gnome/sources/libsoup
- - gal (GNOME Application Library) - 0.20 or later
+ * evolution-data-server 1.1.1 or later
- - gtkhtml - 1.1.2 or later
+ ftp://ftp.gnome.org/pub/gnome/sources/evolution-data-server
- - SOUP - 0.7.x
+ * gtkhtml 3.5.0 or later
- *** If you are compiling from CVS, grab the soup-0-7 branch.
+ ftp://ftp.gnome.org/pub/gnome/sources/gtkhtml
-Other non-GNOME Dependencies:
+ * [Optional] Mozilla NSPR/NSS libraries
- - Berkeley's libdb - 3.1.17
+ These are needed if you want to compile Evolution with SSL and S/MIME
+ support.
- db3 is available from http://www.sleepycat.com. Make sure to get
- 3.1.17, which isn't the latest version.
+ http://www.mozilla.org/
- --- IMPORTANT WARNING ---
+ Many distributions ship these as Mozilla development
+ packages.
- The on-disk format of DB files has been changing between versions
- 2, 3 and 4. Also, because of the libdb API, there is no way to
- easily handle the different formats from within the application.
- For this reason, Evolution has chosen to use one specific version
- of the library (version 3) and stick to it, so that users do not
- need to convert their addressbook files to use them with
- different version of Evolution.
+ * [Optional] gnome-spell 1.0.1 or later
- That's why Evolution REQUIRES libdb 3.1.17, and NO OTHER VERSION.
+ This is only necessary if you want to have the spell
+ checking functionality in Evolution's message composer.
- If you force the check to accept a version different from 3.1.17,
- your binary of Evolution will be using a different format from
- the chosen one; this means that it will not be able to read
- addressbook databases created by other versions of Evolution
- which were compiled in the standard way. Also, we DO NOT
- GUARRANTEE that Evolution will work with different versions of
- libdb at all, even if it can be trivially made to compile against
- them.
+ ftp://ftp.gnome.org/pub/gnome/sources/gnome-spell
- SPECIAL NOTE FOR BINARY PACKAGERS:
-
- If you are making binary packages for end-users (e.g. if you are
- a distribution vendor), please statically link Evolution to
- Berkeley DB 3.1.17, as mandated by the configure.in check. DO
- NOT patch configure.in to work around the check. Forcing the
- check to link to a different version of the library will only
- give headaches and pain to your users, who will see their
- addressbook disappear and will complain to us (the Evolution
- team) about losing their data.
-
- Besides, libdb will be linked statically, which means that your
- distribution doesn't actually need to ship DB 3.1.17 itself
- separately.
-
- The Evolution team will be infinitely grateful for your
- co-operation. Thanks.
-
-
-COMPILING BERKELEY DB
+CONFIGURING EVOLUTION
---------------------
-If you don't have 3.1.17 installed on your system or Evolution doesn't
-detect it for some reason, here is a way to get Evolution to link to
-it without messing up your system installation.
-
- * Get the Sleepycat tarball from:
-
- http://www.sleepycat.com/update/snapshot/db-3.1.17.tar.gz
-
- * Install the content somewhere _other_ than the evolution source tree.
- e.g: NOT evolution/db-3.1.17
+First you have to decide whether you want to install Evolution (and
+its dependencies) into the same prefix as the rest of your GNOME
+install, or into a new prefix.
- * Compile according to instructions, but installing into some custom
- prefix, for example:
+Installing everything into the same prefix as the rest of your GNOME
+install will make it much easier to build and run programs, and easier
+to switch between using packages and building it yourself, but it may
+also make it harder to uninstall later. Also, it increases the chance
+that something goes wrong and your GNOME installation gets ruined.
- ../dist/configure --prefix=/home/user/berkeleydb-3.1.17
+If you want to install in a different prefix, you need to do the
+following things:
- * Autogen Evolution specifying that it has to look for the DB
- library there, for example:
+ * Set the PKG_CONFIG_PATH environment variable to contain a
+ colon-separated list of all the pkg-config directories that
+ will be involved in the build. This basically means a list
+ of $prefix/lib/pkgconfig directory names, where $prefix is
+ the prefix where a library is installed.
- ./autogen.sh --prefix=/opt/gnome
- --with-db3-includes=/home/user/berkeleydb-3.1.17/include
- --with-db3-libs=/home/user/berkeleydb-3.1.17/lib
+ For example, if you have GNOME installed in /usr and you
+ are installing Evolution and its dependencies in
+ /opt/evolution, you want to do something like the following
+ (assuming you are using Bash):
+ export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/opt/evolution/lib/pkgconfig
-COMPILING PALM PILOT SUPPORT
-----------------------------
+ * Edit the bonobo-activation-config.xml file (which is
+ normally found in /etc/bonobo-activation/) to include the
+ location where you are installing Evolution.
-If you want support for PalmPilot syncing you will also need recent
-versions of:
+ In the example given above (GNOME in /usr, Evolution and
+ dependencies in /opt/evolution), your
+ bonobo-activation-config.xml will have to look like this:
-1) pilot-link
-http://www.pilot-link.org
+ <?xml version="1.0"?>
+ <oafconfig>
+ <searchpath>
+ <item>/usr/lib/bonobo/servers</item>
+ <item>/opt/evolution/lib/bonobo/servers</item>
+ </searchpath>
+ </oafconfig>
-2) gnome-pilot
-http://www.eskil.org/gnome-pilot/
+ * Pass an appropriate --prefix parameter to the configure
+ scripts of Evolution and its dependencies, eg:
-3) evolution
-In your evolution source directory do ./autogen.sh --prefix=<evo-prefix>
---with-pisock=<pilot-link-prefix> --enable-pilot-conduits=yes
-make
-make install
+ ./configure --prefix=/opt/evolution
+More information on how to use the configure script is available in
+the INSTALL file which is part of the Evolution tarball.
-SSL SUPPORT
------------
-If you want SSL support (and someday S/MIME), you will also need
-mozilla-nspr and mozilla-nss, which can be found at
-http://www.mozilla.org.
+OPTIONAL FEATURES
+-----------------
-Once you have those libraries (and their respective includes)
-installed, in your evolution source directory do:
+Some optional features can be enabled at compilation time by passing
+appropriate flags to the configure script:
-./autogen.sh --prefix=<evo-prefix> --with-nspr-includes=<nspr-includes-prefix>
---with-nspr-libs=<nspr-libs-prefix> --with-nss-includes=<nss-includes-prefix>
---with-nss-libs=<nss-libs-prefix>
+ * SSL support.
+ Make sure you have Mozilla's NSS nad NSPR libraries
+ installed and pass the following flag:
-NEWSGROUP (NNTP) SUPPORT
-------------------------
+ --enable-nss
-Experimental support for NNTP is enabled if you use the --enable-nntp
-configure option, but it's currently unmaintained and highly unstable
-and experimental.
diff --git a/README.translators b/README.translators
new file mode 100644
index 0000000000..98eaef0148
--- /dev/null
+++ b/README.translators
@@ -0,0 +1,11 @@
+Evolution is translated like most GNOME projects, by updating the
+.po files in evolution/po and by translating the help files in
+evolution/help/C and placing them in a locale specific dir, ie
+evolution/help/fr. In addition, the default welcome message is in
+evolution/mail/default/C/Inbox and can be translated by translating the
+message in the file and also putting it in a locale specific dir, ie
+evolution/mail/default/fr/Inbox. The file name 'Inbox' should not be
+changed, as this is an internally defined string (the name in the
+folder list will still be translated though). The content of the Quick
+Reference in the "Help" menu can also be translated, see
+https://bugzilla.gnome.org/show_bug.cgi?id=307856#c3 for a how-to.
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
deleted file mode 100644
index 0993815312..0000000000
--- a/RELEASE-NOTES
+++ /dev/null
@@ -1,110 +0,0 @@
-FIXME: http://bugzilla.ximian.com/show_bug.cgi?id=31896
-
-WARNING
-
-Evolution 1.1.1 is a BETA quality release. This means that it has
-bugs, including possibly destructive bugs that can cause valuable data
-to be lost.
-
-For this reason, please make sure you back up your mail and your
-calendar/addressbook information before using Evolution 1.1.1 on them.
-In particular, you are strongly advised to backup the `evolution'
-directory in your home directory if you are upgrading from a 1.0.x
-version of Evolution to Evolution 1.1.1.
-
-
-UPGRADING FROM 1.0.x
-
-The format of certain configuration files has changed in this version
-of Evolution. When you start Evolution 1.1.1 for the first time, it
-will automatically migrate your configuration so that it will work as
-expected with this version.
-
-
-RETURNING TO 1.0.x
-
-If you want to return to a 1.0.x version after trying 1.1.1, you have
-to restore the original configuration files. From the command-line,
-you can do the following, after having quit Evolution:
-
- killev
- cd ~/evolution
- mv filters.xml.bak-1.0 filters.xml
- mv vfolders.xml.bak-1.0 vfolders.xml
- mv shortcuts.xml.bak-1.0 shortcuts.xml
- mv mail/imap.bak-1.0 mail/imap
-
-Note that any changes to filters, vfolders or shortcuts made with
-1.1.1 will be lost after this operation.
-
-Also note that the upgrade mechanism runs automatically only the first
-time you run 1.1.1. For this reason, if you run Evolution 1.1.1, then
-go back to 1.0 using the aforementioned procedure, and then go back to
-using 1.1.1 again, the settings will not be upgraded.
-
-To force the upgrade to happen again in this case, use the following
-command to start Evolution 1.1.1:
-
- evolution --force-upgrade
-
-
-SEARCH CRITERIA CHANGES
-
-When you specify multiple words in search "contains" criterion,
-Evolution will now search the mail messages that contain all the words
-specified, in any order. (The 1.0.x behavior was to look for the
-whole string in "subject contains" matches, and matched no messages in
-the case of body searches.)
-
-This applies to the search bar, the filter rules and the vfolder
-rules. Filter rules and vfolder rules might need to be re-adjusted
-after you upgrade to version 1.1.1.
-
-
-IMAP FOLDER NAME CHANGES (I18N)
-
-If you created any folder names using non-ASCII characters using prior
-versions of Evolution, you will find they may not be displayed
-properly anymore. This is because previous versions did not implement
-IMAP I18N folder names correctly as specified in RFC 2060.
-
-The upgrade script will try to rectify any filters or vfolders using
-any such names. However, as it does not know the character set used
-by the server, non ISO-8859-1 (latin-1) characters will not be
-properly converted. You may need to reverify the filter and vFolder
-rules in this case.
-
-Also note that if such folder names do not display properly that it is
-purely cosmetic and may be fixed by renaming the folder(s) in
-question.
-
-
-KNOWN BUGS
-
-If you have any unnamed contact lists in any of your addressbook
-folders, you might experience hangs and/or crashes when specifying
-destination addresses, for example when composing meeting requests.
-Giving a name to all the contact lists will fix the problem. This
-problem will be fixed in the next Evolution release.
-
-
-NOTE FOR SOLARIS/CDE USERS
-
-This release of Evolution doesn't install icons in the CDE
-"Application" group as Evolution 1.0.x used to do. While this doesn't
-affect users who are running Ximian Desktop, users who wish to run
-Evolution under the CDE environment will also have to set the PATH,
-GNOME_PATH and LD_LIBRARY_PATH environment variables to point to the
-Evolution installation before launching the `evolution' executable.
-
-This can be done, for example, with a shell script like the following:
-
- PATH=/opt/gnome/bin:/usr/bin:${PATH}
- GNOME_PATH=/opt/gnome:/usr
- LD_LIBRARY_PATH=/opt/gnome/lib:/usr/lib:${LD_LIBRARY_PATH}
-
- export LD_LIBRARY_PATH GNOME_PATH PATH
-
- exec evolution
-
-This problem will be fixed in the next release of Evolution.
diff --git a/acconfig.h b/acconfig.h
deleted file mode 100644
index 0d2011510f..0000000000
--- a/acconfig.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#undef ENABLE_NLS
-#undef HAVE_CATGETS
-#undef HAVE_GETTEXT
-#undef HAVE_LC_MESSAGES
-#undef HAVE_STPCPY
-#undef HAVE_LIBSM
-#undef PACKAGE
-#undef VERSION
-#undef ENABLE_THREADS
-#undef SENDMAIL_PATH
-#undef SYSTEM_MAIL_DIR
-#undef HAVE_LDAP
-#undef HAVE_TIMEZONE
-#undef HAVE_ALTZONE
-#undef HAVE_TM_GMTOFF
-#undef HAVE_KRB4
-#undef NEED_KRB_SENDAUTH_PROTO
-#undef HAVE_KRB5
-#undef HAVE_NSS
-#undef HAVE_OPENSSL
-#undef HAVE_SSL
-#undef USE_DOT
-#undef USE_FCNTL
-#undef USE_FLOCK
-#undef ENABLE_NNTP
-#undef HAVE_BROKEN_SPOOL
-#undef ENABLE_PEDANTIC_PGPMIME
-#undef HAVE_KDE_APPLNK
-
-/* db3 version */
-#undef EVOLUTION_DB_VERSION_MAJOR
-#undef EVOLUTION_DB_VERSION_MINOR
-#undef EVOLUTION_DB_VERSION_PATCH
-
-/* Sub-version identification string. */
-#undef SUB_VERSION
-
-/* Preview-release string */
-#undef VERSION_COMMENT
-
-/* Define if ctime_r takes three arguments */
-#undef CTIME_R_THREE_ARGS
-
-/* Define if gethostbyname_r takes five arguments */
-#undef GETHOSTBYNAME_R_FIVE_ARGS
-
-/* Define if gethostbyaddr_r takes seven arguments */
-#undef GETHOSTBYADDR_R_SEVEN_ARGS
-
-/* Define to `int' if your system doesn't have `socklen_t'. */
-#undef socklen_t
diff --git a/acinclude.m4 b/acinclude.m4
deleted file mode 100644
index be1d20c998..0000000000
--- a/acinclude.m4
+++ /dev/null
@@ -1,170 +0,0 @@
-# evolution/acinclude.m4
-# shared configure.in hacks between Evolution and Connector
-
-# EVO_CHECK_LIB(dispname, pkgname, minvers[, maxvers])
-# Checks if the package with human-readable name @dispname, known
-# to gnome-config as @pkgname exists and has an appropriate version.
-# The version must be >= @minvers. If @maxvers is equal to @minvers,
-# it must be exactly that version. Otherwise, if @maxvers is set,
-# the version must be LESS THAN @maxvers (not less than or equal).
-AC_DEFUN(EVO_CHECK_LIB, [
- dispname="$1"
- pkgname="$2"
- minvers="$3"
- maxvers="$4"
-
- AC_MSG_CHECKING(for $dispname)
-
- if gnome-config --libs $pkgname > /dev/null 2>&1; then
- pkgvers=`gnome-config --modversion $pkgname | sed -e 's/^[[^0-9]]*//'`
- else
- pkgvers=not
- fi
- AC_MSG_RESULT($pkgvers found)
-
- pkgvers=`echo $pkgvers | awk -F. '{ print $[]1 * 1000000 + $[]2 * 10000 + $[]3 * 100 + $[]4;}'`
- cmpminvers=`echo $minvers | awk -F. '{ print $[]1 * 1000000 + $[]2 * 10000 + $[]3 * 100 + $[]4;}'`
- cmpmaxvers=`echo $maxvers | awk -F. '{ print $[]1 * 1000000 + $[]2 * 10000 + $[]3 * 100 + $[]4;}'`
- ok=yes
- if test "$pkgvers" -lt $cmpminvers; then
- ok=no
- elif test -n "$maxvers"; then
- if test "$pkgvers" -gt $cmpmaxvers; then
- ok=no
- elif test "$maxvers" != "$minvers" -a "$cmpmaxvers" -eq "$pkgvers"; then
- ok=no
- fi
- fi
- if test $ok = no; then
- case $maxvers in
- "")
- dispvers="$minvers or higher"
- ;;
- $minvers)
- dispvers="$minvers (exactly)"
- ;;
- *)
- dispvers="$minvers or higher, but less than $maxvers,"
- ;;
- esac
-
- AC_MSG_ERROR([
-""
-"You need $dispname $dispvers to build $PACKAGE"
-"If you think you already have this installed, consult the README."])
- fi
-])
-
-
-# EVO_PURIFY_SUPPORT
-# Add --enable-purify. If the user turns it on, subst PURIFY and set
-# the automake conditional ENABLE_PURIFY
-AC_DEFUN(EVO_PURIFY_SUPPORT, [
- AC_ARG_ENABLE(purify,
- [ --enable-purify=[no/yes] Enable support for building executables with Purify.],,enable_purify=no)
- AC_PATH_PROG(PURIFY, purify, impure)
- AC_ARG_WITH(purify-options, [ --with-purify-options=OPTIONS Options passed to the purify command line (defaults to PURIFYOPTIONS variable).])
- if test "x$with_purify_options" = "xno"; then
- with_purify_options="-always-use-cache-dir=yes -cache-dir=/gnome/lib/purify"
- fi
- if test "x$PURIFYOPTIONS" = "x"; then
- PURIFYOPTIONS=$with_purify_options
- fi
- AC_SUBST(PURIFY)
- AM_CONDITIONAL(ENABLE_PURIFY, test "x$enable_purify" = "xyes" -a "x$PURIFY" != "ximpure")
- PURIFY="$PURIFY $PURIFYOPTIONS"
-])
-
-
-# EVO_LDAP_CHECK(default)
-# Add --with-openldap and --with-static-ldap options. --with-openldap
-# defaults to the given value if not specified. If LDAP support is
-# configured, HAVE_LDAP will be defined and the automake conditional
-# ENABLE_LDAP will be set. LDAP_CFLAGS and LDAP_LIBS will be set
-# appropriately.
-AC_DEFUN(EVO_LDAP_CHECK, [
- default="$1"
-
- AC_ARG_WITH(openldap, [ --with-openldap=[no/yes/PREFIX] Enable LDAP support in evolution])
- AC_ARG_WITH(static-ldap, [ --with-static-ldap=[no/yes] Link LDAP support statically into evolution ])
- AC_CACHE_CHECK([for OpenLDAP], ac_cv_with_openldap, ac_cv_with_openldap="${with_openldap:=$default}")
- case $ac_cv_with_openldap in
- no|"")
- with_openldap=no
- ;;
- yes)
- with_openldap=/usr
- ;;
- *)
- with_openldap=$ac_cv_with_openldap
- LDAP_CFLAGS="-I$ac_cv_with_openldap/include"
- LDAP_LDFLAGS="-L$ac_cv_with_openldap/lib"
- ;;
- esac
-
- if test "$with_openldap" != no; then
- AC_DEFINE(HAVE_LDAP)
-
- case $with_static_ldap in
- no|"")
- if test -f $with_openldap/lib/libldap.la; then
- with_static_ldap=yes
- else
- with_static_ldap=no
- fi
- ;;
- *)
- with_static_ldap=yes
- ;;
- esac
-
- AC_CACHE_CHECK(if OpenLDAP is version 2.x, ac_cv_openldap_version2, [
- CPPFLAGS_save="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $LDAP_CFLAGS"
- AC_EGREP_CPP(yes, [
- #include "ldap.h"
- #if LDAP_VENDOR_VERSION > 20000
- yes
- #endif
- ], ac_cv_openldap_version2=yes, ac_cv_openldap_version2=no)
- CPPFLAGS="$CPPFLAGS_save"
- ])
- if test "$ac_cv_openldap_version2" = no; then
- AC_MSG_ERROR(evolution requires OpenLDAP version >= 2)
- fi
-
- AC_CHECK_LIB(resolv, res_query, LDAP_LIBS="-lresolv")
- AC_CHECK_LIB(socket, bind, LDAP_LIBS="$LDAP_LIBS -lsocket")
- AC_CHECK_LIB(nsl, gethostbyaddr, LDAP_LIBS="$LDAP_LIBS -lnsl")
- AC_CHECK_LIB(lber, ber_get_tag, [
- if test "$with_static_ldap" = "yes"; then
- LDAP_LIBS="$with_openldap/lib/liblber.a $LDAP_LIBS"
-
- # libldap might depend on OpenSSL... We need to pull
- # in the dependency libs explicitly here since we're
- # not using libtool for the configure test.
- if test -f $with_openldap/lib/libldap.la; then
- LDAP_LIBS="`. $with_openldap/lib/libldap.la; echo $dependency_libs` $LDAP_LIBS"
- fi
- else
- LDAP_LIBS="-llber $LDAP_LIBS"
- fi
- AC_CHECK_LIB(ldap, ldap_open, [
- if test $with_static_ldap = "yes"; then
- LDAP_LIBS="$with_openldap/lib/libldap.a $LDAP_LIBS"
- else
- LDAP_LIBS="-lldap $LDAP_LIBS"
- fi],
- LDAP_LIBS="", $LDAP_LDFLAGS $LDAP_LIBS)
- LDAP_LIBS="$LDAP_LDFLAGS $LDAP_LIBS"
- ], LDAP_LIBS="", $LDAP_LDFLAGS $LDAP_LIBS)
-
- if test -z "$LDAP_LIBS"; then
- AC_MSG_ERROR(could not find OpenLDAP libraries)
- fi
-
- AC_SUBST(LDAP_CFLAGS)
- AC_SUBST(LDAP_LIBS)
- fi
- AM_CONDITIONAL(ENABLE_LDAP, test $with_openldap != no)
-]) \ No newline at end of file
diff --git a/addressbook/.cvsignore b/addressbook/.cvsignore
deleted file mode 100644
index 09980ae6ba..0000000000
--- a/addressbook/.cvsignore
+++ /dev/null
@@ -1,6 +0,0 @@
-.deps
-.libs
-Makefile
-Makefile.in
-*.lo
-*.la
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog
deleted file mode 100644
index c67db48937..0000000000
--- a/addressbook/ChangeLog
+++ /dev/null
@@ -1,13190 +0,0 @@
-2002-10-15 Dan Winship <danw@ximian.com>
-
- * backend/ebook/e-card.c (e_card_email_match_string): Return right
- away rather than crashing if card->email is NULL.
- (e_card_email_find_number): Likewise.
-
-2002-10-10 Kjartan Maraas <kmaraas@gnome.org>
-
- [ Fix #7094, #7064, #7095, #31944, #31945 ]
- * gui/component/Makefile.am: Hook up new etspec file.
- * gui/component/addressbook-config.c: Remove ETable spec.
- * gui/component/addressbook-config.etspec: New file.
- * gui/component/ldap-config.glade: Fix typo.
- * gui/component/select-names/e-select-names.c: Remove inline spec.
- * gui/component/select-names/e-select-names.etspec: New file.
- * gui/contact-list-editor/Makefile.am: Hook up etspec.
- * gui/contact-list-editor/e-contact-list-editor.c: Remove inline spec.
- * gui/contact-list-editor/e-contact-list-editor.etspec: New file.
- * gui/widgets/Makefile.am: Hook up new spec.
- * gui/widgets/e-addressbook-view.c: Remove inline spec.
- * gui/widgets/e-addressbook-view.etspec: New file.
-
-2002-10-02 Chris Toshok <toshok@ximian.com>
-
- [ Fix #28392 ]
- * gui/widgets/e-addressbook-view.c (do_popup_menu): #if 0 out the
- gal_view submenu, since it's not spec'ed to be there anyway (as
- per bug #16250).
-
-2002-09-30 Chris Toshok <toshok@ximian.com>
-
- [ Fixes #31321 ]
- * backend/ebook/e-card.c (e_card_get_vobject): add VERSION:2.1 to
- exported vCards.
-
-2002-09-30 Chris Toshok <toshok@ximian.com>
-
- [ Fixes #31434 ]
- * backend/pas/pas-backend-file.c (do_summary_query): always
- retrieve the card from the db. use the summary strictly for
- matching, not for storing all information. This fixes completion
- of contact lists, since only 3 addresses were being stored and
- contact lists can have more.
-
-2002-09-30 Aaron Weber <aaron@ximian.com>
-
- * gui/widgets/e-addressbook-util.c (e_addressbook_show_multiple_cards): rephrase string on l. 213
-
-2002-09-30 Dan Winship <danw@ximian.com>
-
- * backend/ebook/e-card.c (e_card_list_send): update for
- Composer_setHeaders change.
-
-2002-09-27 Chris Toshok <toshok@ximian.com>
-
- [ fixes #27521 ]
- * gui/contact-editor/e-contact-quick-add.c (editor_closed_cb):
- always unref the contact editor when we get the editor_closed
- signal.
-
-2002-09-27 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (check_schema_support): set the
- timeout to 30 seconds.
- (query_ldap_root_dse): same, and also return the ldap_error since
- this function is the one that actually causes openldap to
- connect() to the ldap host.
- (pas_backend_ldap_connect): check the return value of
- query_ldap_root_dse, and error out if it's not SUCCESS.
-
-2002-09-26 Dan Winship <danw@ximian.com>
-
- * gui/component/addressbook-storage.c (load_source_data): Change
- folder type to "contacts/ldap".
- (addressbook_storage_add_source): Likewise.
- (create_ldap_folder): Check for type being "contacts" not
- ldap contacts, since the ldap-specific type doesn't appear in the
- menu.
-
-2002-09-25 Dan Winship <danw@ximian.com>
-
- * gui/component/addressbook-component.c (folder_types): Rename
- "ldap-contacts" to "contacts/ldap" and add "contacts/public".
- (IS_CONTACT_TYPE): update for new types.
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_init): Use "contacts/*" for selector_types.
-
- * gui/widgets/e-addressbook-util.c (e_addressbook_transfer_cards):
- Likewise.
-
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: add
- "evolution:config_item:type" = "contacts/ldap" to the LDAP sources
- control so it comes up by default when you open Preferences in an
- LDAP folder.
-
-2002-09-23 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-addressbook-table-adapter.c (addressbook_destroy):
- free adapter->priv.
-
- * gui/widgets/e-addressbook-model.c (addressbook_destroy): free
- model->query.
-
- * gui/component/select-names/e-select-names-manager.c
- (load_completion_books): use e_book_expand_uri here, and free the
- expanded uri after calling addressbook_load_uri, plugging a leak.
-
- * gui/component/select-names/e-select-names.c (set_book): unref
- esn->model before we unref esn. fixes an edge case memory
- corruption bug.
- (clear_widget): utility function to set a widget's ref to NULL
- when it's destroyed.
- (e_select_names_init): hook the status_message, categories option
- menu, and select_entry to clear_widget.
- (addressbook_model_set_uri): use e_book_expand_uri.
-
-2002-09-23 JP Rosevear <jpr@ximian.com>
-
- * conduit/Makefile.am: add libeutil to the link and link with
- libcamel instead of libcamel-static.la
-
-2002-09-22 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names-manager.h: oops, add
- cached_folder_list to struct _ESelectNamesManager.
-
-2002-09-22 Chris Toshok <toshok@ximian.com>
-
- [ Fixes #30481 ]
- * gui/component/select-names/e-select-names.c
- (e_select_names_init): initialize the select names dialog with the
- default contacts folder.
-
-2002-09-22 Chris Toshok <toshok@ximian.com>
-
- [ Fixes #28165, 29171 ]
- * gui/component/select-names/e-select-names-manager.c
- (uris_listener): check to see if the value has really changed.
- the way the preferences dialog works is such that we'll get called
- when any of the Folder Options are changed (default folders,
- offline stuff, etc.) we really only want to tear down and build
- back up the completion books if the autocomplete folder setting
- changed.
- (read_completion_books_from_db): cache the folder list, and call
- load_completion_books.
- (load_completion_books): new function, loads from the
- cached_folder_list.
- (e_select_names_manager_init): init cached_folder_list to NULL.
- (e_select_names_manager_destroy): g_free (cached_folder_list).
-
-2002-09-20 Chris Toshok <toshok@ximian.com>
-
- [ Fixes #30483 ]
- * gui/component/select-names/e-select-names-completion.c
- (name_style_query): argh, contains => beginswith.
-
-2002-09-17 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-component.c (add_creatable_item):
- don't add the user creatable item for ldap-contact folders atm,
- since it results in their being duplicate New Contact and New
- Contact List menu items.
-
-2002-09-17 Kjartan Maraas <kmaraas@gnome.org>
-
- * gui/component/ldap-config.glade: Fix a typo.
-
-2002-09-13 Chris Toshok <toshok@ximian.com>
-
- [ Fixes bug #30250 ]
- * backend/ebook/e-destination.c (e_destination_get_name): handle
- "Unnamed Lists" here by setting their name to _("Unnamed List').
-
- * backend/ebook/e-card-simple.c (e_card_simple_get): same.
-
- * gui/contact-list-editor/e-contact-list-editor.c (is_named): new
- function, return TRUE if the name field is filled in.
- (prompt_to_save_changes): return TRUE if the list isn't named
- (meaning it's not saveable.)
- (command_state_changed): saving requires a name.
- (add_email_cb): always call command_state_changed.
- (remove_entry_cb): same.
- (list_name_changed_cb): same.
- (visible_addrs_toggled_cb): same.
- (table_drag_data_received_cb): same.
-
-2002-09-12 Dan Winship <danw@ximian.com>
-
- * backend/ebook/e-card-simple.c (e_card_simple_get): return
- g_strdup("true"), not "true".
-
-2002-09-11 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_start_query): institute an arbitrary
- minimum limit on the number of characters before we actually try
- to autocomplete. It's 3, btw.
-
-2002-09-11 Chris Toshok <toshok@ximian.com>
-
- [ fixes the other half of #17336 ]
- * gui/contact-editor/e-contact-quick-add.c (quick_add_set_name):
- parse the name when we're asked to set it, so the full name
- doesn't get stored as (potentially) "Last, First" in the card.
-
-2002-09-11 Chris Toshok <toshok@ximian.com>
-
- [ fixes part of #17336 ]
- * gui/contact-editor/e-contact-editor-fullname.c
- (e_contact_editor_fullname_init): get the window title from the
- .glade file, and supply a suitable wm icon.
-
- * gui/contact-editor/e-contact-editor-address.c
- (e_contact_editor_address_init): same.
-
-2002-09-11 Chris Toshok <toshok@ximian.com>
-
- [ fixes #30208 ]
- * gui/component/addressbook.c (load_uri_auth_cb): if the user
- clicked cancel in the password dialog, let them off the hook and
- bind anonymously. Otherwise (if they failed to auth), prompt them
- for the password again.
- (addressbook_authenticate): new function, split out 99% of the
- auth machinery here so it can be called multiple times. Also,
- call the callback with E_BOOK_STATUS_CANCELLED if the user clicked
- the cancel button in the dialog.
- (load_uri_cb): call addressbook_authenticate if the book has auth
- enabled.
- (addressbook_load_uri): use g_new0.
-
-2002-09-05 Anna Dirks <anna@ximian.com>
- * gui/component/GNOME_Evolution_Addressbook.oaf.in : Changed the
- description of the Directory Servers page of the settings dialog
- to be a little less wordy {This page can be used to configure blah-->
- Configure blah.}
-
-
-2002-09-04 Chris Toshok <toshok@ximian.com>
-
- [ Fixes #29904 ]
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_activate_obj): we need to activate
- either a contact list editor or contact editor depending on if
- it's a list (this screams for a utility function.)
-
-2002-09-04 Dan Winship <danw@ximian.com>
-
- * gui/component/addressbook-storage.c
- (addressbook_get_other_contact_storage): Pass FALSE to
- evolution_storage_new: the Other Contacts storage doesn't support
- shared folders.
-
-2002-09-04 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c (create_component): Pass
- NULL as @unpopulate_folder_context_menu_fn to
- evolution_shell_component_new().
-
-2002-09-03 Mike Kestner <mkestner@ximian.com>
-
- * gui/component/select-names/e-select-names.c (e_select_names_destroy):
- unref the "without", adapter, and model, then chain up the GnomeDialog
- destroy function.
-
-2002-09-03 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: Use
- ldap-settings.png instead of evolution-contacts.png.
-
-2002-09-03 Chris Toshok <toshok@ximian.com>
-
- [ fixes #29699 ]
- * gui/component/addressbook-config.c
- (addressbook_add_server_druid): call _set_source with a NULL
- source to fill in dialog settings that are set from the option
- menus (like the SSL setting).
-
-2002-09-03 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook.c (delete_contact_cb): Fix typo
- [`view>view' instead of `view->view']. Also, cast to
- GTK_WINDOW instead of GTK_WIDGET as it should be.
-
-2002-08-30 Dan Winship <danw@ximian.com>
-
- * backend/idl/addressbook.idl (CallStatus): add QueryRefused, for
- when the backend refuses to perform a query. (part of #25782)
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_convert_status): translate
- GNOME_Evolution_Addressbook_BookViewListener_QueryRefused.
-
- * gui/component/addressbook.c (search_result): Handle
- E_BOOK_VIEW_STATUS_QUERY_REFUSED.
-
-2002-08-30 Chris Toshok <toshok@ximian.com>
-
- [ fixes #27923]
- * backend/pas/pas-backend-summary.c: up the version to 4_0 (4000).
- (pas_backend_summary_load_item): handle wants_html{_set}, list,
- and list_show_addresses.
- (pas_backend_summary_save_item): same.
- (pas_backend_summary_add_card): same.
- (pas_backend_summary_get_summary_vcard): same.
-
-2002-08-29 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-component.c (add_creatable_item): call
- evolution_shell_component_add_user_creatable_item twice here, once
- for the "contacts" folder type, and once for "ldap-contacts".
-
-2002-08-29 Chris Toshok <toshok@ximian.com>
-
- [ fixes #20347 ]
- * gui/widgets/e-addressbook-view.c (e_addressbook_view_init): hook
- up the backend_died signal.
- (backend_died): new function, pop up an error dialog saying the
- backend died.
-
- * gui/widgets/e-addressbook-model.c (backend_died): new function,
- emit the backend_died signal.
- (e_addressbook_model_class_init): create the backend_died signal.
- (e_addressbook_model_init): init backend_died_id
- (e_addressbook_model_set_arg): disconnect the backend_died signal
- from the old book and hook it up to the new book.
-
- * gui/widgets/e-addressbook-model.h: add the backend_died signal.
-
- * backend/ebook/e-book.c (backend_died_cb): new function, emit the
- backend_died signal.
- (e_book_do_response_open): create the component listener and hook
- up the backend_died signal.
- (e_book_destroy): disconnect the component listener and unref it.
-
- * backend/ebook/e-book.h: add backend_died signal.
-
-2002-08-29 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-card-sexp.c (is_helper): use strcasecmp
- here, since all the other helpers use case insensitive
- comparisons.
-
- * backend/pas/pas-backend-summary.c (is_helper): same.
-
-2002-08-29 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (category_ber): return NULL if
- the list is empty.
- (pas_backend_ldap_connect): always try to use ldapv3, not just
- when we want to use tls.
-
-2002-08-29 Chris Toshok <toshok@ximian.com>
-
- [ fixes #25038 ]
- * gui/contact-editor/Makefile.am (INCLUDES): need to have
- EVOLUTION_ICONSDIR defined.
-
- * gui/contact-list-editor/Makefile.am (INCLUDES): same.
-
- * gui/contact-editor/e-contact-editor.c (e_contact_editor_init):
- set the window icon to the contact mini icon.
-
- * gui/contact-list-editor/e-contact-list-editor.c
- (e_contact_list_editor_init): set the window icon to the new
- contact list icon.
-
- * gui/widgets/e-minicard.c (LIST_ICON_FILENAME): change to (the
- prettier, imo) "contact-list-16.png"
-
-2002-08-28 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_search): spew
- the filter we're using for the search.
-
-2002-08-28 Mike Kestner <mkestner@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c : stop the
- EBookViews before unreffing.
-
-2002-08-28 Dan Winship <danw@ximian.com>
-
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: Add an
- evolution:shell_component_launch_order and rename
- evolution:shell_component_icon.
-
-2002-08-28 Chris Toshok <toshok@ximian.com>
-
- [ oops, merged the .h and .glade file back to the HEAD from the
- 1-0 branch, but missed the .c file. ]
- * gui/component/select-names/e-select-names.c (status_message): set
- the status label's text.
- (e_select_names_init): get the status message widget from the
- glade ui.
-
-2002-08-28 Chris Toshok <toshok@ximian.com>
-
- [ fixes #19286 ]
- * gui/component/addressbook.c (delete_contact_cb): confirm
- deletion of contacts when using the menubar or toolbar.
-
-2002-08-28 Chris Toshok <toshok@ximian.com>
-
- [ fixes #28897 ]
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_clear_book_data): set book_data to NULL
- after clearing/freeing the list. fixes a crash.
-
-2002-08-28 Chris Toshok <toshok@ximian.com>
-
- [ fixes #20348 ]
- * backend/pas/evolutionperson.schema: deprecate "categories" in
- favor of "category". evolution no longer uses "categories".
-
- * backend/pas/pas-backend-ldap.c (category_populate): new
- function, "category" is the new name, and it's multivalued so we
- need the complex-prop stuff..
- (category_ber): new function, same.
- (category_compare): new function, same.
-
- * gui/component/addressbook.c (addressbook_search_activated): the
- text is "Category is" so we should use "is" instead of "contains"
- for the query.
-
-2002-08-27 Chris Toshok <toshok@ximian.com>
-
- [ Fixes #14835 ]
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_search):
- notify_complete with InvalidQuery if the parse fails.
-
-2002-08-27 Chris Toshok <toshok@ximian.com>
-
- [ fixes #26907 ]
- * gui/component/addressbook.c (addressbook_search_activated): use
- beginswith for email.
-
-2002-08-26 Chris Toshok <toshok@ximian.com>
-
- * printing/e-contact-print.c (complete_sequence): change prototype
- for complete_sequence to match sequence_complete.
- (e_contact_print_button): same.
-
-2002-08-26 Chris Toshok <toshok@ximian.com>
-
- [ fixes #29446 ]
- * gui/component/addressbook-config.c (scope_optionmenu_activated):
- searching_modify_func can be NULL (since we don't require changes
- to enable the "Next" button on this page when you create a
- directory server.)
-
-2002-08-26 Chris Toshok <toshok@ximian.com>
-
- [ Fixes (almost certainly) #24649, #25494, #27351, and other LDAP search crashes ]
- * backend/pas/pas-backend-ldap.c (view_destroy): use an EList
- instead of a GList to store the book_view's so we don't have weird
- issues with modifying the list while it's being traversed.
- (find_book_view): same.
- (create_card_handler): same.
- (remove_card_handler): same.
- (modify_card_modify_handler): same.
- (poll_ldap): same, and also ref the book_view before calling
- ldap_search_op_timeout (and therefore send_pending_adds).
- (ldap_search_handler): same.
- (ldap_op_add): warn about conflicting ldap msgid's (shouldn't ever
- happen..)
- (homephone_populate): make this a bit more robust (if values[0] ==
- NULL, values[1] won't be valid).
- (business_populate): same.
- (build_card_from_entry): break out of the prop_info loop when we
- get a match, and only set the simple field if the value != NULL.
- (ldap_search_dtor): free all the pending adds stuff.
- (pas_backend_ldap_process_get_book_view): g_list_prepend =>
- e_list_append.
- (pas_backend_ldap_remove_client): simplify the removing of the
- book (use g_list_remove instead of searching and then using
- g_list_remove_link.)
- (pas_backend_ldap_destroy): unref the book_views list.
- (pas_backend_ldap_init): initialize the EList for book_views.
-
-2002-08-25 Mike Kestner <mkestner@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (remove_book_view): stop the
- view before unref, in case the listener has pending events.
-
-2002-08-20 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c (book_open_cb): not sure what i was
- thinking here... the EBook isn't valid if we couldn't open it, so
- we can't turn around and query it for its capabilities.
-
-2002-08-19 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names-manager.h: add the
- listener_id slot.
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_new): store off the listener_id.
- (e_select_names_manager_destroy): remove the bonobo listener -
- fixes a crash when modifying the completion folders after you
- bring up a compose window.
- (e_select_names_manager_entry_new): another random timeout change
- - make the completion at 100ms.
-
-2002-08-19 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-book-view.c (pas_book_view_notify_complete):
- take and pass the CallStatus to our listener.
-
- * backend/pas/pas-book-view.h: change the prototype for
- notify_complete to include the CallStatus.
-
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_seq_complete_cb): add the status arg.
-
- * gui/widgets/e-addressbook-view.c
- (e_addressbook_view_class_init): init the search_result signal.
- (e_addressbook_view_init): connect to the model's search_result
- signal.
- (emit_search_result): emit our search_result signal.
- (search_result): call emit_search_result.
-
- * gui/widgets/e-addressbook-view.h (struct
- _EAddressbookViewClass): add the search_result signal.
-
- * gui/widgets/e-addressbook-model.c (sequence_complete): emit both
- a "search_result" as well as the "stop_state_changed" signal.
- (e_addressbook_model_class_init): init the search_result signal.
-
- * gui/widgets/e-addressbook-model.h: add search_result signal.
-
- * gui/component/addressbook.c (search_result): pop up a dialog
- telling the user why the search failed or was truncated.
- (addressbook_factory_new_control): connect to the "search_result"
- signal on the view.
-
- * conduit/address-conduit.c (sequence_complete): add the status
- parameter to sequence_complete.
-
- * backend/idl/addressbook.idl: add BookViewListener_CallStatus,
- and change notifySequenceComplete to take a CallStatus.
-
- * backend/pas/pas-backend-ldap.c (create_card_handler): pass
- status back in the notify_complete call.
- (remove_card_handler): same.
- (modify_card_modify_handler): same
- (ldap_search_handler): same, and parse out the ldap return code so
- we can report limits being properly.
-
- * backend/pas/pas-backend-file.c (do_summary_query): pass status
- back in the notify_complete call.
- (pas_backend_file_search): same, and get rid of the
- status_message, as the status is passed back properly.
- (pas_backend_file_search): pass status
- back in the notify_complete call.
- (pas_backend_file_changes): same.
- (pas_backend_file_process_create_card): same.
- (pas_backend_file_process_remove_card): same.
- (pas_backend_file_process_modify_card): same.
-
- * backend/ebook/e-book-util.c (simple_query_sequence_complete_cb):
- add status parameter.
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_queue_status_event): change name from
- _queue_empty_event, and take a status arg.
- (e_book_view_listener_queue_id_event): init resp->status (to
- SUCCESS).
- (e_book_view_listener_queue_sequence_event): same.
- (e_book_view_listener_queue_message_event): same.
- (impl_BookViewListener_notify_sequence_complete): call
- queue_status_event, and convert the corba status to
- EBookViewStatus.
- (e_book_view_listener_convert_status): new function, conver the
- corba status to EBookViewStatus.
-
- * backend/ebook/e-book-view-listener.h: add a "status" slot to
- EBookViewListenerResponse.
-
- * backend/ebook/e-book-view.h: change prototype for
- sequence_complete signal.
-
- * backend/ebook/e-book-view.c (e_book_view_do_complete_event):
- sequence_complete takes a parameter now (EBookViewStatus).
- (e_book_view_class_init): add the enum arg to the signal.
-
- * backend/ebook/e-book-types.h: add EBookViewStatus enum.
-
-2002-08-19 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_get_static_capabilities): add
- "cache-completions" here, since file completion results are
- blanket cached (as they're generated from a summary).
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_process_get_cursor): there should be no search
- limit on the get_cursor_request, as it's meant to match every card
- it can.
- (ldap_search_handler): parse the ldap result in the
- RES_SEARCH_RESULT case. we'll want more here soon, so we can
- notify the front end if the result was truncated due to either the
- size or time limit being exceeded.
- (pas_backend_ldap_process_get_book_view): in the case of a
- completion view, we hardcode (yeah yeah, i know, but really) the
- search limit to MIN (100, user-specified-limit).
- (pas_backend_ldap_search): each view has its own limit now,
- defaulting from the user specified one for normal searches but
- possibly different for completion views. use the view's limit
- here.
-
-2002-08-19 Dan Winship <danw@ximian.com>
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_get_property_fn): add an "addresses" property, to get the
- "Dan Winship <danw@ximian.com>" form, as opposed to "text", which
- gets you what's displayed, which might be just "Dan Winship".
- (entry_set_property_fn): When setting, just reuse the "text" code,
- since it should properly cardify everything for us anyway.
- (impl_SelectNames_get_entry_for_section): Add the property.
-
-2002-08-16 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-config.c
- (addressbook_source_dialog_set_source): fix c&p error that was
- losing the ssl setting.
-
-2002-08-16 Iain <iain@ximian.com>
-
- * backends/e-book/evolution-ldif-importer.c (ebook_create): Use the
- default EBook instead of the local one.
-
- * backends/e-book/evolution-vcard-importer.c (ebook_create): Ditto.
-
-2002-08-16 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (book_view_notify_status): new
- function to save a little typing.
- (find_book_view): same.
- (pas_backend_ldap_connect): reorder things a bit - set the version
- to VERSION3 *before* doing TLS, as tls requires v3, and if we're
- doing ldaps://, do tls a little differently (not sure if this is
- strictly necessary, but the openldap source did it.. *shrug*).
- also, guard the schema check as this function can be called
- multiple times for the same server (if the server goes down or
- times us out.)
- (pas_backend_ldap_reconnect): new function, reconnect and if
- necessary reauth the user.
- (pas_backend_ldap_process_create_card): use
- find_book_view/book_view_notify_status/pas_backend_ldap_reconnect.
- (pas_backend_ldap_process_remove_card): same.
- (pas_backend_ldap_process_modify_card): same.
- (pas_backend_ldap_process_get_vcard): same.
- (pas_backend_ldap_process_get_cursor): same.
- (pas_backend_ldap_search): same.
- (poll_ldap): reconnect if ldap_result returns -1.
- (pas_backend_ldap_process_authenticate_user): ick ick ick save off
- the dn/passwd we auth with so we can use them to reauthenticate.
-
-2002-08-16 Chris Toshok <toshok@ximian.com>
-
- [ fix 27333 ]
- * gui/widgets/e-addressbook-model.c (get_view): "local" ->
- "do-initial-query".
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_get_static_capabilities): "local" ->
- "local,do-initial-query".
-
- * gui/widgets/e-addressbook-model.c (get_view): "local" ->
- "do-initial-query".
-
- * gui/component/addressbook.c (book_open_cb): Only assume the
- addressbook is local if "local" appears in its static
- capabilities. We still use the ldap special case, but be nicer to
- other networked backends.
-
-2002-08-12 Dan Winship <danw@ximian.com>
-
- * gui/component/addressbook-component.c (user_create_new_item_cb):
- If invoked from a non-contact folder, add the contact to the
- default contact folder, not the local one. If invoked from a
- contact folder, don't append "addressbook.db" to the URI, let
- ebook do the right thing. Fixes #28327 and #28325.
-
- * backend/idl/addressbook.idl (CallStatus): Add NoSuchBook.
- (Initially intended as part of a fix for #28327, but the other
- changes make it so the error code never ends up getting used any
- more, but it's still good to have.)
-
- * gui/widgets/e-addressbook-util.c (e_addressbook_error_dialog):
- Handle NO_SUCH_BOOK.
-
- * backend/ebook/e-book-types.h (EBookStatus): Add
- E_BOOK_STATUS_NO_SUCH_BOOK.
-
- * backend/ebook/e-book-listener.c
- (e_book_listener_convert_status): add case for NoSuchBook.
-
- * backend/ebook/e-book-util.c (e_book_load_local_address_book):
- Kill this. Nothing should ever explicitly load the local
- addressbook.
- (e_book_use_default_book): Replaces e_book_use_local_address_book,
- using the default book instead.
- (e_book_default_book_open): Fall back to local contact folder on
- E_BOOK_STATUS_NO_SUCH_BOOK too.
- (e_book_query_address_default): Use default book, not local.
-
- * gui/component/e-address-widget.c (query_idle_fn): Use the
- default book, not the local book.
-
- * gui/component/select-names/e-select-names-popup.c
- (edit_contact_info_cb): Use the default book, not the local book.
-
- * backend/ebook/e-destination.c (e_destination_cardify): Use the
- default book, not the local book.
- (e_destination_touch): Query the default book, not the local book.
-
- * backend/ebook/e-card-compare.c (e_card_locate_match,
- e_card_locate_match_full): Use the default book, not the local
- book.
-
-2002-08-08 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-summary.c (pas_backend_summary_init):
- initialize summary->upgraded to quiet valgrind.
-
-2002-08-06 Dan Winship <danw@ximian.com>
-
- * backend/ebook/test-client.c (TEST_VCARD): Use "\r" rather than
- including literal CRs in the string, which confuses gcc on OS X.
-
- * backend/ebook/test-card.c (TEST_VCARD): Likewise.
-
-2002-08-01 Chris Toshok <toshok@ximian.com>
-
- [ fixes bug #25958 ]
- * gui/component/addressbook.c (alphabet_state_changed): use
- FULL_NAME in the case where we're untoggling a letter, and... well
- use FULL_NAME in the other case too - we should never pop up the
- advanced dialog.
-
-2002-08-01 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names.h (struct
- _ESelectNames): no more search_entry.
-
- * gui/component/select-names/e-select-names.c (update_query): no
- more search_entry, search_entry => select_entry, and add file_as
- to the query since some entries don't have names (like the Ximian,
- Inc. default card.)
- (e_select_names_init): no more search_entry, and add an "activate"
- handler on select_entry that updates the query.
-
-2002-08-01 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names.h (struct
- _ESelectNames): remove folders and folders_by_uri, and the 2
- listeners.
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_destroy): remove the hash_table_destroys of
- folders and folders_by_uri, since they no longer exist. same for
- other_contacts_listener and local_listener.
-
-2002-08-01 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c (create_component): Use
- "contact-list-16.png" for the "New Contact List" item.
-
-2002-07-31 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c (create_component): Change
- the order so that "New Contact" is first and "New Contact List" is
- next.
-
-2002-07-31 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c (add_creatable_item): Pass
- "contacts" as the @folder_type to
- evolution_shell_component_add_user_creatable_item().
-
-2002-07-31 Chris Toshok <toshok@ximian.com>
-
- [ roll in the following change from the 1.0 branch.]
- * backend/pas/pas-backend-ldap.c:
- (prop_info): change the CALURI and FBURL ecard attributes to map to the
- RFC 2739 specified attributes.
- (check_schema_support): check to see if calEntry is supported.
- (add_objectclass_mod): insert calEntry if it's supported.
- * backend/pas/evolutionperson.schema: deprecate freeBusyURI
- and calendarURI.
-
-2002-07-31 Ettore Perazzoli <ettore@ximian.com>
-
- [Patch by Jacob Berkman <jacob@ximian.com>, fixes #25968]
-
- * backend/ebook/e-book.c (activate_factories_for_uri): Don't
- double free protocol and query.
-
-2002-07-27 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-summary.c (save_string): don't save
- empty strings.
- (pas_backend_summary_save): print out the errno when we fail.
-
-2002-07-26 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook.c: Don't set up the ContactNew and
- ContactNewList verbs.
- (update_command_state): Don't set the sensitivity of
- /commands/ContactNew and /commands/ContactNewList anymore.
- (new_contact_cb): Removed.
- (new_contact_list_cb): Removed.
-
-2002-07-24 Peter Williams <peterw@ximian.com>
-
- * conduit/Makefile.am (libeaddress_conduit_la_LIBADD): Change
- libversit.la -> libversit.a for danw's changes.
-
-2002-07-24 Dan Winship <danw@ximian.com>
-
- * conduit/Makefile.am (libeaddress_conduit_la_LIBADD):
- s/libversit_lt/libversit/
-
-2002-07-22 Dan Winship <danw@ximian.com>
-
- * backend/pas/Makefile.am: Split pas-backend-file and
- pas-backend-ldap out of libpas and build them as separate (noinst)
- libraries libpasfile.a and libpasldap.a. This gets the db3 and
- LDAP dependencies out of libpas, and people trying to create an
- addressbook backend shouldn't be calling functions from the
- existing backends anyway so there's no reason to install them.
-
-2002-07-16 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/select-names.glade: remove the option
- menu and browse button, and add a custom widget placeholder for
- the folder-selector.
-
- * gui/component/select-names/e-select-names.c
- (addressbook_model_set_uri): move the "append /addressbook.db"
- stuff here.
- (e_addressbook_create_ebook_table): remove the code setting
- initial uri from here.
- (e_select_names_folder_free): gone.
- (e_select_names_option_activated): gone.
- (add_menu_item): gone.
- (update_option_menu): gone.
- (new_folder): gone.
- (removed_folder): gone.
- (folder_browse): gone.
- (hookup_listner): gone.
- (add_additional_select_names_uris): gone.
- (e_select_names_hookup_listners): gone.
- (e_addressbook_create_folder_selector): new function, create the
- folder selector button.
- (folder_selected): new function, callback for the folder selector.
- just calls addresbook_model_set_uri.
- (e_select_names_init): get the folder selector and initialize it
- to show /local/Contacts. also, set the model's uri here to the
- same folder. nuke the code involving the old option menu and
- browse button.
-
-2002-07-08 Peter Williams <peterw@ximian.com>
-
- * backend/ebook/Makefile.am: Install libebook-static.la.
- Also change --all-static to -all-static, which is the right flag.
-
- * backend/pas/Makefile.am: Install the PAS headers in
- $(includedir)/evolution/pas. Install libpas.a
-
-2002-07-08 Peter Williams <peterw@ximian.com>
-
- * gui/component/select-names/Makefile.am (idl_DATA): Install the
- SelectNames IDL and ancillary changes.
-
-2002-07-12 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-summary.c (free_summary_item): free the
- full_name (as well as given_name. oops.)
- (pas_backend_summary_new): new summaries are version 3.0 now.
- (pas_backend_summary_load_item): all loaded summaries should be
- 3.0+, as we fail to load versions lower than that.
- (pas_backend_summary_load_header): if the summary isn't version
- 3.0 fail out, as we need to rebuild the entire file to cache the
- full_name fields.
- (pas_backend_summary_save_item): save out the full_name.
- (pas_backend_summary_add_card): put the item's full_name in the
- card.
-
-2002-07-12 Dan Winship <danw@ximian.com>
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_get_property_fn): Make the
- ENTRY_PROPERTY_ID_SIMPLE_CARD_LIST case not crash, although
- there's still something wrong.
-
-2002-07-10 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_start_query): e_book_get_book_view =>
- e_book_get_completion_view, so the backends have the option of
- using a pregenerated summary.
-
-2002-07-10 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-summary.c (clear_items): actually remove
- the items from the pointer array too, so an error while loading
- doesn't leave the memory summary corrupted.
- (pas_backend_summary_load_header): bleah, load the num_items and
- summary_mtime in the right order :) Also, set upgraded to TRUE if
- we loaded a v1.0 summary.
- (pas_backend_summary_open): make this return a gboolean, return
- TRUE if the summary is already open (priv->fp != NULL). return
- FALSE in error conditions.
- (pas_backend_summary_load): if summary_open returns FALSE, return
- FALSE, also set the dirty flag to FALSE after we load, and if the
- summary was upgraded write it out.
- (pas_backend_summary_save): update the in memory mtime to that of
- the file when we save.
- (summary_flush_func): if we're not dirty, do nothing and return.
- (pas_backend_summary_is_up_to_date): make sure we've opened the
- summary.
- (pas_backend_summary_get_summary_vcard): fix compiler warning.
-
-2002-07-10 Peter Williams <peterw@ximian.com>
-
- * backend/ebook/e-book-view-listener.h: Oops, missed this one.
-
- * backend/ebook/Makefile.am (libebookinclude_HEADERS): Also
- put addressbook.h here because several headers reference it.
-
-2002-07-08 Peter Williams <peterw@ximian.com>
-
- * backend/ebook/e-book.h: Normalize includes to <ebook/foo.h>, so
- that the installed headers will work sanely.
-
- * backend/ebook/e-card-cursor.h:
- * backend/ebook/e-book-view.h:
- * backend/ebook/e-card-simple.h:
- * backend/ebook/e-card.h:
- * backend/ebook/e-destination.h: Same.
-
- * printing/Makefile.am (INCLUDES): add -Iaddressbook/backend
- to access the ebook headers. Also the builddir version to get
- the generated addressbook.h
-
- * conduit/Makefile.am (INCLUDES): Same.
-
- * gui/widgets/Makefile.am (INCLUDES): Same builddir fix.
-
- * gui/merging/e-card-merging.c: Fix an ebook #include.
-
- * gui/merging/Makefile.am (INCLUDES): Same idea.
-
- * gui/contact-list-editor/Makefile.am (INCLUDES): Same.
-
- * gui/contact-editor/Makefile.am (INCLUDES): Same builddir
- change.
-
-2002-07-10 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-storage.c (load_source_data): Pass
- zero as the @sorting_priority to evolution_storage_new_folder().
- (addressbook_storage_add_source): Likewise.
-
-2002-07-10 Chris Toshok <toshok@ximian.com>
-
- * backend/idl/addressbook.idl: add Book.getCompletionView.
-
- * backend/ebook/e-book.c (e_book_get_completion_view): new
- function, basically c&p of e_book_get_book_view, but call
- getCompletionView.
-
- * backend/ebook/e-book.h: add prototype for
- e_book_get_completion_view.
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_process_client_requests): add a
- GetCompletionView case here that just calls the same code as
- GetBookView (since we don't build summaries for the ldap backend.)
-
- * backend/pas/pas-backend-file.c (do_summary_query): add
- @completion_search. If it's TRUE, just create the vcards from the
- summary using pas_backend_summary_get_summary_vcard instead of
- looking them up from the db.
- (pas_backend_file_search): add @completion_search and pass it on
- to do_summary_query.
- (pas_backend_file_process_get_book_view): pass FALSE to
- pas_backend_file_search.
- (pas_backend_file_process_get_completion_view): new function,
- basically c&p pas_backend_file_process_get_book_view, but pass
- TRUE to pas_backend_file_search.
- (pas_backend_file_process_client_requests): add a case for
- GetCompletionView.
- (pas_backend_file_load_uri): track the change to the summary api -
- create the summary filename
-
- * backend/pas/pas-book.c (pas_book_queue_get_completion_view): new
- function, queue a GetCompletionView request to our queue.
- (impl_GNOME_Evolution_Addressbook_Book_getCompletionView): new
- function, call pas_book_queue_get_completion_view.
- (pas_book_respond_get_completion_view): new function, just call
- notifyViewRequested.
- (pas_book_free_request): add a case for GetCompletionView.
- (pas_book_get_epv): fill in epv->getCompletionView.
-
- * backend/pas/pas-book.h: add a GetCompletionView PASOperation,
- and a new structure (PASGetCompletionViewRequest). Also, add
- get_completion_view to PASRequest.
-
- * backend/pas/pas-backend-summary.c (clear_items): remove the
- items from the hash table.
- (pas_backend_summary_new): db_path -> summary_path.
- (pas_backend_summary_destroy): db_.path -> summary_path, and
- destroy the hash table.
- (pas_backend_summary_init): db_path = summary_path, and initialize
- the id_to_item hashtable.
- (pas_backend_summary_load_header): handle the upgrading from
- version 1.0 to version 2.0 (the addition of an mtime field in the
- header)
- (pas_backend_summary_load_item): version 1.0 and 2.0 have the same
- format for items.
- (pas_backend_summary_open): new function. open the summary so we
- can load the header (and get the mtime).
- (pas_backend_summary_load): rework this a bit since the header has
- already been loaded, and also add the items to the hashtable.
- (pas_backend_summary_add_card): add the new item to the hashtable.
- (pas_backend_summary_remove_card): remove the item from the hash
- table.
- (pas_backend_summary_is_up_to_date): new function, chekc @t
- against the summary's mtime.
- (pas_backend_summary_get_summary_vcard): create a vcard from the
- fields we have in the summary.
-
- * backend/pas/pas-backend-summary.h: add prorotypes for
- pas_backend_summary_is_up_to_date and
- pas_backend_summary_get_summary_vcard.
-
-2002-07-09 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-storage.c (load_source_data): Pass
- NULL @custom_icon_name to evolution_storage_new_folder().
- (addressbook_storage_add_source): Likewise. [Note we could be
- passing a nice custom here. ;-)]
-
-2002-07-02 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c (add_creatable_item): New
- arg @tooltip; pass it to
- evolution_shell_component_add_user_creatable_item() [which now has
- a @tooltip arg].
-
-2002-06-29 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/Makefile.am (libpas_a_SOURCES): add
- pas-backend-summary.[ch].
-
- * backend/pas/pas-backend-file.c (string_to_dbt): move this to the
- top of the file so it can be used in..
- (build_summary): loop over the db, adding cards ot the summary.
- (do_summary_query): call pas_backend_summary_search and loop over
- the returned id's looking them up in the db.
- (pas_backend_file_search): call
- pas_backend_summary_is_summary_query, and either call
- do_summary_query if it's a query over just the set of attributes
- in the summary or use the old, slow method if not.
- (pas_backend_file_process_create_card): call
- pas_backend_summary_add_card.
- (pas_backend_file_process_remove_card): call
- pas_backend_summary_remove_card.
- (pas_backend_file_process_modify_card): call remove_card/add_card.
- (pas_backend_file_load_uri): try to load the summary file, and if
- it doesn't exist create it.
- (pas_backend_file_destroy): unref the summary.
-
- * backend/pas/pas-backend-summary.[ch]: new files, reading and
- writing (and querying) summaries.
-
-2002-06-27 Sean Atkinson <sean@cantab.net>
-
- * gui/component/addressbook-config.c (query_for_supported_bases):
- don't unref selection_model (otherwise 3 clicks of
- "Show Supported Bases" crashes if LDAP server isn't running).
-
-2002-06-25 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-component.c (create_component):
- reorder the adding of creatable items so the default is a new
- contact, not a new contact list.
-
-2002-06-21 Sean Atkinson <sean@cantab.net>
-
- * gui/component/addressbook-config.c (addressbook_edit_server_dialog):
- remove source argument (get it from the dialog).
- (edit_source_clicked): same.
- (sources_table_double_click): added to edit server by double-clicking.
- (ldap_dialog_new): use sources_table_double_click.
-
-2002-06-17 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (e_addressbook_view_save_as):
- pass NULL to e_contact_list_save_as. modality sucks. fixes
- broken build.
- (save_as): same.
-
-2002-06-15 Chris Toshok <toshok@ximian.com>
-
- [ fixes bug #26130 ]
- * gui/contact-editor/e-contact-editor.c (file_save_as_cb): pass
- ce->app as parent_window.
-
- * gui/contact-list-editor/e-contact-list-editor.c
- (file_save_as_cb): same .
-
- * gui/contact-editor/e-contact-save-as.c (e_contact_list_save_as):
- if a parent_window is specified, the file selector should be
- modal/transient for that window.
- (e_contact_save_as): same.
-
- * gui/contact-editor/e-contact-save-as.h: track prototype changes
- (addition of GtkWindow *parent_window to both calls.)
-
-2002-06-15 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_connect): use
- ldap_unbind_ext.
- (create_card_handler): don't leak the new vcard.
- (pas_backend_ldap_process_authenticate_user): don't leak the dn.
-
-2002-06-14 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_search): up the
- max threshold to 3000 cards from 1000 cards.. seems to improve
- performance a bit. also remove the g_list_reverse since it
- doesn't matter what order the cards arrive to the gui.
- (pas_backend_file_changes): plug memory leaks.
-
-2002-06-14 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-compare.c (compare_email_addresses): Made
- "" compare as not equal to "" for addresses.
- (use_common_book_cb): Don't bother checking for nickname here
- since we don't use it as a match later. Don't add "" as an
- address to the list of query parts.
-
-2002-06-13 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c (enable_writable_fields):
- Don't enable fields if the editor isn't editable and the
- widget_field_mappings lists this field as being desensitize for
- read only.
-
-2002-06-11 Chris Toshok <toshok@ximian.com>
-
- [ fixes bug #17332 ]
- * backend/ebook/e-book.c (e_book_get_static_capabilities): we
- shouldn't ever return NULL here. in error cases we need to return
- g_strdup("");
-
-2002-06-11 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-minicard-view.c (e_minicard_view_event): Made
- double clicking on read only folders not do anything.
-
-2002-06-10 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-book-util.c (e_book_expand_uri): Made expand_uri
- a bit more robust and readable.
- (e_book_get_default_book_uri): Made e_book_get_default_book_uri
- use e_book_expand_uri if using the bonobo_config value.
-
- * gui/component/e-address-popup.c (start_query): Handle the
- failure state here by acting as if there are no matches.
-
-2002-06-05 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-minicard.c (e_minicard_event): Call
- e_minicard_selected in the GDK_BUTTON_RELEASE case here.
- (e_minicard_drag_begin): Set E_REFLOW (parent)->maybe_in_drag =
- FALSE if it's an EReflow.
-
-2002-06-04 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_book_ready): Commented out this unused
- function.
-
- * gui/component/select-names/e-select-names-manager.c
- (open_book_cb): Ref if we're keeping the book. Don't unref if
- we're not keeping the book.
- (clean_cb): Commented out this unused function.
-
-2002-06-04 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (init_collection): Set the
- title of our GalVIewCollection.
-
-2002-05-29 Anna Marie Dirks <anna@ximian.com>
-
- * gui/component/select-names/select-names.glade: Changed some spacing
- and expanding behavior to make this dialog behave more like I intended
- to.
-
-2002-05-24 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-config.c (CONFIG_CONTROL_FACTORY_ID):
- put this back in, accidentally got snipped with the hacking going
- on in here.
-
-2002-05-24 Chris Toshok <toshok@ximian.com>
-
- [ part of #25047 ]
- * gui/component/addressbook-config.c: remove the autocompletion
- config control from here, as it lives in the shell now.
-
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: same.
-
-2002-05-24 Chris Toshok <toshok@ximian.com>
-
- [ #24189 ]
- * gui/component/select-names/e-select-names-manager.c
- (focus_out_cb): ifdef out the body of this because it only works
- with a single completion book. not sure what to do here, but it
- doesn't impact most usage scenarios.
- (completion_popup_cb): same.
- (e_select_names_manager_entry_new): add the books that have been
- loaded successfully by the time this entry is created.
- (open_book_cb): add the opened book to the entries that have
- already been created, and store it in our list so that entries
- that are created in the future can catch up.
- (read_completion_books_from_db): slurp in the folder list from the
- config db and load all the uris.
- (uris_listener): listener function - when there's a change it
- calls _clear_books on all the created entries, and clears our
- list. It then re-reads the books from the db.
- (e_select_names_manager_new): create our bonobo listener and call
- read_completion_books_from_db.
- (e_select_names_manager_init): init completion_books.
- (e_select_names_manager_destroy): free our list of
- completion_books.
-
- * gui/component/select-names/e-select-names-manager.h: switch from
- a single EBook to a GList of completion_books here.
-
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_add_book): deal with the case where
- there's an active query (by effectively restarting it.) This is
- quite a contrived edge case.
- (e_select_names_completion_clear_books): stop the current query
- and clear our list of books.
- (e_select_names_completion_new): track change to prototype, and
- axe the majority of this method since an EBook* isn't passed
- anymore.
- (e_select_names_completion_clear_book_data): split this code out
- from the destroy method so it can be called from _clear_books.
-
- * gui/component/select-names/e-select-names-completion.h: the
- constructor no longer takes an EBook -- pass in as many as you
- want using _add_book. Also, add prototype for _clear_books.
-
- * gui/component/addressbook.c (load_uri_cb): when
- storing/retrieving passwords, use the cleaned (without params)
- version of the uri, so changing things like download limit don't
- cause the user to be prompted for a password again.
-
- * gui/component/addressbook-component.c
- (ensure_completion_uris_exist): new function - probably doesn't
- belong in this file. Make sure the basic local Contacts folder
- exists in the completion uris.
- (addressbook_component_factory_init): call
- ensure_completion_uris_exist.
-
- * backend/ebook/e-book-util.h: add prototype for
- e_book_get_default_book_uri.
-
- * backend/ebook/e-book-util.c (e_book_get_default_book_uri): new
- function, just return the default contacts uri.
- (e_book_load_default_book): change
- to use e_book_get_default_book_uri.
-
-2002-05-23 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-config.c (addressbook_root_dse_query):
- fix parameter/local variable overloading.
-
-2002-05-21 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook.c (load_uri_cb): Don't try to invoke
- e_book_get_uri() on NULL. Fixes #25069.
-
-2002-05-17 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-addressbook-util.c (e_addressbook_error_dialog):
- make sure we map status -> string correctly (add missing strings).
-
- * backend/ebook/e-book-types.h (EBookStatus): add the missing
- AUTHENTICATION_REQUIRED status code, to map to the idl response.
-
- * backend/ebook/e-book-listener.c
- (e_book_listener_convert_status): make sure we map all idl status
- codes to EBookStatus statuses.
-
-2002-05-20 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-storage.c (load_source_data): Pass
- FALSE for @sync_offline to evolution_storage_new_folder().
- (addressbook_storage_add_source): Pass FALSE for @sync_offline to
- evolution_storage_new_folder().
-
-2002-05-16 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c (request_quit): New, quit
- handler for the EvolutionShellComponent.
- (add_creatable_item): Set it up.
-
- * gui/contact-editor/e-contact-list-editor.c
- (e_contact_list_editor_request_close_all): New.
- (e_contact_list_editor_new): Put the contact editor in a static
- list and gtk_object_weakref() it.
- (contact_list_editor_destroy_notify): New, GtkDestroyNotify
- function for the contact editors.
-
- * gui/contact-editor/e-contact-editor.c
- (e_contact_editor_request_close_all): New.
- (e_contact_editor_new): Put the contact editor in a static list
- and gtk_object_weakref() it.
- (contact_editor_destroy_notify): New, GtkDestroyNotify function
- for the contact editors.
-
-2002-05-15 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c (create_component): Pass
- NULL as @request_quit_fn.
-
-2002-05-13 Christopher James Lahey <clahey@ximian.com>
-
- * backend/idl/addressbook.idl: Removed an incorrect comment here.
-
-2002-05-13 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c (enable_writable_fields):
- Enable the dropdown widgets even if the contact is not editable so
- that you can view any email address, phone number, or postal
- address on read only contacts.
-
-2002-05-10 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/Evolution-Addressbook-SelectNames.idl:
- Added SimpleCard interface.
-
- * gui/component/select-names/Makefile.am: Added
- e-simple-card-bonobo.c and e-simple-card-bonobo.h.
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_get_property_fn): Added SIMPLE_CARD_LIST arg.
-
- * gui/component/select-names/e-simple-card-bonobo.c,
- gui/component/select-names/e-simple-card-bonobo.h: New class to
- represent an ECardSimple across Bonobo.
-
-2002-05-09 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_get_property_fn): Added "first_email" property.
-
-2002-05-09 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-storage.c
- (addressbook_get_other_contact_storage): Pass %FALSE as
- @has_shared_folders to evolution_storage_new().
-
-2002-05-08 JP Rosevear <jpr@ximian.com>
-
- * conduit/Makefile.am: link against the libtool version of
- libversit
-
-2002-05-07 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-config.c
- (addressbook_config_control_new): oops, add the NULL back at the
- end of possible_types.
-
-2002-05-07 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-config.c (addressbook_ldap_init):
- bleah, need to pass the GtkWindow here so we can pop up the a
- modal parented dialog (gtk modal dialogs suck?).
- (addressbook_ldap_auth): same.
- (addressbook_root_dse_query): same.
- (do_ldap_root_dse_query): same.
- (addressbook_config_control_new): add "ldap-contacts" to the list
- of possible types.
-
-2002-05-07 Dan Winship <danw@ximian.com>
-
- * gui/component/addressbook-storage.c (create_ldap_folder):
- s/ldap_config/addressbook_config/
-
-2002-05-03 Chris Toshok <toshok@ximian.com>
-
- * backend/ebook/e-book.c (activate_factories_for_uri): finally
- remove the #if 0's and use the oaf query stuff to get backends
- that handle specific protocols.
-
-2002-05-03 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook-config.c
- (addressbook_folder_list_changed_callback): Call
- evolution_config_control_changed when the EFolderList changes.
-
-2002-05-03 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: Updated this
- to have the ConfigControlFactory have an addressbookwide generic
- name and added OAFIID:GNOME_Evolution_Addressbook_ConfigControl.
-
- * gui/component/Makefile.am (evolution_addressbook_SOURCES),
- gui/component/addressbook-component.c,
- gui/component/addressbook-storage.c, gui/component/addressbook.c:
- Replaced ldap-config.c and ldap-config.h with addressbook-config.c
- andaddressbook-config.h.
-
- * gui/component/addressbook-config.c,
- gui/component/addressbook-config.h: Based on ldap-config.c and
- ldap-config.h. Added a folder list control. Made this a multi
- factory.
-
- * gui/component/ldap-config.c, gui/component/ldap-config.h:
- Replaced these with addressbook-config.c and addressbook-config.h.
-
-2002-05-02 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c (selection_change):
- Desensitize the to, cc, and bcc buttons if there's no selection
- here. Fixes Ximian bug #21482.
-
-2002-05-01 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-list-editor/e-contact-list-editor.c (verbs): Changed
- some of these to bind to the ContactListEditor verbs since they're
- marked as that in the ui file. Fixes Ximian bug #13034.
-
-2002-04-30 JP Rosevear <jpr@ximian.com>
-
- * gui/component/Makefile.am (EXTRA_DIST): fix
-
-2002-04-30 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-model.c,
- gui/widgets/e-addressbook-model.h
- (e_addressbook_model_peek_card): Added this function so that there
- would be less duplication of cards during run time when
- duplication is unnecessary.
-
- * gui/widgets/e-addressbook-view.c: Cleaned up get_card_list and a
- number of associated functions to be much more uniform and
- simpler.
- (get_has_email_address): Don't show the "Send Message to Contact"
- menu item if there are no email addresses in the listed contacts.
- Fixes bug #1298.
-
-2002-04-30 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card.c (e_card_list_send): Changed this to set a
- subject when sending a contact. This makes the signature be set
- properly also.
-
-2002-04-26 Jeffrey Stedfast <fejj@ximian.com>
-
- * printing/Makefile.am: Don't link to libibex anymore.
-
- * conduit/Makefile.am: Same.
-
- * backend/ebook/Makefile.am: Again here.
-
- * gui/component/Makefile.am: And finally here.
-
-2002-04-26 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_child_free): Unref the text_model here instead of
- the model, since the model never gets set. Removed the model
- field since it's no longer used.
-
-2002-04-24 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/ldap-config.c: Updated this for the new
- e_table_memory_store_insert function prototype.
-
-2002-04-24 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c,
- gui/component/select-names/e-select-names.h,
- gui/component/select-names/select-names.glade (folder_browse):
- Added a "Browse..." button to switch to a different addressbook
- folder.
-
- * gui/widgets/e-addressbook-util.c (e_addressbook_transfer_cards):
- Moved extern EvolutionShellClient out of this function so that
- it'd be more readable.
-
-2002-04-23 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c,
- gui/component/select-names/e-select-names.h: Coded handling of the
- select_entry to search within the displayed contacts.
-
- * gui/component/select-names/select-names.glade: Updated this
- dialog to have an entry-select instead of an entry-find.
-
-2002-04-23 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/select-names.glade: Updated this
- dialog to match the redesign.
-
-2002-04-23 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (do_popup_menu): Make unused
- menu items disappear instead of graying out.
-
-2002-04-23 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-reflow-adapter.c,
- gui/widgets/e-addressbook-reflow-adapter.h: Removed
- e_addressbook_reflow_adapter_right_click and
- e_addressbook_reflow_adapter_base_right_click.
-
- * gui/widgets/e-addressbook-view.c: Handle right click menu for
- both types of view. Merged right click on white space with right
- click on main area. General clean up.
-
- * gui/widgets/e-minicard-view-widget.c,
- gui/widgets/e-minicard-view-widget.h: Removed a couple unnecessary
- functions. Added e_minicard_view_widget_get_view. Added
- right_click signal.
-
- * gui/widgets/e-minicard-view.c, gui/widgets/e-minicard-view.h:
- Added the right_click signal and the e_minicard_view_get_card_list
- function.
-
-2002-04-22 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.h: Removed an unused
- variable here.
-
- * gui/widgets/e-addressbook-view.c (table_right_click,
- table_white_space_event): Added a current view submenu to the
- popup menu here.
-
-2002-04-22 Jeffrey Stedfast <fejj@ximian.com>
-
- * gui/widgets/e-minicard-view.c (e_minicard_view_drag_begin):
- Allow GDK_ACTION_COPY also, since the composer for example does
- not accept MOVE's. Completes bug #8448.
-
-2002-04-18 Chris Toshok <toshok@ximian.com>
-
- * gui/component/ldap-config.glade: change order of scope option
- menu to match how it's stored.
-
-2002-04-18 Chris Toshok <toshok@ximian.com>
-
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: change ldap
- config control text so it fits in the config dialog.
-
- * gui/component/ldap-config.c: #ifdef lots of stuff HAVE_LDAP so
- it'll build/run in either case.
- (addressbook_source_dialog_destroy): rename
- addressbook_add_server_druid_destroy to this, and free lots more
- stuff.
- (addressbook_add_server_druid):
- addressbook_add_server_druid_destroy ->
- addressbook_source_dialog_destroy.
- (do_schema_query): add 3 second timeout to schema query.
- (addressbook_edit_server_dialog): hook up destroy signal.
- (config_control_new): if HAVE_LDAP isn't defined, put up a label
- saying so.
-
-2002-04-18 Chris Toshok <toshok@ximian.com>
-
- * gui/component/Makefile.am (INCLUDES): add LDAP_CFLAGS to INCLUDES
-
-2002-04-18 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c (book_open_cb): no more
- source->type.
-
-2002-04-18 Chris Toshok <toshok@ximian.com>
-
- * gui/component/ldap-config.c (addressbook_dialog_get_source):
- fill in source->ssl.
- (addressbook_source_dialog_set_source): set up auth/scope/ssl
- option menus properly.
-
- * gui/component/addressbook-storage.c
- (addressbook_storage_init_source_uri): always include the
- limit/ssl in the uri so we don't need to rely on defaults
- everywhere.
- (ldap_source_foreach): store the ssl option.
-
- * gui/component/addressbook-storage.h: reorder SSLType to match
- the UI.
-
- * backend/pas/pas-backend-ldap.c: (struct _PASBackendLDAPPrivate)
- add field for ldap_timeout.
- (pas_backend_ldap_connect): reorder things a bit - we need to
- start tls before the root dse query, if we can.
- (pas_backend_ldap_load_uri): track the way ssl parameters are
- given in the uri, and parse out the timeout.
-
- * gui/component/ldap-config.c (port_changed_func): use the
- symbolic SSL name instead of an integer constant.
-
-2002-04-18 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (get_ldap_library_info): fix
- memory leaks.
-
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: remove the
- Addressbook_ConfigControl stuff to LDAP_ConfigControl.
-
- * gui/component/Makefile.am (evolution_addressbook_SOURCES):
- remove addressbook-config.* and add ldap-config.*
- (glade_DATA): same.
- (evolution_addressbook_LDADD): add LDAP_LIBS.
-
- * gui/component/addressbook-component.c (owner_set_cb):
- addressbook_config_register_factory =>
- ldap_config_register_factory.
-
- * gui/component/addressbook.c (book_open_cb): remove source->type
- check - they're always LDAP.
- (load_uri_cb): same.
-
- * gui/component/addressbook-storage.c (ldap_unparse_ssl): new
- function.
- (ldap_parse_ssl): new function.
- (addressbook_storage_init_source_uri): use a more flexible scheme
- to build up the uri's, and add in the ssl parameter.
- (load_source_data): fill in source->ssl, and remove source->type
- assignment.
- (addressbook_source_copy): copy source->ssl, and remove
- source->type copy.
- (create_ldap_folder): addressbook_create_new_source =>
- ldap_config_create_new_source.
-
- * gui/component/addressbook-storage.h: remove
- AddressbookSourceType (it was always LDAP), and add
- AddressbookLDAPSSLType.
-
-2002-04-18 Dan Winship <danw@ximian.com>
-
- * backend/ebook/e-book-util.c (e_book_load_default_book): Append
- /addressbook.db to the end of the default URI if it starts with
- file:
-
- * backend/ebook/e-book.c (e_book_load_uri_step): Fix this to not
- loop forever if you have more than one backend.
-
-2002-04-17 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_create_categories): Changed this to use
- ECategoriesMasterListOptionMenu.
-
- * gui/component/select-names/e-select-names.c
- (section_right_click_cb),
- gui/widgets/e-addressbook-reflow-adapter.c,
- gui/widgets/e-addressbook-view.c: Updated these to match the new
- EPopupMenu.
-
-2002-04-11 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook-component.c: Include
- addressbook-config.h here as this file uses it.
-
- * gui/component/select-names/e-select-names.c (SPEC, SPEC2): Made
- this dialog searchable by typing in the ETable.
-
- * gui/widgets/e-addressbook-model.c: Include e-addressbook-util.h
- here.
-
- * gui/widgets/e-addressbook-reflow-adapter.c
- (e_addressbook_reflow_adapter_right_click),
- gui/widgets/e-addressbook-view.c (table_right_click): Fixed a
- memory leak here by using "selection-done" signal.
-
- * gui/widgets/e-addressbook-reflow-adapter.c,
- gui/widgets/e-addressbook-reflow-adapter.h,
- gui/widgets/e-addressbook-view.c, gui/widgets/e-minicard-view.c:
- Added a right click menu for areas that aren't cards.
-
-2002-04-09 Dan Winship <danw@ximian.com>
-
- * backend/ebook/e-book-util.c (e_book_load_default_book): Update
- for new-and-improved consistent default folder uri.
-
- * gui/component/addressbook.c (addressbook_load_default_book): Use
- e_book_load_default_book rather than duplicating most of its logic
- here.
- (load_uri_cb): Modify to work as a callback for
- addressbook_load_default_book as well as addressbook_load_uri.
-
-2002-04-08 Dan Winship <danw@ximian.com>
-
- * gui/component/addressbook-component.c (create_view): Add
- view_info arg, but don't do anything with it.
-
-2002-04-06 JP Rosevear <jpr@ximian.com>
-
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: add
- config_item:type
-
-2002-04-04 JP Rosevear <jpr@ximian.com>
-
- * conduit/Makefile.am: link to the static libversit
-
-2002-04-04 Dan Winship <danw@ximian.com>
-
- * gui/widgets/e-addressbook-util.c (e_addressbook_transfer_cards):
- Update for evolution_shell_client_user_select_folder API change.
-
-2002-04-04 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook.c: Remove AddressbookConfig,
- ContactNew, ContactNewList EPixmap entries.
-
- * gui/component/addressbook-factory.c (main): Print out a
- debugging message just before the main loop starts, for debugging
- purposes.
-
-2002-04-02 Dan Winship <danw@ximian.com>
-
- * backend/ebook/e-card-simple.h: Fix spelling of
- E_CARD_SIMPLE_PHONE_ID_TTYTDD and E_CARD_SIMPLE_FIELD_PHONE_TTYTDD
- (they previously ended with "TTD" instead of "TDD")
-
- * backend/ebook/e-card-simple.c: Update for spelling fix.
-
- * backend/pas/pas-backend-ldap.c: Likewise
-
-2002-04-01 Dan Winship <danw@ximian.com>
-
- * gui/component/select-names/e-select-names-text-model.c:
- parent_class should be static. (From Max Horn <max@quendi.de>)
-
-2002-03-29 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: Add priority
- for the config page. Renamed to "Directory Servers".
-
-2002-03-27 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_process_create_card): don't free req->vcard.
- it's freed in pas_book_free_request.
- (pas_backend_file_process_remove_card): don't free req->id for the
- same reason.
- (pas_backend_file_process_modify_card): don't free req->vcard for
- the same reason.
- (pas_backend_file_process_get_changes): don't free req->change_id
- or release_unref the listener for the same reason.
-
-2002-03-27 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (check_schema_support): make sure
- to call ldap_value_free (values);, and ldap_msgfree (resp).
- (get_ldap_library_info): don't ask me why, but it appears we have
- to free each extension char*.
- (query_ldap_root_dse): make sure to free values in the
- subschemaSubentry code before overwriting it, and call
- ldap_msgfree(resp) when we're all done.
- (build_card_from_entry): don't leak the DN, ldap attributes, or
- the berval the ldap_*_attribute calls use to step through the
- attributes. the docs say this berval is freed when
- ldap_next_attribute returns NULL, but if we don't free it it leaks
- a substantial amount of memory.
- (pas_backend_ldap_search): make sure to only allocate *op once,
- and fix the g_warning since op isn't valid in its scope anymore.
-
-2002-03-19 Dan Winship <danw@ximian.com>
-
- * backend/ebook/Makefile.am: Update for libversit change: Use .a
- rather than .la now.
-
- * printing/Makefile.am: Likewise
-
- * gui/component/Makefile.am: Likewise
-
-2002-03-18 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook.c (addressbook_menu_activated):
- Removed.
- (addressbook_factory_new_control): Don't connect anymore, as this
- signal has been removed from the ESearchBar.
- (addressbook_factory_new_control): No more custom menu items here.
-
-2002-03-15 Jeffrey Stedfast <fejj@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (table_right_click): Update to
- use new EPopupMenu API.
-
- * gui/widgets/e-addressbook-reflow-adapter.c
- (e_addressbook_reflow_adapter_right_click): Update to use new
- EPopupMenu API.
-
- * gui/component/select-names/e-select-names.c
- (section_right_click_cb): Update to match new EPopupMenu api.
-
-2002-03-15 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook.c: Remove the
- `addressbook_search_menu_items'.
- (addressbook_menu_activated): Removed.
- (addressbook_factory_new_control): Don't connect. No menu items.
-
-2002-03-15 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook.c (control_activate): Call
- `e_search_bar_set_ui_component()' to set the BonoboUIComponent for
- the search bar.
-
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: Add an icon
- for the LDAP sources configuration control.
-
-2002-03-12 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook.c: Remove verb "AddressbookConfig".
- (config_cb): Removed.
-
- * gui/component/addressbook-config.c: Remove `dialog' member from
- `AddresbookDialog'. Instead, add a `config_control' member.
- (config_control_new): New.
- (addressbook_config): Removed.
- (addressbook_config_register_factory): New.
- (config_control_factory_fn): New, factory function for the
- ConfigControl page.
- (addressbook_source_edit_changed): Don't change the sensitivity of
- the dialog. Rather, invoke ::changed on the ConfigPage.
- (auth_checkbutton_changed): No need to manually change the
- sensitiviness of the buttons here either.
- (add_source_clicked): Likewise, just invoke
- evolution_config_control_changed().
- (edit_source_clicked): Likewise.
- (addressbook_dialog_close): Removed.
- (config_control_destroy_callback): New, callback for when the
- config control gets destroyed.
- (addressbook_dialog_apply): Removed.
- (config_control_apply_callback): New callback for
- EvolutionConfigControl::apply.
- (addressbook_dialog_ok): Removed.
- (addressbook_config_control_new): Set up ->config_control and
- connect the signals.
-
- * gui/component/addressbook-config.glade: Call the main hbox in
- the addressbook_sources dialog `addressbook_sources_main_hbox'.
-
- * gui/component/addressbook-component.c (owner_set_cb): Call
- `addresbook_config_register_factory'.
-
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: Add items for
- OAFIID:GNOME_Evolution_Addresbook_ConfigControl and
- OAFIID:GNOME_Evolution_Addressbook_ConfigControlFactory.
-
-2002-03-11 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names.c (update_query):
- change contains x-evolution-any-field to beginswith on email,
- full_name, and nickname. faster, and more applicable to this
- dialog.
-
-2002-03-09 Chris Toshok <toshok@ximian.com>
-
- * backend/idl/addressbook.idl: add TLSNotAvailable to
- BookLister_CallStatus.
-
- * backend/ebook/e-book-types.h: add TLS_NOT_AVAILABLE to the EBookStatus enum.
-
- * backend/ebook/e-book-listener.c
- (e_book_listener_convert_status): add TLS_NOT_AVAILABLE to the
- switch.
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_get_static_capabilities): fix name.
- (pas_backend_ldap_class_init): fix name.
- (pas_backend_ldap_connect): change return type to CallStatus so we
- can return different errors from here. Also, do STARTTLS if the
- user has asked for it and the connection supports it, returning
- TLSNotAvailable (and close the connection) if they chose to
- require it.
- (pas_backend_ldap_load_uri): return pas_backend_ldap_connect.
- (func_beginswith): pull in change from evolution-1-0-branch to
- make full_name beginswith search both cn and sn.
-
-2002-03-09 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (jump_to_letter): since I've
- gone ahead and made the file backend (by way of
- pas-backend-card-sexp.c) use case insensitive searches for
- beginswith, there's no need to list upper and lower case here.
-
- * gui/component/addressbook.c (addressbook_search_option_items):
- reorder things to put "Any field contains" at the end, since it's
- the least efficient search. Also reorder the enum to the same
- ordering. Change "Name contains" to "Name begins with" and change
- "Email contains" to "Email is".
- (addressbook_search_activated): change FULL_NAME to beginswith,
- and change EMAIL to is to match the labels.
-
- * backend/pas/pas-backend-card-sexp.c (compare_name): new
- function, so we can compare both full and family names (so
- beginswith can operate on them both.)
- (endswith_helper): use e_utf8_strstrcase here, since all the
- backends backends use case insensitive searching.
- (func_endswith): same.
-
-2002-03-06 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-book.c (pas_book_queue_create_card): track
- union/struct change.
- (pas_book_queue_remove_card): same.
- (pas_book_queue_modify_card): same.
- (pas_book_queue_get_cursor): same.
- (pas_book_queue_get_vcard): same.
- (pas_book_queue_authenticate_user): same.
- (pas_book_queue_get_book_view): same.
- (pas_book_queue_get_changes): same.
- (pas_book_free_request): new function - free everything we need to
- for each type of request.
- (pas_book_destroy): call pas_book_free_request here instead of
- just freeing 3 elements of the old struct. yay plugging memleaks.
-
- * backend/pas/pas-book.h: make PASRequest a union and split out
- members into structs, so it's a little clearer which fields are
- used by which requests. Also, add prototype for
- pas_book_free_request so backends can just free everything at once
- (usually in their requests_queued signal func.)
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_process_create_card): track struct/union change.
- (pas_backend_file_process_remove_card): same.
- (pas_backend_file_process_modify_card): same.
- (pas_backend_file_build_cards_list): same.
- (pas_backend_file_process_get_vcard): same.
- (pas_backend_file_process_get_cursor): same.
- (pas_backend_file_process_get_book_view): same.
- (pas_backend_file_process_get_changes): same.
- (pas_backend_file_process_check_connection): same.
- (pas_backend_file_process_authenticate_user): same.
- (pas_backend_file_process_get_supported_fields): same.
- (pas_backend_file_process_client_requests): case the union to the
- specific struct and pass it to the process_* functions. also,
- call pas_book_free_request here, instead of relying on each of the
- functions to free their stuff.
-
-2002-03-07 Dan Winship <danw@ximian.com>
-
- * gui/component/addressbook-storage.c
- (addressbook_get_other_contact_storage): Update for
- evolution_storage_new() change.
-
-2002-03-05 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-minicard-view-widget.c
- (e_minicard_view_widget_realize): don't set "editable" here, as
- the way things work the backend isn't able to override a setting
- from the UI, so writable books never show up as writable.
-
-2002-03-04 Chris Toshok <toshok@ximian.com>
-
- [fixes bug #20871]
- * gui/component/select-names/select-names.glade: add the
- status-message label.
-
- * gui/component/select-names/e-select-names.h (struct
- _ESelectNames): add status_message field.
-
- * gui/component/select-names/e-select-names.c (status_message):
- new function, set the label's text from the message.
- (e_select_names_init): get the status-message label, and if it's
- valid, connect to the status_message signal of the
- EAddressbookModel.
-
-2002-02-28 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_search): don't
- ref the view here, since it keeps the view alive until the search
- is over, which we don't want. we want the view's death to cancel
- the search. This speeds up starting new searches after one is
- already active (since switching searches actually creates a new
- book view and destroys the old one.)
- (ldap_search_dtor): remove the matching unref here. The unref as
- it was was incorrect anyway, and caused a crash (we needed
- search_op->view, not op->view.)
-
-2002-02-27 Chris Toshok <toshok@ximian.com>
-
- [fixes bug #20690]
- * backend/pas/pas-backend-ldap.c (func_and): the data arg is not
- GList** anymore, it's PASBackendLDAPSExpData*, so use
- ldap_data->list instead of *list.
- (func_or): same.
- (func_not): same.
- (func_contains): same.
- (func_is): same.
- (func_endswith): same.
- (func_beginswith): same, but also special case the beginswith
- "fileAs" query type (the one used by the alphabet buttons on the
- right hand side, so we can deal with entries that don't have
- fileAs attributes, and return meaningful responses.)
- (pas_backend_ldap_build_query): initialize the
- PASBackendLDAPSExpData struct and pass that instead of &list.
- Also, take the PASBackendLDAP arg to add to the struct in case we
- need it at some point in the future.
- (ldap_search_handler): pass in the PASBackendLDAP.
-
-2002-02-26 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_search): move
- card_count++ inside the if that checks to see if a card matches
- (and adds the card to the list).
-
-2002-02-24 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c (addressbook_query_changed): only
- handle the ESB_ADVANCED case here now. the actual query work is
- done in addressbook_search_activated.
- (addressbook_search_activated): split out all the searching
- functionality here.
- (addressbook_factory_new_control): hook up "search_activated" to
- addressbook_search_activated.
-
-2002-02-24 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-config.c
- (addressbook_source_dialog_set_source): make the right auth page
- start up open.
-
- * gui/component/addressbook-storage.c (addressbook_source_free):
- free the binddn.
- (addressbook_source_copy): copy the binddn;
-
-2002-02-22 Chris Toshok <toshok@ximian.com>
-
- [ Fixes bugs 20740, 16680, and god knows what else :) ]
- * gui/widgets/e-addressbook-model.c (create_card): double the
- allocated size every time we need more space instead of using a
- fixed size increment. this helps huge queries. Also, remove the
- gtk_object_get of "file_as", as it was dead code.
- (book_view_loaded): handle errors here (by popping up a dialog).
-
- * backend/pas/pas-backend-ldap.c (view_destroy): search_idle ->
- search_timeout.
- (build_card_from_entry): comment out some spew, and unref ecard
- when we're done to plug a memory leak.
- (send_pending_adds): send along to the client all the cards we've
- been saving up.
- (poll_ldap): use a timeout for ldap_result to keep the backend
- from blocking (and it turns out keep the frontend from hanging
- waiting on a ref to complete) on large db's with few matches.
-
- Also, add some fairly smart, self-tuning aggregating of cards.
- Keep track of the number of cards we've sent the last time through
- as well as this time, and estimate the number we want to aggregate
- the next time based on them (we average them at the moment),
- subject to maximum/minimum number of cards. also, we have a
- maximum aggregation time, after which we force a flush if there
- are pending cards and recalculate our target pending number.
- there's a minimum wait time to possibly keep outselves from
- spamming the ui, although it's 0 at the moment.
-
- Lastly, make sure to only notify the GUI of status messages when
- we need to. this results in a *huge* savings.
- (ldap_search_handler): initialize all the pending card stuff, and
- use a timeout instead of an idle function for poll_ldap.
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_queue_response): performance optimization
- for large adds. If we're a CardAddedEvent and there's an existing
- CardAddedEvent at the end of the queue, just concat the lists of
- cards together. This is to keep the gui from falling further and
- further behind the ldap backend, which is merrily spewing updates
- at the gui.
-
-2002-02-21 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/Makefile.am: Define $(iconsdir).
-
- * gui/component/addressbook-component.c (add_creatable_item): New
- helper function.
- (create_component): Add the icons for the user creatable items as
- well.
-
-2002-02-20 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_load_uri):
- track change to signature, and (for now) just change all the
- return FALSE's to _RepositoryOffline (what FALSE used to map to in
- pas_book_factory_process_request), and change TRUE to _Success.
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_load_uri):
- track change to signature, and differentiate between
- pas_backend_ldap_connect failing (RepositoryOffline), and
- ldap_url_parse failing (OtherError).
-
- * backend/pas/pas-book-factory.c
- (pas_book_factory_process_request): since pas_backend_load_uri
- returns status now, use it to nodify the BookListener if there's a
- failure.
-
- * backend/pas/pas-backend.c (pas_backend_load_uri): track change
- to signature.
-
- * backend/pas/pas-backend.h: change return type of
- pas_backend_load_uri to
- GNOME_Evolution_Addressbook_BookListener_CallStatus to allow
- differentiation between failure types.
-
- * backend/ebook/e-book-listener.c
- (e_book_listener_convert_status): handle _AUTHENTICATION_FAILED.
-
- * backend/ebook/e-book-types.h (EBookStatus): add
- _AUTHENTICATION_FAILED.
-
-2002-02-18 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-book-factory.c
- (pas_book_factory_process_request): if the load_uri fails, notify
- the listener that the repository is offline. (partial fix for bug
- 20347)
-
-2002-02-18 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (create_dn_from_ecard): escape
- commas in the dn, since they're used by ldap to specify the node's
- placement in the tree. (fixes bug 20089)
- (rfc2254_escape): just use sprintf and %02X instead.
-
-2002-02-13 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c (set_book): Keep a
- ref of the model in this case as well.
-
-2002-02-13 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c (set_book): Make
- sure to only set the query once when creating a new book and not
- at all on addressbook model creation. This prevents an accidental
- pair of changes from making the addressbook model load a remote
- addressbook.
-
- * gui/widgets/e-addressbook-model.c (get_view): If this is the
- first_get_view and the addressbook is remote, empty the view
- instead of leaving it in the state it used to be in. This only
- occurs if you set the book after the model has existed for a
- while.
- (e_addressbook_model_set_arg): When setting the book, set
- first_get_view to TRUE.
-
-2002-02-13 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (display_view): Attach to the
- emvw instead of the emv here.
-
- * gui/widgets/e-minicard-view-widget.c, e-minicard-view-widget.h:
- Made this object have a "column_width" argument and a
- "column_width_changed" signal which are a simple layer down to the
- EMinicardView contained within.
-
- * gui/widgets/gal-view-minicard.c, gui/widgets/gal-view-minicard.h
- (gal_view_minicard_attach): Made this attach to an
- EMinicardViewWidget instead of a EMinicardView.
-
-2002-02-13 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-book-util.c, backend/ebook/e-book-util.h
- (e_book_expand_uri, e_book_load_address_book_by_uri,
- e_book_use_address_book_by_uri): New functions that take a file://
- url ending in the directory name and automatically append the
- addressbook.db and do the appropriate thing.
-
- * backend/pas/pas-backend-card-sexp.c,
- backend/pas/pas-backend-card-sexp.h: Added copyright notice here.
-
- * gui/component/addressbook-component.c
- (destination_folder_handle_drop), gui/component/addressbook.c
- (set_prop): Use e_book_expand_uri instead of
- addressbook_expand_uri.
-
- * gui/component/addressbook-storage.c: Fixed the fcntl include
- here.
-
- * gui/component/addressbook.c (ContactsCopyToFolder,
- ContactsMoveToFolder): Added handlers for these two verbs.
-
- * gui/component/addressbook.h: Removed addressbook_expand_uri in
- favor of e_book_expand_uri.
-
- * gui/widgets/e-addressbook-reflow-adapter.c (transfer_cards):
- Added code to handle Move to and Copy to right click menu items.
-
- * gui/widgets/e-addressbook-util.c,
- gui/widgets/e-addressbook-util.h (e_addressbook_transfer_cards):
- New function to pop up a dialog and transfer a set of cards to the
- given folder.
-
- * gui/widgets/e-addressbook-view.c,
- gui/widgets/e-addressbook-view.h (display_view): Don't attach to
- the view if it doesn't exist yet. We have to make this then
- attach later.
- (e_addressbook_view_copy_to_folder,
- e_addressbook_view_move_to_folder): New functions utilizing
- e_addressbook_transfer_cards.
- (table_right_click): Add copy_to_folder and move_to_folder to the
- right click menu for tables here.
- (e_addressbook_view_discard_menus): Handle menu unmerging here.
-
- * gui/widgets/e-minicard-view-widget.h (struct
- _EMinicardViewWidget): Removed unused field.
-
-2002-02-13 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (display_view): Attach the
- GalViewMinicard to the EMinicardView here.
-
- * gui/widgets/gal-view-minicard.c, gui/widgets/gal-view-minicard.h
- (gal_view_minicard_load, gal_view_minicard_save): Made these save
- the column width of the view.
- (gal_view_minicard_attach, gal_view_minicard_detach): Added these
- functions to allow the GalViewMinicard to set the column width of
- a EMinicardView and to monitor its changes.
-
-2002-02-12 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-reflow-adapter.c
- (addressbook_get_arg): Added an argument to get the model.
-
- * gui/widgets/e-addressbook-view.c (writable_status): Don't bother
- connecting to the writable_status callback on the book, simply
- rely on the writable_status callback on the addressbook model.
-
- * gui/widgets/e-minicard-view.c, gui/widgets/e-minicard-view.h
- (set_empty_message): Handle the case of a read only view here.
-
-2002-02-07 JP Rosevear <jpr@ximian.com>
-
- * gui/component/addressbook-component.c (create_component): remove
- "New" from user creatable menu items
-
-2002-02-07 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-view.c,
- gui/widgets/e-addressbook-view.h
- (e_addressbook_view_setup_menus): Changed this function to use the
- new GalViewMenus which takes a GalViewInstance, instead of a
- GalViewCollection.
-
-2002-02-04 JP Rosevear <jpr@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c (find_address_mailing): tidy
-
- * conduit/address-conduit.c (addrconduit_load_configuration): load
- default address setting
- (addrconduit_save_configuration): save default address setting
- (e_addr_gui_new): new gui routine for conduit settings
- (e_addr_gui_fill_widgets): ditto
- (e_addr_gui_fill_config): ditto
- (e_addr_gui_destroy): ditto
- (e_addr_context_destroy): destroy the gui and new_cfg
- (local_record_from_ecard): reinstate commented out bits, determine
- which address to sync to pilot
- (ecard_from_remote_record): determine which address to sync from
- pilot
- (fill_widgets): put the gui widgets in
- (create_settings_window): create gui
- (save_settings): fill gui
-
-2002-02-04 JP Rosevear <jpr@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c (address_text_changed): if
- the shown address in the mailing address or there is no mailing
- address, set the default flag and make sure the button is checked
- (address_mailing_changed): set the flags properly when the mailing
- address changes
- (e_contact_editor_init): listen for the check button being toggled
- (find_address_mailing): find the address (if any) with the default
- flag
- (set_address_field): set the mailing address button appropriately
- (fill_in_info): find the mailing address
-
- * gui/contact-editor/e-contact-editor.h: add new class data member
-
- * gui/contact-editor/contact-editor.glade: show mailing address
- check button
-
-2002-02-01 Jeffrey Stedfast <fejj@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_is_auto_recipient):
- New function to find out if a destination was one which was
- auto-matically set by Evolution.
- (e_destination_set_auto_recipient): Set whether or not the dest is
- an auto-recipient.
- (e_destination_touch): Don't touch the address if it is an
- auto_recipient.
- (e_destination_list_to_vector_sized): New function to avoid having
- to calculate the length of the list ourselves. Allows for a bit of
- optimization if our caller knows the length of the list.
- (e_destination_xml_encode): Encode the auto_recipient bit.
- (e_destination_xml_decode): Decode the auto_recipient bit.
-
-2002-02-01 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-simple.c (e_card_simple_sync_card): Made
- this preserve addressbook flags other than the first three.
-
- * backend/ebook/e-card-types.h: Added E_CARD_ADDR_MASK and
- E_CARD_ADDR_DEFAULT.
-
- * backend/ebook/e-card.c (get_address_flags): Added "PREF" to
- E_CARD_ADDR_DEFAULT mapping.
-
- * backend/ebook/test-client.c: Added #include "e-book-util.h".
-
-2002-01-30 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_changes):
- compute the change db filename based on our contact db filename.
- (pas_backend_file_load_uri): store the filename in
- bf->priv->filename.
- (pas_backend_file_destroy): free the filename, and (!) free
- bf->priv too.
-
-2002-01-28 Jeffrey Stedfast <fejj@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_is_valid): Revert
- my previous change as trow says this will break auto-completion
- stuff.
-
-2002-01-27 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/contact-editor/Makefile.am: Use EVOLUTION_ADDRESSBOOK_CFLAGS.
- * gui/contact-list-editor/Makefile.am: Likewise.
- * gui/merging/Makefile.am: Likewise.
- * gui/search/Makefile.am: Likewise.
- * gui/component/select-names/Makefile.am: Likewise.
-
-2002-01-25 Jeffrey Stedfast <fejj@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_is_valid): Don't
- check for an @ in the email address. This is to fix bug #10960.
-
-2002-01-24 Chris Toshok <toshok@ximian.com>
-
- [ fixes bug 16097 ]
- * gui/component/addressbook-config.glade: gui love for the new
- auth stuff.
-
- * gui/component/addressbook.c (load_uri_cb): track change to auth,
- and offer up different prompt strings depending on which method
- (binddn or email) we're using.
-
- * gui/component/addressbook-storage.c (ldap_unparse_auth): use the
- new auth types for ldap.
- (ldap_parse_auth): same.
- (addressbook_storage_auth_type_to_string): new function.
- (load_source_data): get the binddn too.
- (ldap_source_foreach): store out binddn or emailaddr, depending on
- the auth type chosen.
-
- * gui/component/addressbook-storage.h: add the more detailed auth
- types, add "binddn" to the source structure, and add a prototype
- for addressbook_storage_auth_type_to_string.
-
- * gui/component/addressbook-config.c (auth_checkbutton_changed):
- set the auth stuff (in)sensitive.
- (auth_optionmenu_activated): new function.
- (addressbook_source_dialog_set_source): track UI change.
- (addressbook_source_dialog_get_source): same.
- (add_scope_activate_cb): rename add_activate_cb to this to
- distinguish it from the auth stuff.
- (add_auth_activate_cb): new function.
- (addressbook_source_dialog): track change to auth UI stuff.
- (addressbook_storage_auth_type_to_string): new function.
-
- * backend/ebook/e-book.h: add auth_method arg to
- e_book_authenticate_user.
-
- * backend/ebook/e-book.c (e_book_authenticate_user): track change
- to prototype - add auth_method arg, and pass it along to the CORBA
- call.
-
- * backend/ebook/test-client.c (book_open_cb): track api change -
- keep this building.
-
- * backend/pas/pas-book.h: add auth_method slot in PASRequest.
-
- * backend/pas/pas-book.c (pas_book_queue_authenticate_user): add
- auth_method arg and add it to the PASRequest.
- (impl_GNOME_Evolution_Addressbook_Book_authenticateUser): track
- idl change, add auth_method and pass it along to
- pas_book_queue_authenticate_user.
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_process_authenticate_user): support both
- "ldap/simple-email" and "ldap/simple-binddn" auth methods.
-
- * backend/idl/addressbook.idl: add "in string authMethod" to
- authenticateUser.
-
-2002-01-24 Ettore Perazzoli <ettore@ximian.com>
-
- * conduit/Makefile.am: Use EVOLUTION_ADDRESSBOOK_CONDUIT_CFLAGS
- and EVOLUTION_ADDRESSBOOK_CONDUIT_LIBS and remove unused flags
-
- * gui/component/Makefile.am: Use EVOLUTION_ADDRESSBOOK_CFLAGS and
- EVOLUTION_ADDRESSBOOK_LIBS and remove unused flags.
- * backend/pas/Makefile.am: Likewise.
- * backend/ebook/Makefile.am: Likewise.
- * printing/Makefile.am: Likewise.
- * backend/ebook/Makefile.am: Likewise.
- * gui/widgets/Makefile.am (INCLUDES): Likewise.
-
-2002-01-23 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c (create_component): Pass a
- NULL @icon to
- `evolution_shell_component_add_user_creatable_item()'.
-
-2002-01-23 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/contact-editor/e-contact-editor-address.c: #include
- <locale.h>.
-
-2002-01-22 Chris Toshok <toshok@ximian.com>
-
- [ fixes bug # 16864 ]
- * backend/ebook/evolution-ldif-importer.c (getValue): create and
- return a GString here, instead of writing to a fixed size buffer.
- (parseLine): use a GString here instead of a fixed size buffer.
-
-2002-01-21 Christopher James Lahey <clahey@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (ldap_search_handler): Set the
- number of cards to return to the value specified in the ldap uri,
- leaving the default at 100. Fixes Ximian bug #13953.
-
- * gui/component/addressbook-config.c (addressbook_source_dialog),
- gui/component/addressbook-config.glade: Added a limit entry here
- to edit the limit field of the source.
-
- * gui/component/addressbook-storage.c,
- gui/component/addressbook-storage.h
- (addressbook_storage_init_source_uri): Added a limit field to this
- class and pass that value through in the uri that's generated.
-
-2002-01-18 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-compare.c: Made username match with no
- domain match be vague instead of partial. Fixes Ximian bug
- #13612.
-
-2002-01-18 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook.c (view_contact_cb): New verb to open
- a bunch of cards.
-
- * gui/widgets/e-addressbook-reflow-adapter.c (open_card): Call
- e_addressbook_show_multiple_cards instead of doing this ourselves.
-
- * gui/widgets/e-addressbook-util.c,
- gui/widgets/e-addressbook-util.h
- (e_addressbook_show_multiple_cards): Added this function to show a
- bunch of cards, including a dialog if lots of windows are going to
- appear.
-
- * gui/widgets/e-addressbook-view.c (e_addressbook_view_view,
- e_addressbook_view_can_view): e_addressbook_view_view calls
- e_addressbook_show_multiple_cards on the appropriate list of
- cards.
-
-2002-01-18 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/e-contact-editor-address.c
- (fill_in_countries), gui/contact-editor/fulladdr.glade: Sort
- country list. Country list moves from fulladdr.glade to
- e-contact-editor-address.c, but only a few country names have
- actually changed. Fixes Ximian bug #16545.
-
-2001-12-20 Zbigniew Chyla <cyba@gnome.pl>
-
- Fixes #17725
-
- * evolution/addressbook/printing/e-contact-print.c (complete_sequence):
- Do not assume that the first byte of file_as is the first letter, use
- utf8 functions instead.
-
-2002-01-16 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c: move all functions here, get rid of
- header files, use e-pilot-settings to display gui
-
-2002-01-15 JP Rosevear <jpr@ximian.com>
-
- * gui/component/select-names/select-names.glade: remove misleading
- title and fix spacing
-
-2002-01-11 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook.c (alphabet_state_changed): Handle
- setting the search bar to "Advanced..." when the alphabet buttons
- are pushed and back when they're cleared. Fixes Ximian bug
- #12904.
- (addressbook_menu_activated): When the user calls Search->clear,
- set the search to ESB_ANY and "", don't just set the text. This
- is especially useful when it's set to ESB_ADVANCED.
-
- * gui/widgets/e-addressbook-view.c,
- gui/widgets/e-addressbook-view.h (alphabet_state_change): Added
- this signal which gets emitted when the alphabet buttons are
- pushed.
- (command_state_change): Removed the ref pair here. It's not
- necessary. gtk_signal_emit refs the object itself.
-
-2002-01-11 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-compare.c (name_synonyms): Added a couple
- of names here.
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_get_nth_obj): Removed an unused
- variable.
-
-2002-01-11 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-view.c,
- gui/widgets/e-addressbook-view.h (create_alphabet): Use toggle
- buttons here. Fixes Ximian bug #10734.
-
-2002-01-09 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c (set_fields): Choose the
- first filled in address field here. Fixes Ximian bug #2222.
-
-2002-01-03 Joe Shaw <joe@ximian.com>
-
- * backend/ebook/test-card.c: Add a test for getting arbitrary
- fields.
-
- * backend/pas/pas-backend-card-sexp.c (compare_arbitrary): Added.
- (prop_info_table): Add a LIST_PROP for arbitrary fields.
-
-2002-01-03 Nat Friedman <nat@ximian.com>
-
- * backend/ebook/e-book.c (activate_factories_for_uri): Free the
- query if the oaf response is of zero length.
-
-2001-12-27 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (real_add_address_cb): When we clean, don't clean the model's last
- element. This helps keep things working properly when we have
- signal-character separators.
- (section_right_click_cb): Changed to work properly with our
- EText-emitted popup signal.
- (e_select_names_add_section): Use ETexts for the recipient
- sections, rather than tables. This lets us make them directly
- editable. (Bug #1721)
-
- * gui/component/select-names/e-select-names-popup.c
- (popup_info_new): Pass in a ESelectNamesTextModel, not a
- ESelectNamesModel.
- (e_select_names_popup): Adjust for the new signature for
- e_select_names_model_text_pos.
-
- * gui/component/select-names/e-select-names-manager.c
- (focus_out_cb): Schedule a cleaning when we focus out.
- (focus_in_cb): Cancel pending cleaning when we get focus. This
- helps us avoid bad things happening during the fast focus out/ins
- that happen when the completion dropdown appears.
- (completion_handler): Adjust for new signatures of
- e_select_names_model_text_pos and e_select_names_model_name_pos.
- (e_select_names_manager_entry_new): Pass in our
- ESelectNamesTextModel when constructing the
- ESelectNamesCompletion.
- (e_select_names_manager_entry_free): Cancel any pending clean-ups.
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_get_property_fn): Get the text off of the text model.
- Which is the only way that really makes sense when you think about
- it.
-
- * gui/component/select-names/e-select-names-completion.c: Added a
- copy of the associated ESelectNamesTextModel to
- ESelectNamesCompletionPrivate. This replaces the
- ESelectNamesModel.
- (e_select_names_completion_destroy): Unref ->text_model.
- (e_select_names_completion_handle_request): Pass in our text
- model's separator info when calling e_select_names_model_text_pos.
- (e_select_names_completion_new): Pass in the text model as an arg
- instead of the model, and ref it as needed.
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_init): Set separator as either ", " or
- ",", depending on the value of the EVOLUTION_DISABLE_MAGIC_COMMA
- environment variable.
- (e_select_names_text_model_destroy): Free the separator.
- (changed_cb): Flush our cached text on changed.
- (e_select_names_text_model_set_source): Use our own changed_cb
- callback on changed, rather than just connecting up
- e_text_model_changed.
- (e_select_names_text_model_set_separator): Added. Lets the
- separator between recipients be specified.
- (e_select_names_text_model_get_text): Cache the text we get from
- calling e_select_names_model_get_textification.
- (e_select_names_text_model_insert_length): A bunch of small
- changes to properly support generic separators, rather than
- (implicit and explicitly) assuming ", ".
- (e_select_names_text_model_delete): More small tweaks to handle
- generic separators.
- (e_select_names_text_model_get_nth_obj): Use new signature when
- calling e_select_names_model_name_pos, and use our cached text.
-
- * gui/component/select-names/e-select-names-model.c
- (e_select_names_model_destroy): We don't cache the text or
- addr_text anymore, so no need to free them here.
- (e_select_names_model_changed): ...and no need to reset our text
- and addr_text caches here.
- (e_select_names_model_get_textification): Take a separator as an
- arg, rather than just using ", ". Also, no caching.
- (e_select_names_model_get_address_text): Take a separator as an
- arg, rather than just using ", ". And no caching here either.
- (e_select_names_model_clean): Add arg that give us control over
- whether or not the last entry should get cleaned. We need this
- when using a one-character separator, so that new destinations
- that get tacked onto the end don't get immediately cleaned away
- for being empty.
- (e_select_names_model_name_pos): Take the separator length as an
- argument, remove implicit assumption of length 2.
- (e_select_names_model_text_pos): Take the separator length as an
- argument, remove implicit assumption of length 2.
-
-2001-12-20 Ettore Perazzoli <ettore@ximian.com>
-
- [Fix #17377, Evolution doesn't work on multi-depth displays.]
-
- * gui/component/addressbook-factory.c (main): Push GdkRGB visual
- and colormap.
-
-2001-12-19 Jon Trowbridge <trow@ximian.com>
-
- * gui/widgets/e-addressbook-reflow-adapter.c
- (e_addressbook_reflow_adapter_right_click): Add cut/copy/paste to
- right-click menu.
-
- * gui/widgets/e-addressbook-view.c (table_right_click): Add
- cut/copy/paste to right-click menu. (Fixes bug #14528.) Also,
- disable some right-click options if our addressbook isn't
- editable.
-
-2001-12-18 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (check_for_slow_setting): go slow and
- clear the map if the last uri and the current uri do not match
- (post_sync): save the last uri
-
- * conduits/address-conduit-config.h: handle a last uri config
- option
-
-2001-12-18 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c (addressbook_default_book_open):
- change this to match its e-book counterpart, and only failover to
- the local addressbook if the protocol wasn't supported. that way
- errors like "failure to connect" are still reported to the user.
-
- * backend/ebook/e-book-util.h: add prototypes for
- e_book_load_default_book and e_book_get_config_database.
-
- * backend/ebook/e-book-util.c (e_book_default_book_open): new
- function, basically cut and paste addressbook_default_book_open
- from addressbook.c here.
- (e_book_load_default_book): cut and past
- addressbook_load_default_book here, pretty much, except leave off
- the auth stuff.
- (e_book_get_config_database): new function, returns the
- Bonobo_ConfigDatabase for e_book_load_default_book to use.
-
- * conduit/address-conduit.c (start_addressbook_server): use
- e_book_load_default_book here.
-
-2001-12-17 Chris Toshok <toshok@ximian.com>
-
- [ fixes bug 17355 ]
- * gui/component/select-names/e-select-names.c (new_folder): if
- we're dealing with an LDAP folder, prepend [LDAP] to it. Now that
- we have 3 different places where folders are coming from, it helps
- to be able to differentiate "Contacts" in ~/evolution and a
- "Contacts" ldap server and a "Contacts" exchange folder.
- (add_additional_select_names_uris): loop through the bonobo conf
- settings for additional folders, adding them to the option menu.
- (e_select_names_hookup_shell_listeners): call
- add_additional_select_names_uris.
-
-2001-11-28 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-minicard-view-widget.c
- (e_minicard_view_widget_realize): Use an #ECanvasBackground here
- instead of a #GnomeCanvasRect.
-
-2001-12-16 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c: Added
- 'cache_complete' flag to ESelectNamesCompletionPrivate.
- (e_select_names_completion_seq_complete_cb): Set cache_complete
- to TRUE if our query wasn't interrupted.
- (e_select_names_completion_start_query): Set cache_complete to
- FALSE at the beginning of a potentially-cached query.
- (e_select_names_completion_do_query): Only reuse cached cards
- if cache_complete is TRUE. (Fixes bug #10241)
-
-2001-12-15 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (e_addr_context_destroy): don't free
- the hash table keys, we didn't allocate them and free the change
- objects and unref the associated cards
- (local_record_from_uid): unref the temp card we create
- (replace_record): ref the new card associated with the card change
- and unref the old one
-
-2001-12-13 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (local_record_from_ecard): Make sure
- to copy the custom fields so they are not overwritten
-
-2001-12-13 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-book-util.c (simple_query_new): Used
- g_strdup_printf to dup a string. Doh! Changed to g_strdup.
- (Bug #17126)
-
-2001-12-07 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_entry_new): Remove a reference to code
- I don't want to commit yet. :-)
-
- * gui/component/select-names/e-select-names-manager.c: Extensively
- refactored -- this code had gotten _really_ ugly. Untangle things
- to the point where our reference counting problems are fixable.
-
- * gui/component/select-names/e-select-names-bonobo.c
- (impl_destroy): Remove all of the ugly hacks to work around our
- memory management problems, and just unref the manager.
- (Fixes #14412)
-
-2001-12-05 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c
- (search_for_dn_with_objectclasses): move search_for_dn's contents
- here, and add an "existing_objectclasses" parameter that we pass
- on to build_card_from_entry.
- (search_for_dn): call search_for_dn_with_objectclasses with NULL
- for existing_objectclasses.
- (build_card_from_entry): if existing_objectclasses is non-NULL,
- fill it in with the list of existing objectclass values for this
- entry.
- (add_objectclass_mod): if existing_objectclasses is non-NULL,
- meaning we're modifying an entry, search in the existing
- objectclasses for the ones we want to be there, and only add
- what's missing. If none are missing, don't add objectclass_mod to
- the list of mods.
- (create_card_handler): track change to add_objectclass_mod (pass
- NULL).
- (modify_card_handler): use search_for_dn_with_objectclasses
- instead of search_for_dn, and pass the existing objectclasses to
- add_objectclass_mod. also, free the list when we're done.
- (poll_ldap): track change to build_card_from_entry (pass NULL).
-
-2001-12-05 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c (enable_writable_fields):
- we need to be able to disable non-labels here as well. since
- we're using enable_widget and not gtk_widget_set_sensitive, it's
- okay to handle entries/text's, etc, here.
- (widget_field_mappings): add label-caluri and label-fburl here.
-
- * gui/contact-editor/contact-editor.glade: change the label names
- for the freebusy/calendar urls to have more descriptive names,
- since we use them in e-contact-editor.c now.
-
- * backend/pas/pas-backend-ldap.c: add support for
- caluri/calendarURI, fburl/freeBusyURI.
-
- * backend/pas/evolutionperson.schema: add calendarURI and
- freeBusyURI.
-
-2001-12-04 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/contact-editor.glade: Fixed up the
- accelerators and such here.
-
- * gui/contact-editor/e-contact-editor.c (file_save_as_cb):
- Translate this string.
- (pixmaps): Added a pixmap for the ContactEditorSaveClose command.
- (setup_tab_order): Fixed up the tab order here.
-
- * gui/contact-editor/fulladdr.glade: Made the country combo
- focusable here.
-
-2001-12-03 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_equal): Make address
- comparisons case-insensitive. (Fixes 11776)
-
- * backend/ebook/e-card.c (e_card_email_match_single_string): Make address
- host comparisons case-insensitive. (Fixes 11776)
-
- * gui/component/select-names/e-select-names-manager.c (focus_out_cb): Clean
- ESelectNamesModel on focus-out. (Half of a fix for 15656)
-
- * backend/ebook/e-destination.c (nonempty): Fix this function
- and make it utf8-safe. (The other half of the fix for 15656)
-
-2001-11-28 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-list-editor/e-contact-list-editor.c: Consistency
- fixes with standard contact editor. Added Save As, Send As, and
- Send To. Replaced Save toolbar with Save and Close and added Save
- and Close menu item. Added a trash icon.
-
-2001-11-28 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/e-contact-editor-address.c (setup_tab_order):
- Setup the tab order here. Fixes Ximian bug #13751.
-
-2001-11-28 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook.c (connect_master_list_changed,
- make_suboptions): Changed how this list of categories gets
- computed. Fixes Ximian bugs #7707 and #7708.
-
-2001-11-15 Zbigniew Chyla <cyba@gnome.pl>
-
- * printing/e-contact-print-envelope.c (ecpe_linelist_dimensions),
- printing/e-contact-print.c (e_contact_divide_text, e_contact_output,
- e_contact_rectangle, e_contact_print_letter_tab,
- e_contact_print_letter_heading, e_contact_get_card_size,
- e_contact_print_card, e_contact_print_phone_list):
- s/gnome_font_get_width_string/gnome_font_get_width_utf8/
- s/gnome_font_get_width_string_n/gnome_font_get_width_utf8_sized/
-
-2001-11-14 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (search_for_dn): check against
- LDAP_SUCCESS as the return value, not -1.
- (pas_backend_ldap_build_all_cards_list): same.
- (pas_backend_ldap_process_authenticate_user): same.
-
-2001-11-12 Chris Toshok <toshok@ximian.com>
-
- [ Fixes Ximian bug #14843 ]
- * backend/pas/pas-backend-ldap.c (func_and): don't crash if a
- subexpression wasn't filled in.
-
- * backend/pas/pas-backend-ldap.c (func_or): same.
-
-2001-11-12 Jon Trowbridge <trow@ximian.com>
-
- * gui/contact-list-editor/e-contact-list-editor.c (list_added_cb):
- Release callback's reference to EContactListEditor.
- (list_modified_cb): Release callback's reference to
- EContactListEditor.
- (save_card): Ref the EContactListEditor on behalf of the
- e_book_foo callback. (Fixes bug #14743)
- (save_card): Set changed to false once we've saved.
- (list_deleted_cb): Release callback's reference.
- (delete_cb): Hold reference for the callback.
-
-2001-11-12 Jon Trowbridge <trow@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c (categories_clicked): If
- our call to e_categories_new returns NULL, put up an error dialog
- and return. (Fixed #14780)
-
-2001-11-09 Chris Toshok <toshok@ximian.com>
-
- [ Fixes Ximian bug #14687 ]
- * backend/pas/pas-backend-file.c
-
- * backend/pas/pas-book-factory.c
- (pas_book_factory_process_request): do load_uri before add_client,
- so we know if the load actually worked (add_client uses this
- information to respond to the new client.) before this change,
- the client would still think the book was in a useful state even
- if the load_uri failed.
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_add_client): if
- the we're not connected, say so.
-
- * backend/pas/pas-backend-file.c (pas_backend_file_add_client):
- same.
- (pas_backend_file_load_uri): don't report_writable here,
- add_client does it. was only needed before because of the
- improper ordering in pas-book-factory.c above.
-
-2001-11-09 Chris Toshok <toshok@ximian.com>
-
- [ Fixes Ximian bug #14646 ]
- * gui/component/addressbook.c (addressbook_default_book_open): new
- function. if the default_book failed to load, load the local
- addressbook in its place.
- addressbook_load_default_book): if we're loading the default_book
- uri, use addressbook_default_book_open as the open_response.
-
- * backend/ebook/e-book.c (e_book_load_uri_step): reset the
- load_state to NotLoaded so we can attempt another load_uri on
- the book if it fails.
-
-2001-11-08 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-bonobo.c
- (impl_destroy): Explicitly destroy entries. Part of the fix for
- the lingering completion window bug.
-
-2001-11-04 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c: Use ordering of the pilot's phone
- label list to find fields we sync in order to avoid strcmp'ing the
- pilot's labels rendering phone syncing usable only for english
- language pilots
-
-2001-11-03 Chris Toshok <toshok@ximian.com>
-
- [ Fixes Ximian bug #14410 ]
- * gui/contact-editor/e-contact-editor.c (e_contact_editor_init):
- init in_async_call to FALSE.
- (card_added_cb): turn the UI back on and set in_async_call to
- FALSE.
- (card_modified_cb): same.
- (card_deleted_cb): same.
- (save_card): turn off the UI by setting the dialog insensitive,
- and set in_async_call to TRUE.
- (delete_cb): same.
- (app_delete_event_cb): if we're in an async call don't let the
- window get deleted.
-
- * gui/contact-editor/e-contact-editor.h (struct _EContactEditor):
- add in_async_call flag for when we make a wombat call and need to
- disable the UI.
-
- * gui/contact-list-editor/e-contact-list-editor.c
- (e_contact_list_editor_init): init in_async_call to FALSE.
- (list_added_cb): turn the UI back on and set in_async_call to
- FALSE.
- (list_modified_cb): same.
- (list_deleted_cb): same.
- (save_card): turn off the UI by setting the dialog insensitive,
- and set in_async_call to TRUE.
- (delete_cb): same.
- (app_delete_event_cb): if we're in an async call don't let the
- window get deleted.
-
- * gui/contact-list-editor/e-contact-list-editor.h (struct
- _EContactListEditor): add in_async_call flag for when we make a
- wombat call and need to disable the UI.
-
-2001-11-02 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-simple.c (e_card_simple_get): Check for
- NULL dates before converting them to strings. Fixes Ximian bug
- #14394.
-
-2001-11-02 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-bonobo.c
- (impl_destroy): Leak select-names related data structures until
- the memory management issues get sorted out. Fixed bug #14086.
-
-2001-10-31 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/e-cardlist-model.c,
- gui/component/select-names/e-select-names-table-model.c,
- gui/widgets/e-addressbook-table-adapter.c: Make the pre_changes
- and changes match here.
-
-2001-10-31 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_destroy): Check that local_listener and
- other_contacts_listener are non-NULL before
- disconnecting/unrefing.
-
- * gui/component/select-names/e-select-names-manager.c
- (entry_destroyed): The entry shouldn't unref the manager.
- (e_select_names_manager_create_entry): The entry shouldn't hold a
- ref to the manager. It becomes circular.
- (e_select_names_manager_create_entry): On the other hand, we
- should hold a ref to the entry we create.
-
- * gui/component/select-names/e-select-names-bonobo.c
- (impl_destroy): Remove the explicit dialog destroy hack.
-
-2001-10-30 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-bonobo.c
- (impl_destroy): Force the select names dialog to be destroyed.
- This is a hack to fix bug #14002 -- I'll clean up the refcounting
- issues post-freeze. At least now it won't crash.
-
-2001-10-30 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (ecard_from_remote_record): make sure
- to translate the character sets of the names
-
-2001-10-30 JP Rosevear <jpr@ximian.com>
-
- * gui/component/select-names/e-select-names-bonobo.c
- (manager_ok_cb): send a null bonobo arg to prevent explosion
-
-2001-10-30 JP Rosevear <jpr@ximian.com>
-
- * gui/widgets/e-addressbook-view.c: correct include typo
-
-2001-10-29 Jon Trowbridge <trow@ximian.com.
-
- * gui/widgets/e-minicard.c (add_field): Five characters, not four!
-
- * gui/widgets/e-addressbook-table-adapter.c
- (addressbook_value_at): Convert xml-ified destinations into proper
- addresses.
-
-2001-10-29 Jon Trowbridge <trow@ximian.com.
-
- * gui/component/select-names/e-select-names-bonobo.c (init):
- Connect to manager's "ok" signal.
- (manager_ok_cb): Emit "ok" bonobo-signal.
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_class_init): Added "ok" signal.
- (e_select_names_clicked): Emit 'ok' signal.
-
-2001-10-29 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-addressbook-util.c
- (e_addressbook_prompt_save_dialog): new function, a "Do you want
- to save changes?" dialog.
-
- * gui/widgets/e-addressbook-util.h: add prototype for
- e_addressbook_prompt_save_dialog.
-
- * gui/contact-editor/e-contact-editor.c (prompt_to_save_changes):
- call e_addressbook_prompt_save_dialog and save the card if they
- select save. return TRUE if the dialog should be closed, FALSE
- otherwise.
- (file_close_cb): check prompt_to_save_changes before closing the
- dialog.
- (app_delete_event_cb): same.
-
- * gui/contact-list-editor/e-contact-list-editor.c
- (prompt_to_save_changes): call e_addressbook_prompt_save_dialog
- and save the card if they select save. return TRUE if the dialog
- should be closed, FALSE otherwise.
- (file_close_cb): check prompt_to_save_changes before closing the
- dialog.
- (app_delete_event_cb): same.
-
-2001-10-29 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (add_objectclass_mod): overload
- this function for modifying objectclasses too, so we can make sure
- evolutionPerson shows up in the objectclasses of an entry if it
- shows up in the schema for the server.
- (create_card_handler): add @replace = FALSE in the call to
- add_objectclass_mod.
- (modify_card_handler): call add_objectclass_mod with @replace =
- TRUE.
- (anniversary_compare): fix typo - return "equal", not "TRUE".
- (birthday_compare): same.
-
-2001-10-29 Jon Trowbridge <trow@ximian.com>
-
- * conduit/address-conduit.c (pre_sync): Comment out spew.
-
- * gui/contact-list-editor/e-contact-list-editor.c (fill_in_info):
- Comment out spew.
-
- * gui/component/addressbook-component.c
- (destination_folder_handle_drop): Comment out spew.
- (get_dnd_selection): Comment out spew.
-
- * gui/widgets/e-addressbook-table-adapter.c
- (addressbook_set_value_at): Comment out spew.
-
-2001-10-29 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/addressbook.c (update_command_state): Check that
- our BonoboUIComponent has a container so we don't get a lot of
- annoying debug spew.
-
- * printing/smallbook.ecps: Fixed fonts.
-
- * printing/phonelist.ecps: Fixed fonts.
-
- * printing/medbook.ecps: Fixed fonts.
-
- * printing/e-contact-print.c (e_contact_get_card_size): Commented
- out spew.
-
- * gui/widgets/e-minicard.c (remodel): Check that e_minicard->card
- != NULL.
-
-2001-10-29 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_destroy): We were using
- book_data->book_view immediately after unrefing it. Reordered the
- code a bit to avoid this.
-
-2001-10-29 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-book-factory.h: add prototype for
- pas_book_factory_dump_active_backends.
-
- * backend/pas/pas-book-factory.c
- (pas_book_factory_dump_active_backends): new function.
- (dump_active_server_map_entry): new function.
-
-2001-10-29 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (make_match): Drop a match if either of the text fields is NULL.
- This could happen if any of the utf-8 involved is invalid, for
- example. (Bug #13757)
-
-2001-10-29 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (is_syncable): fix bug that allowed
- for phone's not to be in priority order and the item to still be
- syncable
-
- * conduit/address-conduit-config.h
- (addrconduit_load_configuration): get management by id
-
-2001-10-29 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (is_syncable): a card also needs to
- have its phone nums in priority order to be "syncable"
-
-2001-10-29 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (is_syncable): move the syncable
- checking code to a different function
- (ecard_from_remote_record): set the name parts individually
- (local_record_from_ecard): use is_syncable
-
-2001-10-29 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-simple.c (file_as_get_style,
- file_as_set_style): Use the actual ECardName in the ECard instead
- of parsing the full_name here.
-
-2001-10-29 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h
- (e_card_simple_set_name): New function to set the ECardName on
- this card and fix the file_as if necessary.
-
-2001-10-29 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h
- (e_card_simple_get): Handle returning dates here.
- (e_card_simple_get_allow_newlines): New function. Returns whether
- it makes much sense to have newlines in this string.
-
- * gui/component/addressbook-config.c,
- gui/component/addressbook-config.h
- (addressbook_create_new_source): The first argument here should
- be const.
-
- * gui/component/addressbook-storage.c: Added #include
- "addressbook-config.h".
-
- * gui/widgets/e-minicard-label.c (e_minicard_label_event): On an
- escape here, cancel editing and remove the focus from the text.
-
- * gui/widgets/e-minicard.c (add_field): Set allow_newlines here.
- (field_activated): Stop editing on the activate signal and remove
- the focus from the text. Fixes Ximian bug #12286.
-
-2001-10-28 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.h: tidy
-
- * conduit/address-conduit-config.h: ditto
-
- * conduit/address-conduit.c (add_record): unref ecard when done
-
-2001-10-28 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-card.c (e_card_date_from_string): Expose this
- function.
- (e_card_date_to_string): ...and this one. Fixes build problem in
- pas-backend-ldap.c.
-
-2001-10-28 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_hookup_shell_listeners): Change "this should never
- happen" dialog to not give my name/e-mail. Sorry translators.
- But this really should never happen, thanks to my fix below.
-
- * gui/component/addressbook-component.c: Initialize
- global_shell_client to NULL. (Bug #6625)
-
-2001-10-27 Chris Toshok <toshok@ximian.com>
-
- [ bug #12979 ]
- * backend/pas/pas-backend-ldap.c (anniversary_populate): new
- function.
- (anniversary_ber): new function.
- (anniversary_compare): new function.
- (birthday_populate): new function.
- (birthday_ber): new function.
- (birthday_compare): new function.
-
-2001-10-27 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_destroy): free up all the book_data
- list stuff.
- (e_select_names_completion_got_book_view_cb): deal with book_data
- being passed as the closure, and increment the
- pending_completion_seq counter.
- (e_select_names_completion_card_added_cb): deal with book_data
- being passwd as the closure.
- (e_select_names_completion_seq_complete_cb): same, and decrement
- the pending_completion_seq if we haven't gotten one for this book
- view before.
- (e_select_names_completion_stop_query): cancel all the
- book_data's.
- (e_select_names_completion_start_query): use the books_not_ready
- counter instead of book_ready. also, do e_book_get_book_view on
- each of the book's in our list.
- (e_select_names_completion_do_query): change to deal with our
- list.
- (e_select_names_completion_book_ready): decrement the
- book_not_ready counter.
- (e_select_names_completion_new): add the book we're created with
- to our list.
- (e_select_names_completion_add_book): implement.
-
- * gui/component/select-names/e-select-names-completion.h: add
- prototype for e_select_names_completion_add_book.
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_new): use addressbook_config_data, and
- don't unref the db.
- (e_select_names_manager_create_entry): always add NULL for a book
- (which corresponds to the local book), and if the completion_book
- is present, add it to the list of books to complete again.
-
-2001-10-27 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-editor/e-contact-quick-add.c (merge_cb): change to
- EBookCallback signature, and unref the book.
- (quick_add_merge_card): use addressbook_load_default_book.
- (ce_have_book): change to EBookCallback signature, and unref the
- book.
- (edit_card): use addressbook_load_default_book.
-
- * gui/component/e-address-popup.c (email_table_save_card_cb):
- change to EBookCallback signature, and unref the book.
- (add_card_idle_cb): use addressbook_load_default_book, and call
- the cb if it fails.
- (e_address_popup_cleanup): fix type -- should be "pop->card =
- NULL", not "pop = NULL".
- (contact_editor_cb): change to EBookCallback signature.
- (edit_contact_info_cb): use addressbook_load_default_book.
- (start_query): change to EBookCallback signature.
- (e_address_popup_query): use addressbook_load_default_book.
-
- * gui/widgets/e-minicard-control.c (book_open_cb): change to
- EBookCallback signature, and unref the book.
- (save_in_addressbook): use addressbook_load_default_book instead
- of e_book_use_local_address_book.
-
- * gui/widgets/Makefile.am (INCLUDES): change includes since we're
- including addressbook.h which has it's own set of funky include
- path requirements.
-
-2001-10-27 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-book.c (activate_factories_for_uri): Don't leak
- stuff. (Bug #13709)
-
-2001-10-27 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-destination.c (name_and_email_simple_query_cb,
- nickname_simple_query_cb): Set book_uri when cardification occurs.
-
-2001-10-27 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_add_section): Turned off use_ellipsis (it breaks
- emulate_label_resize) and on emulate_label_resize. Fixes Ximian
- bug #13693.
-
-2001-10-27 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (make_match): Doh! We should be sorting our contacts so that the
- most frequently used ones are at the top of the list, not the
- bottom.
-
- * backend/pas/pas-book.c (pas_book_check_queue): That should be a
- bonobo_object_unref, not a gtk_object_unref.
- (pas_book_queue_request): Likewise, we need to bonobo_object_ref
- here.
- (pas_book_destroy): If our pas_book_check_queue timeout is still
- active, disable it. This should never happen, but it never hurts
- to be careful.
- (pas_book_destroy): Set book->priv to NULL after we free it.
-
-2001-10-27 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (local_record_from_ecard): copy phone
- labels and show phone as well, clear correct entry text and
- correctly detect unsyncable cases
-
-2001-10-27 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (local_record_from_ecard): touch the
- record on lookup
- (check_for_slow_setting): write touched only if we are doing a
- slow sync
- (card_removed): don't touch on lookup
- (match): touch on lookup
-
-2001-10-27 Jon Trowbridge <trow@ximian.com>
-
- * backend/pas/pas-book.c (pas_book_check_queue): Added paranoid
- reentrancy guards.
- (pas_book_queue_request): Changed our idle handler into a timeout,
- so as to work w/ reentrancy guards.
- (pas_book_init): Explicit initialization.
-
-2001-10-26 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.h: add prototypes for
- addressbook_config_database, and addressbook_load_default_book.
-
- * gui/component/addressbook.c (addressbook_config_database): new
- function, so we aren't activating the db everywhere we need to use
- it.
- (addressbook_load_default_book): load the default book, after
- getting the uri from bonobo-config.
-
-2001-10-26 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-book-util.c (simple_query_card_added_cb): Return
- on cancellation.
- (simple_query_sequence_complete_cb): Act if not cancelled.
- (simple_query_book_view_cb): Free & return on cancellation.
- (e_book_simple_query_cancel): Set cancellation flag.
-
- * gui/component/e-address-popup.c (e_address_popup_query): Hold a
- reference to ourselves for the duration of our addressbook fetch.
- (start_query): Release when we've fetched our addressbook.
- (e_address_popup_cleanup): Break out most of what we do in
- _destroy into a separate function.
- (e_address_popup_destroy): Class cleanup.
- (contact_editor_cb): Paranoid clean-up.
- (add_contacts_cb): Paranoid clean-up.
- (e_address_popup_ambiguous_email_add): Paranoid clean-up.
-
-2001-10-26 JP Rosevear <jpr@ximian.com>
-
- * conduit/e-address.conduit.in: remove the merges as valid sync
- types
-
- * conduit/address-conduit.c (pre_sync): write out only the touched
- records if we are doing copies
-
- * conduit/address-conduit-config.h
- (addrconduit_load_configuration): get the sync type
-
-2001-10-26 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/e-address-popup.c (e_address_popup_destroy):
- Cancel any pending queries.
-
- * gui/contact-editor/e-contact-editor.c (close_dialog): Don't
- assert, but check if ce->app != NULL, since this function can
- (apparently) get called multiple times.
-
- * gui/contact-editor/e-contact-save-as.c (file_exists): Remove bad
- dialog ref-counting crap.
-
- * gui/contact-editor/e-contact-editor.c (save_card): Ref our
- EContactEditor, since we are holding a pointer to it in
- EditorCloseStruct.
- (card_modified_cb): Unref our EContactEditor when we free our
- EditorCloseStruct.
- (card_added_cb): Unref our EContactEditor when we free our
- EditorCloseStruct.
-
-2001-10-26 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (check_for_slow_setting): make debug
- info more accurate
-
-2001-10-26 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (e_addr_context_destroy): prevent
- double unref
- (cursor_cb): correct typo
- (card_removed): remove the card from the map if was archived and
- is now deleted
-
-2001-10-26 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.h: new member
-
- * conduit/address-conduit.c (print_remote): free the struct after
- using it
- (e_addr_context_new): make consistent with other conduits
- (e_addr_context_destroy): properly destroy the context
- (cursor_cb): no need to ref the card, its done for us
- (clear_entry_text): util function to free a field
- (free_local): free a local record
- (local_record_to_pilot_record): use a static buffer so we don't
- have to free it later
- (local_record_from_ecard): only fill in the fields we might not
- sync, clear a field before replacing the contents
- (for_each): track locals
- (for_each_modified): ditto
- (free_match): use free_local
-
-2001-10-26 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-minicard.c, gui/widgets/e-minicard.h
- (set_has_cursor): Added has_cursor argument. Setting the argument
- to TRUE if the minicard doesn't have focus will grab the focus.
- Fixes Ximian bug #3024.
-
-2001-10-24 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/addressbook-factory.c (main): Initialize
- gnome-vfs.
-
- * gui/component/addressbook-component.c (xfer_file): Added.
- (Copied from the calendar.)
- (xfer_folder): Fixed to allow renaming of contact folders.
-
-2001-10-24 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-view.c
- (e_addressbook_view_class_init): Removed key_press handler here
- since delete and backspace are now handled by keybindings.
-
-2001-10-23 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/addressbook.c: Fix command paths when we specify
- our pixmaps, so we don't get a lot of totally useless & very ugly
- bonobo-ui spew.
-
- * backend/ebook/e-book-util.c (e_book_nickname_query): The empty
- string as an arg shouldn't generate a warning.
-
- * gui/component/select-names/e-select-names-completion.c: Removed
- our cancelled flag and e_select_names_completion_cancel function,
- since we were just duplicating stuff that had ended up in
- ECompletion.
- (match_name): Form our menu_text properly on an additional-name
- match.
- (e_select_names_completion_got_book_view_cb): Store handles for
- our signals, disconnect them properly when we switch book views.
- (e_select_names_completion_stop_query): Disconnect signals when we
- stop our query.
- (check_capabilities): Spew if we are using LDAP for completion.
- (e_select_names_completion_destroy): Disconnect our signals when
- we destroy.
- This all should fix bug #10241.
-
-2001-10-23 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_add_section): Set "draw_button" argument to TRUE
- on this EEntry.
-
-2001-10-22 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/e-contact-save-as.c (save_it): Put up an
- error dialog if there's an error while saving. If the person hits
- cancel on the "file exists" dialog, don't close the file selection
- dialog. Fixes Ximian bug #7055.
-
-2001-10-21 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-reflow-adapter.c
- (model_and_selection_free): right_click_up here when we let go of
- the popup.
-
- * gui/widgets/e-minicard-view.c (e_minicard_view_selection_event):
- right_click_up here.
-
-2001-10-21 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_add_section, e_select_names_set_default): Use an
- EEntry here instead of a GtkLabel. Fixes Ximian bug #7067.
-
-2001-10-21 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/addressbook.c (control_activate_cb): Call
- e_addressbook_model_force_folder_bar_message when we activate the
- component. (Fixes bug #11749)
-
- * gui/widgets/e-addressbook-model.c
- (e_addressbook_model_force_folder_bar_message): Added. Forces
- emission of a folder_bar_message.
-
-2001-10-20 Larry Ewing <lewing@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_set_default): stick with the style font if the
- efont bold font does not exist.
- (e_select_names_set_default): don't forget to unref the oldstyle.
-
-2001-10-20 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (name_style_query): Fix memory leak.
-
- * gui/widgets/e-addressbook-view.c (jump_to_letter): Free our
- string vector letter_v when we are done with it.
-
- * gui/contact-editor/e-contact-quick-add.c (edit_card): Unref our
- QuickAdd structure.
-
- * gui/component/e-address-popup.c (e_address_popup_construct):
- Unref our style after we are done with it.
-
-2001-10-20 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-book.c (activate_factories_for_uri): We
- shouldn't leak the info returned by oaf_query.
-
- * gui/contact-editor/e-contact-quick-add.c (card_added_cb): Remove
- superfluous call to quick_add_unref.
- (editor_closed_cb): Remove superfluous call to quick_add_unref.
-
- * gui/component/select-names/e-select-names.c (esn_get_key_fn): We
- need to unref the card returned by e_addressbook_model_get_card.
-
-2001-10-20 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c: Make LDAP servers
- non-user-creatable.
-
-2001-10-20 Jon Trowbridge <trow@ximian.com>
-
- * printing/e-contact-print.c (e_contact_print_card): Check that the
- string we are checking for xml-ness is non-NULL.
-
- * backend/ebook/e-destination.c (e_destination_importv): Filter
- out empty destinations. (also Bug #13036)
-
- * printing/e-contact-print.c (e_contact_build_style): Use
- gnome_font_new_closest; if gnome_font_new fails and returns NULL,
- our spacing gets all messed up. (Bug #10785)
-
- * gui/widgets/e-addressbook-view.c (e_addressbook_view_can_print):
- Allow printing if there are any cards in our view. The selection
- has nothing to do with it.
-
- * backend/ebook/e-destination.c (e_destination_is_empty): Check
- for strings that contain non-whitespace, rather than just looking
- for a non-zero first character. (Bug #13036)
-
-2001-10-20 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-minicard-view.c (e_minicard_view_selection_event):
- Handle focus_change in event by selecting that contact. Fixes
- Ximian bug #3024.
-
- * gui/component/addressbook-component.c (owner_unset_cb):
- Repeatedly call gtk_main_quit here as long as there is a main loop
- around. This is an ugly hack around Ximian bug #11760.
-
-2001-10-20 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c: Added #include
- <gal/widgets/e-unicode.h>.
-
- * gui/widgets/e-minicard-control.c: Made this display the number
- of extra cards in the attachment as well as made it save them all
- to the local addressbook if the person selects the button. Fixes
- Ximian bug #9507.
-
-2001-10-20 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-minicard.c (e_minicard_event): Changed this to not
- grab on a right click. Fixes Ximian bug #12660.
-
-2001-10-19 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c
- (destination_folder_handle_motion): Get @folder_type here too [to
- match the changes in the EvolutionShellComponentDnd interface].
- Also, remove a debugging message.
- (destination_folder_handle_drop): Likewise.
-
-2001-10-18 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names.c (add_menu_item):
- Translate labels in select-names option menu. (Bug #9604)
-
- * gui/search/e-addressbook-search-dialog.c
- (e_addressbook_search_dialog_init): Made the default window size
- slightly wider. (Bug #7516)
-
-2001-10-18 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h
- (e_card_list_get_vcard): Made this take a const GList.
-
-2001-10-18 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (check_capabilities): Added. Check if our book is local or
- networked.
- (e_select_names_completion_book_ready): Call check_capabilities.
- (e_select_names_completion_new): Call check_capabilities.
- (e_select_names_completion_do_query): If we have a networked book,
- keep trying if we haven't been able to cache any cards --- our
- earlier attempts could have failed due to too many matches. (Bug
- #12932)
-
- * gui/component/select-names/e-select-names-manager.c
- (focus_out_cb): Lag our cardification on focus-out. This seems to
- help with the unintended cardifications that can result from the
- weird focus-out/focus-in events that get generated when the popup
- disappears.
-
- * backend/ebook/e-card-compare.c: Removed some debug spew.
-
-2001-10-17 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-config.c (addressbook_source_dialog):
- grab focus in the Account entry when preparing the dialog, fixes
- #10406.
-
-2001-10-17 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names.c (new_folder): make
- sure to also add "ldap-contacts" folders to the option menu.
-
-2001-10-17 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (ecard_from_remote_record): sync all
- the fields we can, with out overwriting
- (local_record_from_ecard): write the fields to the pilot in
- priority order unless there are fields on the pilot we can't
- store, then fill in the fields as they are on the pilot
-
-2001-10-17 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card.c (e_card_get_vobject): Did a bit of clean
- up here. Might fix some crashes, specifically Ximian bug #10164.
-
- * gui/widgets/e-addressbook-view.c (SPEC): Updated the model
- column numbers here. Fixes Ximian bug #12308.
-
-2001-10-17 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_upgrade_db):
- add upgrade from 0.1 to 0.2, where we make sure id dbt's match
- vcard id's, fixes longstanding bug (#7406) where cards were not
- modifiable or removable after having been created during a 1-2
- week long window in early betas.
- (PAS_BACKEND_FILE_VERSION): change to 0.2
- (PAS_ID_PREFIX): #define this here.
- (pas_backend_file_create_unique_id): use PAS_ID_PREFIX instead of
- the string.
-
-2001-10-16 Iain Holmes <iain@ximian.com>
-
- * backend/ebook/evolution-ldif-importer.c (support_format_fn): Return
- FALSE if no extension.
-
-2001-10-16 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-card.c (e_card_get_id): If card->id is NULL,
- return an empty string.
- (e_card_set_id): Don't allow the card id to be set to NULL; use
- the empty string instead.
- (e_card_get_vobject): When building our vcard, pass in the empty
- string as the id if card->id is NULL. (Bug #10164)
-
-2001-10-16 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (local_record_from_ecard): don't set
- the phone info if it is blank
- (ecard_from_remote_record): save up to 3 fax numbers
-
-2001-10-15 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_add_client):
- unref the book after we pass it off to evolution-addressbook.
-
-2001-10-15 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (create_card_dtor): unref
- op->view.
- (pas_backend_ldap_process_create_card): ref op->view.
- (remove_card_dtor): unref op->view.
- (pas_backend_ldap_process_remove_card): ref op->view.
- (modify_card_dtor): unref op->view.
- (pas_backend_ldap_process_modify_card): ref op->view.
- (ldap_search_dtor): unref op->view.
- (pas_backend_ldap_search): ref op->view.
-
-2001-10-15 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_process_get_book_view): make sure to unref the
- book_view here so we don't leak them.
-
-2001-10-12 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-factory.c (main): call
- e_passwords_init and e_passwords_shutdown.
-
-2001-10-15 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card.c (addPropValueQP, addPropValueSets,
- e_card_get_vobject): Properly decide whether a property needs to
- be marked as QP by searching for '\n'. Fixes Ximian bug #3021.
-
-2001-10-15 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/e-contact-save-as.c (e_contact_save_as,
- e_contact_list_save_as): Set the default file name here. Fixes
- Ximian bug #7053.
-
-2001-10-14 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_hookup_shell_listeners): Added linebreaks to our
- "this shouldn't happen" dialog message. (Bug #12498)
-
-2001-10-12 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/addressbook-factory.c (main): Add a component name
- to the e_passwords_init() call.
-
-2001-10-12 Chris Toshok <toshok@ximian.com>
-
- * backend/ebook/evolution-ldif-importer.c: commit the importer
- originally from Michael M. Morrison, with fixups by toshok.
-
- * backend/ebook/Makefile.am (bin_PROGRAMS): add
- evolution-ldif-importer.
- (oaf_in_files): add
- GNOME_Evolution_Addressbook_LDIF_Importer.oaf.in.
-
- * backend/ebook/e-card-simple.h: add WANTS_HTML and IS_LIST.
-
- * backend/ebook/e-card-simple.c (field_data): add WANTS_HTML and
- IS_LIST.
- (e_card_simple_set): fix typo.
-
- * backend/ebook/.cvsignore: ignore
- GNOME_Evolution_Addressbook_LDIF_Importer.oaf and
- evolution-ldif-importer.
-
- * backend/ebook/GNOME_Evolution_Addressbook_LDIF_Importer.oaf.in:
- ldif importer oafinfo.
-
-2001-10-12 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h:
- Added a boolean type here.
-
-2001-10-12 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (addressbook_model_set_uri): Check to see if the uri we are
- setting is the same as the current uri. If so, do nothing.
- (Bug #11324)
-
-2001-10-11 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-destination.c
- (e_destination_reverting_is_a_good_idea): Added. Heuristic for
- whether or not we want to revert to an earlier cardified state.
- (e_destination_cardify): Don't be quite as aggressive about
- reverting to previous cardified states. (Bug #11890)
-
-2001-10-11 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-simple.c (e_card_simple_destroy,
- fill_in_info, e_card_simple_sync_card, e_card_simple_set_phone,
- e_card_simple_set_address, e_card_simple_set_delivery_address,
- file_as_get_style, file_as_set_style, e_card_simple_set,
- e_card_simple_set_arbitrary),
- gui/contact-editor/e-contact-editor-address.c
- (e_contact_editor_address_destroy,
- e_contact_editor_address_set_arg,
- e_contact_editor_address_get_arg),
- gui/contact-editor/e-contact-editor-fullname.c
- (e_contact_editor_fullname_destroy,
- e_contact_editor_fullname_set_arg,
- e_contact_editor_fullname_get_arg),
- gui/contact-editor/e-contact-editor.c (phone_entry_changed,
- address_text_changed, name_entry_changed, full_name_clicked,
- full_addr_clicked, fill_in_info): Changed these to use the new ref
- and unref functions for ECard auxillary types.
-
- * backend/ebook/e-card-simple.h: Added a comment.
-
- * backend/ebook/e-card-types.h: Added ref_count field to all the
- types.
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Added ref and
- unref functions here for all the ECard auxillary types. Removed
- the corresponding free functions. Switched to using these
- functions where appropriate.
-
- * gui/component/addressbook-factory.c: #include
- <e-util/e-passwords.h>
-
- * gui/component/addressbook.c (load_uri_cb): const correctify.
-
- * gui/component/select-names/e-select-names-manager.c,
- gui/component/select-names/e-select-names.c: #include
- <addressbook/gui/component/addressbook.h>
-
- * gui/widgets/e-addressbook-model.c (modify_card): Removed an
- unnecessary ref here.
-
-2001-10-11 Dan Winship <danw@ximian.com>
-
- * gui/component/select-names/e-select-names.c (update_folder):
- Don't need this any more.
-
-2001-10-11 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/addressbook.c (new_contact_cb): Check that
- view->view != NULL.
- (save_contact_cb): Check that view->view != NULL.
- (search_cb): Check that view->view != NULL.
- (delete_contact_cb): Check that view->view != NULL.
- (print_cb): Check that view->view != NULL.
- (print_preview_cb): Check that view->view != NULL.
- (stop_loading_cb): Check that view->view != NULL.
- (cut_contacts_cb): Check that view->view != NULL.
- (copy_contacts_cb): Check that view->view != NULL.
- (paste_contacts_cb): Check that view->view != NULL.
- (select_all_contacts_cb): Check that view->view != NULL.
- (send_contact_cb): Check that view->view != NULL.
- (send_contact_to_cb): Check that view->view != NULL.
- (update_command_state): Check that view->view != NULL. Hold a
- reference to the AddressbookView for the duration of the function,
- in case we exit during bonobo-reentrancy.
- (addressbook_view_ref): Added.
- (addressbook_view_unref): Added. Simple ref counting for
- AddressbookView objects.
- (addressbook_view_clear): Zero out an AddressbookView. This is
- now separated from the deallocation of the AddressbookView object,
- so that we don't leave a dangling pointer if we exit during
- bonobo-reentrancy in update_command_state. (Which often seems to
- happen if we exit while addressbook operations are going on.)
- (destroy_callback): Replace previous call to addressbook_view_free
- with addressbook_view_clear/addressbook_view_unref calls.
- (addressbook_factory_new_control): Initialize the reference count
- in the AddressbookView object.
-
- * gui/widgets/e-addressbook-view.c (e_addressbook_view_destroy):
- Carefully zero out our destroyed object.
- (command_state_change): Hold a reference to ourselves during the
- signal emission.
- (get_selected_cards): Ref cards as we add them to the list.
- (e_addressbook_view_stop): Check for view != NULL.
- (e_addressbook_view_can_create): Check for view != NULL.
- (e_addressbook_view_can_print): Check for view != NULL.
- (e_addressbook_view_can_save_as): Check for view != NULL.
- (e_addressbook_view_can_send): Check for view != NULL.
- (e_addressbook_view_can_send_to): Check for view != NULL.
- (e_addressbook_view_can_delete): Check for view != NULL.
- (e_addressbook_view_can_cut): Check for view != NULL.
- (e_addressbook_view_can_copy): Check for view != NULL.
- (e_addressbook_view_can_paste): Check for view != NULL.
- (e_addressbook_view_can_select_all): Check for view != NULL.
- (e_addressbook_view_can_stop): Check for view != NULL.
-
- * gui/widgets/e-addressbook-model.c (addressbook_destroy): Be
- careful about zeroing out our destroyed object.
-
- * backend/ebook/e-book-view.c (e_book_view_stop): Added. Stops
- event processing in the underlying listener.
-
-2001-10-10 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_destroy): If our select names dialog is
- still around, destroy it. Otherwise, the dialog will hang around
- after our composer goes away.
-
-2001-10-06 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-config.glade: add an Email Address
- field/label/help text.
-
- * gui/component/addressbook-config.c
- (addressbook_source_dialog_set_source): fill in the email entry
- from the source. also, set the initial state of the email
- label/entry.
- (auth_checkbutton_changed): set the email label/entry
- sensitive/editable if auth is turned on, and
- insensitive/uneditable if it's off.
- (addressbook_source_dialog_get_source): get the email address from
- the email entry.
- (addressbook_source_dialog): hook up the email entry to the
- changed signal foo, as well as the focus handler for displaying
- help text.
-
-2001-10-06 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_new): db isn't a BonoboObject, so don't
- bonobo_object_unref it!
-
-2001-10-05 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (addressbook_model_set_uri): e_book_load_uri ->
- addressbook_load_uri.
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_new): e_book_load_uri ->
- addressbook_load_uri.
-
- * gui/component/addressbook.c (forget_passwords_cb): new function,
- call e_passwords_forget_passwords.
- (verbs): Add ContactsForgetPasswords.
- (load_uri_auth_cb): new function, call the callback and free up
- our closure stuff.
- (load_uri_cb): once the uri is loaded, check if we're configured
- to authenticate for it, and do so, using the e_passwords stuff.
- (addressbook_load_uri): wrapper around e_book_load_uri. save off
- the parameters and start the load-with-auth machinery.
- (book_open_cb): remove all the auth stuff from here, as it's
- handled elsewhere now.
-
- * gui/component/addressbook-factory.c (main): call
- e_passwords_init.
-
- * gui/component/addressbook-component.c (user_create_new_item_cb):
- e_book_load_uri -> addressbook_load_uri.
- (destination_folder_handle_drop): same.
-
- * gui/component/addressbook.h: add prototype for
- addressbook_load_uri (a wrapper around e_book_load_uri that also
- handles authentication if the user selects it.)
-
-2001-10-05 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (real_add_address_cb): Check to make sure our call to
- e_addressbook_model_get_card doesn't return NULL.
-
- * gui/widgets/e-addressbook-model.c
- (e_addressbook_model_get_card): Chek that we aren't requesting a
- negative row.
-
- * gui/contact-list-editor/e-contact-list-editor.c (add_email_cb):
- Move to the bottom of the scrolled window, so we can see the
- address we just added.
- (table_drag_data_received_cb): Move to the bottom of the scrolled
- window, so we can see the contact we just dropped.
-
- * gui/component/addressbook.c (addressbook_factory_new_control):
- We don't own the string returned by e_categories_master_list_nth,
- so terrible things will happen if we free it. (Bug 10916)
-
-2001-10-05 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (e_addressbook_view_set_arg):
- don't set the editable field on the model - let the book do that.
- (book_writable_cb): call writable_status to propagate a ui-change
- event up (and sensitize the write-only toolbar buttons after you
- authenticate with ldap.)
-
-2001-10-04 Chris Toshok <toshok@ximian.com>
-
- * backend/ebook/e-book.c (activate_factories_for_uri): for some
- reason, matching on protocol is causing problems for me.
- disabling it for now.
-
-2001-10-04 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-component.c: use ldap.png for ldap
- contacts.
-
-2001-10-03 Iain Holmes <iain@ximian.com>
-
- * addressbook/gui/component/addressbook-storage.c
- (addressbook_storage_setup): Only load_storages if you have LDAP.
- (load_source_data): Only do stuff if you have LDAP.
-
-2001-10-03 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-reflow-adapter.c (addressbook_height),
- gui/widgets/e-minicard.c (remodel): Fixed these to determine the
- fields to use properly.
-
-2001-10-02 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (name_style_query): Strip out commas before forming our query.
- (match_name): Use e_card_compare_name_to_string_full, rather
- than our crufty old matching code. Not only is this cleaner,
- but that crufty old code was very broken when it came to
- handling strings with whitespace. (Bug 8988)
- (match_nickname): utf8 and bug fixes.
-
- * backend/ebook/e-card-compare.c
- (e_card_compare_name_to_string_full): Added. This is basically
- e_card_compare_name_to_string with a bunch of extra options, so
- that it can more readily be reused in other contexts.
- (e_card_compare_name_to_string): This is now just a call to
- e_card_compare_name_to_string_full with the extra args filled in
- to defaults that simulate the old behavior.
-
-2001-10-02 Chris Toshok <toshok@ximian.com>
-
- * backend/ebook/e-book.c (e_book_construct): remove most of the
- oaf stuff from here. we do it in load_uri, where we'll have more
- information (namely, the protocol we're using.)
- (activate_factories_for_uri): do an oaf query to get a list of all
- objects implementing our BookFactory interface and also supporting
- the protocol used in the uri.
- (e_book_load_uri): try activating book factories to handle this
- uri, and start the iteration over the list.
- (e_book_load_uri_from_factory): try and load the uri.
- (e_book_load_uri_open_cb): callback function for the
- BookFactory_openBook call - if it succeeds, call the user's
- callback. otherwise step to the next factory.
- (e_book_load_uri_step): go to the next factory in our list, and
- error out if there are no more.
-
-2001-10-02 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names-model.c
- (e_select_names_model_get_textification): Made the max length of
- the textification be 2047 characters. Fixes Ximian bug #3021.
-
-2001-10-01 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (ecard_from_remote_record): if there
- was no first name or last name, file as the company.
-
-2001-10-01 JP Rosevear <jpr@ximian.com>
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_changes_foreach_key): if there is a db error,
- assume deletion
- (pas_backend_file_changes): write after all is done for efficiency
-
-2001-09-28 JP Rosevear <jpr@ximian.com>
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_changes_foreach_key): g_strdup
- (pas_backend_file_changes): ditto, make sure to free all data and
- do a hash write after each add/remove
-
- * conduit/address-conduit.c (local_record_to_pilot_record): use
- the local record category
- (local_record_from_ecard): ndle the fields and category we don't
- sync by making sure we don't overwrite them
-
-2001-09-27 Chris Toshok <toshok@ximian.com>
-
- * backend/ebook/e-book.c (e_book_construct): do an oaf query to
- get a list of all objects implementing our BookFactory interface,
- instead of just activating the one IID. this should really be a
- global list, not a per EBook.
- (e_book_load_uri): start the iteration over our list of
- BookFactory's.
- (e_book_load_uri_from_factory): try and load the uri.
- (e_book_load_uri_open_cb): callback function for the
- BookFactory_openBook call - if it succeeds, call the user's
- callback. otherwise step to the next factory.
- (e_book_load_uri_step): go to the next factory in our list, and
- error out if there are no more.
-
-2001-09-27 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (local_record_from_ecard): use the old
- record (if there was one) so as not to overwrite fields we don't
- sync
- (pre_sync): store the dbi in the context and don't make it object
- data
-
-2001-09-26 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-book-factory.c (pas_book_factory_destroy): use
- priv->iid instead of the hardcoded string here.
- (pas_book_factory_activate): parameterize the factory's iid, as in
- the calendar server, and provide a default if iid == NULL.
-
- * backend/pas/pas-book-factory.h: add iid parameter for
- pas_book_factory_activate.
-
-2001-09-26 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_get_textrep): Use
- camel_address_format, not camel_address_encode.
-
-2001-09-26 Anna Marie Dirks <anna@ximian.com>
-
- * gui/contact-editor/contact-editor.glade: Added help text (thanks
- to Aaron) and re-worded the labels, and fixed the shortcuts on the
- brand-spanking-new Collaboration tab.
-
-
-2001-09-26 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names-manager.h: add
- completion_book.
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_new): get /Addressbook/Completion/uri, and
- if it's present, use the corresponding EBook for completing
- addresses.
- (focus_out_cb): use manager->completion_book here instead of NULL,
- which corresponds to the local addressbook.
- (completion_popup_cb): same.
- (e_select_names_manager_create_entry): same.
-
-2001-09-26 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-card-compare.c (e_card_compare_name_to_string):
- Properly handle names when the individual elements (given,
- addition, family) contain whitespace. (Bug #10502)
-
- * backend/ebook/e-destination.c (e_destination_set_name): Reset
- textrep when we change the name.
- (e_destination_set_email): Reset textrep when we change the email.
- (e_destination_get_textrep): Make sure that the textrep version of
- the address is properly quoted if it contains unsafe characters.
- (All related to bug #10796)
-
- * gui/component/select-names/e-select-names-completion.c
- (match_nickname): Fix nickname matching. (bug #9698)
- (make_match): Use e_completion_match_new when building our match,
- rather than ad hoc manipulation of the struct.
-
-2001-09-26 JP Rosevear <jpr@ximian.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_changes): set
- the last_use and use_score fields of the card to known values so
- the card doesn't register as changed when only they have changed
-
-2001-09-26 Peter Williams <peterw@ximian.com>
-
- * conduit/address-conduit.c (ecard_from_remote_record): Fix this function
- to set email addresses properly, and handle multiple occurrences of
- email addresses, home phone numbers, and business phone numbers.
-
-2001-09-25 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook-component.c (user_create_new_item_cb):
- Handle creating the new contact in the current folder if it's a
- contacts folder. Fixes Ximian bug #7814.
-
-2001-09-24 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/Makefile.am (LDAP_SCHEMA): add
- evolutionperson.schema
- (EXTRA_DIST): add LDAP_SCHEMA to the dist (but don't install it).
-
-2001-09-23 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (ecard_from_remote_record): sync the
- note the to pilot and make sure to blank fields when appropriate
- (local_record_from_ecard): sync the note to the desktop
-
-2001-09-22 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-file.c (do_create): g_free (id) in the
- error case to plug a memory leak.
-
-2001-09-22 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-minicard.c (remodel): when creating the cards,
- don't display any of the subname fields (surname, given, middle,
- suffix, etc.)
-
-2001-09-22 Chris Toshok <toshok@ximian.com>
-
- * backend/ebook/e-card-simple.c
- (e_card_simple_get): add getters for the additional name fields.
- (field_data): move FAMILY_NAME to the end of the list, and add
- GIVEN_NAME, ADDITIONAL_NAME (middle name), and NAME_SUFFIX.
-
- * backend/ebook/e-card-simple.h: same.
-
-2001-09-21 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook.c (print_preview_cb): Hooked up print
- preview button.
-
- * gui/widgets/e-addressbook-view.c,
- gui/widgets/e-addressbook-view.h
- (e_addressbook_view_print_preview): Added this function.
-
- * printing/e-contact-print.c, printing/e-contact-print.h
- (e_contact_print_preview): Added this function.
-
-2001-09-19 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-destination.c (name_and_email_simple_query_cb):
- Use the default e-mail address if we have nothing else to go on.
- Previously we just failed, which basically meant that name-only
- searches would never work properly.
- (nickname_simple_query_cb): The logic was a bit tangled here; if
- our query status isn't SUCCESS, always give up but don't leak the
- destination. And if our nickname query fails and we try the
- name-and-email query, use the textrep for a name-only search. The
- only reason we are doing a nickname query in the first place is if
- we have an obviously invalid e-mail.
- (launch_cardify_query): Use e_destination_is_valid to determine
- if we should try a nickname query first.
- These changes basically fix bug 7728, and generally make the
- auto-cardification of addresses a lot more clever and robust.
-
- * backend/ebook/e-book-util.c (name_and_email_cb): Use
- e_card_compare_name_to_string instead of e_card_name_match_string.
- (e_book_name_and_email_query): The arguments to g_strsplit were
- in the wrong order. Doh!
-
- * backend/ebook/e-card-compare.c (e_card_compare_name_to_string):
- Added. Replaces e_card_name_match_string, and actually works.
-
- * backend/ebook/e-card.c: Removed e_card_name_match_string
- function, which didn't work particularly well.
-
-2001-09-19 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (cursor_cb): don't add to the complete
- list of cards if the card is a list
- (card_added): don't add to the list of changes if the card is a
- list
- (card_changed): ditto
- (card_removed): ditto
-
-2001-09-19 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_hookup_shell_listeners): Change the "this should
- never happen" message into a request for people to e-mail me
- directly with info if they encounter that error.
-
- * backend/ebook/e-book-util.c (e_book_name_and_email_query):
- Freeing name[i] instead of namev[i] is a bad idea. (bug #10270)
-
- * gui/component/select-names/e-select-names-popup.c
- (popup_menu_card): Properly handle our GnomeUIInfo labels so that
- they won't be leaked if they are dynamic strings, so that they
- will be i18n-correct, and so that underscores won't be interpreted
- as key accelerators. What a PITA. Also, don't leak our
- iterators. (Bug #10200.)
- (popup_menu_list): The same GnomeUIInfo tweaking as in
- popup_menu_card.
- (popup_menu_nocard): Ditto.
-
-2001-09-18 JP Rosevear <jpr@ximian.com>
-
- * backend/ebook/e-card-simple.c (field_data): add caluri field data
-
- * backend/ebook/e-card.c (e_card_get_vobject): add the caluri
- property when appropriate
- (parse_caluri): handle read caluri
- (e_card_class_init): add caluri arg
- (e_card_destroy): free the caluri
- (e_card_get_arg): return caluri arg
- (e_card_set_arg): set caluri from arg
- (e_card_init): init caluri to null
-
- * backend/ebook/e-card-simple.h: new simple field
-
- * backend/ebook/e-card.h: new member
-
- * gui/contact-editor/e-contact-editor.c (field_changed): util
- callback to change the command state
- (set_entry_changed_signal_field): hook up a change signal to above
- (set_entry_changed_signals): use above function
-
- * gui/contact-editor/e-contact-editor.glade: Add collaboration
- page and fields
-
-2001-09-18 JP Rosevear <jpr@ximian.com>
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_build_cards_list): create a sexp and check if
- the cards match before adding them to the list
- (pas_backend_file_process_get_cursor): send extra param
-
-2001-09-18 Larry Ewing <lewing@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (book_query_process_card_list): unref the destination regardless
- of whether we get an email addresss.
-
-2001-09-17 Larry Ewing <lewing@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (name_style_query): use g_strfreev.
- (match_name): s/g_free/g_strfreev.
- (match_file_as): s/g_free/g_strfreev.
-
- * backend/ebook/e-book-util.c (e_book_name_and_email_query): fix
- the memory handling here. All there members of the vector need to
- be freed all the time.
-
- * backend/ebook/load-pine-addressbook.c (parse_line): free the
- string outside of the test that makes sure there are three
- entries.
-
- * gui/component/select-names/e-select-names-completion.c
- (match_nickname): don't malloc a match we will never use.
-
- * gui/widgets/e-addressbook-model.c (get_view): free the dup'd
- capabilities.
-
-2001-09-17 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_is_valid): We want
- to assume that a destination that comes from a card is
- automatically valid, but the right way to check that is by calling
- e_destination_from_card, not by checking if dest->priv->card !=
- NULL. (Fixed bug #10017)
-
- * gui/component/select-names/e-select-names-completion.c
- (match_name): Fixed a stupid bug was causing completion to fail
- for contacts who have only one name. (The classic example we all
- know and love is 'George <jirka@5z.com>') (bug #8353)
-
- * backend/ebook/e-card.c (e_card_list_send): Do the right thing if
- the card we are trying to send to has no valid e-mail addresses.
- (bug #10137)
-
- * gui/widgets/e-minicard.c (e_minicard_event): Code implicitly
- assumed that event->button.button is 1, 2, or 3, causing disaster
- when using a wheel-mouse. Fixed. (bug #9400)
-
-2001-09-16 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c (_phone_arrow_pressed):
- use enable_widget instead of gtk_widget_set_sensitive.
- (_email_arrow_pressed): same.
- (_address_arrow_pressed): same.
- (disable_widget_foreach): same.
- (enable_writable_fields): same.
- (set_editable): same.
- (enable_widget): new function, using both gtk_widget_set_sensitive
- and *_set_editable to allow the user to select text in GtkEntry's
- and GtkText's.
-
- * gui/contact-editor/e-contact-editor-fullname.c
- (e_contact_editor_fullname_set_arg): use set_editable as well as
- set_sensitive, to allow the user to select text in GtkEntry's.
-
- * gui/contact-editor/e-contact-editor-address.c
- (e_contact_editor_address_set_arg): same.
-
-2001-09-16 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/evolutionperson.schema: fix syntax errors (which are
- broken, imo...)
-
-2001-09-16 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-storage.h: reorder the LDAP scopes so
- that they match the order of the option menus in the glade file.
-
- * gui/component/addressbook-config.c (auth_checkbutton_changed):
- new function, mostly there to house some #ifdef'ed out code.
- (option_menuitem_activated): new function, to keep track of
- changes to the ldap scope optionmenu.
- (addressbook_source_dialog_set_source): set the menu history as
- well as the dialog's copy of the scope.
- (addressbook_source_dialog_get_source): fill in the source's scope
- from the dialog's copy, and add more #if the_ui_gods_smile_on_me
- code.
- (add_activate_cb): new function, add an activate callback for the
- optionmenu's items.
- (addressbook_source_dialog): more #if the_ui_gods_smile_on_me
- code, always start the dialog on page 0, and hook up the
- scope optionmenu's items.
-
-2001-09-15 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-card-compare.c (e_card_compare_name): No
- loose name matches on family names. (#8802)
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_activate_obj): We can't use NULL as the
- first arg for e_addressbook_show_contact_editor anymore. Damn.
- (#8535)
-
- * backend/ebook/e-book-listener.c (e_book_listener_stop): Make
- "stop" do nothing but set the stopped flag, as in
- e-book-view-listener.c.
- (e_book_listener_destroy): Clean up our queue here, rather than in
- e_book_listener_stop.
- (response_free): Added. Move the rather lengthy bit of code
- needed to free a EBookListenerResponse into one place.
- (e_book_listener_check_queue): Properly deal with the stopped
- flag.
- (e_book_listener_queue_response): If the stopped flag is set, just
- drop the incoming response.
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_stop): Make "stop" do nothing but set the
- stopped flag.
- (e_book_view_listener_destroy): Move all of the clean-up that used
- to be in e_book_view_listener_stop here. This considerably simplifies
- the logic required to avoid various race conditions.
- (e_book_view_listener_check_queue): Properly deal with the stopped flag.
- (e_book_view_listener_queue_response): Drop all incoming responses if
- we are stopped.
-
-2001-09-14 Jon Trowbridge <trow@ximian.com>
-
- * backend/pas/pas-book.c (pas_book_queue_request): Hold a
- reference to the book on behalf of our idle function.
- (pas_book_check_queue): When we are finished, drop the reference
- we've been holding on behalf of the idle function.
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_process_create_card): Hold a reference to the
- book_view while sending our notifications.
- (pas_backend_file_process_remove_card): Hold a reference to the
- book_view while sending our notifications.
-
- * gui/contact-editor/e-contact-quick-add.c (quick_add_unref): Remove
- debugging spew.
-
- * backend/ebook/e-book-util.c: Remove a lot of unused code that
- worked around bugs that have long since been fixed.
- (simple_query_disconnect): Added. Breaks out the part of
- simple_query_free that disconnect signals.
- (simple_query_free): Replace code w/ a call to
- simple_query_disconnect.
- (simple_query_sequence_complete_cb): Call simple_query_disconnect
- before executing the callback, so that our callbacks don't get
- triggered by any book changes that might occur during that
- callback.
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_check_queue): Changed to be consistent with
- e_book_listener_check_queue.
- (e_book_view_listener_queue_response): Also changed to use a
- high-frequency timeout.
-
- * backend/ebook/e-book-listener.c (e_book_listener_check_queue):
- OK, I've agonized over this stupid little function, and it should
- now be race-free.
- (e_book_listener_queue_response): We process our response queue in
- a high-frequency timeout rather than an idle. Using an idle
- function leads to some tricky race conditions and bad interactions
- with bonobo's semi-broken attempts to take over event processing.
- (e_book_view_listener_stop): Manually disable our timeout and
- clean up.
-
-2001-09-14 Ettore Perazzoli <ettore@ximian.com>
-
- [Automake 1.5 fixes pointed out by Richard Boulton
- <richard@tartarus.org>, as per #9258.]
-
- * gui/component/select-names/Makefile.am: Set CLEANFILES directly
- instead of using `+='.
-
- * backend/pas/Makefile.am: Rename `LDAP_BACKEND_SOURCES' to
- `LDAP_BACKEND_FILES'.
-
- * backend/ebook/Makefile.am: Set CLEANFILES directly instead of
- using `+='.
-
-2001-09-13 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_connect): use
- ldap_init. ldap_open is deprecated in openldap 2.x.
-
-2001-09-12 Iain Holmes <iain@ximian.com>
-
- * backends/ebook/evolution-vcard-importer.c (check_file_is_vcard):
- Fix the check.
-
-2001-09-12 Larry Ewing <lewing@ximian.com>
-
- * backend/ebook/e-destination.c: free the values that are being
- leaked here.
-
-2001-09-12 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c (match_email):
- printf arguments were reversed by mistake. Fixed bug #9693.
-
-2001-09-09 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-popup.c
- (popup_menu_list): Added. Treat right-clicks on a contact list as
- a special case.
- (e_select_names_popup): Check if we are dealing with a contact
- list.
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_check_queue): See
- e_book_listener_check_queue below.
- (e_book_view_listener_queue_response): See
- e_book_listener_queue_response below.
-
- * backend/ebook/e-book-listener.c (e_book_listener_check_queue):
- Explicitly prohibit reentrancy. Use gtk-unref rather than
- bobobo-unref.
- (e_book_listener_queue_response): Hold a gtk-ref to the listener
- while the idle function runs, not a bonobo-ref. As far as I can
- tell, it is impossible to avoid a race condition here when we have
- to worry about bonobo reentrancy.
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_insert_length): Alter a copy of the
- original EDestination, rather than just using a new one. We need
- to do this to preserve prior-card information for possible
- reversion later.
- (e_select_names_text_model_delete): Ditto.
-
- * backend/ebook/e-destination.c (e_destination_clear_card): When
- clearing a destination where ->card != NULL, store it for possible
- reversion later.
- (e_destination_revert): If we have an old card stored, go back to
- using it for the destination.
- (e_destination_is_valid): Tries to detect obviously broken
- addresses.
- (e_destination_cardify): If our destination is invalid, first try
- to cardify simply by reverting to an older card.
- (e_destination_destroy): Unref any cached old card.
- (e_destination_copy): Copy the old card information.
-
-2001-09-07 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (sync_table_and_models): Show all rows in the table, and then
- remove the rows that correspond to entries in the
- ESelectNamesModels in the children.
- (real_add_address): Freeze/thaw our ESelectNamesModel, so that we
- don't change our table while we are in the middle of iterating
- over the selection.
- (remove_address): Just delete the address from the
- ESelectNamesModel, the signal handler will do the rest.
- (selected_rows_foreach_cb): Call remove_address to do our dirty
- work.
- (e_select_names_add_section): Connect to the 'changed' signal from
- the ESelectNamesModel, and call sync_table_and_models explicitly to
- get our initial state correct.
-
- * gui/component/select-names/e-select-names-table-model.c
- (fill_in_info): Deal with EDestinations in our table that don't
- come from cards.
-
- * gui/component/select-names/e-select-names-manager.c: Added
- another ESelectNamesModel* to the ESelectNamesManagerSection
- struct. Called 'original_model', this contains a copy of the
- model as it is when we begin using the SelectNames dialog.
- (section_copy): Copy the original model.
- (section_free): Free the original model.
- (e_select_names_manager_add_section_with_limit): Initialize the
- original model.
- (e_select_names_clicked): I've changed the semantics of this
- dialog quite a bit... no UI freeze can stop me! If OK is clicked,
- we do nothing. If Cancel is clicked, we revert to the
- 'original_model' copy of our address entry state before we started
- editting. Finally, we close the dialog before any of thing. Doing
- it last caused problems, because signals were being triggered
- which had dangling pointers as their closures.
- (e_select_names_manager_activate_dialog): Copy our current state
- to the original model, and share the same ESelectNamesModel
- between the dialog and the address entry in the composer..
- (e_select_names_manager_get_cards): Removed. It had been
- #if 0/#endif-ed out for a while.
-
- * gui/component/select-names/e-select-names-model.c
- (e_select_names_model_freeze): Added.
- (e_select_names_model_thaw): Added.
- (e_select_names_model_uncardify): Added. If possible,
- "uncardifies" a specific model entry.
- (e_select_names_model_changed): Changed to pay attention
- to the freeze count.
-
- * gui/component/select-names/e-select-names-completion.c
- (clean_query_text): Strip leading/trailing whitespace from
- queries.
-
- * backend/ebook/e-destination.c (e_destination_uncardify): Added.
- Converts a card-associated destination into a text-associated
- destination w/ the e-mail address.
- (e_destination_list_to_vector): Added. A convenience routine.
- (e_destination_freev): Added. A convenience routine.
- (e_destination_touchv): Added. I'm lazy.
-
-2001-09-08 Chris Toshok <toshok@ximian.com>
-
- (make_contact_editor_cb): show the right contact editor (the list
- editor for list cards).
-
-2001-09-08 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names-popup.c
- (popup_menu_card): do the EDestination xml magic on email
- addresses we put in the popup.
-
-2001-08-27 Zbigniew Chyla <cyba@gnome.pl>
-
- * gui/component/addressbook.c (addressbook_factory_new_control):
- For every category:
- - set .translate to FALSE (e_categories_master_list_nth returns
- translated category name)
- - convert category name in UTF-8 to locale's encoding
-
-2001-08-23 Zbigniew Chyla <cyba@gnome.pl>
-
- * gui/component/select-names/e-select-names-popup.c
- (popup_menu_card): Fixed two bugs:
- - missing coversion of contact name to GTK+ locale,
- - passing dynamically created string (contact name) inside uiinfo struct
- to gnome-app-helper functions.
- Remember: these functions may change strings, trying to translate them!
- (popup_menu_nocard): Ditto
-
-2001-09-07 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook-component.c: Removed unused factory
- variable.
-
-2001-09-06 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-storage.c (notify_listener): new
- function, notify the bonobo listener.
- (remove_ldap_folder): track change to EvolutionStorage signal.
- (create_ldap_folder): same, and make sure the type is
- "ldap-contacts".
- (load_source_data): folders that we create should have
- "ldap-contacts" as their type.
- (addressbook_storage_add_source): same.
-
- * gui/component/addressbook-component.c: (folder_types): add
- "ldap-contacts", for display of ldap servers (they get their own
- icon, and their own name in the Create New Folder dialog.
- (create_view): use IS_CONTACT_TYPE since we support two folder
- types now.
- (create_folder): same.
- (remove_folder): same.
- (xfer_folder): same.
-
-2001-09-06 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c: (pixmaps): change
- /Toolbar/ContactEditorSave to /Toolbar/ContactEditorSaveClose.
-
-2001-09-06 Chris Toshok <toshok@ximian.com>
-
- * gui/component/Makefile.am (INCLUDES): add -DEVOLUTION_IMAGESDIR.
-
- * gui/widgets/e-addressbook-view.c (card_deleted_cb): remove
- status messages from here.
- (e_addressbook_view_delete_selection): same.
-
- * gui/widgets/e-addressbook-model.c (sequence_complete): emit a
- NULL status message along with the stop_state_changed. The null
- status message will clear the status bar for this view.
-
- * gui/component/addressbook.c (set_status_message): use the
- EvolutionActivityClient stuff.
-
- * backend/pas/pas-backend-ldap.c (view_destroy): remove status
- message for abandoning a search.
- (ldap_op_process_current): wrap status messages in _().
- (ldap_op_process): same.
- (create_card_handler): same, and remove the notify_status for ""
- and add a notify_complete call after the card is added.
- (remove_card_handler): same.
- (modify_card_handler): same.
- (poll_ldap): wrap status messages with _(), and remove the "Search
- Complete" message.
- (ldap_search_handler): wrap status message.
-
- * backend/pas/pas-backend-file.c (pas_backend_file_search): use
- _() on status messages, and make sure the last notify_* called is
- notify_complete.
-
-2001-09-05 Ettore Perazzoli <ettore@ximian.com>
-
- [Fix #958, ShellComponents should not be created by factories, for
- the addressbook.]
-
- * gui/component/addressbook-component.c
- (GNOME_EVOLUTION_ADDRESSBOOK_COMPONENT_FACTORY_ID): Removed.
- (GNOME_EVOLUTION_ADDRESSBOOK_COMPONENT_ID): New.
- (create_component): Renamed from `factory_fn'. Just register the
- thing on OAF.
- (addressbook_component_factory_init): Just call it.
-
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: Remove the
- ShellComponentFactory.
-
-2001-09-04 Iain Holmes <iain@ximian.com>
-
- * backend/ebook/evolution-vcard-importer.c (load_file_fn): Return FALSE
- if the file isn't a valid VCard file.
-
-2001-08-05 Zbigniew Chyla <cyba@gnome.pl>
-
- I18n fixes (mainly making buttons on the right side less Anglocentric :-)
-
- * backend/ebook/e-card-simple.c
- (field_data): Marked "name" and "short_name" fields for translation.
- (e_card_simple_get_name, e_card_simple_get_short_name): Return
- localized version of the name (using U_() macro).
-
- * gui/contact-editor/e-contact-editor.c (set_entry_changed_signals):
- Connect "changed" signal from "entry-web" entry to widget_changed.
- (changing this field wasn't making "Save and Close" button sensitive)
-
- * gui/widgets/Makefile.am (glade_DATA): Removed alphabet.glade.
-
- * gui/widgets/e-addressbook-view.c
- (button_labels, button_letters): New strings containing a list of
- labels and "values" of all buttons placed on the right side of the
- addressbook view (intended for localization).
- (struct LetterClosure): Changed the type of letter field to gunichar.
- (e_utf8_split): New function, similar to g_strsplit, but operates on
- UTF-8 strings.
- (jump_to_letter): Don't hardcode letters, build queries dynamically
- using UTF-8 and localized letters stored in button_letters.
- (connect_button): Removed.
- (create_alphabet): Don't use glade file, build buttons manually using
- (localized) labels from button_labels. Use (localized) values from
- button_letters when creating LetterClosure.
-
- * gui/widgets/e-minicard-view-widget.[ch]
- (e_minicard_view_widget_jump_to_letter): Changed the type of the
- second argument from char to gunichar.
-
- * gui/widgets/e-minicard-view.c
- (compare_to_utf_str): Renamed from compare_to_letter, now operates on
- UTF-8 string.
- (e_minicard_view_jump_to_letter): Changed the type of the second
- argument from char to gunichar + conversion to UTF-8 string.
-
- * gui/widgets/e-minicard-view.h
- (e_minicard_view_jump_to_letter): Changed the type of the second
- argument from char to gunichar.
-
-2001-09-02 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-book.c (e_book_add_card, e_book_commit_card),
- backend/pas/pas-backend-file.c (do_create),
- backend/pas/pas-backend-ldap.c
- (create_card_handler, remove_card_handler, modify_card_handler,
- pas_backend_ldap_process_get_vcard, poll_ldap): Use
- e_card_get_vcard_assume_utf8 instead of e_card_get_vcard here
- since all internal communications and database storage are assumed
- to be utf8.
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h
- (e_card_simple_duplicate): Simplified this function considerably.
- (e_card_simple_get_vcard_assume_utf8): Added this function.
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h (e_card_new,
- e_card_load_cards_from_file, e_card_load_cards_from_string): Made
- these functions pay attention to charset attributes.
- (e_card_new_with_default_charset,
- e_card_load_cards_from_file_with_default_charset,
- e_card_load_cards_from_string_with_default_charset): New functions
- that let you change the default charset from UTF-8.
- (e_card_get_vcard): Made this write out charset attributes when
- necessary.
- (e_card_get_vcard_assume_utf8): New function that writes out a
- card without writing out charset attributes.
-
- * backend/ebook/evolution-vcard-importer.c (book_open_cb),
- backend/ebook/load-gnomecard-addressbook.c (book_open_cb),
- backend/ebook/test-card.c (main),
- gui/component/addressbook-component.c
- (destination_folder_handle_drop), gui/contact-editor/test-editor.c
- (main), gui/contact-list-editor/e-contact-list-editor.c
- (table_drag_data_received_cb), gui/widgets/e-addressbook-view.c
- (selection_received), gui/widgets/e-minicard-control.c
- (pstream_load): Changed the default charset to be used here to
- ISO-8859-1.
-
- * backend/ebook/load-gnomecard-addressbook.c (add_card_cb),
- backend/ebook/load-pine-addressbook.c (add_card_cb),
- backend/ebook/test-client-list.c (get_cursor_cb),
- backend/ebook/test-client.c (get_cursor_cb, get_card_cb): Use
- e_card_get_vcard_assume_utf8 to print out testing strings.
-
- * gui/component/select-names/e-select-names-model.c,
- gui/component/select-names/e-select-names-model.h
- (e_select_names_model_contains): Changed this to be const
- EDestination *dest to fix a warning.
-
- * gui/contact-editor/e-contact-editor.c (e_contact_editor_init):
- Translate window title here.
-
-2001-08-31 Zbigniew Chyla <cyba@gnome.pl>
-
- * gui/component/addressbook-storage.c
- (addressbook_get_other_contact_storage): s/_/U_/
-
- * gui/widgets/e-addressbook-reflow-adapter.c (addressbook_compare):
- Use g_utf8_collate.
-
- * gui/widgets/e-minicard.c (e_minicard_compare):
- Ditto.
-
- * printing/e-contact-print.c (card_compare):
- Ditto.
-
-2001-08-29 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_clicked): Use e_select_names_model_merge to
- combine the selected names with any existing ones. This causes
- you to not lose addresses typed directly into the entry while the
- SelectNames dialog is up. (Bug #8058)
-
- * gui/component/select-names/e-select-names-model.c
- (e_select_names_model_merge): Merge the contents of one
- ESelectNamesModel into another, avoiding duplicates.
-
- * backend/ebook/e-destination.c (e_destination_equal): Added.
- Determines if two destinations appear to refer to the same
- recipient.
-
- * backend/ebook/e-card.c (e_card_list_send): Added cast to
- g_free args to silence compiler warnings.
-
- * gui/contact-editor/e-contact-quick-add.c (quick_add_set_name):
- Paranoia. Check that name != qa->name.
- (quick_add_set_email): Check that email != qa->email.
- (ce_have_book): Store the QuickAdd data structure in object data,
- so that we can be extra-careful and avoid having a dangling
- pointer floating around out somewhere as the closure for a signal.
- Fixes bug #8155, I think.
- (card_added_cb): Clear object data to ensure single unref.
- (editor_closed_cb): Clear object data to ensure single unref.
-
- * gui/component/select-names/e-select-names-completion.c
- (book_query_score): Make sure that comp->priv->query_text isn't
- NULL. (Fixes bug #8195)
-
- * backend/ebook/e-book-listener.c (e_book_listener_check_queue):
- This function can be re-entrant during the signal emission; Added
- extra ref/unrefs and checks to avoid problems if this happens.
- This is similar to my recent changes to
- e_book_view_listener_check_queue. (Fixes bug #7400)
-
-2001-08-27 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c: Get rid of a warning by
- initializing the closing NULL element in folder_types correctly.
-
- * gui/component/select-names/e-select-names.c: Updated to match
- the studlyCapsification of attributes in shell/Evolution*.idl.
-
-2001-08-27 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (sexp_file_as): Added. Generated queries against file_as.
- (match_file_as): Added. Match results of queries against
- file_as. (Bug #8152)
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_check_queue): Added ref/unref pair to make
- sure that our listener doesn't get finalized during the signal
- emission and leave us with a dangling pointer. (Bug #7661)
-
- * backend/ebook/e-card.c (e_card_list_send): Removed some debugging
- spew that I left in by mistake.
-
- * gui/widgets/e-addressbook-model.c (create_card): Removed debugging
- spew.
-
- * backend/ebook/e-card.c (e_card_list_send): Do the right thing if
- the card we are trying to send to is a contact list. (Bug #6580)
-
-2001-08-27 Zbigniew Chyla <cyba@gnome.pl>
-
- * gui/widgets/e-addressbook-util.c (e_addressbook_error_dialog):
- Display localized status string (added missing _()).
-
-2001-08-24 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_set_card): Put a
- freeze/thaw around our the set of operations that changes the
- internal state of our card, so 'changed' signal callbacks won't be
- invoked on a card in an intermediary state. This fixes the bug
- that was causing the e-mail addresses in cards to be blank when
- replying to a message. (An unexpected side-effect of toshok's
- change on 8/22 to make sure that priv->email != NULL).
- (e_destination_get_name): Code slightly rearranged for (IMO)
- clarity.
-
-2001-08-23 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-minicard.c (e_minicard_event): add
- BUTTON_PRESS_MASK so double clicks still work.
-
-2001-08-23 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c (addressbook_query_changed): switch
- "full_name" to "x-evolution-any-field" in all the queries where we
- want to match all cards, since the backends universally handle
- this special case more efficiently.
-
-2001-08-22 Jon Trowbridge <trow@ximian.com>
-
- * gui/contact-list-editor/e-contact-list-editor.c (extract_info):
- In the GUI, the toggle is labelled "hide addresses", not "show
- addresses" -- so we have to reverse the boolean value we read in.
- (fill_in_info): Same bug as before: since the GUI reads "hide", we
- have to initialize the toggle to '!show_addresses', not
- 'show_addresses'.
-
- * backend/ebook/e-destination.c
- (e_destination_list_show_addresses): Added.
- (e_destination_xml_encode): Encode the value of
- e_destination_list_show_addresses into the XML.
- (e_destination_xml_decode): Read and store the "show_addresses"
- flag.
-
-2001-08-22 jacob berkman <jacob@ximian.com>
-
- * gui/component/e-address-popup.c (emit_event): emit an event from
- our event source
- (contact_editor_cb): emit a destroy event so our control frame can
- be destroyed.
- (edit_contact_info_cb): emit a hide event so our control frame can
- be hidden
- (e_address_popup_cardify):
- (add_contacts_cb): emit the destroy event
- (e_address_popup_factory_new_control): don't unref our object at
- widget destroy time as that was really really broken
- (e_address_popup_factory_new_control): create an event source and
- aggregate ourself with it
-
- * gui/contact-editor/e-contact-editor.c (enable_writable_fields):
- display a nicer warning when we can't find a widget for a given
- field
- (e_contact_editor_raise): only raise if there is a window
-
- * gui/contact-editor/contact-editor.glade: name some widgets that
- got unnamed, and set the first entry as defaultable
-
- * gui/contact-editor/e-contact-editor.c: envelope printing is
- disabled in 1.0
-
-2001-08-22 Chris Toshok <toshok@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_get_email): make
- sure we don't get into a situation where priv->email == NULL.
-
-2001-08-21 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-minicard.c (e_minicard_event): if we're dragging,
- drag_button_down won't be true in the BUTTON_RELEASE case, since
- we set it to false in MOTION_NOTIFY once the threshold is reached.
- (e_minicard_drag_end): remove this function, since it was needed
- to work around a bug in gnome-canvas.
-
-2001-08-20 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_addressbook_create_ebook_table): Wrap our addressbook table
- adapter in an ETableWithout, so that we can make addresses appear
- and disappear when we remove/add them to the section lists
- (To/Cc/Bcc) on the right of the dialog.
- (real_add_address_cb): When we add an address, hide it in the main
- list.
- (e_select_names_init): Get pointer to our without table from the
- table's object data, and store it.
- (remove_address): When we remove an address, show it in the main
- list.
- (card_key): Added. Allocate a unique key from an ECard.
- (esn_get_key_fn): Added. Callback for ETableWithout.
- (esn_dup_key_fn): Added. Callback for ETableWithout.
- (esn_free_gotten_key_fn): Added. Callback for ETableWithout.
- (esn_free_duped_key_fn): Added. Callback for ETableWithout.
-
- * backend/ebook/e-card-simple.c (e_card_simple_get): Changed
- E_CARD_SIMPLE_FIELD_NAME_OR_ORG to first try the FILE_AS
- type. This allows the cards in the ESelectName dialog to
- appear in proper sort order (i.e. as 'Doe, John' rather than
- 'John Doe'). Fixes ximian #6002.
-
-2001-08-20 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-addressbook-reflow-adapter.c
- (e_addressbook_reflow_adapter_class_init): fix arg info - we're
- only passing 1 GTK_TYPE_POINTER arg, not 2.
-
- * gui/widgets/e-minicard.c (e_minicard_event): lots of fixes for
- DnD. For GDK_BUTTON_PRESS, we grab immediately. For
- GDK_BUTTON_MOTION, we start the drag after a certain threshold,
- and connect to the "drag_end" signal on our canvas so we'll know
- when the drag is complete. For GDK_BUTTON_RELEASE, we release the
- grab if we were dragging and get the event.
- (e_minicard_drag_end): new function, just remove the pointer/gtk
- grabs and disconnect.
-
- * gui/widgets/e-minicard.h (struct _EMinicard): add "gint
- drag_button"
-
-2001-08-20 JP Rosevear <jpr@ximian.com>
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_changes_foreach_key): use DB_NOTFOUND const
-
-2001-08-20 JP Rosevear <jpr@ximian.com>
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_process_get_changes): null out card_sexp so that
- we don't crash when copying
-
-2001-08-20 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c: fix warnings, get compiling again
-
- * conduit/address-conduit-config.h: remove c/p typos
-
- * conduit/address-conduit.h: ditto
-
- * conduit/Makefile.am: link against the static camel
-
-2001-08-20 Damon Chaplin <damon@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c: use bigger Save icon for
- toolbar. Used Delete icon in menu.
-
- * gui/component/addressbook.c: use 'Save As' icon rather than 'Save'
- as it seems more appropriate. Also added delete icon for menu.
-
-2001-08-19 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c: Update the folder list to
- include a display name and a description.
-
-2001-08-19 Damon Chaplin <damon@ximian.com>
-
- * gui/component/addressbook.c: use new Cut/Copy/Paste/Save/Search
- icons.
-
-2001-08-19 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook.c (set_folder_bar_label),
- gui/widgets/e-addressbook-model.c,
- gui/widgets/e-addressbook-model.h (update_folder_bar_message),
- gui/widgets/e-addressbook-view.c, gui/widgets/e-addressbook-view.h
- (folder_bar_message): Set the folder bar message here. Fixes
- Ximian bug #4670.
-
- * gui/component/select-names/e-select-names-model.c (SEPLEN): Use
- strlen(SEPARATOR) here so that if the separator changes the length
- will work properly.
-
-2001-08-19 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/fulladdr.glade: Added full country list.
- Fixes Ximian bug #5123.
-
-2001-08-18 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook.c: Hook up `delete-message.png' as the
- icon for "ContactDelete".
- * gui/contact-editor/e-contact-editor.c: Likewise.
-
-2001-08-17 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-storage.h: add prototype for
- addressbook_get_other_contact_storage.
-
- * gui/component/addressbook-storage.c
- (addressbook_get_other_contact_storage): rename register_storage
- to this, and return the EvolutionStorage.
- (load_source_data): register_storage =>
- addressbook_get_other_contact_storage.
- (addressbook_storage_add_source): register_storage =>
- addressbook_get_other_contact_storage.
-
-2001-08-17 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c
- (set_entry_changed_signals): connect to the "changed" signal on
- "entry-web" to update command state.
-
-2001-08-17 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-list-editor/e-contact-list-editor.c (list_added_cb):
- call e_card_set_id on the list's card so we can continue to use
- this dialog. also, call command_state_changed if we aren't
- closing the dialog so the toolbar is properly sensitized.
- (list_deleted_cb): always close the dialog after we successfully
- delete a list.
-
- * gui/contact-editor/e-contact-editor.c (card_added_cb): call
- e_card_set_id on the card so we can continue to use this dialog
- (to modify or delete the card.)
- (card_deleted_cb): always close the dialog after we successfully
- delete a card.
-
-2001-08-17 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c (addressbook_query_changed): call
- e_sexp_encode_string on the search string the user types in so it
- doesn't break sexp parsing in the wombat.
-
-2001-08-17 Damon Chaplin <damon@ximian.com>
-
- * gui/component/addressbook.c: changed to new print icon.
-
-2001-08-17 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names.c: (struct
- ESelectNamesFolder): rename physical_uri to uri, since it includes
- the addressbook.db for file: uris.
- (e_select_names_folder_free): physical_uri => uri.
- (e_select_names_option_activated): physical_uri => uri, and we
- don't need to strdup_printf "addressbook.db" onto the end anymore.
- (new_folder): if the physical_uri is a file: uri, append
- /addressbook.db onto it.
- (hookup_listener): new function, split out lots of code from
- e_select_names_hookup_shell_listener.
- (e_select_names_hookup_shell_listeners): rename
- e_select_names_hookup_shell_listener to this, and hookup both the
- local and "Other Contacts" listener, using hookup_listener.
- (e_select_names_destroy): disconnect from the
- other_contacts_listener and unref it.
-
- * gui/component/select-names/e-select-names.h (struct
- _ESelectNames): add a listener for Other Contacts, and rename
- "listener" to "local_listener."
-
-2001-08-17 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_seq_complete_cb): If we get the
- "sequence_complete" signal when we aren't searching, it means the
- addressbook changed out from under us. Clear the search cache, so
- that future completion requests won't use the out-of-date cached
- data. Also, don't unref book_view... we leave the EBookView open
- so that we can catch these addressbook changes.
- (e_select_names_completion_do_query): Don't use the book_view
- being non-NULL as a sign that another query is still running.
- (e_select_names_completion_got_book_view_cb): Properly unref any
- previous value in book_view.
-
-2001-08-17 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-reflow-adapter.c
- (e_addressbook_reflow_adapter_right_click),
- gui/widgets/e-addressbook-view.c (table_right_click): Changed the
- messages here in the right click menus.
-
-2001-08-17 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (view_destroy): unref our
- card_sexp.
- (create_card_handler): make sure to set the id of the vcard so it
- gets properly transmitted back to the BookView, and notify all
- matching BookViews to add the created card.
- (remove_card_handler): notify all matching BookViews to remove the
- card.
- (modify_card_handler): notify all matching BookViews to modify the
- card.
- (pas_backend_ldap_process_get_book_view): init card_sexp based on
- the view's search.
-
-2001-08-17 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_book_view_copy): use card_sexp.
- (pas_backend_file_book_view_free): same.
- (vcard_matches_search): use the new pas_backend_card_sexp_match_vcard call.
- (pas_backend_file_search): use card_sexp.
- (pas_backend_file_process_get_book_view): same.
-
- * backend/pas/Makefile.am (libpas_a_SOURCES): add
- pas-backend-card-sexp.[ch].
-
-2001-08-17 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook-component.c (factory_fn): Added code
- so the user can create a new contact or contact list from anywhere
- in evolution.
-
-2001-08-16 Jeffrey Stedfast <fejj@ximian.com>
-
- * backend/pas/evolutionperson.schema: Added a closing paren.
-
-2001-08-16 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_handle_request): Renamed from _begin to
- match changes in gal 0.10.99.3.
-
- * gui/contact-editor/e-contact-quick-add.c (e_contact_quick_add):
- Check that name != NULL before we start messing with it.
- (Fixes bug #7329)
-
-2001-08-16 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (match_nickname): Boost scoring on an exact nickname match.
- Manually addressify match.
- (match_name): Manually addressify matches.
- (book_query_score): Remove automatic addressification.
-
- * gui/component/addressbook.c (addressbook_query_changed): Minor
- tweak to avoid a crash if we have a negative subid with id
- ESB_CATEGORY. This should never happen.
- (addressbook_menu_activated): Reset the entry/option when we
- select "Clear".
- Some changes to reflect renaming in ESearchBar.
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_set_property_fn): Cardify after importing destinations.
- This might fix a problem that Damon is having.
-
-2001-08-15 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-config.glade: set title of initial
- dialog to Addressbook Sources (bug #6704).
-
-2001-08-15 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-storage.c (create_ldap_folder): don't
- let people add subdirs in the ldap server storage - everything is
- toplevel there.
-
-2001-08-14 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_process_get_vcard): implement using
- search_for_dn.
-
-2001-08-14 Federico Mena Quintero <federico@ximian.com>
-
- * gui/component/addressbook.c (addressbook_factory_new_control):
- Tell the search bar to translate the subitem texts.
-
-2001-08-14 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/addressbook.c (addressbook_factory_new_control):
- Add "Any Category" option for category searches.
- (addressbook_query_changed): Do the right thing on an
- "Any Category" search.
-
-2001-08-14 Dan Winship <danw@ximian.com>
-
- * backend/pas/pas-backend-ldap.c: Fix up to match the
- pas_book_new/get_vcard changes.
-
-2001-08-14 Christopher James Lahey <clahey@ximian.com>
-
- * gui/merging/e-card-merging-book-commit-duplicate-detected.glade:
- Got rid of an extraneous _ here.
-
- * gui/widgets/e-addressbook-util.c (e_addressbook_error_dialog):
- Changed Canceled to Cancelled here. Fixes Ximian bug #2465.
-
-2001-08-14 Christopher James Lahey <clahey@ximian.com>
-
- * backend/pas/pas-book.c (pas_book_respond_get_vcard): Oops,
- forgot to write this function.
-
-2001-08-14 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/contact-editor.glade: Added focus targets
- here. Fixes part of Ximian bug #5843.
-
-2001-08-14 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c (e_contact_editor_init):
- Grab focus here. Fixes Ximian bug #2265.
-
-2001-08-14 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook.c (addressbook_factory_new_control):
- (addressbook_query_changed): Fixed two const warnings here.
-
- * printing/e-contact-print-envelope.c,
- printing/e-contact-print-envelope.h: Fixed some missing includes
- here.
-
-2001-08-14 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-book-view.c (add_book_iterator): Call
- e_card_set_book here.
-
- * backend/ebook/e-book.c (e_book_do_response_get_vcard): Call
- e_card_set_book here.
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Pulled out the
- part where the uri is made part of the uid. Made uri a separate
- field. Fixes Ximian bug #6490.
-
- * backend/ebook/e-destination.c, backend/ebook/e-destination.h:
- Change this to use ECard's split uids and uris.
-
-2001-08-13 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (add_to_supported_fields): don't
- g_strdup the stuff we're passing into e_list_append, since it does
- the copy for us.
- (check_schema_support): don't initialize supported_fields list
- here, since there's a gross case where the programmer/user can
- bring up the contact editor before the connection stuff is
- finished, and we don't want to crash.
- (pas_backend_ldap_init): move it here to we can guarantee it's
- there. (bug #6546).
-
-2001-08-13 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-config.c
- (addressbook_source_dialog_set_source): don't access source->auth
- if source == NULL (bug #7086).
-
-2001-08-13 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-book-listener.c,
- backend/ebook/e-book-listener.h, backend/ebook/e-book.c,
- backend/ebook/e-book.h, backend/idl/addressbook.idl,
- backend/pas/pas-backend-file.c, backend/pas/pas-book.c,
- backend/pas/pas-book.h: Changed get_card to be asyncronous.
-
- * backend/ebook/e-card.c, backend/ebook/test-client.c: Changed
- these to deal with the new get_card functionality.
-
-2001-08-11 Kjartan Maraas <kmaraas@gnome.org>
-
- * gui/component/select-names/e-select-names.c: Mark a string for translation.
- * This fixes bug #7052
- * printing/e-contact-print.h: Add headers to make it stand on itw own.
- * printing/e-contact-print.c: Marked some strings for translation.
- * printing/e-contact-print-envelope.c: Same here.
-
-2001-08-10 Jon Trowbridge <trow@ximian.com>
-
- * gui/contact-editor/e-contact-quick-add.c (e_contact_quick_add):
- Remove single- or double-quotes from names before sticking them
- into the addressbook. (Bug #6499)
-
- * gui/component/addressbook.c (addressbook_query_changed):
- Properly handle "Category is" queries by checking the search bar
- suboption.
- (addressbook_factory_new_control): Attach subitems corresponding
- to all wombat categories to the "Category is" ESearchBarItem.
-
- * gui/component/addressbook.c: Set the ESearchBarItem
- subitems explicitly to NULL.
-
-2001-08-10 Anna Marie Dirks <anna@ximian.com>
- * gui/component/select-names/select-names.glade: did a little
- packing-magic to get the two tables at bottom of this dialog
- to seem to line up.
-
- *gui/component/select-names/e-select-names.c: changed the title
- of this dialog to "Select Contacts from Addressbook".
-
-2001-08-09 Anna Marie Dirks <anna@ximian.com>
- * gui/component/select-names/select-names.glade: redesigned
- this dialog to fix bug #6815.
-
- *gui/component/select-names/e-select-names.c: connected the
- widgets (or one of them anyway. clahey did the rest) for my
- new and lovely glade file.
-
-2001-08-09 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c: remove passwd_cb.
-
-2001-08-09 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-text-model.c
- This change is dedicated to Jacob Berkman.
- (e_select_names_text_model_insert_length): If the last character
- we inserted was a "magic comma", remember its position.
- (e_select_names_text_model_delete): If the last character we
- inserted was a "magic comma", and if the next thing we do is to
- hit backspace, delete both the comma and the extra whitespace we
- added.
- (e_select_names_text_model_init): Initialize our last magic comma
- position.
-
-2001-08-09 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_create_entry): Hook up some magic to
- (basically) cardify an entry on focus-out. (What we do is actually
- more complicated than that.)
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_set_property_fn): After we set an entry's text, try to
- cardify it. We need to do this so that (for example) reply
- e-mails get properly cardified.
-
- * gui/component/select-names/e-select-names-model.c
- (e_select_names_model_duplicate): Use e_select_names_model_append,
- rather than manipulating lists directly.
- (e_select_names_model_insert): Connect "changed" signal proxy for
- added EDestination.
- (e_select_names_model_append): Ditto.
- (e_select_names_model_replace): Ditto, and disconnect signals for
- replaced EDestination.
- (e_select_names_model_delete): Ditto on the disconnection.
- (e_select_names_model_delete_all): Ditto.
- (e_select_names_model_cardify): Added. Try to cardify a specified
- EDestination.
- (e_select_names_model_cancel_cardify): Added. Cancel the pending
- cardification of a single EDestination.
- (e_select_names_model_cardify_all): Added. Cardify all of the
- EDestinations in the model.
- (e_select_names_model_cancel_cardify_all): Added. Cancel's any
- and all pending cardifications.
-
- * backend/ebook/e-destination.c (e_destination_class_init): Added
- "changed" and "cardified" signals.
- (e_destination_freeze): Added (static).
- (e_destination_thaw): Added (static).
- (e_destination_clear_card): Reset allow_cardify and
- cannot_cardify, cancel any pending cardifications, and emit the
- "changed" signal.
- (e_destination_clear_strings): Emit the "changed" signal.
- (e_destination_clear): Do freeze/thaw to prevent multiple signal
- emissions.
- (e_destination_set_card): Check that the card we are setting is
- not equal to the current card, and emit the "changed" signal if we
- are actually changing.
- (e_destination_set_card_uri): Emit "changed" signal, if necessary.
- (e_destination_set_name): Emit "changed" signal, if necessary.
- (e_destination_set_email): Emit "changed" signal, if necessary.
- (e_destination_set_html_mail_pref): Emit "changed" signal, if
- necessary.
- (use_card_cb): If we've just loaded/set the ECard, emit the
- "changed" signal.
- (e_destination_set_raw): Emit "changed" signal, if necessary.
- (e_destination_allow_cardification): Added.
- (e_destination_set_allow_cardification): Added.
- (e_destination_cardify): Added. Tries to automatically convert
- a string-based EDestination to one based on an ECard.
- (e_destination_cardify_delayed): Added. Cardifies in a timeout.
- (e_destination_cancel_cardify): Added. Cancels any pending
- cardifications.
- (e_destination_xml_decode): Added freeze/thaw.
-
- * backend/ebook/e-book-util.c (e_book_nickname_query): Added. A
- canned simple query for nicknames.
-
- * backend/ebook/e-card.c (e_card_email_find_number): Added. Given
- a card and an string containing an email address, return the index
- number of the address inside of the card, or -1 if the address is
- not found.
-
-2001-08-09 Chris Toshok <toshok@ximian.com>
-
- [ Fixes ximian bugs #5080, #6021, #6704, #6705 ]
-
- * gui/component/addressbook.c (book_open_cb): create our own
- dialog that prompts for both the email address and the password.
- the email address is stored in the source and filled in for the
- user after the first time they enter one and press OK.
-
- * gui/component/addressbook-storage.c (create_ldap_folder): has a
- return value, not a int* parameter.
- (create_ldap_folder): new function, we can create ldap servers
- from the File->New->Folder menu item now.
- (register_storage): hook up the "create_folder" signal.
- (addressbook_storage_init_source_uri): remove the file case, we
- only build ldap uris here.
- (load_source_data): remove the file source stuff, and handle
- "emailaddr".
- (save_source_data): call ldap_source_foreach directly.
- (addressbook_source_free): remove file source stuff.
- (addressbook_source_copy): same.
-
- * gui/component/addressbook-storage.h: get rid of all the file
- source stuff from AddressbookSource, since this is only being used
- for ldap servers.
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_process_authenticate_user): look up the ldap
- entry based on the provided email address and use the resulting
- DN/passwd to authenticate.
-
- * gui/component/addressbook-config.c: pretty much gutted to make
- it work with the new UI.
-
- * gui/component/addressbook-config.glade: new version from anna.
-
-2001-08-09 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (SPEC): Upped the minimum width
- on all addressbook columns to 75. Fixes Ximian bug #2773.
-
-2001-08-08 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-editor/e-contact-quick-add.c (ce_have_book): mark
- the dialog as changed so the save button is immediately available.
-
- * gui/contact-editor/e-contact-editor.c (card_modified_cb): once
- we save reset the change flag to false if we aren't closing the
- dialog.
- (card_added_cb): same.
- (e_contact_editor_class_init): add a "changed" arg.
- (e_contact_editor_set_arg): add setter for "changed".
- (e_contact_editor_get_arg): add getter for "changed".
-
-2001-08-08 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-editor/e-contact-quick-add.c (ce_have_book): better
- to assume that we can write to the local addressbook than that we
- can't write to it :)
-
-2001-08-08 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-list-editor/e-contact-list-editor.c (create_ui):
- call e_pixmap_update so we can use the same save/save-as pixmaps
- as the contact editor.
-
-2001-08-08 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-addressbook-reflow-adapter.c (open_card): new
- function, used by the context menu.
- (e_addressbook_reflow_adapter_right_click): put "Open" at the top
- of the menu. also, disable "Delete" if the addressbook isn't
- writable.
-
-2001-08-08 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (rfc2254_escape): escape *, \, (,
- and ), as per rfc2254.
- (func_contains): escape the string.
- (func_is): same.
- (func_beginswith): same.
- (func_endswith): same.
-
-2001-08-08 Nat Friedman <nat@ximian.com>
-
- * gui/widgets/e-addressbook-reflow-adapter.c (print_envelope): If 0'd out
- since Envelope printing is disabled for 1.0.
- * gui/widgets/e-addressbook-view.c (print_envelope): Likewise.
- * gui/contact-editor/e-contact-editor.c (print_envelope_cb): Likewise.
-
- * gui/widgets/e-addressbook-reflow-adapter.c
- (e_addressbook_reflow_adapter_right_click): Removed "Print
- Envelope" menu item.
- * gui/widgets/e-addressbook-view.c (table_right_click): Likewise.
- * gui/contact-editor/e-contact-editor.c (verbs): Likewise.
-
-2001-08-07 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-storage.c (remove_ldap_folder): ifdef
- this HAVE_LDAP.
-
-2001-08-07 Chris Toshok <toshok@ximian.com>
-
- * gui/search/e-addressbook-search-dialog.c
- (e_addressbook_search_dialog_init): set the title of the window to
- "Advanced Search".
-
-2001-08-07 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c (search_cb): pass view->view instead
- of the EBook.
- (addressbook_search_menu_items): remove E_FILTERBAR_ADVANCED.
- (addressbook_menu_activated): remove E_FILTERBAR_ADVANCED.
- (addressbook_search_option_items): add "Advanced..." here.
- (addressbook_query_changed): add special handling for Advanced...
-
- * gui/search/e-addressbook-search-dialog.h (struct
- _EAddressbookSearchDialog): add EAddressbookView and remove the
- model/adapter fields. Also fix prototype of
- e_addressbook_search_dialog_new.
-
- * gui/search/e-addressbook-search-dialog.c
- (e_addressbook_search_dialog_class_init): get rid of
- set_arg/get_arg.
- (button_press): set the query on the EAddressbookView, and always
- close the dialog.
- (e_addressbook_search_dialog_init): get rid of the minicard view,
- and pack the other widgets accordingly.
- (e_addressbook_search_dialog_new): pass EAddressbookView instead
- of EBook.
- (e_addressbook_search_dialog_destroy): remove model/adapter stuff.
-
-2001-08-07 Chris Toshok <toshok@ximian.com>
-
- [ Fixes bug #5066 ]
- * gui/component/addressbook-storage.c (remove_ldap_folder): new
- function, remove the source.
- (register_storage): connect to the "remove_folder" signal so we
- know when to remove the folder.
-
-2001-08-07 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (build_card_from_entry): use
- g_strcasecmp since ldap attribute names are not case sensitive.
-
-2001-08-07 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-list-editor/e-contact-list-editor.c
- (table_drag_data_received_cb): make sure we update the changed
- state if a successful drop happens.
-
-2001-08-07 Jason Leach <jleach@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_init): Make the OK button the keyboard default
- instead of Cancel. Bug #4942.
-
-2001-08-06 Radek Doulik <rodo@ximian.com>
-
- * backend/ebook/e-book.c (e_book_op_free): new EBookOp destructor
- (e_book_unqueue_op): use e_book_op_free
- (e_book_do_response_create_card): ditto
- (e_book_do_response_generic): ditto
- (e_book_do_response_get_cursor): ditto
- (e_book_do_response_get_view): ditto
- (e_book_do_response_get_changes): ditto
- (e_book_do_response_open): ditto
- (e_book_do_response_get_supported_fields): ditto
-
-2001-08-05 Radek Doulik <rodo@ximian.com>
-
- * backend/ebook/e-book.c (e_book_do_response_get_view): set
- op->listener to NULL to catch possible use of freed op
- (e_book_do_response_get_changes): ditto
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_check_queue): this callback could be (and
- indeed is) called from signal emited above,
- signal handler could call e_book_view_listener_stop, so we need to check
- if idle is still set and if not we don't want to unref again
-
-2001-08-04 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-compare.c (e_card_compare_name): Made it so
- that if there's one less match than possible compares are
- considered more VAGUE. Fixes Ximian bug #3400.
-
-2001-08-03 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_hookup_shell_listener): Check for storage != NULL
- here. This shouldn't come up unless addressbook has crashed
- previously within this session of evolution, but this is just a
- bit of insurance. Fixes Ximian bug #3699.
-
-2001-08-03 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card.c (e_card_name_match_string): Changed the
- criteria of whether the first part of each iteration matched or
- the second one did. Before it got it wrong sometimes and caused
- the pointer to jump off the end of the array. Fixes Ximian bug
- #4674.
-
-2001-08-03 Jason Leach <jleach@ximian.com>
-
- * gui/component/addressbook-storage.c (load_source_data): Update
- for EvolutionStorage API changes.
- (addressbook_storage_add_source): Ditto.
-
-2001-08-03 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (jump_to_letter): Made this
- change the query based on which letter is clicked. Fixes Ximian
- bug #2202.
-
-2001-08-03 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook.c (addressbook_factory_new_control):
- Fixed warnings here.
-
- * gui/component/select-names/e-select-names-completion.c
- (hash_cleanup_fn): Removed this unused function.
-
-2001-08-03 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-simple.c (e_card_simple_sync_card,
- fill_in_info): Made the list of E_CARD_PHONE types in
- phone_correspondences more complete by adding the new 5
- E_CARD_PHONE types. Also, made it a bit less restrictive for some
- types (E_CARD_PHONE_HOME will actually match
- E_CARD_SIMPLE_PHONE_ID_HOME now.) Made e_card_simple_sync_card
- and fill_in_info search for an exact match in the list of
- phone_correspondences and then look for a partial match. Got rid
- of not going forward when doing a remove from an EList since EList
- handles this case automatically.
-
- * backend/ebook/e-card-types.h: Added E_CARD_PHONE types for
- assistant, callback, radio, telex, and ttytdd.
-
- * backend/ebook/e-card.c (get_phone_flags, set_phone_flags):
- Handle the new E_CARD_PHONE types.
-
-2001-08-02 Jon Trowbridge <trow@ximian.com>
-
- * printing/Makefile.am (ecpsdir): Add camel dependency.
-
- * gui/component/Makefile.am: Add camel dependency.
-
- * backend/ebook/Makefile.am: Add camel dependency.
-
- * gui/component/addressbook-factory.c (main): Properly init camel.
-
- * backend/ebook/e-destination.c (e_destination_clear_strings):
- Clear ->raw.
- (e_destination_is_empty): We aren't empty if ->raw is set..
- (e_destination_set_raw): Replaces e_destination_set_string.
- (e_destination_get_name): Use camel's parser to extract the name
- from ->raw.
- (e_destination_get_email): Use camel's parser to extract the email
- address from ->raw.
- (e_destination_get_address): Use camel to produce properly quoted,
- RFC-compliant addresses. Thanks camel! (Bug #5860)
-
- * gui/component/select-names/e-select-names-completion.c
- (emailify_match): Always append an e-mail address, as long as it
- doesn't have one already at it's beginning or end. Don't limit
- self to just emailifying entries tied to cards with multiple
- addresses. (I didn't really want to do this, but people seem to
- like keeping multiple cards for the same person, and other
- solutions (like scanning all matches for duplicate names, and only
- emailifying those) just seemed like way too much work for such a
- limited payoff.)
-
- * gui/component/select-names/e-select-names-text-model.c:
- s/e_destination_set_string/e_destination_set_raw/.
-
- * gui/component/select-names/e-select-names-popup.c
- (popup_menu_card): Quote _'s in our popup menus, so that "foo_bar"
- doesn't get displayed as "foobar" w/ the 'b' underlined. (Bug
- #5558)
- (popup_menu_nocard): Ditto.
-
-2001-08-02 Jason Leach <jleach@ximian.com>
-
- * gui/component/addressbook.c (addressbook_factory_new_control):
- Removed some extra padding and pack the addressbook view into a
- frame with inward shadowing, just because it looks prettier.
-
- * gui/contact-editor/e-contact-editor.c: Use the updated Save,
- Save As, and Print icons for the menus and toolbar.
-
-2001-08-02 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook.c: Added ContactsSaveAsVCard,
- ContactsSendContactToOther, and ContactsSendMessageToContact verbs
- here.
-
- * gui/widgets/e-addressbook-view.c,
- gui/widgets/e-addressbook-view.h (e_addressbook_view_save_as,
- e_addressbook_view_send, e_addressbook_view_send_to): New
- functions to allow outside users to cause the addressbook to save,
- send, or send a message to its selection.
-
-2001-08-01 Christopher James Lahey <clahey@ximian.com>
-
- * contact-editor/.cvsignore: Removed this file from this unused
- directory.
-
-2001-08-01 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/Makefile.am: Added file-exists.glade.
-
- * gui/contact-editor/e-contact-save-as.c (file_exists),
- gui/contact-editor/file-exists.glade: Added a dialog to ask the
- user whether to replace an already existing file. Mostly from a
- patch by Jos Dehaes. Fixes Ximian bug #2231.
-
-2001-08-01 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_check_queue): Removed thrash checking code
- here since thrashing shouldn't happen now that we've cleaned this
- up some.
-
- * backend/ebook/e-book.c (e_book_do_response_get_view): Properly
- handle cases where construction fails.
-
-2001-07-30 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/evolution-vcard-importer.c: Added #include
- <e-util/e-path.h>.
-
-2001-07-23 Zbigniew Chyla <cyba@gnome.pl>
-
- * gui/component/addressbook-config.c (addressbook_source_dialog):
- Convert translated string to UTF8 before calling put_html.
-
-2001-07-30 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_do_query): Properly handle the case
- where our "cleaned" completion is the empty string. This happens,
- for example, if the query text is the string "\"". (Bug #5610).
-
- * backend/ebook/e-destination.c (e_destination_get_address_textv):
- Reassure fejj that I'm not doing something stupid here.
- (e_destination_get_address): Fix address quoting. This is a
- stop-gap measure until I can change this code to use Camel's
- superior address-handling routines. (Also Bug #5610)
-
-2001-07-30 Jason Leach <jleach@ximian.com>
-
- * gui/component/addressbook-storage.c (load_source_data): Fix a
- return value bug, to make it so if it fails to load an
- addressbook-sources.xml file (either a parse error or it doesn't
- exist for example), it deregisters the storage.
- (register_storage): Don't make a storage for users who don't have
- LDAP support built in. Bug #1950.
-
-2001-07-30 Frederic Crozat <fcrozat@mandrakesoft.com>
-
- * addressbook/gui/component/addressbook-factory.c: Fix crashes
- when gtkhtml is compiled with gconf support
-
-2001-07-27 JP Rosevear <jpr@ximian.com>
-
- * conduit/Makefile.am: Tidy ldadds
-
-2001-07-26 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-bonobo.c: Fixing a
- small, stupid mistake; use e_select_names_model_get_textification
- for the getter for "text".
-
- * backend/ebook/e-card.c: Removed some debugging chatter.
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_create_entry): Store the completion
- handler in the entry's object data.
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_get_property_fn): Added support for getting "destinations"
- and "allow_contact_lists" properties.
- (entry_set_property_fn): Added support for setting "destinations"
- and "allow_contact_lists" properties.
- (impl_SelectNames_get_entry_for_section): Added definitions for
- "destinations" and "allow_contact_lists" properties.
-
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_get_match_contact_lists): Added.
- (e_select_names_completion_set_match_contact_lists): Added.
- Controls whether contact lists are offered as options during
- completion.
- (book_query_process_card_list): Check if match_contact_lists
- is set before (duh!) matching on a contact list.
- (e_select_names_completion_init): Set match_contact_lists
- to TRUE by default.
-
-2001-07-25 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (func_contains): change the way
- x-evolution-any-field is converted to an ldap query. it used to
- be we'd nest queries like: (|(|(|(foo=*x*))(bar=*x*))(baz=*x*)).
- now we build it like: (|(foo=*x*)(bar=*x*)(baz=*x*)). much more
- efficient (both in the building, and on the server side no doubt).
-
-2001-07-25 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_get_name): Properly dup
- the results of e_destination_get_email.
-
- * gui/component/select-names/e-select-names-popup.c
- (e_select_names_popup): Check that our destination isn't empty
- before building our popup. (Bug #5250)
-
- * backend/ebook/e-destination.c (e_destination_is_empty): Made
- argument const.
-
-2001-07-24 Jon Trowbridge <trow@ximian.com>
-
- * gui/contact-list-editor/e-contact-list-model.c: Added checks
- for all of the args of the exposed functions, so that
- we won't crash on bad inputs. (Related to bug #4856.)
-
-2001-07-24 Jason Leach <jleach@ximian.com>
-
- * gui/merging/e-card-duplicate-detected.glade: "_Add Anyway" to
- "Add Anyway".
-
-2001-07-24 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_get_name): Added
- fallbacks for the name in the case of an e-card, to avoid the
- "nameless contact" bug.
-
-2001-07-24 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-minicard.c (remodel): need the EDestination magic
- here too for when we modify an already shown card.
-
- * gui/contact-list-editor/e-contact-list-model.c: make
- parent_class static, just to be anal.
-
- * gui/contact-list-editor/e-contact-list-editor.c
- (remove_entry_cb): removing entries changes the list, so flag it.
- (table_drag_data_received_cb): restrict cards we add to lists to
- be non-list cards.
- (extract_info): clear out the email list in the card before we
- repopulate it from the contact list model.
- (fill_in_info): set the checkbox to active/inactive based on
- thecard.
-
-2001-07-24 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c (wants_html_changed): call
- widget_changed.
- (phone_entry_changed): same.
- (email_entry_changed): same.
- (address_text_changed): same.
- (name_entry_changed): same.
- (company_entry_changed): same.
- (widget_changed): new function that we can either call or set as a
- signal to change the "changed" flag on the dialog.
- (set_entry_changed_signals): connect lots of "changed" signals on
- widgets to widget_changed.
- (add_lists): connect "changed" to widget_changed.
-
-2001-07-24 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_hookup_shell_listener): Check if
- evolution_shell_client_get_local_storage returns CORBA_OBJECT_NIL,
- which it should never do. If it does, print a warning in a dialog
- and try to recover w/o crashing. (Bug #5193)
-
-2001-07-24 Dan Winship <danw@ximian.com>
-
- * backend/ebook/e-book-listener.c (e_book_listener_stop): Don't
- stop the idle_queue and unref from here, since this might be
- called from inside e_book_listener_check_queue, and we don't want
- to return to that function with the listener having been
- destroyed.
- (e_book_listener_check_queue): Don't exit early if the queue is
- stopped. Proceed through the check if the queue is NULL (which is
- must be if the queue is stopped), and then reach the existing code
- to remove the idle handler. Combined with the above, this fixes
- ximian #4485 (again). This is not a plot to boost my
- showstopper-bugfixing count by fixing the same bug over and over
- again.
-
-2001-07-23 Dan Winship <danw@ximian.com>
-
- Re-fix for my 07-18 not-quite-fix.
-
- * backend/ebook/e-book-listener.c: Add a "stopped" flag like
- EBookViewListener.
- (e_book_listener_check_queue): Don't emit signals if the listener
- is stopped.
- (e_book_listener_queue_generic_response, etc): Don't queue
- responses if the listener is stopped.
- (e_book_listener_stop): Flush the queue and stop queue/emitting
- further responses.
-
- * backend/ebook/e-book.c (e_book_unload_uri): Revert the previous
- change and call e_book_listener_stop() instead.
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_stop): When removing an idle handler, unref
- the listener as well, since e_book_view_listener_queue_response
- will have ref'ed it.
-
-2001-07-22 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c (remove_folder): Add a
- @type arg. If the type is not "contacts", report an
- `UNSUPPORTED_TYPE' error through the listener. Also, remove
- `g_print()' debugging messages.
- (xfer_folder): Likewise.
-
-2001-07-21 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c: Make the "contacts"
- folders user-creatable by setting `user_creatable' to %TRUE in the
- `EvolutionShellComponentFolderType's.
-
-2001-07-18 Chris Toshok <toshok@ximian.com>
-
- [ patch contributed by Jos Dehaes <jos.dehaes@bigfoot.com> ]
-
- * gui/component/addressbook-storage.c (register_storage): new
- function, register our evolution_storage.
- (addressbook_storage_setup): remove storage registration from
- here.
- (load_source_data): register the storage here before we load
- addressbook-sources.xml, and deregister it if there are no sources
- listed.
- (addressbook_storage_remove_source): unregister the storage if the
- list of sources hits 0 length.
-
-2001-07-18 Dan Winship <danw@ximian.com>
-
- * backend/ebook/e-book.c (e_book_unload_uri): Flush the listener's
- queue before unreffing it to ensure that it doesn't emit any more
- "responses_queued" signals after the EBook is destroyed.
-
- * backend/ebook/e-book-listener.c (e_book_listener_check_queue,
- e_book_listener_queue_response, e_book_listener_new): Use
- bonobo_object_ref/unref rather than gtk_object_ref/unref.
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_queue_response, e_book_view_listener_new):
- Likewise.
-
-2001-07-18 Chris Toshok <toshok@ximian.com>
-
- * backend/ebook/e-card-compare.c (simple_query_cb): prune the list
- of cards that match our query using the avoid list here, instead
- of using the avoid list in the query itself, since ldap can't
- handle that.
- (use_common_book_cb): remove the block of code including the avoid
- list in the query sent to wombat.
-
-2001-07-17 Chris Toshok <toshok@ximian.com>
-
- [ Fixes bugs #4611 - crash searching in the name field at Bigfoot for "\"
- and #4554 - general ldap search crash ]
-
- * backend/pas/pas-backend-ldap.c (func_contains): the length of
- the big query string needs to take into account the length of the
- footer as well as the header - fix random memory corruption here.
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_build_query):
- list can be NULL, specifically if there's a parsing error in the
- sexp, so deal with it.
-
-2001-07-17 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_queue_response): Hold a reference to our
- listener while the idle function is active.
- (e_book_view_listener_check_queue): Only unref the listener when
- the idle function is finished.
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_clicked): Instead of replacing section->model with
- source, copy source onto section->model with
- e_select_names_model_overwrite_copy. #if 0/#endif out all of the
- stuff related to ETextModels, because it doesn't make any sense to
- me, and everything appears to work without it.
- (Die bug #2059. Die! Die! Die!)
-
- * gui/component/select-names/e-select-names-model.c
- (e_select_names_model_overwrite_copy): Added. Copies the contents
- of one ESelectNamesModel onto another.
-
- * backend/ebook/e-destination.c (e_destination_copy): Made the argument
- const.
-
- * backend/ebook/e-destination.c (e_destination_set_string): Removed
- old, broken code and annoying g_messages.
-
- * backend/ebook/e-book-listener.c
- (e_book_listener_queue_response): Hold a reference to the listener
- while the idle function is active.
- (e_book_listener_check_queue): Only release our reference to the
- listener when the queue is empty. These two changes fix a race
- condition, since the listener could be unrefed while the listener
- was still active. (Seems to fix bug #4485)
-
-2001-07-17 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/contact-editor.glade,
- gui/merging/e-card-duplicate-detected.glade,
- gui/merging/e-card-merging-book-commit-duplicate-detected.glade,
- printing/e-contact-print.glade: Patch from Taylor Hayward
- <thayward@gjpc.com>. Added accelerators to a few dialogs.
-
-2001-07-16 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/Evolution-Addressbook-SelectNames.idl:
- Added addSectionWithLimit to the SelectNames interface.
-
- * gui/component/select-names/e-select-names-bonobo.c
- (impl_SelectNames_add_section_with_limit): Added. Implements
- addSectionWithLimit.
- (e_select_names_bonobo_construct): Set up as a BonoboEventSource.
- (init): Listen for "changed" signals from our manager.
- (manager_changed_cb): Notify our listeners if we get a changed
- signal from our manager.
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_class_init): Added a "changed" signal".
- (section_copy): Propogate the signal connection.
- (section_free): Disconnect the changed handler.
- (e_select_names_manager_add_section_with_limit): Connect to the
- new section's model, listening for changes.
- (e_select_names_manager_activate_dialog): Connect to the "working
- copy" model, listening for changes.
- (e_select_names_manager_add_section_with_limit): Added.
- (e_select_names_manager_add_section): Changed to just be a special
- case of e_select_names_manager_add_section_with_limit.
-
- * gui/component/select-names/e-select-names-model.c
- (e_select_names_model_set_limit): Added. Allows a max number of
- names allowed in the model.
- (e_select_names_model_get_limit): Added. Returns the limit.
- (e_select_names_model_at_limit): Added. Returns TRUE if the
- model is "full".
- (e_select_names_model_insert): Check that we aren't at the
- limit before inserting. Silently return if we are.
- (e_select_names_model_append): Check that we aren't at the
- limit before appending. Silently return if we are.
-
-2001-07-16 Chris Toshok <toshok@ximian.com>
-
- [ Fix bug #4705 - LDAP storage gets saved with corrupted binddn]
-
- * gui/component/addressbook-config.c (addressbook_dialog_apply):
- call addressbook_storage_write_sources here after we're done
- rebuilding them.
-
- * gui/component/addressbook-storage.c
- (addressbook_storage_clear_sources): don't write the source file
- here.
- (addressbook_storage_add_source): same.
- (addressbook_storage_remove_source): same.
- (addressbook_storage_write_sources): new function, write the
- source file out.
- (addressbook_source_copy): g_strdup the binddn so we don't end up
- free'ing it multiple times thanks to copies freeing theirs.
-
- * gui/component/addressbook-storage.h: add prototype for
- address_storage_write_sources.
-
-2001-07-16 Iain Holmes <iain@ximian.com>
-
- * backend/pas/evolution-vcard-importer.c (ebook_create): Don't just
- use the default directory. Use the directory that is passed into the
- load file function.
-
-2001-07-15 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_set_string):
- Commented out some unused variables and labels.
- (e_destination_importv): Check for the xml not parsing correctly
- and just return NULL here.
-
- * gui/component/select-names/e-select-names-model.c
- (e_select_names_model_import_destinationv): Handle a NULL destv
- here.
-
-2001-07-15 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (table_drag_data_get): Added a
- call to e_table_view_to_model_row here.
- (e_addressbook_view_can_print, e_addressbook_view_can_delete,
- e_addressbook_view_can_copy): If the selection model is NULL here,
- return NULL (this was done before in a g_return_val_if_fail which
- is only conditionally included.)
-
-2001-07-13 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/contact-editor.glade: Changed Company to
- Organization here.
-
-2001-07-12 JP Rosevear <jpr@ximian.com>
-
- * backend/pas/Makefile.am: add ldap cflags
-
-2001-07-12 Jeffrey Stedfast <fejj@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_xml_decode):
- Oops. I introduced my own bug, accidently set `email' to a
- g_free'd pointer - eek!
-
-2001-07-12 Jeffrey Stedfast <fejj@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_importv): Optimized
- the same way I optimized g_strsplit. If you use a GPtrArray
- instead of a linked list, you save yourself from having to iterate
- through the list an extra 3 times.
- (e_destination_xml_decode): Do NOT, I repeat: do NOT!
- e_utf8_xml1_decode something which is already in UTF-8 or you'll
- corrupt it!! I smack thee who hath done this evil deed!
-
-2001-07-12 Iain Holmes <iain@ximian.com>
-
- * backend/e-book/evolution-vcard-importer.c (support_format_fn):
- Check for no extension. Actually same as Jason's fix below :) but
- also check the file contents.
-
-2001-07-12 JP Rosevear <jpr@ximian.com>
-
- * gui/component/addressbook-config.glade: add accelerators,
- taylor's patch
-
-2001-07-12 Jason Leach <jleach@ximian.com>
-
- * backend/ebook/evolution-vcard-importer.c (support_format_fn):
- Crash fix because strcmp() hates NULL arguments. Bug #3777.
-
-2001-07-11 Jason Leach <jleach@ximian.com>
-
- * gui/component/select-names/e-select-names.c (remove_cb): Added
- some comments for clarity and fixed a pretty noticable bug with
- how right click "Remove" was deleting more than it should with
- consecutive runs.
-
-2001-07-10 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/evolutionperson.schema: assign OID's to the schema
- entries, and add schema support for contact lists.
-
-2001-07-10 Christopher James Lahey <clahey@ximian.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_load_uri): Set
- bf->priv->file_db before calling do_create.
-
-2001-07-06 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook-component.c (factory_fn): Fixed order
- of arguments to evolution_shell_component_new.
-
-2001-07-08 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_insert_length): Check that str isn't
- the empty string before doing an insert.
-
- * backend/ebook/e-destination.c (e_destination_set_string): We were
- being too smart for our own good here, and causing problems for
- the completion code... (bug #4253, bug #4255, bug #4280)
- (e_destination_set_name): Clear any cached address.
- (e_destination_set_email): Clear any cached address.
- (e_destination_get_address): Handle the cases where the name
- contains some e-mail information.
-
-2001-07-09 Kjartan Maraas <kmaraas@gnome.org>
-
- * gui/contact-list-editor/e-contact-list-editor.c: Marked a
- string for translation. Also add the neccesary includes to make
- _() macros work.
-
-2001-07-07 Jon Trowbridge <trow@ximian.com>
-
- * gui/widgets/e-minicard.c (add_field): Detect the embedded
- EDestination XML, and convert it to a nice-looking e-mail address.
-
- * gui/contact-list-editor/e-contact-list-editor.c: Adjusted to
- reflect changes to EContactListModel. (Yeah, this is vague,
- but the changes are _really_ obvious and boring.)
-
- * gui/contact-list-editor/e-contact-list-model.c: Revamped
- to make everything an EDestination, rather than storing either
- cards or strings.
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_insert_length): Use
- e_destination_get_textrep.
-
- * gui/component/select-names/e-select-names-table-model.c
- (fill_in_info): Use e_destination_get_name and
- e_destination_get_email.
-
- * gui/component/select-names/e-select-names-popup.c
- (popup_menu_card): Use e_destination_get_name instead of
- e_card_name_to_string.
- (quick_add_cb): Use e_destination_get_address.
- (popup_menu_nocard): Use e_destination_get_name.
-
- * gui/component/select-names/e-select-names-model.c
- (e_select_names_model_changed): Removed obsolete debugging code.
- (e_select_names_model_get_textification): Use e_destination_get_textrep.
- (e_select_names_model_get_address_text): Use e_destination_get_address.
- (e_select_names_model_get_string): Use e_destination_get_textrep.
- (e_select_names_model_replace): Use e_destination_get_textrep.
- (e_select_names_model_name_pos): Use e_destination_get_textrep.
-
- * gui/component/select-names/e-select-names-completion.c
- (emailify_match): Match only if this isn't a contact list.
- (match_email): Match only if this isn't a contact list.
- (match_name): Do the right thing in the case of a contact list.
- (book_query_process_card_list): Don't construct a match for
- each possible e-mail address if this is a contact list.
-
- * backend/ebook/e-destination.c: Major-league de-crufting and
- rationalization, combined with lots of hacks to make things work
- properly with contact lists.
- (e_destination_copy): Copy contact list info.
- (e_destination_clear_card): Clear contact list info.
- (e_destination_is_empty): If we contain a contact list, we aren't
- empty.
- (e_destination_set_card_uri): Added. Allows us to set a
- destination by card URI.
- (e_destination_set_name): Allows the contact's name only ("Jane
- Smith") to be set.
- (e_destination_set_email): Allows the contact's e-mail only
- ("jane@assbarn.com") to be set.
- (e_destination_set_string): Takes a free-form string containing a
- contact's name and/or e-mail, and tries to do the right thing with
- it.
- (e_destination_contains_card): Renamed. Used to be
- e_destination_has_card.
- (e_destination_from_card): Added. Returns TRUE if the
- EDestination comes from either a ECard (which we presently hold)
- or is specified by an ECard URI.
- (e_destination_use_card): Allows an EDestination's ECard to be
- accessed, via a callback. If we only are holding the URI, the
- card will be loaded and stored in the EDestination.
- (e_destination_get_name): Returns the name only ("Jane Smith"), or
- NULL.
- (e_destination_get_email): Returns the email only
- ("jane@assbarn.com"), or NULL.
- (e_destination_get_address): Added. Returns a "full address" if
- both the name & e-mail are available ("Jane Smith
- <jane@assbarn.com>"), or just the e-mail if the name is unknown
- ("jane@assbarn.com>"). If the destination is a contact list,
- returns a comma-separated list of addresses.
- (e_destination_get_textrep): Added. Returns a "text
- representation" of the EDestination. This is what is now
- displayed for completed, "cardified" destinations in addressbook
- entries.
- (e_destination_is_evolution_list): Check to see if this
- destination is for a contact list.
- (e_destination_xml_encode): Added. Build an XML data structure
- representing an EDestination.
- (e_destination_xml_decode): Added. Parse an XML data structure,
- constructing an EDestination.
- (e_destination_export): Added. Returns a null-terminated string
- containing an XML representation of the EDestination, with
- newlines and excess whitespace removed.
- (e_destination_import): Added. Parses a string containing an XML
- representation of an EDestination.
- (e_destination_exportv): Added. Returns a null-terminated string
- containing an XML representation of a collection of EDestinations,
- with newlines and excess whitespace removed.
- (e_destination_importv): Added. Takes an XML representation of a
- collection of destinations, parses it, and returns a vector of
- EDestinations.
-
- * backend/ebook/e-card.c (e_card_duplicate): Copy the ->book
- pointer.
- (e_card_get_id): Check that the argument is valid.
- (e_card_set_id): Check that the argument is valid.
- (e_card_get_book): Added. Return the EBook the ECard came from.
- (e_card_get_uri): Added. Tries to returns a URI for the ECard,
- which is of the form (EBook URI)/(ECard unique ID). Returns NULL
- if the EBook URI or the ID are unknown/not set.
- (e_card_get_vobject): If we have the URI, use it as the
- VCUniqueStringProp, rather than just the ID. This is a hack to
- make DnD work properly.
- (parse_id): Detect if the unique ID we've been passed is a URI or
- just a plain card ID, and do the right thing in either case.
- (e_card_uri_extract_book_uri): Added. Convenience function for
- parsing card URIs.
- (e_card_uri_extract_card_id): Added. Convenience function for
- parsing card URIs.
- (e_card_load_uri): Added. Allows an ECard to be loaded by its
- URI.
-
- * backend/ebook/e-book-view.c: Added a EBook * to the
- _EBookViewPrivate struct. This is meant to contain the EBook the
- EBookView is associated with.
- (add_book_iterator): Added. A convenience function for attaching
- the EBook to a GList of cards (if no EBook is already stored).
- (e_book_view_do_added_event): Record the EBook in the added
- ECards.
- (e_book_view_do_modified_event): Record the EBook in the modified
- ECards.
- (e_book_view_set_book): Added. Stores a pointer to the
- EBookView's "parent" EBook.
- (e_book_view_init): Init book_view->priv->book to NULL.
- (e_book_view_destroy): Unref book_view->priv->book.
-
- * backend/ebook/e-book.c: Added a uri field to _EBookPrivate.
- (e_book_unqueue_op): Removed debugging spew.
- (e_book_do_response_get_view): Attach the current EBook to the
- created EBookView.
- (e_book_do_response_get_changes): Attach the current EBook to the
- created EBookView.
- (e_book_load_uri): Save a copy of the uri in the EBook.
- (e_book_get_uri): Added. Just returns book->priv->uri.
- (e_book_get_card): Attach a pointer to the Ebook to the
- newly-loaded ECard.
- (e_book_add_card): Attach a pointer to the EBook to the
- newly-added ECard.
- (e_book_commit_card): Attach a pointer to the EBook to the
- committed ECard.
- (e_book_init): Initialize the uri to NULL.
- (e_book_destroy): Free the uri string on destruction.
-
-2001-07-06 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c (populate_context_menu):
- Removed. [It was just bogus testing code for the right-click menu
- populating interface in the shell].
- (factory_fn): Pass NULL as the PopulateContextMenuFn.
-
-2001-07-05 Anna Marie Dirks <anna@ximian.com>
-
- * gui/contact-list-editor/contact-list-editor.glade:
- Added some accelerators, padding, and a "memebers" frame;
- also fixed spacing and growth behaviour of this dialog.
-
-2001-07-05 Christopher James Lahey <clahey@ximian.com>
-
- * backend/pas/pas-backend-file.c (compare_category): Fix a memory
- leak here.
-
-2001-07-05 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-compare.c (match_search_info_free): Set
- info->avoid = NULL. This shouldn't make a difference, but it
- can't hurt.
-
-2001-07-05 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-table-adapter.c
- (addressbook_is_cell_editable): Check if the row is within our
- table and return from this function as if the card is a standard
- card, not a list.
-
-2001-07-03 Damon Chaplin <damon@ximian.com>
-
- * backend/ebook/Makefile.am (evolution_vcard_importer_LDADD):
- added $(BONOBO_CONF_LIBS) to get it to compile.
-
-2001-07-02 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/Makefile.am (evolution_addressbook_LDADD): Added
- $(BONOBO_CONF_LIBS).
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_create_categories),
- gui/contact-editor/e-contact-editor.c (categories_clicked):
- Switched to an ECategoriesMasterListWombat instead of an
- ECategoriesMasterListArray here.
-
-2001-07-02 Peter Williams <peterw@ximian.com>
-
- * gui/contact-editor/Makefile.am (INCLUDES): srcdir !=
- builddir compile fix.
-
- * gui/contact-list-editor/Makefile.am (INCLUDES): Same.
-
- * gui/widgets/Makefile.am (INCLUDES): Same.
-
- * gui/search/Makefile.am (INCLUDES): Same.
-
-2001-07-02 Christopher James Lahey <clahey@ximian.com>
-
- * gui/contact-editor/e-contact-editor.c (categories_clicked):
- Turned off wombatification of the categories master list here.
-
-2001-07-01 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-list-editor/e-contact-list-editor.c (fill_in_info):
- use ECARD_UID_LINK_PREFIX.
-
- * gui/contact-list-editor/e-contact-list-model.c
- (e_contact_list_model_get_email): use ECARD_UID_LINK_PREFIX.
-
- * backend/ebook/e-destination.h: add prototype for
- e_destination_importv_list.
-
- * backend/ebook/e-destination.c (e_destination_importv_list): new
- function, take an ECard corresponding to an address list and
- resolve any linked cards, returning an EDestination vector.
-
- * backend/ebook/e-card.h (ECARD_UID_LINK_PREFIX): #define this here,
- since we need to use it in a few places.
-
-2001-07-02 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Added
- related_contacts field.
-
- * gui/component/select-names/e-select-names-model.c,
- gui/component/select-names/e-select-names-model.h
- (e_select_names_model_import_destinationv): Added this function.
-
- * gui/contact-editor/contact-editor.glade: Replaced the entry here
- for related contacts with a table which is filled in in the C code.
-
- * gui/contact-editor/e-contact-editor.c,
- gui/contact-editor/e-contact-editor.h (add_lists): Added a select
- names entry here for the related contacts field.
-
- * gui/widgets/Makefile.am: Removed all the test programs here
- since there are circular dependencies now.
-
-2001-07-01 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_get_string): Fall
- back to use the name field if all else fails (which can happen
- with imported EDestinations).
-
- * backend/ebook/e-destination.c (e_destination_is_empty): Fix for the
- "recipient not specified" bug --- we were not correctly checking
- for whether or not an EDestination was actually empty.
-
-2001-06-30 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-card.c (e_card_evolution_list): Check args.
- Somewhere in the code (somewhere in the minicard stuff) this can
- be called with a NULL arg, which was causing crashes.
- (e_card_evolution_list_show_addresses): Check args.
-
- * backend/ebook/e-destination.c (build_field): I was accidentally
- comparing characters and strings here, and didn't see the compiler
- warning. Fixed.
- (e_destination_exportv): Don't export any empty destinations.
- (bug#3825).
-
-2001-06-30 Zbigniew Chyla <cyba@gnome.pl>
-
- * gui/component/e-address-popup.c (e_address_popup_construct): Marked
- strings for translation.
-
-2001-06-30 Jon Trowbridge <trow@ximian.com>
-
- * gui/merging/e-card-merging.c (match_query_callback): Make the
- standard for considering two cards to be match stricter.
-
- * gui/component/select-names/e-select-names-completion.c
- (make_match): Use the card's use-score to set the match's
- sort_major value.
- (match_name): Removed obsolete code.
- (e_select_names_completion_begin): Added (double) cast to make
- match->score calculation come out properly.
-
- * backend/ebook/e-card.c: Added X-EVOLUTION-LAST-USE and
- X-EVOLUTION-USE-SCORE to attribute_jump_array.
- (e_card_get_today): Added. A convenience routine for getting
- today's date and putting it in a GDate.
- (e_card_get_use_score): Added. Compute the current, time-decayed,
- use-score for the card.
- (e_card_touch): Increment the use-score by one; update the last
- used date.
- (e_card_date_to_string): Added as a convenience routine, getting
- rid of some code duplication.
- (e_card_get_vobject): Add handlers for X-EVOLUTION-USE-SCORE and
- X-EVOLUTION-LAST-USE.
- (parse_last_use): Added.
- (parse_use_score): Added.
- (e_card_class_init): Added args for last-use and use-score.
- (e_card_get_arg): Added handlers for last-use and use-score.
- o
- (e_card_set_arg): Added handlers for last-use and use-score.
-
- * backend/ebook/e-destination.c: Added pending_card_id to
- EDestinationPrivate struct.
- (e_destination_copy): Copy the pending_card_id.
- (e_destination_is_empty): Check for a pending_card_id. We are
- non-empty if we have one.
- (e_destination_clear_card): Clear pending_card_id.
- (e_destination_set_card): Clear pending_card_id.
- (e_destination_has_pending_card): Added.
- (e_destination_use_card): Added. An asynchronous way to load a
- pending card and then apply a callback to it.
- (build_field): Be paranoid, map our special characters to '_'.
- (e_destination_export): Use EXPORT_MAX_FIELDS symbol rather than a
- hard-wired array size. Added the "card" entry.
- (e_destination_import): Fix bug in handling of the "name" field.
- Process the "card" field.
- (e_destination_touch): "Touch" and commit the ECard corresponding
- to the e-mail address in the destination. (A query against the
- local addressbook is actually performed, in case the destination
- isn't cardified.
-
- * backend/ebook/e-card-compare.c (e_card_compare_name): Revamp the
- way E_CARD_MATCH_FOO results are mapped to comparison results.
- Report better matches when the family name is matched.
-
-2001-06-29 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c (update_query):
- Added a search field to the query here.
- (e_select_names_init): Update the query on a number of signals here.
-
- * gui/component/select-names/e-select-names.h: Added search_entry
- here.
-
- * gui/component/select-names/select-names.glade: Added the search
- entry here. Added some labels. Removed the update button.
-
-2001-06-29 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_option_activated): Change the uri here to have
- addressbook.db at the end.
-
- * gui/component/select-names/select-names.glade: Changed the name
- of the folder option menu here to match the name used in the code.
-
-2001-06-29 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c (update_query):
- Change the query when the "Update List" button is pushed.
-
- * gui/component/select-names/e-select-names.h: Removed
- currently_selected field. Added categories_entry field.
-
- * gui/component/select-names/select-names.glade: Added "Update
- List" button.
-
-2001-06-29 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/Makefile.am (INCLUDES): add EVOLUTION_IMAGESDIR
- define.
-
- * gui/widgets/e-minicard.h (struct _EMinicard): add our pixbuf and
- pixbuf size.
-
- * gui/widgets/e-minicard.c (e_minicard_init): init the icon pixbuf
- and its size.
- (e_minicard_destroy): unref the list_icon_pixbuf.
- (e_minicard_realize): create the list_icon GnomeCanvasPixbuf.
- (e_minicard_resize_children): clip the header_text by the
- list_icon, and place the list_icon in the right spot.
- (remodel): show the list_icon if we're a list, and hide it
- otherwise.
-
-2001-06-28 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (table_double_click): pop up
- list editor for lists, contact editor otherwise.
-
- * gui/widgets/e-minicard.c (e_minicard_event): same.
-
- * gui/widgets/e-minicard.h (struct _EMinicard): change "editor" to
- GtkOjbect, since it can be either a contact editor or contact list
- editor.
-
- * gui/widgets/e-addressbook-table-adapter.c
- (addressbook_is_cell_editable): don't allow editting of any fields
- except the name and file_as for lists.
-
-2001-06-28 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-list-editor/Makefile.am (INCLUDES): remove ancient
- e-table include, and add include for contact-editor so we can
- reuse the confirm_delete dialog.
-
- * gui/contact-list-editor/e-contact-list-editor.h (struct
- _EContactListEditor): remove prototype for
- e_contact_list_editor_close, since the function no longer exists.
-
- * gui/contact-list-editor/e-contact-list-editor.c
- (list_deleted_cb): new function, emit our "list_deleted" signal.
- (delete_cb): new function, called from the Delete toolbar item.
- (e_contact_list_editor_raise): flesh out function.
- (extract_info): "evolution_list" => "list".
- (fill_in_info): same.
-
-2001-06-28 Chris Toshok <toshok@ximian.com>
-
- * backend/ebook/e-card.c (e_card_get_vobject): add support for
- X-EVOLUTION-LIST and X-EVOLUTION-LIST-SHOW-ADDRESSES.
- (parse_list): new function, parse the boolean X-EVOLUTION-LIST.
- (parse_list_show_addresses): new function, parse the boolean
- X-EVOLUTION-LIST-SHOW-ADDRESSES.
- (e_card_class_init): add args for "list" and
- "list_show_addresses".
- (e_card_set_arg): add support for list and list_show_addresses.
- (e_card_get_arg): same.
- (e_card_init): init list and list_show_addresses.
-
-2001-06-27 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c (factory_fn): Pass NULL as
- the @external_uri_schemas argument to
- `evolution_shell_component_new()'.
-
-2001-06-27 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-list-editor/e-contact-list-model.c
- (contact_list_row_count): track storage change - we're only using
- 1 array now.
- (contact_list_value_at): same.
- (contact_list_model_destroy): same.
- (e_contact_list_model_init): same.
- (e_contact_list_model_add_email): same.
- (e_contact_list_model_add_card): same.
- (e_contact_list_model_remove_row): same.
- (e_contact_list_model_remove_all): new function - just free/unref
- all existing rows.
- (e_contact_list_model_get_email): new function, returns the
- alloc'ed string containing either an email address or an encoded
- ECardId.
-
- * gui/contact-list-editor/e-contact-list-model.h: remove the 2
- separate arrays for email and cards, and store them in the same
- array.
-
- * gui/contact-list-editor/e-contact-list-editor.h (struct
- _EContactListEditor): add the visible_addr_checkbutton widget.
-
- * gui/contact-list-editor/e-contact-list-editor.c
- (visible_addrs_toggled_cb): new function.
- (e_contact_list_editor_init): connect to "toggled" on
- visible_addrs_checkbutton.
- (file_save_cb): new function.
- (tb_save_and_close_cb): new function.
- (verbs): add Save and Save & Close.
- (list_added_cb): new function.
- (list_modified_cb): new function.
- (save_card): new function - we do *not* use e_card_merging_* calls
- here.
- (e_contact_list_editor_get_arg): un-#if 0 code in the "card"
- getter.
- (e_contact_list_editor_set_arg): same for the "card" setter.
- (extract_info): new function.
- (fill_in_info): new function.
-
- * gui/contact-list-editor/contact-list-editor.glade: add a
- checkbutton at the bottom to determine whether to visibly include
- mail addresses in mail sent to this list.
-
-2001-06-26 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_create_categories): Oops. Can't use the wombat
- version of the master categories list yet.
-
-2001-06-26 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-table-adapter.c (create_card): memmove
- counts were off in this function.
- (remove_card, modify_card): Moved the table notifications around a
- bit here.
-
-2001-06-26 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names.c,
- gui/component/select-names/e-select-names.h,
- gui/component/select-names/select-names.glade
- (e_select_names_create_categories): Added a categories combo here.
- It's not used yet.
-
-2001-06-26 Christopher James Lahey <clahey@ximian.com>
-
- * gui/search/addresstypes.xml: Added category searching to the
- advanced search dialog here.
-
-2001-06-26 Christopher James Lahey <clahey@ximian.com>
-
- * backend/pas/pas-backend-file.c (compare_category): Added
- category searching to the file backend.
-
- * gui/component/addressbook.c (addressbook_query_changed): Added
- category searching to the search bar.
-
-2001-06-25 Peter Williams <peterw@ximian.com>
-
- * conduit/Makefile.am (INCLUDES): Fix for srcdir != builddir.
-
-2001-06-25 Chris Toshok <toshok@ximian.com>
-
- * gui/contact-list-editor/contact-list-editor.glade: change layout
- slightly, the icon no longer pushes everything to the left, and
- make the buttons on the right smaller and more in line with the
- other widgets.
-
- * gui/contact-list-editor/e-contact-list-model.c
- (contact_list_value_at): return the SimpleAndString->string
- instead of querying the ecardsimple.
- (e_contact_list_model_init): initially allocate 10 of each type
- (email and simple).
- (e_contact_list_model_add_email): realloc if need be.
- (e_contact_list_model_add_card): same, and initialize the string
- displayed to be "[Name] [<email>]".
- (e_contact_list_model_remove_row): change for SimpleAndString.
- (contact_list_model_destroy): free our 2 arrays.
-
- * gui/contact-list-editor/e-contact-list-model.h: add alloc counts
- and the SimpleAndString struct.
-
- * gui/contact-list-editor/e-contact-list-editor.c: Helix Code =>
- Ximian.
- (e_contact_list_editor_init): hook up d&d destination signals, and
- un-#if 0 the delete_event signal.
- (table_drag_motion_cb): new function.
- (table_drag_drop_cb): new function.
- (table_drag_data_received_cb): new function.
- (file_close_cb): new function.
- (verbs) uncomment the close verb.
- (close_dialog): new function.
- (app_delete_event_cb): new function.
-
- * gui/contact-list-editor/e-contact-list-editor.h: Helix Code =>
- Ximian.
-
-2001-06-25 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/e-address-popup.c: Add a huge steaming pile of
- code to handle the case of single-address merging. In other
- words, if you go to "harvest" an address by right-clicking on it
- in the mail viewer, and you already have a closely-matching
- contact (w/ a different e-mail address), this gives you the
- option of editting that contact's e-mail addresses to add the
- one you just clicked on.
-
- * backend/ebook/e-card-compare.c (match_search_info_free): It is
- amazing how much better things work when you don't try to
- dereference the pointer you just freed.
-
-2001-06-24 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/Makefile.am (minicard_test_LDADD): correct path to
- libecontacteditor.a.
- (minicard_widget_test_LDADD): same.
- (INCLUDES): same, for the includes.
-
- * gui/widgets/e-minicard.h: correct e-contact-editor.h path.
-
- * gui/widgets/e-addressbook-util.h: correct path to
- e-contact-editor.h, and add e-contact-list-editor.h. Add
- prototype for e_addressbook_show_contact_list_editor.
-
- * gui/widgets/e-addressbook-util.c: remove #include
- "e-contact-editor.h" (our header includes it.)
- (added_cb): rename card_added_cb to this, and make it so it can be
- reused in both the list and card cases. remove the g_print too.
- (modified_cb): same for modified case.
- (deleted_cb): same for deleted case.
- (editor_closed_cb): change first arg to GtkObject* so we can reuse
- this for both list and card.
- (e_addressbook_show_contact_editor): use added_cb, modified_cb,
- deleted_cb, and pass FALSE as user_data.
- (e_addressbook_show_contact_list_editor): new function, same as
- above but creating a contact-list-editor, and pass TRUE as
- user_data.
-
- * gui/component/e-address-popup.c: correct path to contact-editor.
-
- * gui/component/e-address-widget.c: same.
-
- * gui/component/select-names/e-select-names-popup.c: same.
-
- * gui/component/select-names/e-select-names-text-model.c: same.
-
- * gui/component/addressbook.c (new_contact_list_cb): new function.
- (update_command_state): update ContactNewList command.
- (verbs): remove ViewAll from the toolbar from the verb list. Add
- ContactNewList.
- (pixmaps): same for pixmaps.
-
- * gui/component/Makefile.am (evolution_addressbook_LDADD): new
- path for contact-editor.
- (INCLUDES): same.
-
- * gui/contact-list-editor/e-contact-list-model.h:
- * gui/contact-list-editor/e-contact-list-model.c:
- * gui/contact-list-editor/e-contact-list-editor.h:
- * gui/contact-list-editor/e-contact-list-editor.c:
- * gui/contact-list-editor/Makefile.am: Initial contact-list editor
- commit.
-
- * gui/Makefile.am (SUBDIRS): add contact-editor.
-
- * Makefile.am: (SUBDIRS): remove contact-editor.
-
-2001-06-21 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-popup.c
- (make_contact_editor_cb): Renamed. (The old name,
- edit_contact_info_have_book_cb was a hold-over from before, when
- we weren't using e_book_use_local_address_book.)
-
- * gui/component/e-address-popup.c
- (e_address_popup_schedule_refresh): A Added. We now do the name
- refreshes in an idle function, rather than in the setters.
- (e_address_popup_set_free_form): Added. Properly handle inputs of
- the form "Foo <bar@zar.com>", extracting the name and e-mail
- address.
- (e_address_popup_set_name): Check to make sure that the free-form
- handler shouldn't be used to handle the input. Schedule a refresh
- after making any changes.
- (e_address_popup_set_email): Check to make sure that the free-form
- handler shouldn't be used to handle the input. Schedule a refresh
- after making any changes.
- (e_address_popup_name_only_matches): Temporary place-holder for
- handling name-only matches.
- (query_cb): If our initial query fails (and included e-mail
- information), do a name-only query. This is to handle the case of
- adding new e-mail addresses to existing contacts.
- (e_address_popup_query): Eliminated the "common_book" crap; using
- e_book_use_local_address_book instead.
-
- * backend/ebook/e-card-compare.c (match_search_info_free): Make
- sure that the ->avoid list gets properly freed.
-
-2001-06-20 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_process_get_supported_fields): fix a refcounting
- memleak.
-
-2001-06-20 Chris Toshok <toshok@ximian.com>
-
- * backend/ebook/e-book-listener.c
- (e_book_listener_queue_get_supported_fields_response): fix memory
- leak.
-
-2001-06-20 Chris Toshok <toshok@ximian.com>
-
- * contact-editor/e-contact-editor.c: add prototype for
- close_dialog to remove warnings.
-
-2001-06-20 Dave Camp <dave@ximian.com>
-
- * backend/ebook/e-card.c (e_card_list_send): Changed attach_data
- to be a GNOME_Evolution_Composer_AttachmentData rather than a
- CORBA_char*.
-
-2001-06-19 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (table_double_click): track
- change to e_addressbook_show_contact_editor signature.
-
- * gui/widgets/e-minicard-view.c (e_minicard_view_event): same.
-
- * gui/widgets/e-minicard.c (e_minicard_event): same.
-
- * gui/widgets/e-addressbook-util.c (e_addressbook_error_dialog):
- add an entry for "Card ID already exists".
- (e_addressbook_show_contact_editor): track the change to signal
- names and e_contact_editor_new signature here.
-
- * gui/widgets/e-addressbook-util.h: change
- e_addressbook_show_contact_editor's signature to match
- e_contact_editor_new more closely.
-
- * gui/widgets/e-addressbook-table-adapter.c (unlink_model): free
- up the simple mapping to plug a potentially sizeable memory leak.
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_activate_obj): call
- e_addressbook_show_contact_editor here.
-
- * gui/component/select-names/e-select-names-popup.c
- (edit_contact_info_have_book_cb): remove the get_supported_fields
- stuff, since the contact editor handles it for us now, and call
- e_addressbook_show_contact_editor.
-
- * gui/component/e-address-popup.c (edit_contact_info_cb): same.
-
- * gui/component/addressbook.c (new_contact_cb): track change to
- e_addressbook_show_contact_editor.
-
-2001-06-19 Chris Toshok <toshok@ximian.com>
-
- * contact-editor/e-contact-quick-add.c (ce_have_book): rename
- ce_book_found_fields to this, remove the fetching of fields (the
- contact editor code handles that now.), and change the add_card
- signal to card_added.
- (card_added_cb): copied somewhat from merge_cb above. we don't
- need to do the merge here, just call the callback.
-
- * contact-editor/e-contact-editor.c (e_contact_editor_class_init):
- track signal change. add book arg, and is_read_only -> editable.
- (wants_html_changed): if the card isn't already changed, flag it
- as such (and update the commands.)
- (phone_entry_changed): same.
- (email_entry_changed): same.
- (address_text_changed): same.
- (name_entry_changed): same.
- (company_entry_changed): same.
- (full_name_clicked): is_read_only -> editable.
- (full_addr_clicked): same.
- (card_added_cb): new function, emit our card_added signal, and
- close the dialog if we're supposed to. properly deal with error
- status here.
- (card_modified_cb): same, modulo card_added -> card_modified.
- (save_card): actually call e_card_merging_book_{add/commit}_card
- instead of using a signal. Also, add a gboolean arg to tell
- whether or not to close the dialog after saving the card.
- (card_deleted_cb): new function, just emit our "card_deleted"
- signal.
- (delete_cb): actually call e_book_remove_card here, instead of
- using a signal.
- (tb_save_and_close_cb): call save_card with TRUE for should_close.
- (e_contact_editor_init): init changed = FALSE;
- (e_contact_editor_destroy): unref our book if we have one.
- (e_contact_editor_new): new signature, set the "book" arg, and
- call e_book_get_supported_fields here.
- (supported_fields_cb): new function, show the contact editor.
- (e_contact_editor_set_arg): initialize changed to FALSE when
- setting the card (but *after*, since the changed callbacks will
- set it to TRUE.) also, call command_state_changed if editable
- changes. also handle setting "book". oh, and is_read_only ->
- editable.
- (command_state_changed): new function - set the state of the
- commands we care about.
- (e_contact_editor_get_arg): add "book" handling, and is_read_only
- -> editable.
- (_phone_arrow_pressed): is_read_only -> editable.
- (_email_arrow_pressed): same.
- (_address_arrow_pressed): same.
- (enable_writable_fields): same.
- (set_editable): rename set_read_only to this, and is_read_only ->
- editable.
-
- * contact-editor/e-contact-editor.h (struct _EContactEditor):
- is_read_only -> editable, add a "changed" flag so we can sensitize
- commands correctly, and add an EBook* arg to e_contact_editor_new
- and to the EContactEditor struct. Also, change all the signals to
- past tense, and send the EBookStatus in them.
-
- * contact-editor/e-contact-editor-address.c
- (e_contact_editor_address_class_init): is_read_only -> editable.
- (e_contact_editor_address_set_arg): same.
- (e_contact_editor_address_get_arg): same.
-
- * contact-editor/e-contact-editor-address.h (struct
- _EContactEditorAddress): same.
-
- * contact-editor/e-contact-editor-fullname.c
- (e_contact_editor_fullname_class_init): same.
- (e_contact_editor_fullname_set_arg): same.
- (e_contact_editor_fullname_get_arg): same.
-
- * contact-editor/e-contact-editor-fullname.h (struct
- _EContactEditorFullname): same.
-
- * contact-editor/Makefile.am: don't build contact-editor-test now,
- until contact-editor gets moved to gui/ and we can more easily
- depend on the e_card_merging_* calls.
-
- * backend/pas/pas-backend-ldap.c (ldap_error_to_response): return
- CardIdAlreadyExists for LDAP_ALREADY_EXISTS.
-
- * backend/idl/addressbook.idl: Add CardIdAlreadyExists to the
- BookListener status enum.
-
- * backend/ebook/e-book-types.h: add
- E_BOOK_STATUS_CARD_ID_ALREADY_EXISTS.
-
- * backend/ebook/e-book-listener.c
- (e_book_listener_convert_status): add support for
- CardIdAlreadyExists.
-
-2001-06-19 Jon Trowbridge <trow@ximian.com>
-
- * contact-editor/e-contact-quick-add.c: Serious de-crufting,
- removal of gtk_object_set_data() hacks, simplified by using
- some of the newer ebook convenience routines, etc.
- (ce_book_found_fields):
- s/e_contact_editor_raise/e_contact_editor_show/, to accomodate the
- small changes in the contact editor API.
-
-2001-06-18 Eskil Heyn Olsen <eskil@eskil.dk>
-
- * conduit/address-conduit.c: (check_for_slow_setting),
- (conduit_get_gpilot_conduit):
- Tweaked for some gnome-pilot api changes
-
-2001-06-15 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (search_for_dn): implement this
- properly, using base and (objectclass=*).
-
-2001-06-14 Chris Toshok <toshok@ximian.com>
-
- * contact-editor/e-contact-editor.c (delete_cb): save ourselves a
- function call - call close_dialog instead of file_close_cb.
-
-2001-06-14 Jeffrey Stedfast <fejj@ximian.com>
-
- * gui/component/addressbook-component.c: Set the
- "expoted_dnd_types" to NULL in the folder_types.
-
-2001-06-11 Dan Winship <danw@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (search_override_check): Add a workaround for an EText bug.
- (e_select_names_completion_begin): Fix up the match scoring in the
- search_override case so the lines are offered in the correct
- order.
-
-2001-06-11 Christopher James Lahey <clahey@ximian.com>
-
- * gui/merging/Makefile.am (glade_DATA): Added
- e-card-merging-book-commit-duplicate-detected.glade here.
-
- * gui/merging/e-card-merging-book-commit-duplicate-detected.glade:
- Added this file. The GUI for asking whether to commit a modified
- card.
-
- * gui/merging/e-card-merging.c, gui/merging/e-card-merging.h
- (e_card_merging_book_commit_card): Added this function.
-
- * gui/widgets/e-addressbook-table-adapter.c
- (addressbook_set_value_at), gui/widgets/e-addressbook-util.c
- (commit_card_cb), gui/widgets/e-minicard.c (e_minicard_event): Use
- e_card_merging_book_commit_card instead of e_book_commit_card here.
-
-2001-06-11 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h:
- Made e_card_simple_get_id return const char *.
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Made
- e_card_get_id return const char *.
-
- * gui/component/e-cardlist-model.c (e_cardlist_model_add): Made id
- variable const here. Added a break to make it slightly more
- efficient.
-
- * gui/widgets/e-minicard.c, gui/widgets/e-minicard.h: Made
- e_minicard_get_card_id return const char *.
-
-2001-06-11 Christopher James Lahey <clahey@ximian.com>
-
- * backend/pas/pas-backend-file.c (entry_compare): Made this handle
- the "id" property in searches.
- (pas_backend_file_process_modify_card): Made id variable const
- here.
-
- * backend/pas/pas-backend-ldap.c (modify_card_handler): Made id
- variable const here.
-
-2001-06-11 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-book-listener.c,
- backend/ebook/e-book-listener.h, backend/ebook/e-book.c: Rolled
- back the change 2 ago, dated 06/11/2001 01:51 in CVS, involving
- e-book-listener.[ch] and e-book.c.
-
-2001-06-11 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-book.c (e_book_load_uri,
- e_book_get_supported_fields, e_book_authenticate_user,
- e_book_remove_card_by_id, e_book_add_vcard, e_book_commit_vcard,
- e_book_get_cursor, e_book_get_book_view, e_book_get_changes): Made
- it so that all of these functions queue their ops before calling
- their CORBA functions. This way, if the response is sent back
- before the CORBA function returns there's no problem. Added
- e_book_unqueue_op so that the op could be unqueued if the CORBA
- call fails.
-
-2001-06-11 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-book-listener.c, backend/ebook/e-book-listener.h
- (e_book_listener_unpop_response): Added this function to put a
- response back into the queue.
-
- * backend/ebook/e-book.c (e_book_check_listener_queue,
- e_book_queue_op): Handle the case where the op hasn't been queued
- yet when we get the response. In this case we unpop the response.
- Also, when queueing an op, we check to see if there are any
- responses waiting.
-
- * This change has been reverted.
-
-2001-06-11 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-compare.c, backend/ebook/e-card-compare.h
- (e_card_locate_match_full): Added this function to let you do
- slightly more complicated searches.
-
- * gui/merging/e-card-merging.c (e_card_merging_book_add_card): Use
- e_card_locate_match_full to check if the card exists in the book
- it's being added to instead of in the default book.
-
-2001-06-09 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (match_name): Removed unused email variable.
-
-2001-06-09 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-compare.c (use_common_book_cb): Null
- terminate the strv here.
- (e_card_locate_match): ref here instead of unref.
-
- * backend/ebook/e-card-simple.c (e_card_simple_get): Handle a NULL
- card here.
-
- * contact-editor/Makefile.am (INCLUDES), gui/widgets/Makefile.am
- (INCLUDES): Added addressbook/gui/merging here.
-
- * contact-editor/e-contact-quick-add.c (book_ready_cb),
- gui/component/addressbook-component.c (dnd_drop_book_open_cb),
- gui/widgets/e-addressbook-table-adapter.c
- (addressbook_append_row), gui/widgets/e-addressbook-util.c
- (add_card_cb), gui/widgets/e-addressbook-view.c
- (selection_received), gui/widgets/e-minicard-control.c
- (book_open_cb): Use e_card_merging_book_add_card instead of
- e_book_add_card here.
-
- * gui/Makefile.am (SUBDIRS): Added merging.
-
- * gui/component/Makefile.am (evolution_addressbook_LDADD),
- gui/widgets/Makefile.am (minicard_test_LDADD,
- minicard_widget_test_LDADD): Added libecardmerging.a here.
-
- * gui/merging/, gui/merging/.cvsignore, gui/merging/Makefile.am:
- New addressbook library.
-
- * gui/merging/e-card-duplicate-detected.glade: Glade file for
- duplicate detected dialog.
-
- * gui/merging/e-card-merging.c, gui/merging/e-card-merging.h: New
- files for detecting duplicates before adding and putting up a
- dialog if duplicates are found.
-
- * gui/widgets/e-minicard-view.c: Include e-addressbook-util.h
- here.
-
-2001-06-08 Chris Toshok <toshok@ximian.com>
-
- * contact-editor/e-contact-editor.c (e_contact_editor_new): remove
- the gtk_widget_show call...
- (e_contact_editor_show): and put it here.
-
- * contact-editor/e-contact-editor.h: add prototype for
- e_contact_editor_show.
-
- * gui/widgets/e-minicard.c (e_minicard_event): call
- e_addressbook_show_contact_editor.
- (card_modified_cb): call e_addressbook_error_dialog if status !=
- SUCCESS.
-
- * gui/widgets/e-minicard-view.c (e_minicard_view_event): call
- e_addressbook_show_contact_editor. also, use card_modified_cb as
- the commit_card callback.
-
- * gui/widgets/e-addressbook-view.c (table_double_click): clean
- this area up alot, call e_addressbook_show_contact_editor.
- (card_deleted_cb): call e_addressbook_error_dialog.
-
- * gui/widgets/e-addressbook-table-adapter.c
- (card_modified_cb): new function, call e_addressbook_error_dialog
- if the status != SUCCESS.
- (addressbook_set_value_at): use card_modified_cb as the callback
- for e_book_commit_card.
-
- * gui/widgets/Makefile.am (libeminicard_a_SOURCES): add
- e-addressbook-util.[ch].
-
- * gui/component/addressbook.c (new_contact_cb): use
- e_addressbook_show_contact_editor here.
-
-2001-06-05 Christopher James Lahey <clahey@ximian.com>
-
- * contact-editor/e-contact-editor.c (categories_clicked): Remove
- references to ECategoryMasterListWombat.
-
-2001-06-05 Jason Leach <jleach@ximian.com>
-
- * gui/component/select-names/e-select-names.c (remove_cb): Make
- this work when multiple names are selected then right
- click->Remove.
-
-2001-06-05 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card.c (e_card_set_arg): Copy dates as they come
- in.
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_changes_foreach_key, pas_backend_file_changes,
- pas_backend_file_process_remove_card,
- pas_backend_file_process_modify_card,
- pas_backend_file_build_all_cards_list, pas_backend_file_get_vcard,
- pas_backend_file_maybe_upgrade_db): memset DBTs to 0 before using
- them.
- (pas_backend_file_build_all_cards_list): Reindented.
-
- * contact-editor/contact-editor.glade: Replaced GnomeDateEdits
- with a custom widget that creates an EDateEdit.
-
- * contact-editor/e-contact-editor.c: Use an EDateEdit here instead
- of a GnomeDateEdit.
-
-2001-06-05 Jason Leach <jleach@ximian.com>
-
- (Fix bug #655: SelectNames doesn't let you remove addresses after
- you add them)
-
- * gui/component/select-names/e-select-names.c
- (section_right_click_cb): New function, provides a popup menu with
- just "Remove" in it.
- (remove_cb): New callback to do the remove.
- (e_select_names_add_section): Attach the "right_click" signal to
- the section_right_click_cb above.
-
-2001-06-05 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-manager.c
- (completion_handler): Change the completion handler to use the
- ECompletionMatch.
-
- * gui/component/select-names/e-select-names-completion.c
- General changes to convert for ECompletionMatch use.
- (emailify_match): Use extra sort keys in ECompletionMatch to let
- us ensure that the primary email address is always the first
- option, the secondary comes second, etc. There was no nice way to
- do this previously.
- (match_name): Removed code that adjusted score based on
- similarities between the "real name" and the e-mail address. It
- seemed like a good idea at the time, but produced unexpected and
- confusing results.
-
-2001-06-04 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-card-compare.c: Added. Code for testing
- if two ECards appear to pertain to the same contact (using loose
- matching rules, as opposed to requiring exact equality) and to
- query the addressbook for the "best match" to ECard.
-
-2001-06-03 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c (set_status_message): remove spew,
- and don't call the ShellView CORBA method if the interface doesn't
- exist (for whatever reason.)
-
- * gui/widgets/e-addressbook-view.c (e_addressbook_view_destroy):
- unref the EAddressbookModel.
- (create_minicard_view): unref the adapter.
- (card_added_cb): call e_book_error_dialog if status != SUCCESS.
- (card_modified_cb): same.
- (card_removed_cb): new function, and same.
- (delete_card_cb): pass card_removed_cb as the callback.
- (emit_status_message): new function, just emit status_message.
- (status_message): change to call emit_status_message.
- (card_deleted_cb): emit_status_message ("Done."), and call
- e_book_error_dialog if status != SUCCESS.
- (do_remove): pass view in the closure arg.
- (e_addressbook_view_delete_selection): emit status "Removing
- cards..." before starting the removal.
- (e_book_error_dialog): new function - pop up a (possibly) helpful
- message about why an operation failed.
-
- * gui/widgets/e-minicard-view-widget.c
- (e_minicard_view_widget_new): ref the EAddressbookReflowAdapter.
- (e_minicard_view_widget_destroy): unref the adapter.
- (e_minicard_view_widget_get_selection_model): if there isn't a
- minicard view return NULL.
-
- * gui/widgets/e-addressbook-table-adapter.c
- (e_addressbook_table_adapter_construct): ref the
- EAddressbookModel.
-
- * gui/widgets/e-addressbook-reflow-adapter.c
- (addressbook_finalize): rename this from addressbook_destroy, to
- reflect the method change.
- (e_addressbook_reflow_adapter_class_init): same.
- (e_addressbook_reflow_adapter_construct): ref the
- EAddressbookModel.
-
- * gui/widgets/e-addressbook-model.h: add editable_set flag.
-
- * gui/widgets/e-addressbook-model.c (writable_status): only record
- the writable state of the addressbook if the user hasn't set it.
- (e_addressbook_model_init): init editable_set to FALSE.
- (e_addressbook_model_set_arg): set editable_set to TRUE.
-
-2001-06-03 Ettore Perazzoli <ettore@ximian.com>
-
- * backend/ebook/Makefile.am (evolution_vcard_importer_LDADD): Move
- `$(DB3_LDADD)' before libeutil.
-
-2001-06-01 Ettore Perazzoli <ettore@ximian.com>
-
- * backend/ebook/Makefile.am (evolution_vcard_importer_LDADD): Add
- $(DB3_LDADD)'.
-
-2001-05-31 Christopher James Lahey <clahey@ximian.com>
-
- * backend/pas/Makefile.am (INCLUDES): Added db3 cflags.
-
- * backend/pas/pas-backend-file.c: Updated this to use db3.
-
-2001-05-31 Federico Mena Quintero <federico@ximian.com>
-
- * gui/widgets/e-addressbook-view.h (EAddressbookView): Added
- fields for the GalViewMenus and GalViewCollection; we need to keep
- them around while the component is active.
-
- * gui/widgets/e-addressbook-view.c
- (e_addressbook_view_setup_menus): Plug leak; unref the spec.
- Unref the factories. Do not unref the collection, since we need
- it for the signal emission (okay, so the views object adds a
- reference to it, but if we are interested in it we should keep a
- reference anyways).
- (e_addressbook_view_setup_menus): Create the collection and views
- on the EAddressbookView's fields so that we can keep them around.
- (e_addressbook_view_discard_menus): New function; gets rid of the
- collection and views objects.
-
- * gui/component/addressbook.c (control_activate_cb): Call
- e_addressbook_view_discard_menus().
-
-2001-05-31 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names.h (struct
- _ESelectNames): add the EAddressbookModel* and change the
- ETableModel's name to "adapter".
-
- * gui/component/select-names/e-select-names.c (set_book),
- (addressbook_model_set_uri): these two things take an
- EAddressbookModel* instead of an ETableModel now.
- (e_addressbook_create_ebook_table): don't case the
- EAddressbookModel* to ETableModel*, create an EAddressbookTableAdapter
- on the EAddressbookModel instead.
- (e_select_names_init): set e_select_names->adapter.
-
-2001-05-31 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-addressbook-model.c (remove_card): decrement
- data_count before emitting the card_removed signal, and break
- after we've removed the matching card.
- (e_addressbook_model_class_init): change signature of
- "card_removed" signal to match what we emit (and what is
- expected.)
-
- * gui/widgets/e-addressbook-view.c (e_addressbook_view_init): the
- signal name is "destroy", not "destroyed".
- (do_remove): new function, actually remove the card.
- (e_addressbook_view_delete_selection): get this working for both
- view types.
-
-2001-05-31 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c: Print Preview =>
- ContactsPrintPreview. Changed peter's change so that the node
- name is more in line with "Print.."'s
-
-2001-05-30 Peter Williams <peterw@ximian.com>
-
- * gui/component/addressbook.c: Use the correct path to the print
- preview menu item.
-
-2001-05-30 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c (cut_contacts_cb): new function, for
- the Cut verb.
- (copy_contacts_cb): new function, for the Copy verb.
- (paste_contacts_cb): new function, for the Paste verb.
- (select_all_contacts_cb): new function, for the Select All verb.
- (update_command_state): add handling for sensitivity of
- Cut/Copy/Paste/Select All.
-
- * gui/widgets/e-addressbook-view.c (e_addressbook_view_init): init
- the invisible and set up selection/destroy signals.
- (get_selection_model): new function, so we can get the
- ETableSelectionModel from either view type. makes lots of the
- other functions easier, since we can get the list of selected
- cards using the same code regardless of view type.
- (invisible_destroyed): new function.
- (selection_get): new function. convert the clipboard list to
- string.
- (selection_clear_event): new function - free up the list of
- ECards.
- (selection_received): if the selection data is valid and
- well-formed, add the corresponding cards to the ebook.
- (add_to_list): new function.
- (get_selected_cards): new function.
- (e_addressbook_view_cut): new function, implement in terms of
- _copy and _delete_selection.
- (e_addressbook_view_copy): claim ownership of the CLIPBOARD
- selection after saving the list of selected ECards.
- (e_addressbook_view_paste): call gtk_selection_convert.
- (e_addressbook_view_select_all): new function, using
- e_selection_model_select_all.
- (e_addressbook_view_can_print): re-implement in terms of
- get_selection_model.
- (e_addressbook_view_can_delete): same.
- (e_addressbook_view_can_cut): new function.
- (e_addressbook_view_can_copy): new function.
- (e_addressbook_view_can_paste): new function. hmm, always return
- TRUE here.
- (e_addressbook_view_can_select_all): new function.
-
- * gui/widgets/e-addressbook-view.h (struct _EAddressbookView): add
- selection stuff - the list of selected cards, and the GtkInvisible
- selection owner, and add prototypes for
- e_addressbook_view_[can]_{cut,copy,paste,select_all}.
-
- * gui/widgets/e-minicard-view-widget.h: add a prototype for
- e_minicard_view_widget_get_selection_model.
-
- * gui/widgets/e-minicard-view-widget.c
- (e_minicard_view_widget_get_selection_model): new function.
-
-2001-05-27 Dan Winship <danw@ximian.com>
-
- * gui/component/addressbook.c: #include
- "evolution-shell-component-utils.h" rather than "e-gui-utils.h"
- for e_pixmaps_update.
-
-2001-05-25 Peter Williams <peterw@ximian.com>
-
- * gui/component/Makefile.am: Reference libeshell.la instead of
- libeshell.a.
-
-2001-05-25 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-reflow-adapter.c (addressbook_height):
- Correct the height calculation here to not include the
- E_CARD_SIMPLE_FIELD_FAMILY_NAME since it won't be displayed.
-
- * gui/widgets/e-minicard.c (remodel): Changed this to continue to
- be more consistent and simpler.
-
-2001-05-23 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (view_destroy): fix strings such
- that ones that happening at the beginning or during an operation
- are followed by "..." and those that stop the operation are
- followed by "."
- (create_card_handler): same.
- (ldap_op_process_current): same, and also call _notify_complete if
- we can't connect to ldap server.
- (poll_ldap): same, and change "Polling for LDAP search result" to
- "Receiving LDAP search results"
-
- * backend/pas/pas-backend-file.c (pas_backend_file_search): call
- notify_status_message at the beginning of this function, and
- whenever we call _notify_complete.
-
-2001-05-23 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-addressbook-model.h: add sequence_complete_id to
- EAddressbookModel and stop_state_changed to
- EAddressbookModelClass. also, add prototype for
- e_addressbook_model_can_stop.
-
- * gui/widgets/e-addressbook-model.c (remove_book_view): disconnect
- from "sequence_complete", and set search_in_progress to FALSE.
- (sequence_complete): set search_in_progress to FALSE and emit
- "stop_state_changed."
- (e_addressbook_model_class_init): create the "stop_state_changed"
- signal.
- (e_addressbook_model_init): init stuff.
- (book_view_loaded): connect to "sequence_complete" signal.
- (book_view_loaded): set search_in_progress to TRUE and emit
- "stop_state_changed"
- (e_addressbook_model_stop): set search_in_progress to false, emit
- "stop_state_changed", and set our status to "Search Interrupted."
- (e_addressbook_model_can_stop): return search_in_progress.
-
- * gui/widgets/e-addressbook-view.c (e_addressbook_view_init):
- connect to the stop_state_changed signal on EAddressbookModel.
- (stop_state_changed): new function.
- (e_addressbook_view_can_stop): call e_addressbook_model_can_stop.
-
- * gui/component/addressbook.c (update_command_state): use
- e_addressbook_view_can_stop to set the sensitivity of the stop
- button.
-
-2001-05-22 Dan Winship <danw@ximian.com>
-
- * backend/ebook/e-book-listener.c (e_book_listener_check_queue):
- ref the listener for the duration of this function, since emitting
- "responses_queued" may cause it to be unreffed by its EBook in
- some cases, which could cause the second response_queue check to
- look at garbage data if it got destroyed.
- (e_book_listener_destroy): Call g_source_remove if idle_id is set.
-
-2001-05-22 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c: track the change in
- evolution-addressbook.xml's bonobo ui path's.
-
-2001-05-21 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c (change_view_type): update_view_type
- is gone, since the menu item is gone.
-
- * gui/widgets/e-addressbook-table-adapter.c (create_card): use
- e_table_model_rows_inserted here.
-
-2001-05-20 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook-config.c
- (addressbook_source_item_new): Removed an unused variable.
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_get_property_fn): Made text here non-const.
-
- * gui/component/select-names/e-select-names-popup.c
- (edit_contact_info_cb): Cast to a gpointer here.
-
- * gui/component/select-names/e-select-names.c
- (e_addressbook_create_ebook_table): Cast to E_TABLE_MODEL here.
-
-2001-05-18 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (match_name): Do a better job constructing match strings, so we
- never try to use a segment of the name that isn't there (resulting
- in ugly (null)'s in the string). Boost our score if some part of
- the name also matches the front part of the e-mail address, so the
- name match will always trump the e-mail match.
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_get_property_fn): Return the serialized EDestinations
- (rather than just a string w/ e-mail addresses) through the bonobo
- component's property bag.
-
- * gui/component/select-names/e-select-names-model.c
- (e_select_names_model_export_destinationv): Added. A convenience routine
- for serializing the model's EDestinations into a string.
-
- * gui/component/select-names/e-select-names-popup.c
- (add_html_mail): Added. Puts in a check menu item for whether or
- not the recipient wants HTML mail.
- (popup_menu_card): Add menu item for HTML mail. Enable edit
- contact info item.
- (popup_menu_nocard): Add menu item for HTML mail. Enable edit
- contact info item.
-
- * backend/ebook/e-book-util.c (e_book_use_local_address_book):
- Added. Fetches the local addressbook and caches it on the first
- call. This is meant to be an easy and efficient way to get at the
- local addressbook with the minimum of code.
- (e_book_query_address_locally): Added. Convenience code that
- does an e-mail only e_book_name_and_email_query against the
- local address book.
-
- * backend/ebook/e-destination.c
- (e_destination_set_html_mail_pref): Added. Allows the intended
- recipient's HTML mail preference to be manipulated.
- (e_destination_get_email_verbose): Added. Cleaned up to use
- e_destination_get_name.
- (e_destination_get_html_mail_pref): Added. Read the recipient's HTML mail
- preference. If the destination is linked to a card, the
- preference is taken from the card (unless it has been explicitly
- overridden by a called to e_destination_set_html_mail_pref).
- (e_destination_get_address_textv): Added. Form a unified address string
- from a NULL-terminated vector of EDestinations.
- (e_destination_export): Added. Serialize an EDestination to a string.
- (e_destination_import): Added. Unserialize a string to build an
- EDestination.
- (e_destination_exportv): Added. Serialize a NULL-terminated vector of
- EDestinations to a string.
- (e_destination_importv): Added. Unserialize a string to build a
- NULL-terminated vector of EDestinations.
-
- * gui/component/select-names/e-select-names-completion.c:
- Implemented local versions of g_strcasecmp and g_strncasecmp
- (which should really be in glib, I think...) for utf8, and used
- them to make this code utf8-safe.
-
-2001-05-17 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c (update_command_state): no more
- ContactFind command.
-
-2001-05-17 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-minicard-view-widget.c
- (e_minicard_view_widget_class_init): add our selection_change
- signal.
- (e_minicard_view_widget_realize): connect to the ESelectionModel's
- selection_changed signal.
- (e_minicard_view_widget_selected_count): new function.
- (selection_change): new function - emit our "selection_change"
- signal.
-
- * gui/widgets/e-minicard-view-widget.h (struct
- _EMinicardViewWidgetClass): add selection_change signal. also,
- add prototype for e_minicard_view_widget_selected_count.
-
- * gui/widgets/e-addressbook-view.c
- (e_addressbook_view_class_init): add our command_state_change
- signal.
- (e_addressbook_view_init): connect to the writable_status signal
- on the EAddressbookModel.
- (minicard_selection_change): new function - calls
- command_state_change.
- (create_minicard_view): connect to selection_change on the
- minicard_view so we know when to update command state.
- (table_selection_change): new function - calls
- command_state_change.
- (writable_status): new function - calls command_state_change.
- (command_state_change): new function - emits our
- "command_state_change" signal.
- (create_table_view): connect to the selection_change signal so we
- know to update the command state.
- (change_view_type): update the command state every time we change
- view types.
- (e_addressbook_view_can_create): new function.
- (e_addressbook_view_can_print): new function.
- (e_addressbook_view_can_delete): new function.
- (e_addressbook_view_can_stop): new function.
-
- * gui/widgets/e-addressbook-view.h (struct
- _EAddressbookViewClass): add command_state_change signal, and
- prototypes of functions the component can use to test the state of
- commands.
-
- * gui/widgets/e-addressbook-model.c (addressbook_destroy): unlink
- the writable_status signal on the EBook.
- (writable_status): new function.
- (e_addressbook_model_class_init): add our writable_status signal.
- (e_addressbook_model_init): init writable_status_id.
- (e_addressbook_model_set_arg): unlink the writable_status signal
- on the old EBook, and connect it on the new one.
-
- * gui/widgets/e-addressbook-model.h: add writable_status signal.
-
- * gui/component/addressbook.c (update_command_state): new
- function, set the sensitivity of the bonobo commands.
- (control_activate): update our command state immediately upon
- activating the control.
- (addressbook_factory_new_control): register command_state_change
- to update the commands.
-
-2001-05-15 Chris Toshok <toshok@ximian.com>
-
- * gui/search/e-addressbook-search-dialog.c
- (e_addressbook_search_dialog_init): initialize the model and
- adapter.
- (button_press): set on the model.
- (e_addressbook_search_dialog_new): same.
- (e_addressbook_search_dialog_set_arg): same.
- (e_addressbook_search_dialog_destroy): unref the model and
- adapter.
-
- * gui/search/e-addressbook-search-dialog.h (struct
- _EAddressbookSearchDialog): add our model and reflow adapter.
-
-2001-05-16 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-minicard-view.c: (e_minicard_view_destroy): Fixed
- up the lifetime of the drag_data_get signal a bit.
-
-2001-05-15 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-minicard-view.c (add_to_list): MinicardViewModel
- -> ReflowAdapter name change.
- (get_card_list): same.
- (e_minicard_view_drag_begin): same.
- (supported_fields_cb): model -> adapter.
- (adapter_changed): hook up signals and set the empty message on
- our adapter.
- (e_minicard_view_set_arg): add support for "adapter", and set
- model -> adapter.
- (e_minicard_view_get_arg): same.
- (disconnect_signals): no more status_message.
- (do_remove): track to use adapter.
- (e_minicard_view_class_init): add adapter arg, and remove
- status_message.
- (e_minicard_view_init): all the code here is in adapter_changed
- now.
-
- * gui/widgets/e-minicard-view.h (struct _EMinicardView):
- EMinicardViewModel -> EAddressbookReflowAdapter.
- (struct _EMinicardViewClass): get rid of status_message.
-
- * gui/widgets/e-minicard-view-widget.c
- (e_minicard_view_widget_class_init): remove the status_message
- signal.
- (e_minicard_view_widget_new): take the adapter as our argument,
- and store it away for when we create the view.
- (e_minicard_view_widget_realize): when we create the view just set
- the adapter field on it. also, don't connect to status_message.
-
- * gui/widgets/e-minicard-view-widget.h (struct
- _EMinicardViewWidget): add our adapter here, so we can pass it
- into the view when we create it.
- (struct _EMinicardViewWidgetClass): remove status_message.
-
- * gui/widgets/e-addressbook-view.c (status_message): new function,
- no more propagating status messages!
- (e_addressbook_view_init): create our model and conenct to its
- status_message signal.
- (book_writable_cb): set "editable" on the model, not our object.
- (e_addressbook_view_set_arg): same, but with "book" and "query" as
- well.
- (create_minicard_view): create our reflow adapter and pass it to
- the minicard view widget. also, call e_reflow_model_changed so
- it'll pick up any already present cards.
- (table_double_click): ADDRESSBOOK_MODEL -> TABLE_ADAPTER.
- (get_card_list_1): remove the cast, since we don't need it any
- longer.
- (table_right_click): ADDRESSBOOK_MODEL -> TABLE_ADAPTER.
- (table_drag_data_get): same.
- (create_table_view): create the table adapter, and use it as our
- ETableModel.
- (change_view_type): remove the status_message hook up and setting
- of query/book/editable.
- (e_addressbook_view_stop): just call e_addressbook_model_stop here
- instead of switching on the view type.
-
- * gui/widgets/e-addressbook-view.h (struct _EAddressbookView): add
- our EAddressbookModel.
-
- * gui/widgets/Makefile.am (libeminicard_a_SOURCES): add the
- adapter files, and remove e-minicard-view-model.[ch].
-
- * gui/widgets/e-minicard-view-model.[ch]: removed.
-
- * gui/widgets/e-addressbook-table-adapter.c: new file.
-
- * gui/widgets/e-addressbook-table-adapter.h: new file.
-
- * gui/widgets/e-addressbook-reflow-adapter.c: new file.
-
- * gui/widgets/e-addressbook-reflow-adapter.h: new file.
-
- * gui/widgets/e-addressbook-model.c: rework this class to now
- subclass from ETableModel anymore. It not subclasses from
- GtkObject, and we use table and reflow adapters to get at the
- data.
-
- * gui/widgets/e-addressbook-model.h: same.
-
-2001-05-14 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-minicard-view-model.c (remove_card): Fix a small
- error not decreasing the data_count here.
-
-2001-05-13 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.h: add prototype for
- addressbook_expand_uri.
-
- * gui/component/addressbook-component.c
- (destination_folder_handle_drop): create an EBook for
- @physical_uri.
- (dnd_drop_book_open_cb): actually add the dropped cards.
-
- * gui/component/addressbook.c (addressbook_expand_uri): abstract
- this code out from the set_prop method so we can use it in the
- component.
- (set_prop): call addressbook_expand_uri.
-
- * backend/ebook/e-card.c (e_card_load_cards_from_string): new
- function.
-
- * backend/ebook/e-card.h: add prototype for
- e_card_load_cards_from_string.
-
-2001-05-12 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-component.c
- (destination_folder_handle_drop): spew the data passed to us.
- (destination_folder_handle_motion): the suggested_action is not an
- ActionSet, but an Action, so don't or together multiple actions.
-
-2001-05-11 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-config.c (addressbook_source_dialog):
- correct bug causing the Ok button to never be enabled.
-
-2001-05-11 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-component.c (populate_context_menu):
- example.
-
-2001-05-11 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-minicard-view.c (e_minicard_view_drag_data_get):
- use e_card_list_get_vcard to build up the data to send.
- (e_minicard_view_init): connect to the model's drag_begin signal.
- (e_minicard_view_drag_begin): gather the list of cards being
- dragged and call gtk_drag_begin.
- (add_to_list): new function.
- (get_card_list): same.
- (disconnect_signals): disconnect the drag_data_get signal.
- (e_minicard_view_init): connect to the drag_begin signal on our
- model.
-
- * gui/widgets/e-minicard-view.h (struct _EMinicardView): change
- drag_card to drag_list.
-
- * gui/widgets/e-minicard-view-model.c (minicard_drag_begin): new
- function, emit our drag_begin signal.
- (addressbook_incarnate): connect to the item's drag_begin signal.
- (e_minicard_view_model_class_init): init our drag_begin signal.
-
- * gui/widgets/e-minicard-view-model.h: add drag_begin signal.
-
- * gui/component/addressbook-config.c (addressbook_source_dialog):
- always loop through all source types here, making LDAP first so
- it's forces as the first notebook item.
- (addressbook_config_auth_label): remove SASL case.
- (addressbook_source_edit_changed): same.
- (addressbook_source_item_new): flag the area of code that needs to
- go into the advanced dialog (if we add one before someone
- graciously redesigns the entire addressbook gui :)
-
-
- * gui/component/addressbook-storage.c (ldap_unparse_auth): remove
- SASL case.
- (ldap_parse_auth): same.
-
- * gui/component/addressbook-storage.h: make LDAP come first in our
- source type enumeration, and remove the SASL auth type.
-
-2001-05-11 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card.c (e_card_set_arg): If the name is set and
- the full_name or file_as haven't been yet, set them.
-
-2001-05-11 Christopher James Lahey <clahey@ximian.com>
-
- * backend/pas/pas-backend-file.c: Reordered the includes here.
- (string_to_dbt): The sleepycat libdb documentation suggests
- memseting the DBT to 0 so we do that here.
-
- * gui/widgets/e-minicard-view-model.c (addressbook_height): Skip
- the E_CARD_SIMPLE_FIELD_FAMILY_NAME field.
-
- * gui/widgets/e-minicard.c (remodel): Skip the
- E_CARD_SIMPLE_FIELD_FAMILY_NAME field.
-
-2001-05-11 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_connect): only
- check schema support if we've connected.
-
-2001-05-11 Chris Toshok <toshok@ximian.com>
-
- * contact-editor/e-contact-editor.c (enable_writable_fields):
- don't leak the ECard or ECardSimple.
-
-2001-05-08 Iain Holmes <iain@ximian.com>
-
- * backend/ebook/GNOME_Evolution_Addressbook_VCard_Importer.oaf.in:
- Renamed the GnomeCard_Importer.oaf.in to this, and change the IID.
-
- * Makefile.am: Rename all the GnomeCard to VCard.
-
- * evolution-vcard-importer.c: Make the GnomeCard a generic
- vcard importer.
-
-2001-05-08 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/Makefile.am (libebookinclude_HEADERS): Removed
- e-card-pairs.h since we're not using it.
-
- * backend/ebook/e-book-view.c (e_book_view_check_listener_queue):
- Added break; to default: case here.
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h:
- Added changed variable so as to avoid sync_card when possible.
- (e_card_simple_destroy): Free all the data here properly.
- (e_card_simple_get_arg): Slight simplification here.
- (fill_in_info, e_card_simple_arbitrary_foreach,
- e_card_simple_get_arbitrary): Call e_card_free_empty_lists here to
- save a bit of memory.
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Fixed up
- includes a bit.
- (e_card_list_get_vcard, e_card_list_send): Added these functions
- for acting on a group of cards.
- (parse_org): Cleaned up this function a bit.
- (e_card_free_empty_lists): Added this function to delete
- unnecessary ELists and save a bit of memory.
- (e_v_object_get_child_value): Made this return NULL if not found
- instead of g_strdup("").
-
- * contact-editor/e-contact-save-as.c,
- contact-editor/e-contact-save-as.h (e_contact_list_save_as): Added
- this function to save multiple contacts.
-
- * gui/widgets/Makefile.am: Commented out reflow test.
- (libeminicard_a_SOURCES): Added e-minicard-view-model.c and
- e-minicard-view-model.h.
-
- * gui/widgets/e-minicard-view-model.c,
- gui/widgets/e-minicard-view-model.h: Model for use in
- EMinicardView.
-
- * gui/widgets/e-minicard-view.c, gui/widgets/e-minicard-view.h:
- Reworked this to use the new EReflow stuff.
-
- * gui/widgets/e-minicard.c (e_minicard_event): Doesn't handle
- right click menus now. Emits a signal on the parent canvas item
- instead.
-
- * printing/e-contact-print-envelope.c,
- printing/e-contact-print-envelope.h
- (e_contact_print_envelope_list_dialog_new): Added this function to
- print multiple envelopes (only prints first for now.)
-
- * printing/e-contact-print.c, printing/e-contact-print.h
- (e_contact_print_card_list_dialog_new): Added this function to
- print multiple cards. Only prints the first for now.
-
-2001-05-07 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-component.c (remove_folder): flesh out
- the function more. It should work now, but there's no way to
- invoke this method from the ui at the moment, heh.
-
-2001-05-07 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook.c (book_open_cb): Use a different
- error message in the ldap support/no ldap support/file cases.
-
-2001-05-07 Gediminas Paulauskas <menesis@delfi.lt>
-
- * gui/component/addressbook.c: use define from
- widgets/misc/e-filter-bar.h instead of own enumeration and search menu
- names.
-
- * gui/component/Makefile.am, gui/component/select-names/Makefile.am:
- removed EVOLUTION_VERSION.
-
-2001-05-04 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-component.c (remove_folder): un-#if 0
- this.
- (xfer_folder): add skeleton code to validate xfer request. always
- notifies with PERMISSION_DENIED at present.
- (populate_context_menu): un-#if 0 this.
- (get_dnd_selection): same.
- (destination_folder_handle_motion): new function.
- (destination_folder_handle_drop): new function.
- (factory_fn): create a EvolutionShellComponentDndDestinationFolder
- interface, and add it to our shell component.
-
-2001-05-04 JP Rosevear <jpr@ximian.com>
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_process_get_book_view): init change_id to NULL
-
-2001-05-02 JP Rosevear <jpr@ximian.com>
-
- * gui/component/addressbook.c (addressbook_view_free): unref the
- book if the view is being destroyed
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_process_get_book_view): unref the book_view when
- we are finished, it is only interesting if someone else has reffed
- it now (weak reference)
- (pas_backend_file_add_client): unref the book for the same reason
- as above
-
- * Fixes bug #2255
-
-2001-04-30 JP Rosevear <jpr@ximian.com>
-
- * backend/pas/pas-backend-file.c (vcard_matches_search): if the
- view does not contain a search context, the result is by default
- false fixes #2470
-
-2001-04-25 Dan Winship <danw@ximian.com>
-
- * gui/component/addressbook-factory.c (main): Remove call to
- unicode_init.
-
-2001-04-23 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/e-address-popup.c: Lots of code has been
- simplified here.
- (e_address_popup_factory_new_control): Rather than directly pop
- our control up in a window (via the e_address_popup_popup
- function, which is now gone), just return the widget and let the
- caller do the popping. This works better, since it means we don't
- have to work around the vagaries of bonobo focus & event handling.
- (e_address_popup_set_name): Refresh when both name & email have
- been set, rather than checking a stupid counter.
- (e_address_popup_set_email): Ditto.
-
-2001-04-22 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook-storage.c
- (addressbook_storage_clear_sources): Added save_source_data here.
-
-2001-04-21 Jon Trowbridge <trow@ximian.com>
-
- * contact-editor/e-contact-quick-add.c (clicked_cb): Properly
- convert to utf8. (Bug #2256)
- (build_quick_add_dialog): Properly convert from utf8. (Bug #2256)
-
-2001-04-16 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-destination.c (e_destination_get_name): Added.
-
- * gui/component/select-names/e-select-names.c
- (real_add_address_cb): Use e_select_names_model_append. It's
- nicer.
-
- * gui/component/select-names/e-select-names-model.c
- (e_select_names_model_append): Added.
-
- * gui/component/select-names/e-select-names-completion.c
- (book_query_process_card_list): Filter out completion matches that
- don't have an associated e-mail address.
- (book_query_score): Give a bonus to the primary address, so that
- it always comes up first in the completion results.
-
- * gui/component/e-address-popup.c (e_address_popup_refresh_names):
- Convert utf8 strings into gtk strings before displaying.
-
-2001-04-14 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-book-view-listener.c,
- backend/ebook/e-book-view-listener.h: Added the function
- e_book_view_listener_stop to tell the book view listener to stop
- sending signals.
-
- * backend/ebook/e-book-view.c (e_book_view_destroy): Tell the
- EBookViewListener to stop when we're destroyed.
-
- * backend/pas/pas-backend-file.c (view_destroy,
- pas_backend_file_process_get_book_view,
- pas_backend_file_process_get_changes): Cleaned these up a bit
- using bonobo_object_ref and bonobo_object_unref.
- (pas_backend_file_process_get_book_view,
- pas_backend_file_process_get_changes): bonobo_object_release_unref
- the EBookListener here.
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_process_get_book_view): Cleaned this up a bit
- using bonobo_object_ref. Make sure to unref the listener when
- we're done with it. Put the new book_view in the list before
- telling the book_listener that it's ready.
-
- * backend/pas/pas-book-view.c (pas_book_view_construct): Cleaned
- this up a bit using bonobo_object_dup_ref.
- (pas_book_view_destroy): Cleaned this up a bit using
- bonobo_object_release_unref.
-
- * backend/pas/pas-book.c (pas_book_queue_get_book_view,
- pas_book_queue_get_changes): bonobo_object_dup_ref here instead of
- just duplicating.
-
-2001-04-14 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-book-listener.c
- (impl_BookListener_respond_get_cursor): Ref the cursor here when
- we receive it.
- (impl_BookListener_respond_get_view,
- impl_BookListener_respond_get_changes): Ref the book_view here
- when we receive it.
- (impl_BookListener_respond_open_book): Ref the book here when we
- receive it.
- (e_book_listener_destroy): Unref the objects in our queue here.
-
- * backend/ebook/e-book-view.c (e_book_view_construct): Cleaned
- this up using bonobo_object_dup_ref.
- (e_book_view_destroy): Cleaned this up using
- bonobo_object_release_unref.
-
- * backend/ebook/e-book.c (e_book_do_response_get_cursor,
- e_book_do_response_get_view, e_book_do_response_get_changes,
- e_book_unload_uri): Cleaned this up using
- bonobo_object_release_unref.
-
-2001-04-13 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_get_property_fn): Get the ESelectNamesModel from the
- widget's text model instead of storing it as a gtk_object_set_data
- since it may change.
-
-2001-04-12 Jason Leach <jasonleach@usa.net>
-
- * backend/pas/pas-backend-file.c (INITIAL_VCARD): Update the Voice
- and Fax phone numbers too, finishing off bug #1667.
-
-2001-04-11 Christopher James Lahey <clahey@ximian.com>
-
- * backend/pas/pas-backend-file.c (INITIAL_VCARD): Update the built
- in VCard.
-
-2001-04-12 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (local_record_from_ecard): put the
- business address into the pilot record as that is what we put into
- the desktop record
- (ecard_from_remote_record): set both the address label and
- delivery address to avoid bad parser guessing, fixes #2143
-
- * backend/ebook/e-card-types.h: remove deprecated pilot code
-
- * backend/ebook/e-card.c: ditto
-
- * backend/ebook/e-card.h: ditto
-
-2001-04-11 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (local_record_from_ecard): Don't add
- more than five phone numbers and set the remaining blank entries
- to some reasonable defaults
-
-2001-04-11 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-simple.h: Added
- E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING.
-
- * gui/component/addressbook-component.c (accepted_dnd_types):
- Fixed a warning here.
-
- * gui/widgets/e-addressbook-model.c: Modified this to have more
- columns, but not let them be edited if they're not a simple
- string.
-
- * gui/widgets/e-minicard-view.c (e_minicard_view_init): Fixed a
- warning and a memory leak here.
-
-2001-04-10 Gediminas Paulauskas <menesis@delfi.lt>
-
- * backend/ebook/evolution-gnomecard-importer.c: added missing #include.
- * contact-editor/e-contact-editor.c (_arrow_pressed): popup menu items were
- not translated after selecting one of them.
- * gui/widgets/e-addressbook-view.c: mark popup menu items with N_().
- Updated list[] for translators.
- * gui/widgets/e-minicard.c: same.
- * gui/widgets/e-minicard-view-widget.c (e_minicard_view_widget_set_arg): fix warning
- for "editable" arg.
- * gui/widgets/e-minicard-view.c: convert "empty_message" to utf8.
-
-2001-04-09 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-component.c (remove_folder): stubbed,
- #if 0'ed
- (xfer_folder): same.
- (populate_context_menu): same.
- (get_dnd_selection): same.
- (factory_fn): add the accepted drag types ("text/x-vard") to
- folder_types.
-
-2001-04-09 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-minicard.c (e_minicard_event): on BUTTON_PRESS: if
- it's button 1, store the button x, y, and set drag_button_down to
- TRUE. on BUTTON_RELEASE: always set drag_button_down to FALSE.
- for MOTION_NOTIFY: initiate drag if the pointer has moved 3
- pixels.
-
- * gui/widgets/e-minicard.h (struct _EMinicard): add fields for
- button x, y, and a bit for if the button has been pressed so we
- can tell whether a motion should be a drag.
- (struct _EMinicardClass): add drag_begin signal.
-
- * gui/widgets/e-minicard-view.c (e_minicard_view_drag_begin): new
- function, starts the drag.
- (book_view_loaded): connect the "drag_data_get" signal.
- (e_minicard_view_drag_data_get): new function.
-
- * gui/widgets/e-minicard-view.h (struct _EMinicardView): add
- drag_card and id for canvas_drag_data_get_id.
-
- * gui/widgets/e-addressbook-view.c (table_drag_data_get): new
- function.
- (create_table_view): add d&d stuff.
-
-2001-04-08 Chris Toshok <toshok@ximian.com>
-
- * printing/e-contact-print.c: add #include <sys/types.h> since
- gnome-print.h uses time_t without including it. this really
- should be fixed in gnome-print.
-
-2001-04-08 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_add_client):
- make sure to notify new clients to the writable status of an
- already open (and authenticated) book.
-
-2001-04-04 Kjartan Maraas <kmaraas@gnome.org>
-
- * contact-editor/e-contact-editor.[ch]: Fix headers.
- * component/addressbook-storage.c: Same here.
- * gui/search/e-addressbook-search-dialog.c: Same here.
- * gui/widgets/e-addressbook-view.c: Same here.
- * gui/widgets/e-minicard-label.c: Same here.
- * gui/widgets/e-minicard-view-widget.c: Same here.
- * gui/widgets/e-minicard-view.c: Same here.
- * gui/widgets/e-minicard-widget-test.c: Same here.
- * gui/widgets/e-minicard-widget.c: Same here.
- * gui/widgets/e-minicard.c: Same here.
- * gui/widgets/test-minicard-label.c: Same here.
-
-2001-04-03 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (table_double_click): Fixed a
- crash here.
-
-2001-04-03 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-model.c (COLS): Made this table model
- more consistent in the number of columns it has.
- (addressbook_append_row): Fixed this function. We removed the col
- offset.
-
-2001-04-02 Iain Holmes <iain@ximian.com>
-
- * backend/ebook/evolution-gnomecard-importer.c (importer_init): Shut
- down and unregister the factory on exit.
-
-2001-04-01 Gediminas Paulauskas <menesis@delfi.lt>
-
- * contact-editor/contact-editor.glade: changed icon to
- evolution-contacts-plain.png.
- * gui/component/addressbook.c: use new pixmap cache. Added icon for new
- contact, print, print preview, changed filenames of renamed icons.
-
-2001-03-31 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (real_add_address_cb): Call e_select_names_model_clean after
- adding address. This should deal with the bug reports related
- to stray commas.
-
- * gui/component/select-names/e-select-names-model.c
- (e_select_names_model_clean): Added. Remove all empty destinations.
-
- * backend/ebook/e-destination.c (e_destination_is_empty): Added. Check
- if an EDestination is in essentially a null state.
-
-2001-03-30 Christopher James Lahey <clahey@ximian.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_add_client):
- Tell new clients that are added whether they're writable.
-
-2001-03-29 Jon Trowbridge <trow@ximian.com>
-
- * printing/e-contact-print.c: Added #include <libgnome/gnome-paper.h>
-
- * printing/e-contact-print-envelope.c: Added #include <time.h>
- and #include <libgnome/gnome-paper.h>
-
-2001-04-03 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (match_email): Better handle matching of "nameless" contacts.
-
- * backend/ebook/e-destination.c (e_destination_get_string): Better
- handle the case of a "nameless" contact.
-
-2001-03-29 Kjartan Maraas <kmaraas@gnome.org>
-
- * *.*: Clean up #includes. Replace <gnome.h>, <bonobo.h> and
- <gtk/gtk.h> with more finegrained headers where needed.
-
-2001-03-28 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card.c (e_card_set_arg): Fixed some crashes.
-
-2001-03-28 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names-table-model.c
- (fill_in_info): Use E_CARD_SIMPLE_FIELD_NAME_OR_ORG instead of
- getting the NAME and then the ORG. That way if we expand
- NAME_OR_ORG, this will use it.
-
- * gui/component/select-names/e-select-names.c
- (e_addressbook_create_ebook_table, SPEC): Use the correct column
- in the SPEC.
-
-2001-03-25 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_seq_complete_cb): Rather than starting
- the pending query by directly calling
- e_select_names_completion_do_query, call
- e_completion_begin_search. Circumventing the ECompletion API was
- causing it to get confused in some cases.
-
-2001-03-23 Jon Trowbridge <trow@ximian.com>
-
- * gui/widgets/e-minicard-widget.c (e_minicard_widget_set_card):
- Added. Call me old-fashioned, but I just prefer to have a real
- API rather than doing everything via gtk_object_get/set-type
- calls.
- (e_minicard_widget_set_arg): Changed to call
- e_minicard_widget_set_card.
-
- * backend/ebook/e-book-util.c: Small changes to get rid of
- compiler warnings. (Casting out const, removed unused variables,
- etc.) Removed some debugging messages.
-
- * gui/component/addressbook-factory.c (main): Added call
- to e_address_popup_factory_init.
-
- * gui/component/e-address-popup.c: Added. A popup gadget that is
- invoked (as a bonobo control) when an address is left-clicked in
- the mailer. The addressbook is queries, and the address is either
- displayed as a minicard (if it already exists) or in a "generic
- format". A button is provided for editting/adding the contact.
- Some of the semantics of this widget are a bit... non-standard,
- because of bonobo issues. I can't really seem to replicate
- popup-menu behavior because of how bonobo propogates events, etc.
- so I've tried to produce something that I think is non-annoying.
- YMMV.
-
-2001-03-22 Iain Holmes <iain@ximian.com>
-
- * backend/ebook/evolution-gnomecard-importer.c: Update to the new
- IDL.
-
-2001-03-20 Miguel de Icaza <miguel@ximian.com>
-
- * gui/component/addressbook.c (update_pixmaps): Added artwork from
- Jakub.
-
-2001-03-19 Christopher James Lahey <clahey@ximian.com>
-
- * Merged branch:
-
-2001-03-14 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-minicard-view.c: Call
- e_selection_model_simple_insert_rows and
- e_selection_model_simple_delete_rows instead of
- e_selection_model_simple_insert_row and
- e_selection_model_simple_delete_row.
-
-End of branch
-
-2001-03-17 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c: Brutally
- refactored to boost performance in large-addressbook situations.
- These fixes give accepable performance (even with the suboptimal
- pas-backend-file searching) using tigert's addressbook-of-death.
-
- * backend/pas/pas-backend-file.c (pas_backend_file_search):
- Start feeding query matches back to the caller before the
- entire search is complete; this gives us some "instant feedback"
- rather than causing evolution to totally lock up...
-
- * backend/ebook/e-book.c (e_book_queue_op): Tag all queued ops.
- (e_book_cancel_op): Added. Search for a pending op with a given
- tag, and mark it as inactive.
- (e_book_do_response_get_cursor): Don't execute callback if this
- operations has been cancelled.
- (e_book_do_response_get_view): Ditto.
- (e_book_do_response_get_changes): Ditto.
- (e_book_do_response_get_supported_fields): Ditto.
- (e_book_get_supported_fields): Return an operation tag (that can
- be used to cancel the operation) rather than just TRUE/FALSE.
- Zero is always an invalid tag and is returned in the case of an
- error, so this shouldn't break any code that looked at the return
- value (unless it did so in a particularly stupid way, of course).
- (e_book_get_cursor): Ditto.
- (e_book_get_book_view): Ditto.
- (e_book_get_changes): Ditto.
- (e_book_cancel): Added. Cancel a pending operation. (Basically
- a call to e_book_cancel_op with error checking, etc.)
-
- * backend/ebook/e-book-types.h: Added E_BOOK_STATUS_CANCELLED.
-
-2001-03-17 Chris Toshok <toshok@ximian.com>
-
- * backend/ebook/e-book-listener.c
- (e_book_listener_queue_writable_status): new function.
- (impl_BookListener_report_writable): new function.
- (e_book_listener_get_epv): fill in epv->notifyWritable.
-
- * backend/ebook/e-book-listener.h: add writable status entries.
-
- * backend/ebook/e-book.c (e_book_do_writable_event): new function.
- (e_book_check_listener_queue): add WritableStatusEvent to the
- switch.
- (e_book_class_init): register writable_status signal.
-
- * backend/ebook/e-book.h: add writable_status signal.
-
- * backend/idl/addressbook.idl: add notifyWritable method to
- BookListener.
-
- * gui/widgets/e-minicard.c (e_minicard_class_init): add "editable"
- arg.
- (e_minicard_init): init editable.
- (e_minicard_set_arg): loop over the minicard fields setting their
- "editable".
- (e_minicard_get_arg): add editable.
- (supported_fields_cb): use editable when creating the
- contact_editor.
- (add_field): set "editable" when creatin the e_minicard.
-
- * gui/widgets/e-minicard.h (struct _EMinicard): add "editable".
-
- * gui/widgets/e-minicard-view.c (e_minicard_view_class_init): add
- editable arg.
- (e_minicard_view_init): init editable.
- (create_card): pass editable to e_minicard canvas item.
- (e_minicard_view_set_arg): bit of a hack - loop over all the
- canvas items setting their "editable."
- (e_minicard_view_get_arg): add editable.
- (supported_fields_cb): use editable when creating the contact
- editor.
-
- * gui/widgets/e-minicard-view.h (struct _EMinicardView): add
- "editable."
-
- * gui/widgets/e-minicard-view-widget.c
- (e_minicard_view_widget_class_init): add "editable" field.
- (e_minicard_view_widget_init): init editable to FALSE.
- (e_minicard_view_widget_set_arg): save editable, and pass it along
- the e-minicard-view.
- (e_minicard_view_widget_realize): same.
- (e_minicard_view_widget_get_arg): add editable.
-
- * gui/widgets/e-minicard-view-widget.h (struct
- _EMinicardViewWidget): add "editable" field.
-
- * gui/widgets/e-minicard-label.h (struct _EMinicardLabel): add
- "editable" field.
-
- * gui/widgets/e-minicard-label.c (e_minicard_label_class_init):
- add "editable" arg.
- (e_minicard_label_set_arg): editable, set it on the e_text too.
- (e_minicard_label_get_arg): editable.
- (e_minicard_label_construct): set the "editable" field when we
- create the e_text cavas item
-
- * gui/widgets/e-addressbook-view.c (e_addressbook_view_init):
- default editable to FALSE.
- (book_writable_cb): new function, set our editable field and
- gtk_object_set it on the active view.
- (e_addressbook_view_set_arg): set the active view's editable when
- we set the view's book, and connect the "writable_status" signal
- to book_writable_cb.
- (change_view_type): same.
- (supported_fields_cb): use our "editable" when creating the
- contact editor.
-
- * gui/widgets/e-addressbook-view.h (struct _EAddressbookView): add
- editable field.
-
- * gui/widgets/e-addressbook-model.c (e_addressbook_model_init):
- change the default of editable to FALSE.
-
- * backend/pas/pas-book.c (pas_book_report_writable): new function.
-
- * backend/pas/pas-book.h: prototype for pas_book_report_writable.
-
- * backend/pas/pas-backend-file.c (pas_backend_file_load_uri): if
- we open the file O_RDWR (or create it) report it as writable. if
- we can't open it as O_RDWR, try opening it read-only before we
- attempt to create it.
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_process_authenticate_user): if we authenticate
- successfully, grant write permissions (this is lacking but there's
- really nothing we can do to determine the extent of the access
- afforded a user.)
-
-
-2001-03-15 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/e-address-widget.c: Added addressbook querying and
- "cardification" functions, which are turned off by default for now
- because of addressbook bugs. Added a popup menu option to turn
- queries on, so that others can enjoy the thrill of massive flaming
- death.
-
- * gui/component/addressbook-factory.c (main): Made warnings always
- be fatal.
-
- * backend/pas/pas-book-view.c: Added some debugging spew.
-
- * backend/pas/pas-backend-file.c (pas_backend_file_search): Added
- a little experimental code to try to make file searches scale
- better. #if 0/#endif-ed out for now.
-
- * contact-editor/e-contact-quick-add.c: #included e-book-util.h.
-
- * backend/ebook/e-card.c (e_card_name_match_string): Added.
- Looser name-matching function.
- (e_card_email_match_string): Added. Loose e-mail matching.
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_check_queue): Added code to cause us to
- abort rather than get trapped in a 100%-CPU-consuming loop in
- certain situations. Now we just need to figure out how to avoid
- these situations altogether.
-
- * backend/ebook/e-book-util.c: Added. Now contains the simple
- query stuff and the open local addressbook functions.
-
- * backend/ebook/e-book.c: Moved simple query stuff and open local
- addressbook functions into e-book-util.c.
-
-2001-03-15 Dan Winship <danw@ximian.com>
-
- * gui/widgets/e-minicard-label.c (e_minicard_label_set_arg):
- * gui/widgets/e-minicard.c (e_minicard_set_arg, e_minicard_event):
- Update arguments to e_canvas_item_grab_focus.
-
-2001-03-13 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/addressbook.c (update_pixmaps): Fix a warning
- here.
-
-2001-03-13 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/Makefile.am (minicard_label_test_LDADD): Change to
- ld order from Greg Williams.
-
-2001-03-13 Christopher James Lahey <clahey@ximian.com>
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_process_get_book_view): Moved where we call
- pas_book_respond_get_book_view.
-
-2001-03-12 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c: add E_STRING_PROP for
- categories.
-
- * backend/pas/evolutionperson.schema: add categories attribute.
-
- * backend/ebook/e-card-simple.c (field_data): add
- E_CARD_SIMPLE_FIELD_CATEGORIES.
-
- * backend/ebook/e-card-simple.h: add
- E_CARD_SIMPLE_FIELD_CATEGORIES.
-
-2001-03-12 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-minicard.c (supported_fields_cb): add is_read_only
- param.
-
- * gui/widgets/e-minicard-view.c (supported_fields_cb): add
- is_read_only param.
-
- * gui/widgets/e-addressbook-view.c (supported_fields_cb): add
- is_read_only param.
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_activate_obj): add is_read_only param.
- also, include a little policy here and make it TRUE, as the user
- shouldn't be editting in this context anyway (imo).
-
- * gui/component/addressbook.c (supported_fields_cb): add
- is_read_only param.
-
- * contact-editor/test-editor.c (main): add is_read_only param.
-
- * contact-editor/e-contact-editor.c (set_read_only): new function,
- that either enables or disables all the text fields, combo boxes,
- and some buttons, depending on the state of is_read_only.
- (e_contact_editor_class_init): add read/write arg "is_read_only".
- (full_name_clicked): set the is_read_only of the fullname dialog
- to the editor's.
- (full_addr_clicked): same.
- (e_contact_editor_new): add is_read_only param, that gets set
- along with the other params.
- (e_contact_editor_set_arg): add setter for is_read_only.
- (e_contact_editor_get_arg): add getter for is_read_only.
- (_phone_arrow_pressed): change TRUE to !editor->is_read_only for
- entry.
- (_email_arrow_pressed): same.
- (_address_arrow_pressed): same.
- (enable_writable_fields): same.
-
- * contact-editor/e-contact-editor-fullname.c
- (e_contact_editor_fullname_class_init): add read/write arg
- "is_read_only".
- (e_contact_editor_fullname_set_arg): add setter for is_read_only
- that enables/disables all the entries/combos.
- (e_contact_editor_fullname_get_arg): add getter for is_read_only.
-
- * contact-editor/e-contact-editor-fullname.h (struct
- _EContactEditorFullname): add is_read_only flag.
-
- * contact-editor/e-contact-editor-address.c
- (e_contact_editor_address_class_init): add read/write arg
- "is_read_only".
- (e_contact_editor_address_set_arg): add setter for is_read_only
- that disables/enables all the entries/combos.
- (e_contact_editor_address_get_arg): add getter for is_read_only.
-
- * contact-editor/e-contact-editor-address.h (struct
- _EContactEditorAddress): add is_read_only flag.
-
-2001-03-13 Iain Holmes <iain@ximian.com>
-
- * backend/ebook/Makefile.am: Change the importer includes around a bit.
-
- * backend/ebook/evolution-gnomecard-importer.c: Correctly add the includes.
-
-2001-03-09 JP Rosevear <jpr@ximian.com>
-
- * conduit/Makefile.am: PISOCK_INCLUDEDIR has become
- PISOCK_CFLAGS in gnome-pilot.m4 and remove capplet foo
-
-2001-03-11 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-book.c (e_book_simple_query): Added. A
- simplified, cancellable query mechanism that lets you avoid
- dealing with EBookView.
- (e_book_simple_query_cancel): Added. Cancels a running query.
-
- * backend/ebook/e-book-types.h: Add enum EBookSimpleQueryStatus.
-
-2001-03-08 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-popup.c
- (quick_add_cb): Switched to use e_contact_quick_add_free_form.
- Removed debugging code, hopefully without introducing any bugs
- in the process.
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_insert_length): Fix bug with commas
- inside of name/address combos. As long as the comma is inside of
- quotes, it will be treated as part of the name rather than as a
- break between addresses.
-
- * gui/component/select-names/e-select-names-completion.c
- (match_nickname): Use e_card_name_to_string for nickname match
- strings.
- (match_email): Use e_card_name_to_string for email match strings.
- (e_select_names_completion_begin): Strip quotes out of query text,
- so we don't produce malformed sexps.
- Added William Blake quote easter egg.
-
- * contact-editor/e-contact-quick-add.c: Further attempts to fix...
- mostly unsuccessful.
- (e_contact_quick_add_free_form): Added. Takes a single string
- and tries to parse out (using some simple, loose rules) the
- name and e-mail -- then calls e_contact_quick_add. An attempt to
- get the computer to automatically Do The Right Thing.
-
- * backend/ebook/e-book.c: Fixed some broken indentation. Yes, I'm
- anal.
-
- * gui/component/GNOME_Evolution_Addressbook.oafinfo: Added oaf_server
- info for EAddressWidget.
-
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: Added oaf_server
- info for EAddressWidget.
-
- * gui/component/addressbook-factory.c (main): Add call to
- e_address_widget_factory_init.
-
- * gui/component/e-address-widget.h:
- * gui/component/e-address-widget.c: Added. A little widget (and a
- Bonobo control, BTW) for displaying addresses, with a left-click
- menu. Used to display addresses in the mail viewer (as embedded
- GtkHTML objects, replacing the text previously used). Still quite
- incomplete.
-
-2001-03-08 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook-component.c (factory_fn): Specify a
- NULL `EvolutionShellComponentGetDndSelectionFn'.
-
-2001-03-06 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_insert_length): Fix glitch with
- inserting comma-delimited stuff when length > 1.
-
-2001-03-06 Jon Trowbridge <trow@ximian.com>
-
- * backend/ebook/e-book.c (e_book_load_local_address_book): Added.
- Just encapsulates opening
- file://~username/evolution/local/Contactes/addressbook.db, so that
- path doesn't need to be hardwired in throughout the code.
-
-2001-03-06 Benjamin Kahn <xkahn@cybersites.com>
-
- * contact-editor/e-contact-quick-add.c (clicked_cb):
- Added the third argument to e_contact_editor_new. (Cheated
- and send NULL for the field argument, which is probably
- troublesome. It will be fixed soon by either clahey or
- toshok.)
-
-2001-03-06 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-model.c
- (e_select_names_model_replace): Fix a reference counting bug.
-
- * gui/component/select-names/e-select-names-manager.c (popup_cb):
- A callback for creating the appropriate popup by calling
- e_select_names_popup.
- (e_select_names_manager_create_entry): Connect popup_cb to the
- entry's popup signal
-
- * gui/component/select-names/e-select-names-popup.c: Added. Code
- for popup right-click menus for recipient entries. Still a bit
- incomplete.
-
- * backend/ebook/e-destination.c (e_destination_get_email_num):
- Added.
-
- * contact-editor/e-contact-quick-add.c: Added. Some code and a
- dialog for very quickly adding entries to the address book.
- Still not fully working.
-
-2001-03-04 Christopher James Lahey <clahey@ximian.com>
-
- * backend/ebook/e-card-simple.c: Cleaned up the formatting in this
- file a bit.
-
- * contact-editor/e-contact-editor.c (e_contact_editor_set_arg):
- Made it so that passing in NULL to the writable_fields arg sets
- the set of writable fields to the empty set.
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_activate_obj): Pass NULL as the
- writable_fields argument here.
-
- * gui/widgets/e-addressbook-model.c: Don't offset by one here.
- This way we will get the file_as field as one of our
- ETableColumns.
-
- * gui/widgets/e-addressbook-view.c (SPEC): Updated this for the
- changes in ECardSimple.
-
- * gui/widgets/e-minicard.c (remodel): Don't remodel if the item
- isn't realized.
-
-2001-03-02 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c: doh, track renaming of
- objectclass from evolvePerson to evolutionPerson.
-
-2001-03-02 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/evolutionperson.schema: rename evolveperson.schema
- to this, and add remaining attributes.
-
- * backend/pas/pas-backend-ldap.c: add remaining fields, and fix up
- ones that were incorrent (either the ldap_attr or the query prop).
-
-2001-03-02 JP Rosevear <jpr@ximian.com>
-
- * conduit/Makefile.am: update sed script
-
- * conduit/e-address.conduit.in: update for new pilot foo
-
-2001-03-02 Chris Toshok <toshok@ximian.com>
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_activate_obj): track change to
- e_contact_editor_new.
-
-2001-03-02 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (add_objectclass_mod): add
- objectclasses for "person", "organizationalPerson", and "top" as
- well, just to be complete.
- (check_schema_support): rename check_for_evolve_person to this, to
- reflect that we're doing more than just checking for that
- objectClass.
- (add_oc_attributes_to_supported_fields): new function.
- (add_to_supported_fields): new function.
- (pas_backend_ldap_destroy): unref supported_fields.
-
-2001-03-02 Chris Toshok <toshok@ximian.com>
-
- * gui/widgets/e-minicard-view.c (supported_fields_cb): new
- function.
- (e_minicard_view_event): split out the creation of the contact
- editor to the supported_fields callback.
-
- * gui/widgets/e-minicard.c (supported_fields_cb): new function.
- (e_minicard_event): split out the creation of the contact editor
- to the supported_fields callback.
-
- * gui/widgets/e-addressbook-view.c (table_double_click): split
- function into two functions, since e_book_get_supported_fields
- requires a callback now.
- (supported_fields_cb): new function.
-
- * gui/component/addressbook.c (new_contact_cb): split this into
- two functions, since e_book_get_supported_fields requires a
- callback now.
- (supported_fields_cb): new function.
-
- * contact-editor/test-editor.c (main): track change to
- e_contact_editor_new (pass NULL for the writable_fields arg.)
-
- * contact-editor/contact-editor.glade: fix several labels so they
- make better sense (since we look them up in e-contact-editor.c.)
-
- * contact-editor/e-contact-editor.h (struct _EContactEditor): add
- writable_fields. also, add it to e_contact_editor_new.
-
- * contact-editor/e-contact-editor.c (e_contact_editor_class_init):
- add writable_fields arg.
- (e_contact_editor_destroy): unref the writable_fields list.
- (e_contact_editor_new): pass @fields as the writable_fields arg.
- (e_contact_editor_set_arg): add writable_fields support.
- (enable_writable_fields): new (very hairy) function, to disable
- everything and reenable just the fields listed in the
- writable_fields list.
- (_email_arrow_pressed): set label-email1, entry-email1, and
- checkbutton-htmlmail to be sensitive since the only way to get
- here is to activate a writable field in the menu.
- (_address_arrow_pressed): set label-address, button-fulladdr, and
- text-address to be sensitive for the same reason.
- (_phone_arrow_pressed): sensitize the label and entry for the same
- reason.
-
-2001-03-02 Chris Toshok <toshok@ximian.com>
-
- * backend/ebook/e-card-simple.c (field_data): add new entries for
- phone enums, and fill in the ecard_field with (bogus in all but a
- few cases) strings. these are the strings sent from wombat to
- evolution-addressbook for supported_fields.
- (e_card_simple_get_ecard_field): new function.
- (e_card_simple_map_phone_to_field): new function.
- (e_card_simple_map_email_to_field): new function.
- (e_card_simple_map_address_to_field): new function.
-
- * backend/ebook/e-card-simple.h: add a few phone entries to the
- ECardSimpleField enum, and add prototypes for mapping the list
- types (phone, email, address) to ECardSimpleField. Also, add
- prototype for e_card_simple_get_ecard_field.
-
- * backend/ebook/e-book.c
- (e_book_do_response_get_supported_fields): don't build the EList
- here, it's already built.
-
- * backend/ebook/e-book-listener.h: change fields from the CORBA
- sequence to the EList in our reponse struct.
-
- * backend/ebook/e-book-listener.c
- (e_book_listener_queue_get_supported_fields_response): we make the
- EList here, since after we return the CORBA list is freed up.
-
-2001-03-02 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_process_get_supported_fields): implement
- properly, we support everything.
-
-2001-03-01 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_set_property_fn): Oops, we do need to be able to write to
- "text" after all (for things like Reply-to: to work properly).
- Fixed.
- (impl_SelectNames_get_entry_for_section): Made "text" a writeable
- property again.
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_insert_length): Increment pos so that
- we don't reverse strings when length > 1 (a particularly amusing
- bug).
-
- * gui/component/select-names/e-select-names-completion.c
- (e_select_names_completion_destroy): Check for NULL before calling
- gtk_object_unref (GTK_OBJECT (---)), to get rid of annoying error
- messages.
-
-2001-03-01 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-completion.c: I am an
- idiot.
-
-2001-03-01 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-table-model.c
- (fill_in_info): Change for new EDestination/ESelectNamesModel API.
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_get_source): Added. A function for
- looking up the ESelectNamesModel by id. (I didn't end up using
- this function, but it might come in handy later.)
- (e_select_names_manager_get_cards): #if 0/#endif out this
- function.
- (e_select_names_manager_create_entry): Modified to attach an
- ESelectNamesCompletion to the entry we create.
- (completion_handler): A post-completion handler for our EEntry, to
- take the completion's extra data (an EDestination) and properly
- stick it into our ESelectNamesModel.
-
- * gui/component/select-names/e-select-names.c
- (real_add_address_cb): Changed to operate on EDestinations rather
- than ECards and to use the new ESelectNamesModel API. This leads
- to a rather nice code simplication.
- (remove_address): Changed for new ESelectNamesModel API.
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_get_property_fn): Rather than just passing the entry's text
- through the property bag, get the "address text" from the model.
- This returns a nice, verbose string of addresses with names
- expanded when the address is tied to an ECard (i.e. "Jon
- Trowbridge <trow@ximian.com>").
- (impl_SelectNames_get_entry_for_section): Make the text property
- read-only.
- (entry_set_property_fn): ...and since it is read-only now, chop
- out the setter code.
-
- * gui/component/select-names/e-select-names-text-model.h:
- * gui/component/select-names/e-select-names-text-model.c: Again,
- this code has been (pretty much) totally rewritten to convert all
- text operations into changes on the ESelectNamesModel. This lets
- us give the associated EEntry some (IMHO) nice semantics regarding
- whitespace, etc. Includes object activation, so destinations tied
- to ECards are underlined and can be double-clicked to bring up a
- contact editor.
-
- * gui/component/select-names/e-select-names-model.h:
- * gui/component/select-names/e-select-names-model.c: I've heavily
- modified this object to both hide all implementation details
- (which the old version exposed a bit too much for my peculiar
- tastes) and to act as an EDestination container. The old code put
- the text model operations here. I've moved them all to
- ESelectNamesTextModel --- so the text model actions (insert,
- delete, etc.) are all done through the API rather than operating on
- ESelectNamesModel internals.
-
- * gui/component/select-names/e-select-names-completion.c: Added. A
- fairly complicated object derived from ECompletion that searches
- our local addressbook in various and sundry ways.
-
- * gui/component/select-names/e-select-names-completion.h:
-
- * backend/ebook/e-destination.h:
- * backend/ebook/e-destination.c: Added. This object encapsulates
- a place to sent an email to, which can either be just a address as
- a string ("trow@ximian.com"), a fancier string ("Jon Trowbridge
- <trow@ximian.com>"), or an ECard and a specific address within
- that ECard.
-
-2001-03-01 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-minicard-view.c, gui/widgets/e-minicard-view.h,
- gui/widgets/e-minicard.c, gui/widgets/e-minicard.h: Used
- ESelectionModelSimple and the changes to EReflow and EReflowSorted
- to get multiple selection in the minicard view.
-
- * gui/widgets/test-reflow.c: Changed this to get it to compile
- with the changes to EReflow.
-
-2001-02-21 Christopher James Lahey <clahey@ximian.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_search): Made
- this pay attention to the return value of e_sexp_parse.
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_activate_obj): Fixed a const
- inconsistency here.
-
-2001-02-21 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-book.c (pas_book_queue_get_supported_fields):
- new function.
- (impl_GNOME_Evolution_Addressbook_Book_getSupportedFields): track
- change to idl.
- (pas_book_respond_get_supported_fields): new function.
-
- * backend/pas/pas-book.h: add GetSupportedFields to the
- PASOperation enum. Also, add a stringlist field to the PASRequest
- struct. lastly, add a prototype for
- pas_book_respond_get_supported_fields.
-
- * backend/pas/pas-backend.h: remove prototype for
- pas_backend_get_supported_fields, and remove it from the vtable.
-
- * backend/pas/pas-backend.c (pas_backend_get_supported_fields):
- remove.
- (pas_backend_class_init): no vtable entry for get_supported_fields
- anymore.
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_process_get_supported_fields): new function.
- (pas_backend_ldap_process_client_requests): add case for
- GetSupportedFields.
- (pas_backend_ldap_class_init): get_supported_fields isn't in
- vtable anymore.
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_process_get_supported_fields): new function.
- (pas_backend_file_process_client_requests): add case for
- GetSupportedFields.
- (pas_backend_file_class_init): get_supported_fields isn't in
- vtable anymore.
-
- * backend/idl/addressbook.idl: Book::getSupportedFields now
- returns void and add BookListener::notifySupportedFields.
-
- * backend/ebook/test-client.c (get_fields_cb): new function.
- (auth_user_cb): track change to e_book_get_supported_fields.
-
- * backend/ebook/e-book.c
- (e_book_do_response_get_supported_fields): new function.
- (e_book_check_listener_queue): add case
- GetSupportedFieldsResponse.
- (e_book_get_supported_fields): switch to async model.
-
- * backend/ebook/e-book.h: switch e_book_get_supported_fields to an
- async model.
-
- * backend/ebook/e-book-listener.c
- (e_book_listener_queue_get_supported_fields_response): new
- function.
- (impl_BookListener_response_get_supported_fields): new function.
- (e_book_listener_get_epv): fill in epv's "notifySupportedFields"
-
- * backend/ebook/e-book-listener.h: add an async response for
- GetSupportedFields and add a stringlist member to the
- EBookListenerResponse struct.
-
-2001-02-20 Federico Mena Quintero <federico@ximian.com>
-
- * backend/pas/pas-book-factory.c (pas_book_factory_activate):
- Moved the register_factory() code to here, since it was the only
- thing being called anyways.
- (PasBookFactoryPrivate): Added a "registered" flag.
- (pas_book_factory_activate): Set the registered flag.
- (pas_book_factory_destroy): Deactivate the factory when we go away.
-
-2001-02-20 Chris Toshok <toshok@ximian.com>
-
- * backend/ebook/e-book.c (e_book_get_supported_fields): new function.
-
- * backend/ebook/e-book.h: add e-book interface to getting
- supported fields.
-
- * backend/ebook/test-client.c (auth_user_cb): shoe-horn in some
- spew about supported fields.
-
-2001-02-19 JP Rosevear <jpr@ximian.com>
-
- * conduit/Makefile.am: Remove PISOCK_LIBDIR
-
-2001-02-19 Jon Trowbridge <trow@ximian.com>
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_create_entry): When creating the entry,
- open up an ebook (corresponding to the local addressbook) and make
- the entry use an EAddressCompletion.
- (completion_handler): Added; this is the actual completion
- handler, which manipulates the entry when the user selects
- something from the drop-down.
-
- * gui/component/select-names/e-select-names-model.c: Various hacks
- by clahey to unbreak e_select_names_model_add_item,
- e_select_names_model_replace_item (which I added) and
- e_select_names_model_remove_item.
-
- * gui/component/select-names/e-select-names-text-model.c
- (e_select_names_text_model_obj_count,
- e_select_names_text_model_get_nth_obj): Make chunks of text that
- correspond to ECards in the ESelectNamesModel be embedded objects.
- (e_select_names_text_model_activate_obj): On activation, pop up a
- contact editor for the embedded object's card.
- (e_select_names_text_model_model_changed): Fixed to work with
- ETextModel API changes.
- (e_select_names_text_model_set_text): Make const correct.
- (e_select_names_text_model_insert): Make const correct.
- (e_select_names_text_model_insert_length): Make const correct.
-
- * backend/ebook/e-address-completion.h,
- backend/ebook/e-address-completion.c: Added. EAddressCompletion
- is a derived class of ECompletion that does asynchronous address
- lookups for completions.
-
-2001-02-17 Chris Toshok <toshok@ximian.com>
-
- * backend/idl/addressbook.idl: add sequence<string> typedef, and
- add getSupportedFields method.
-
- * backend/pas/pas-book.c
- (impl_GNOME_Evolution_Addressbook_Book_getSupportedFields): new
- function.
-
- * backend/pas/pas-backend.c (pas_backend_class_init): init
- get_supported_fields = NULL.
- (pas_backend_get_supported_fields): new function.
-
- * backend/pas/pas-backend.h: add prototype for
- pas_backend_get_supported_fields.
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_get_supported_fields): new function.
- (pas_backend_file_class_init): fill in get_supported_fields.
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_get_supported_fields): new function.
- (pas_backend_ldap_class_init): fill in get_supported_fields.
-
-2001-02-14 Christopher James Lahey <clahey@ximian.com>
-
- * backend/pas/pas-backend-ldap.c: Undefine E_STRING_PROP and
- E_LIST_PROP here.
-
- * contact-editor/e-contact-editor.c,
- contact-editor/e-contact-editor.h (e_contact_editor_raise): Added
- this function.
-
- * gui/widgets/e-minicard.c, gui/widgets/e-minicard.h
- (e_minicard_event): Added an editor field to the EMinicard object.
- Made it so that if you double click on the same card twice, it
- doesn't open a new window, but instead raises the old.
-
-2001-02-08 Iain Holmes <iain@ximian.com>
-
- * gui/component/addressbook-storage.c (addressbook_source_free):
- Free the ldap.binddn.
-
- * gui/widgets/e-addressbook-view.c
- (e_addressbook_view_setup_menus): Free the dir strings.
-
-2001-02-08 Christopher James Lahey <clahey@ximian.com>
-
- * contact-editor/e-contact-editor.c (categories_clicked): Set the
- header on the category dialog we pop up.
-
-2001-02-12 Kjartan Maraas <kmaraas@gnome.org>
-
- * backend/ebook/GNOME_Evolution_Addressbook_GnomeCard_Importer.oaf.in: Translations.
- * gui/component/select-names/GNOME_Evolution_Addressbook_SelectNames.oaf.in:
- Marked strings for translation in this newly created file.
- * gui/component/select-names/Makefile.am: Hook up the .oaf.in files in the
- xml-i18n-tools framework.
- * gui/component/Makefile.am: Same as above.
- * gui/component/GNOME_Evolution_Addressbook.oaf.in: Marked stuff for translation here
- too.
-
-2001-02-11 Jason Leach <jasonleach@usa.net>
-
- * gui/component/addressbook.c: Removed an ancient #include
- <libgnorba/gnorba.h>
-
-2001-02-11 Gediminas Paulauskas <menesis@delfi.lt>
-
- Really use xml-i18n-tools.
-
- * conduit/e-address-conduit-control-applet.desktop: removed.
- * conduit/e-address-conduit-control-applet.desktop.in: added empty.
- * conduit/Makefile.am: reflect above changes, merge translations.
-
- * contact-editor/e-contact-editor-strings.h,
- contact-editor/fulladdr.glade.h, contact-editor/fullname-strings.h,
- contact-editor/e-contact-editor-confirm-delete.glade.h,
- gui/component/select-names/select-names.glade.h:
- removed these files, xml-i18n-extract takes care of strings itself.
-
- * contact-editor/*.glade,
- gui/component/select-names/select-names.glade,
- gui/widgets/alphabet.glade, printing/e-contact-print.glade:
- changed project options to not output_translatable_strings.
-
- * contact-editor/Makefile.am, gui/widgets/Makefile.am,
- gui/component/select-names/Makefile.am, printing/Makefile.am:
- do not include removed files in EXTRA_DIST.
-
-2001-02-07 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (check_for_evolve_person): flesh
- out this check. #ifdef the entire thing OPENLDAP2, as it only
- works with the new schema stuff in openldap 2.x (both on server
- and client, so upgrade your server.)
-
-2001-02-07 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/e-addressbook-view.c: Added N_("* Click here to add
- a contact *").
-
-2001-02-07 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_connect): only
- set the DEBUG_LEVEL if we're OPENLDAP2.
-
-2001-02-06 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (email_compare): return TRUE if
- equal, FALSE otherwise.
- (business_compare): same.
- (homephone_compare): same.
- (email_ber): return NULL if there are no elements in our list.
- (homephone_ber): same.
- (business_ber): same.
- (build_mods_from_ecards): add smarts to handle list elements
- properly (like email, business_phone, home_phone.) now we'll
- properly send updates if any element in the list changes.
-
-2001-02-06 Christopher James Lahey <clahey@ximian.com>
-
- * gui/widgets/Makefile.am (INCLUDES): Added
- -DEVOLUTION_DATADIR=\""$(datadir)"\".
-
- * gui/widgets/e-addressbook-view.c
- (e_addressbook_view_setup_menus): Changed the local and system
- directories.
-
-2001-02-06 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (create_card_handler): doh,
- didn't mean to commit this.
-
-2001-02-06 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/evolveperson.schema: new file. this will eventually
- form the suggested additions to an existing openldap server that,
- along with support for inetorgperson, will allow people to store
- all evolution attributes in ldap.
-
-2001-02-06 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_init): don't
- need the = NULL's since we g_new0.
- (check_for_evolve_person): new function.
- (pas_backend_ldap_connect): check to see if the evolvePerson
- objectclass is there.
- (build_mods_from_ecards): right now, just silently skip the extra
- attributes if we don't support evolvePerson.
- (add_objectclass_mod): new function, add both inetOrgPerson and
- (if it's available) evolvePerson as objectclasses.
- (pas_backend_ldap_process_authenticate_user): also check to see if
- evolvePerson is there, if we couldn't do it (due to auth reasons)
- in the connect method.
- (prop_info): change the telephoneNumber LDAP attribute to be used
- for evolution's business phone numbers. the primary phone number
- will be a single valued attribute on evolvePerson.
- (business_populate): new function.
- (business_ber): new function.
- (business_compare): new function.
-
-2001-02-05 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (create_card_handler): err,
- allocate 2 char*s when i assign 2 char*s.
-
-2001-02-05 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (modify_card_handler): switch to
- ldap_modify_ext_s if OPENLDAP2, as ldap_modify_s is deprecated.
- (build_mods_from_ecards): don't include the mod if the value is ""
- - this isn't valid on schema checking ldap servers.
- (homephone_populate): new function.
- (homephone_ber): new function.
- (homephone_compare): new function.
- (create_card_handler): add spew when adding cards so I can see
- what's going on.
-2001-02-05 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook-config.c (table_add_elem): Save the
- help_text in the closure.
-
-2001-02-05 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/widgets/Makefile.am (libeminicard_a_SOURCES): Added
- gal-view-factory-minicard.c, gal-view-factory-minicard.h,
- gal-view-minicard.c, and gal-view-minicard.h.
-
- * gui/widgets/gal-view-factory-minicard.c,
- gui/widgets/gal-view-factory-minicard.h,
- gui/widgets/gal-view-minicard.c, and
- gui/widgets/gal-view-minicard.h: New classes for minicard view
- type.
-
- * gui/widgets/e-addressbook-view.c: Deploy gal-view stuff
- properly.
-
-2001-02-05 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c (e_card_get_vcard): Make the Note field
- be quoted printable.
-
-2001-01-27 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/search/e-addressbook-search-dialog.c
- (e_addressbook_search_dialog_init): This should be a close button,
- not a cancel button.
-
-2001-02-04 Christopher James Lahey <clahey@ximian.com>
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_activate_dialog): Call
- e_select_names_set_default when appropriate.
-
- * gui/component/select-names/e-select-names.c,
- gui/component/select-names/e-select-names.h: Added support for
- double clicking sending the selected contacts to the default
- section. Added a set_default function. Made multiple selection
- work.
-
-2001-01-29 Chris Toshok <toshok@ximian.com>
-
- * gui/component/addressbook-config.c
- (addressbook_config_source_label): #ifdef INCLUDE_FILE_SOURCE.
- (table_add_elem): add help_text parameter and set up focus_in
- events to display the help in the dialog's html area.
- (focus_help): new function, calls put_html on the help text.
- (addressbook_ldap_auth_item_new): add help texts.
- (addressbook_source_item_new): add help texts.
- (addressbook_source_dialog): add help texts.
-
-2001-01-27 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_add_section): Remove the butt-ugly arrow icon and
- replace it with a less invasive "->" icon.
-
-2001-01-25 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (build_mods_from_ecards): add
- comment about the else block here.
- (prop_info): add home_address, business_address, business_fax,
- assistant, and isdn.
-
-2001-01-25 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_load_uri): Made
- this only add the initial VCard if it finds a file
- "create-initial" in the directory it's creating the database in.
-
- * gui/component/addressbook-component.c (factory_fn): Added a
- create_folder function.
-
- * gui/search/e-addressbook-search-dialog.c
- (e_addressbook_search_dialog_init): Fixed an unused variable
- warning.
-
-2001-01-25 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/widgets/e-addressbook-view.c
- (e_addressbook_view_setup_menus): Setup the view collection
- properly and handle the "display_view" signal.
-
-2001-01-25 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook.c (update_pixmaps): Consider the
- placeholder in the path for the "Print" item.
-
-2001-01-25 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook.c (update_pixmaps): Set the icon for
- "/Toolbar/Find" to "24_find_contact.xpm".
-
-2001-01-25 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component/addressbook.c (set_pixmap): New.
- (update_pixmaps): New function, setting the pixmaps for the items
- of type "pixbuf", using `set_pixmap'.
- (control_activate): Call it.
-
-2001-01-25 Not Zed <NotZed@Ximian.com>
-
- * backend/pas/pas-backend-ldap.c: esexp api change fixes.
-
- * backend/pas/pas-backend-file.c (entry_compare): Fix for e_sexp api changes.
- (vcard_matches_search): esexp api fixes.
- (pas_backend_file_search): Ouch, unref the e-sexp properly (not gtk object).
-
-2001-01-24 Chris Toshok <toshok@ximian.com>
-
- * backend/pas/pas-backend-ldap.c (email_ber_func): make sure to
- add the lengths here (include the \0? anyone?).
- (build_mods_from_ecards): if we're filling in mod->mod_bvalues,
- set mod_op |= LDAP_MOD_BVALUES.
-
-2001-01-23 Jason Leach <jasonleach@usa.net>
-
- (Fix #1225: advanced search cancel/close)
-
- * gui/search/e-addressbook-search-dialog.c
- (e_addressbook_search_dialog_init): Set it up with Search and a
- Cancel button, Search is still the default.
-
-2001-01-23 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (local_record_from_ecard): properly ref
- the ecard. still need to kill some memory leaks.
-
-2001-01-22 JP Rosevear <jpr@ximian.com>
-
- * conduit/Makefile.am: remove vfs dependency
-
-2001-01-21 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (delete_record): Remove
- deleted records from the pilot map so we don't have dupes in the future
-
-2001-01-19 Dan Winship <danw@ximian.com>
-
- * gui/widgets/e-addressbook-view.c (table_right_click):
- * gui/widgets/e-minicard.c (e_minicard_event): Update for
- e_popup_menu_run prototype change.
-
-2001-01-19 Jason Leach <jasonleach@usa.net>
-
- (Adding a boolean "entry_changed" BonoboPropertyBag arg)
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_set_property_fn): Use a gtk_object_set_data to set the
- property to TRUE here.
-
- (entry_changed): New function, calls bonobo_control_set_property
- if entry_changed hasn't been set to TRUE yet.
-
- (impl_SelectNames_get_entry_for_section): Connect "changed" on
- each entry_widget to the new entry_changed() func.
-
-2001-01-19 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (ecard_from_remote_record): always free
- the delivery elements and correct embarrassingly stupid memory error
- that was causing the addressbook conduit problems.
-
- * backend/ebook/e-book-view-listener.c
- (e_book_view_listener_check_queue): ref/unref ourself when processing
- in case someone we signal unrefs us.
-
- * conduit/address-conduit.c (sequence_complete): disconnect signals
- when complete
-
-2001-01-17 Federico Mena Quintero <federico@ximian.com>
-
- * backend/pas/pas-book-factory.c (pas_book_factory_activate): Made
- it return a gboolean; it was completely ignoring the return value
- from register_factory().
-
-2001-01-17 Larry Ewing <lewing@helixcode.com>
-
- * backend/ebook/.cvsignore: add evolution-gnomecard-importer.
-
- * backend/ebook/Makefile.am (oaf_DATA): don't require the pine
- oainfo file until it is actually added to the repository. We need
- to keep the build working for nightlies to work.
-
-2001-01-16 Jason Leach <jasonleach@usa.net>
-
- * backend/pas/pas-backend-file.c (INITIAL_VCARD): s/Helix
- Code/Ximian/ for the initial contact card.
-
-2001-01-15 JP Rosevear <jpr@ximian.com>
-
- * conduit/address-conduit.c (print_local): prevent segfaults and
- buffer overflows
- (print_remote): ditto
-
-2001-01-14 JP Rosevear <jpr@ximian.com>
-
- * conduit/Makefile.am: pass -module and -avoid-version to conduit
- linker
-
-2001-01-12 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook-component.c (factory_fn): Pass NULL as
- the @copy_folder_fn arg to `evolution_shell_component_new'.
-
-2001-01-12 Miguel de Icaza <miguel@ximian.com>
-
- * gui/widgets/e-addressbook-view.c: added i18n for etable.
-
-2001-01-11 Chris Toshok <toshok@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_process_create_card): get a book view from
- somewhere so we can give status messages - choose the first one in
- the list.
- (pas_backend_ldap_process_modify_card): same.
- (pas_backend_ldap_process_remove_card): same.
- (prop_info): add more properties, like home_phone, mobile, pager,
- uri, org_unit, office, title, and manager.
-
-2001-01-09 Miguel de Icaza <miguel@gnu.org>
-
- * gui/widgets/Makefile.am (minicard_widget_test_LDADD): Put GNOME
- libraries at the end to make the thing compile.
-
- * printing/Makefile.am: Order LDADD flags correctly so it compiles.
-
-2001-01-09 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/addressbook.c (addressbook_factory_new_control):
- connect with the EAddressbookView's status_message signal.
- (set_status_message): set the status message on the ShellView
- Interface associated with our control.
- (retrieve_shell_view_interface_from_control): new function. get
- the shell view inteface associated with a control.
-
- * gui/widgets/e-addressbook-view.c
- (e_addressbook_view_class_init): register status_message signal.
- (status_message): new function, emit our status_message signal.
- (change_view_type): connect with the view->object's
- "status_message" signal.
-
- * gui/widgets/e-addressbook-view.h (struct
- _EAddressbookViewClass): add status_message signal.
-
-2001-01-09 Chris Toshok <toshok@helixcode.com>
-
- * gui/widgets/e-minicard-view-widget.c
- (e_minicard_view_widget_class_init): register our status_message
- signal.
- (status_message): new function, emit our status_message signal.
- (e_minicard_view_widget_realize): connect to the EMinicardView's
- status_message signal.
-
- * gui/widgets/e-minicard-view-widget.h: add status_message signal.
-
- * gui/widgets/e-minicard-view.c (e_minicard_view_class_init):
- register our status_message signal.
- (e_minicard_view_init): init status_message_id.
- (status_message): new function, emit our status_message signal.
- (book_view_loaded): connect to the EBookView's status_message
- signal.
- (disconnect_signals): disconnect status_message_id.
-
- * gui/widgets/e-minicard-view.h: add status_mesage_id, and
- status_message signal.
-
- * gui/widgets/e-addressbook-model.c (status_message): new
- function, emit our status_message.
- (e_addressbook_model_class_init): register our "status_message"
- signal.
- (book_view_loaded): connect to the EBookView's status_message
- signal, so we can chain it to our parent.
- (e_addressbook_model_init): init status_message_id.
- (remove_book_view): disconnect status_message_id.
-
- * gui/widgets/e-addressbook-model.h: add status_message_id, and
- status_message signal.
-
- * backend/pas/pas-backend-ldap.c change the objectclass we create
- objects with to "inetOrgPerson" as it encompasses the fields we
- use.
- (create_dn_from_ecard): remove the mail/org handling from
- here. we just prepend cn=$cn onto the base dn.
- (create_card_handler): remove the NULL that build_mods_from_ecards
- adds at the end, and insert our objectClass.
- (modify_card_handler): call search_for_dn to get the ECardSimple
- of the old card, since it might (and does in the current code)
- doing a brute force search.
- (search_for_dn): new function, to search for an entry by its dn.
- right now we brute force (objectclass=*) under the base dn and
- compare dn's. going to add a first pass that explodes the dn and
- searches that way, using (objectclass=*) as a last resort. also,
- here's where we'd put the extensibleMatch code if we want to go
- that route.
-
- * backend/ebook/e-card.c (e_card_set_arg): if we're setting the
- full name regenerate ecard->name.
-
-2001-01-04 Chris Toshok <toshok@helixcode.com>
-
- * backend/ebook/e-book-listener.c
- (e_book_listener_queue_authentication_response): new function.
- (impl_BookListener_respond_authentication_result): new function.
- (e_book_listener_get_epv): fill in
- epv->notifyAuthenticationResult.
-
- * backend/ebook/e-book-listener.h: add AuthenticationResponse to
- EBookListenerOperation.
-
- * backend/ebook/e-book.c (e_book_authenticate_user): new function.
-
- * backend/ebook/e-book.h: add prototype for
- e_book_authenticate_user.
-
- * backend/idl/addressbook.idl (GNOME:Evolution:Addressbook:Book):
- add authenticateUser method.
- (GNOME:Evolution:Addressbook:BookListener): add
- AuthenticationFailed and AuthenticationRequired to CallStatus.
- also add notifyAuthenticationResult method.
-
- * backend/pas/pas-backend-file.c
- (pas_backend_file_process_authenticate_user): dummy
- authenticate_user function that always succeeds.
- (pas_backend_file_process_client_requests): respond to the
- AuthenticateUser request.
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_build_query):
- gtk_object_unref(sexp) => s_exp_unref(sexp).
- (pas_backend_ldap_process_authenticate_user): fill in to use
- ldap_simple_bind_s.
- (pas_backend_ldap_process_client_requests): respond to the
- AuthenticateUser request.
-
- * backend/pas/pas-book.c (pas_book_queue_authenticate_user): new
- function.
- (impl_GNOME_Evolution_Addressbook_Book_authenticateUser): new
- function.
- (pas_book_respond_authenticate_user): new function.
- (pas_book_get_epv): fill in epv->authenticateUser.
-
- * backend/pas/pas-book.h: add AuthenticateUser operation type, and
- add user/passwd to the PASRequest struct.
-
- * gui/component/addressbook-storage.c
- (addressbook_storage_get_source_by_uri): new function. should use
- a hashtable, perhaps, but the lists will generally be small
- anyway.
-
- * gui/component/addressbook-storage.h: add prototype for
- addressbook_storage_get_source_by_uri.
-
- * gui/component/addressbook-config.c
- (addressbook_source_dialog_set_source): fill in the binddn if the
- auth page is shown.
-
- * gui/component/addressbook.c (book_open_cb): shoe-horn
- authentication in here. if the source was configured to use
- authentication, authenticate the user after opening the ebook.
- also, be paranoid and clear out the password after authenticating.
- (book_auth_cb): callback for auth. set the "book" arg on the
- view->view here.
- (passwd_cb): set the view's passwd that'll be used in
- book_open_cb.
- (addressbook_view_free): g_free view->passwd.
-
-2001-01-04 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook-component.c,
- gui/component/addressbook-component.h
- (addressbook_component_get_shell_client): Added this function.
-
- * gui/component/select-names/e-select-names.c,
- gui/component/select-names/e-select-names.h: Added code for the
- ability to switch between different folders. This doesn't work
- yet.
-
- * gui/component/select-names/select-names.glade,
- gui/component/select-names/select-names.glade.h: Added an option
- menu to this dialog.
-
-2001-01-04 JP Rosevear <jpr@helixcode.com>
-
- * conduit/Makefile.am: Fix hard coded library names that were
- accidentally committed (i'm looking at you miggie)
-
- * contact-editor/e-contact-editor.c (categories_clicked): Reflect
- renaming.
-
- * contact-editor/e-contact-editor-categories.[hc]: These are
- living in gal now
-
-2001-01-04 JP Rosevear <jpr@helixcode.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_book_view_free):
- Need to e_sexp_unref the the sexp, not gtk_object_unref it.
-
-2001-01-03 Michael Meeks <michael@helixcode.com>
-
- * gui/widgets/e-addressbook-model.c (get_view): check
- capabilities is valid before doing a strstr.
-
-2001-01-03 Michael Meeks <michael@helixcode.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_search):
- g_strdup things we g_free.
-
-2001-01-02 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c (delete_cb): Make sure this
- won't crash if the given contact is removed from the database
- while this function is being called.
-
- * gui/widgets/e-minicard.c: Made sure this won't crash if the
- given contact is removed from the database while the right click
- menu is being displayed.
-
-2000-12-30 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/addressbook-config.c (edit_source_clicked): copy
- the dialog's source, destroy the dialog after we're done, and make
- sure to update both columns in the clist.
- (add_source_clicked): copy the dialog's source, and destroy the
- dialog when we're done.
- (addressbook_source_dialog_destroy): free up all the dialog's
- memory.
-
- * gui/component/addressbook.c (set_prop): allow file: uri's that
- point to files, not just dirs that contain addressbook.db. The
- rule is the addressbook file has to end in .db.
-
- * gui/component/addressbook-storage.c (file_source_foreach):
- contactserver => contactfile. cut and paste error.
- (addressbook_storage_init_source_uri): use file://%s to build the
- uri.
-
- * gui/component/e-ldap-server-dialog.[ch]: forgot to remove these
- in my last commit.
-
-2000-12-29 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/addressbook.c (config_cb): new function, calling
- our new config ui code.
- (control_activate): no longer load evolution-addressbook-ldap.xml,
- as it's not there.
-
- * gui/component/addressbook-component.c (owner_set_cb):
- setup_ldap_storage => addressbook_storage_setup.
-
- * gui/component/Makefile.am (evolution_addressbook_SOURCES):
- remove e-ldap-storage.[ch] and add addressbook-storage.[ch].
- (glade_DATA): remove ldap-server-dialog.glade and add
- addressbook-config.glade.
- (EXTRA_DIST): same.
-
- * gui/component/addressbook-config.[ch]: add another dialog to
- give a list of our sources and offer the Add/Delete/Edit
- interface. This plugs into the previous dialog work (the source
- editor.)
-
- * gui/component/addressbook-storage.[ch]: new files, containing
- the remains of e-ldap-storage.[ch] and adding the new
- AddressbookSource type and it's subordinates. Also, the xml
- format has changed slightly and the file name is no longer
- ~/evolution/ldap-servers.xml - it's
- ~/evolution/addressbook-sources.xml.
-
- * gui/component/addressbook-config.glade: new file, new config
- interface.
-
- * gui/component/ldap-server-dialog.glade: removed.
-
- * gui/component/e-ldap-storage.[ch]: removed.
-
-2000-12-28 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/Makefile.am (evolution_addressbook_SOURCES): add
- addressbook-config.[ch].
-
- * gui/component/addressbook-config.c,
- gui/component/addressbook-config.h: new files, containing at the
- moment a beautiful "new/edit source dialog" inspired by the
- mail-config-gui code. It'll be ready for prime time after rev'ing
- the .xml file the addressbook uses to store it's "other sources"
- to include files, and the addition of the ldap auth stuff.
-
-2000-12-25 Miguel de Icaza <miguel@helixcode.com>
-
- * gui/widgets/e-minicard.c (e_minicard_realize): Set draw
- background to FALSE.
-
- * gui/widgets/e-minicard-label.c (e_minicard_label_construct): ditto.
- (e_minicard_label_construct): ditto
-
-2000-12-23 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/fullname-strings.h,
- contact-editor/fullname.glade: Added Ms. and Miss to the prefix
- drop down box. Patch submitted by Martin Hicks <mort@bork.org>.
-
-2000-12-21 JP Rosevear <jpr@helixcode.com>
-
- * conduit/address-conduit.c (cursor_cb): Ref the cards that get put
- in the change list
- (next_changed_item): util function to get the real next changed item
- (compute_status): really compute the status of the record
- (local_record_from_uid): Set the id of the temporary card
- (check_for_slow_setting): Make this check a little saner
- (card_added): Only record the CardObjectChange if the card is not
- archived
- (card_changed): ditto
- (card_removed): ditto
- (set_status_cleared): actually clear the status
- (for_each_modified): Clean out cruft and use next_changed_item
- (add_record): Set the new id properly in our local card copy
- (replace_record): handle the case where the record has been deleted
- and we need to call add. need to update the changed_hash entry
- (delete_record): Don't panic if the card is not found, its already
- been deleted.
-
- * backend/pas/pas-backend-file.c (pas_backend_file_book_view_copy):
- The change_context no longer has a del_cards member
- (pas_backend_file_book_view_free): ditto
- (pas_backend_file_process_get_changes): ditto
- (pas_backend_file_changes_foreach_key): just record the id
- (pas_backend_file_changes): notify_remove needs an id not a vcard
-
-2000-12-20 JP Rosevear <jpr@helixcode.com>
-
- * conduit/address-conduit.c (match): Use my own wrapper
- functions instead of trying to *directly* access the the data
- structures my self
- (post_sync): Put in hack to prevent syncing the same records twice
- (local_record_from_uid): set the card id when creating a blank one
- (add_record): Set the id of the card we have and don't go to the
- server to get the latest version
-
-2000-12-19 JP Rosevear <jpr@helixcode.com>
-
- * conduit/address-conduit.c (ecard_from_remote_record): Convert
- pilot strings to utf for the e-cards.
-
-2000-12-19 JP Rosevear <jpr@helixcode.com>
-
- * conduit/address-conduit.c (local_record_from_ecard): Convert ecard
- strings to pilot encodings
-
-2000-12-19 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/widgets/e-addressbook-view.c (delete): Made it so that if
- you select multiple contacts, the right click menu to delete
- deletes them all.
-
-2000-12-18 Chris Toshok <toshok@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c (ldap_error_to_response): always
- use LDAP_NAME_ERROR (in the openldap1 case it's #defined to
- NAME_ERROR).
- (build_card_from_entry): ldap_get_values can return NULL. also,
- openldap2 keeps us from getting at ldap->ld_errno, so we can't
- tell if there was a decoding error like we used to. the double
- free problem where ldap would free the ber if there was a decoding
- problem might be fixed now.. further investigation is needed.
- for now we leak in openldap2.
- (ldap_search_handler): the ldap structure is opaque, so use
- ldap_search_ext to give the extra information (the max responses,
- timeout, etc.) in the openldap2 case.
-
-2000-12-13 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c (ldap_error_to_response): Test
- for the existance of LDAP_NAME_ERROR and if it exists as a macro,
- use it instead of NAME_ERROR.
-
-2000-12-14 Michael Meeks <michael@helixcode.com>
-
- * gui/component/GNOME_Evolution_Addressbook.oafinfo: update cut
- and paste description error.
-
-2000-12-13 Dan Winship <danw@helixcode.com>
-
- * gui/widgets/e-minicard-control.c (stream_read): NULL-terminate
- the returned vcard so we don't sometimes end up with trailing
- junk that makes libversit unhappy.
-
-2000-12-13 Iain Holmes <iain@helixcode.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_add_section): Make the -> into a GNOME stock image.
-
-2000-12-09 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_init): Connect to the "cursor_change" signal on
- the ETable here instead of the ETableScrolled.
- (remove_address): Added the col and event parameters to this
- callback to match the added parameters to the double click signal.
- (e_select_names_add_section): Connect to the "double_click" signal
- on the ETable here instead of the ETableScrolled.
-
-2000-12-09 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c (e_card_set_arg): When setting the "name"
- argument, copy the incoming name. This fixes a crash.
-
-2000-12-09 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Made editing the name using
- the full name button set the file as entry properly. Made it
- so that the address parse that the user chooses after
- clicking on the Full Address... button gets saved.
-
-2000-12-08 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c (full_name_clicked): Made it
- so that the editor->name is set after the entry is changed. This
- means that the reparse that the person chose is saved.
-
-2000-12-07 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/e-ldap-storage.c (setup_ldap_storage): Pass NULL
- as the @toplevel_node_handler_id argument to
- `evolution_storage_new'.
-
-2000-12-08 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c: Fixed some formatting.
-
- * contact-editor/e-contact-editor-categories.h: Removed an
- unneeded #include.
-
- * gui/widgets/e-addressbook-view.c: Connect to the signals on the
- ETable instead of the ETableScrolled.
-
-2000-12-07 JP Rosevear <jpr@helixcode.com>
-
- * conduit/address-conduit.c (local_record_from_uid): Pass "" rather
- than NULL to e_card_new.
- (local_record_from_ecard): Make sure ecard->name is valid
- (check_for_slow_setting): Remove hard coded test value
- (card_added): g_strdup the resul of e_card_get_id
- (card_changed): ditto
-
-2000-12-07 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/widgets/e-addressbook-view.c: Got rid of code referencing
- the ETableScrolled proxy functions.
-
-2000-12-06 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Moved the gal view menu stuff from
- here to EAddressbookView.
-
- * gui/widgets/e-addressbook-view.c,
- gui/widgets/e-addressbook-view.h: New function to set up the menus
- for the EAddressbookView.
-
-2000-12-06 JP Rosevear <jpr@helixcode.com>
-
- * conduit/Makefile.am: Another conduit build fix
-
-2000-12-05 JP Rosevear <jpr@helixcode.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_changes_foreach_key):
- Create an empty vcard with the appropriate id for deleted cards
-
- * conduit/address-conduit.c (ecard_from_remote_record): Ensure the
- address fields are added sensibly
-
-2000-12-05 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/e-ldap-storage.c (setup_ldap_storage): Updated the
- call to `evolution_storage_new()': pass NULL for
- @toplevel_node_uri.
-
-2000-11-28 JP Rosevear <jpr@helixcode.com>
-
- * conduit/address-conduit.c (local_record_to_pilot_record): Return
- a struct rather than a pointer to a struct
- (view_cb): kill warning
- (compare): local_record_to_pilot_record now returns a struct
- (prepare): ditto
- (free_prepare): remove as per gnome-pilot changes
- (conduit_get_gpilot_conduit): don't listen for free_prepare signal
-
-2000-11-27 JP Rosevear <jpr@helixcode.com>
-
- * conduit/address-conduit.h: Remove "complete" field
-
- * conduit/address-conduit.c (print_local): Make it print useful debug
- info
- (print_remote): ditto
- (local_record_from_ecard): Make sure phone numbers get out to the pilot
- (ecard_from_remote_record): Set phone strings to "" if they are null
- (sequence_complete): unref the book view
- (view_cb): ref the book view
- (free_prepare): do nothing
-
- * backend/pas/pas-backend-file.c (pas_backend_file_book_view_free):
- Destroy the card lists with the rest of the view.
- (pas_backend_file_changes): Don't destroy the card lists here
- (pas_backend_file_book_view_free): Free the card/id lists in the
- change context here, the correct place.
- (pas_backend_file_changes): instead of here...
-
-2000-11-22 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-backend-file.c: Set view.change_context to NULL
- in pas_backend_file_process_get_book_view. Changed
- pas_backend_file_book_view_copy a bit.
-
- * backend/pas/pas-backend-ldap.c: Got rid of a warning.
-
-2000-11-18 Matt Bissiri <matt@bissiri.org>
-
- * gui/component/Makefile.am:
- Add widgets/menus/libmenus.la to evolution_addressbook_LDADD
- so that it will link properly now that gal-view-menus.[ch]
- was moved from gal into evolution.
-
-2000-11-15 JP Rosevear <jpr@helixcode.com>
-
- * backend/pas/pas-backend-file.c (pas_backend_file_book_view_copy):
- Initialize destination struct with '0's.
-
-2000-11-12 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c: Changed the mime type from "text/vcard"
- to "text/x-vcard".
-
-2000-11-11 Matt Bissiri <bissiri@eecs.umich.edu>
-
- * backend/ebook/.cvsignore: Add idl-generated files.
- * backend/ebook/e-book.c: (e_book_do_response_get_changes):
- * backend/ebook/e-card.c: (e_card_send):
- s/Evolution_/GNOME_Evolution_/g;
-
-2000-11-11 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/Makefile.am: Link in composer bonobo code.
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Added code to
- send mail to an ECard or send an ECard as a VCard attachment.
-
- * contact-editor/e-contact-editor.c: Add verbs to send the contact
- as a VCard or send mail to the contact.
-
- * gui/search/e-addressbook-search-dialog.c: Removed some unused
- variables.
-
- * gui/widgets/e-addressbook-view.c, gui/widgets/e-minicard.c:
- Added menu items to send the contact as a VCard or send mail to
- the contact.
-
-2000-11-11 Matt Bissiri <bissiri@eecs.umich.edu>
-
- * gui/component/addressbook.oafinfo:
- * gui/component/select-names/evolution-addressbook-select-names.oafinfo:
- Update the remaining "IDL:Evolution*" to "IDL:GNOME/Evolution*"
- to sync up with yesterday's IDL re-scoping.
-
-2000-11-09 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c: Fixed a warning.
-
- * gui/component/addressbook.c: Put in gal view menus for testing
- purposes.
-
- * printing/e-contact-print-envelope.c: Fixed up envelope printing
- a bit. Added code for printing return addresses.
-
-2000-11-09 JP Rosevear <jpr@helixcode.com>
-
- * conduit/address-conduit.h: Add changed_hash, change list and complete bool
-
- * conduit/address-conduit.c (local_record_from_ecard): Add empty field checks
- (card_added): callback for book view
- (card_changed): ditto
- (card_removed): ditto
- (sequence_complete): ditto
- (view_cb): callback for the get changes call
- (pre_sync): force synchronous loading of book view
- (for_each): we already have the card so create the local record directly
- (for_each_modified): Uncomment and fix
- (delete_record): ditto
-
- * conduit/Makefile.am: link against gal for ebook - needs fixing
-
- * backend/ebook/e-book.c (e_book_do_response_get_changes): Properly respond
- to a get_changes call
- (e_book_check_listener_queue): define the get changes response operation
-
- * backend/ebook/e-book-listener.c (e_book_listener_queue_get_changes_response):
- Queue up a get changes response
- (impl_BookListener_respond_get_changes): Implement the get_changes method
- (e_book_listener_get_epv): add get_changes implementation to epv
-
- * backend/pas/pas-backend-file.c (pas_backend_file_book_view_copy): Only
- copy the search_context and change_context elements if they actually exist
- (pas_backend_file_changes): Hard code a path for now, only notify if
- there is something to notify about
-
-2000-11-07 JP Rosevear <jpr@helixcode.com>
-
- * backend/pas/pas-book.h: Update PASRequest structure
-
- * backend/pas/pas-book.c (impl_Evolution_Book_get_changes): update param name
- (pas_book_queue_get_changes): Use PASRequest change_id slot
-
- * backend/pas/pas-backend-file.c (pas_backend_file_book_view_copy):
- Properly copy change_id and change_context
- (pas_backend_file_book_view_free): Free change_id/change_context
- (pas_backend_file_changes_foreach_key): Callback to figure out the
- deleted cards
- (pas_backend_file_changes): Use new e-dbhash stuff to implement.
- Write out updated hash
-
- * backend/idl/addressbook.idl: Rename get_changes param
-
-2000-11-06 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Switched from EAddressbookSearch to
- ESearchBar.
-
- * gui/widgets/Makefile.am, gui/widgets/e-addressbook-search.c,
- gui/widgets/e-addressbook-search.h: Removed EAddressbookSearch.
- This has been moved to filter/ and renamed ESearchBar.
-
- * printing/e-contact-print-envelope.c: Forgot to set the font.
- This works for me now.
-
-2000-11-06 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/select-names/e-select-names-bonobo.c
- (impl_SelectNames_get_entry_for_section): Duplicate the object
- reference before returning.
-
-2000-11-05 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c,
- gui/widgets/e-addressbook-view.c, gui/widgets/e-minicard.c: Add
- menus items to the envelope printing stuff.
-
- * gui/component/addressbook.c: Hook up the search menu.
-
- * gui/widgets/e-addressbook-search.c,
- gui/widgets/e-addressbook-search.h: Add the search menu.
-
- * printing/Makefile.am: Add e-contact-print-envelope.c and
- e-contact-print-envelope.h.
-
- * printing/e-contact-print-envelope.c,
- printing/e-contact-print-envelope.h: Added envelope printing.
-
-2000-11-03 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/component/select-names/Makefile.am: Clean the idl-generated
- files properly.
-
-2000-11-02 Christopher James Lahey <clahey@helixcode.com>
-
- * ename/.cvsignore, gui/minicard/.cvsignore: Removed these
- unnecessary .cvsignores.
-
- * gui/component/addressbook.c: Switch to using EAddressbookSearch
- instead of custom quick search widget.
-
- * gui/component/select-names/e-select-names.c: Made this do a
- slightly better job of rendering names.
-
- * gui/widgets/Makefile.am: Added e-addressbook-search.c and
- e-addressbook-search.h.
-
- * gui/widgets/e-addressbook-search.c,
- gui/widgets/e-addressbook-search.h: New class that puts up an
- entry and a combo box.
-
-2000-11-01 Dan Winship <danw@helixcode.com>
-
- * gui/component/e-ldap-storage.c (load_ldap_data):
- (e_ldap_storage_add_server): Add "highlighted" flag to
- evolution_storage_new_folder
-
-2000-10-31 JP Rosevear <jpr@helixcode.com>
-
- * conduit/address-conduit.c (cursor_cb): Let the warning make sense
- (compute_pid): remove
- (local_record_from_ecard): Create local record from ecard - not finished
- (local_record_from_uid): Obtain local_record from uid with the proper
- e-book way
- (set_status_cleared): Add empty callback
- (add_archive_record): kill
- (delete_archive_record): kill
- (archive_record): Add empty callback
- (conduit_get_gpilot_conduit): Update signal connects
-
- * backend/pas/pas-backend-file.c (vcard_change_type): Function to determine
- the type of change - not finished
- (pas_backend_file_search_changes): Create a view and callback based on
- how the cards have changed
- (pas_backend_file_process_get_changes): Implement the get changes operation
- for files
- (pas_backend_file_process_client_requests): Add GetChanges method for
- processing
-
- * backend/pas/pas-book.c (pas_book_queue_get_changes): Add changes to
- the list
- (impl_Evolution_Book_get_changes): implement object method
- (pas_book_get_epv): Add get changes to epv
- (pas_book_respond_get_changes): Respond to the get changes operation
-
- * backend/pas/pas-book.h: Add GetChanges PASOperation
-
- * backend/idl/addressbook.idl: add get_changes and respond_get_changes
- methods
-
- * backend/ebook/e-book.c (e_book_get_changes): Client function
- to a view of the changed objects
-
- * backend/ebook/e-book.h: New prototype
-
-2000-10-30 Kjartan Maraas <kmaraas@gnome.org>
-
- * backend/e-book/e-card.c: Fixed marking of strings
- for translation. Use "_(" instead of "_ (".
- * gui/component/addressbook-factory.c: Add missing
- calls to bindtextdomain() and textdomain noticed by
- Dan Winship.
- * gui/component/addressbook.c: Marked string for translation.
-
-2000-10-27 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/Makefile.am, gui/search/Makefile.am,
- printing/Makefile.am: Fixed these to include EXTRA_GNOME_CFLAGS.
-
- * gui/component/select-names/e-select-names-manager.c: Turned off
- newlines in header fields.
-
-2000-10-26 Michael Meeks <michael@helixcode.com>
-
- * printing/e-contact-print.c (e_contact_print_letter_tab),
- (complete_sequence, e_contact_do_print_phone_list, lowify):
- unsigned charness.
-
-2000-10-25 Chris Toshok <toshok@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c (ldap_op_process_current): only
- call the handler if the if we're connected, and if we fail to
- connect finish the op and post a message.
- (pas_backend_ldap_connect): add debug spew if DEBUG is defined.
- (modify_card_handler): LDAP_RES_SEARCH_ENTRY => LDAP_SUCCESS.
- (modify_card_handler): only perform the ldap_modify_s if we have a
- list of modifications.
- (get_cursor_handler): use ldap_error_to_response here.
- (pas_backend_ldap_load_uri): use LDAP_PORT instead of the constant
- 389.
-
-2000-10-23 Dan Winship <danw@helixcode.com>
-
- * gui/component/select-names/Makefile.am (INCLUDES):
- * gui/component/Makefile.am (INCLUDES): Update EVOLUTION_LOCALEDIR
-
- * backend/pas/Makefile.am (INCLUDES):
- * backend/ebook/Makefile.am (INCLUDES): Update GNOMELOCALEDIR.
-
-2000-10-23 JP Rosevear <jpr@helixcode.com>
-
- * conduit/address-conduit.h: Use new libeconduit calls and
- abstraction
-
- * conduit/address-conduit.c: ditto
-
-2000-10-23 JP Rosevear <jpr@helixcode.com>
-
- * conduit/address-conduit.c (pre_sync): Use e_pilot_map_read
- (post_sync): Use e_pilot_map_write
-
- * conduit/Makefile.am: Link libeconduit and not libical
-
-2000-10-20 Michael Meeks <michael@helixcode.com>
-
- * contact-editor/e-contact-editor.c (tb_save_and_close_cb):
-
- * gui/component/addressbook.c (toggle_view_as_cb):
-
-2000-10-20 JP Rosevear <jpr@helixcode.com>
-
- * conduit/address-conduit.h: New structure of file - similar
- to calendar/todo conduits
-
- * conduit/address-conduit.c: ditto
-
- * conduit/address-conduit-config.h: Config stuff for conduit
-
- * conduit/.cvsignore: Update
-
- * conduit/Makefile.am: Build fixes
-
- * conduit/address-conduit-control-applet.desktop: Renamed
- to e-address-conduit-control-applet.desktop
-
- * conduit/address.conduit.in: Renamed to e-address.conduit.in
-
-2000-10-19 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/widgets/e-addressbook-view.c (SPEC): Remove Family name
- column since it's a bit weird. This also fixes the initial state
- since all of the column choices were off by one.
-
-2000-10-19 Ettore Perazzoli <ettore@helixcode.com>
-
- * printing/Makefile.am (glade_DATA): Remove
- `e-contact-print.glade.h'.
- (EXTRA_DIST): Move here.
-
- * gui/component/Makefile.am (glade_DATA): Remove
- `ldap-server-dialog.glade.h'.
- (EXTRA_DIST): Move here.
-
-2000-10-19 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c: Change how the extension field acts when
- converting delivery addresses to labels.
-
-2000-10-18 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Added the
- function e_card_delivery_address_to_label.
-
- * contact-editor/e-contact-editor-address.c: Fixed a potential
- crash.
-
- * contact-editor/e-contact-editor.c: Made this save the changed
- data to the string version of the address.
-
-2000-10-19 Michael Meeks <michael@helixcode.com>
-
- * gui/component/addressbook.c (change_view_type): update to new
- UI handler.
- (update_view_type): split from (change_view_type).
- (control_activate): add an update_view_type.
-
-2000-10-18 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-simple.c: Change NAME_OR_ORG to return the
- email address if both name and organization are taken.
-
- * gui/component/select-names/e-select-names.c: Fixed up the spec
- strings in this class. Removed the "cursor_mode" argument to
- ETable since it's part of the spec now.
-
-2000-10-17 Iain Holmes <iain@helixcode.com>
-
- * contact-editor/contact-editor.glade: Change the initial dialog
- visibility to FALSE
- so the contact editor doesn't flash when it appears.
-
-2000-10-16 Iain Holmes <iain@helixcode.com>
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_activate_dialog): Only allow one dialog
- per manager.
-
-2000-10-16 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/fulladdr.glade: Fixed a typo. Made this look a
- bit better.
-
-2000-10-15 Dan Winship <danw@helixcode.com>
-
- * gui/component/select-names/Makefile.am:
- * gui/component/Makefile.am: Remove CPPFLAGS since they just
- duplicate flags that were already in INCLUDES.
-
- * printing/Makefile.am (ecpsdir):
- * gui/widgets/Makefile.am:
- * contact-editor/Makefile.am: Move -D flags from CPPFLAGS to
- INCLUDES so they don't override any CPPFLAGS set at configure
- time.
-
-2000-10-14 Michael Meeks <michael@helixcode.com>
-
- * gui/component/addressbook.c (control_activate): if we are in
- LDAP mode then merge in the extra few items, otherwise just merge
- the standard thing; saves duplication.
-
-2000-10-14 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook.oafinfo: Added
- "evolution:shell-component-icon" property.
-
-2000-10-14 Iain Holmes <iain@helixcode.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_manager_activate_dialog): Only allow one dialog
- per id.
- (e_select_names_manager_destroy): Destroy the hashtable.
- (e_select_names_manager_init): Init the hashtable.
-
-2000-10-13 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/fulladdr.glade, contact-editor/fulladdr.glade.h:
- Rearranged these fields a bit more.
-
-2000-10-13 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor-categories.c,
- gui/component/select-names/e-select-names.c,
- gui/widgets/e-addressbook-view.c: Changed these for boolean
- ascending attribute instead of int ascending attribute. Fixed
- e-select-names to not use a column past the end of its array.
-
- * contact-editor/e-contact-editor-address.c,
- contact-editor/fulladdr.glade, contact-editor/fulladdr.glade.h:
- Rearranged the address editor dialog.
-
-2000-10-11 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor-categories.c: Fixed the column
- elements, the no-headers attribute and added a cursor-mode=line
- attribute.
-
- * gui/component/select-names/e-select-names.c,
- gui/widgets/e-addressbook-view.c: Fixed the column elements here.
-
-2000-10-11 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor-categories.c,
- gui/component/select-names/e-select-names.c,
- gui/widgets/e-addressbook-view.c: Updated these to the new style
- ETables.
-
-2000-10-06 Not Zed <NotZed@HelixCode.com>
-
- * gui/search/e-addressbook-search-dialog.c (get_widget): Removed
- ondemand callback nonsense from rule_context_load().
-
-2000-10-05 Michael Meeks <michael@helixcode.com>
-
- * contact-editor/e-contact-editor.c (create_ui): upd.
- (e_contact_editor_init): upd.
-
- * gui/component/addressbook.c (control_activate_cb): upd.
- (control_deactivate): kill.
- (control_activate): upd.
-
-2000-09-22 Michael Meeks <michael@helixcode.com>
-
- * gui/component/addressbook.c (control_activate): update.
-
- * contact-editor/e-contact-editor.c (create_ui): upd.
-
-Fri Sep 29 07:33:54 2000 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/widgets/e-minicard.c, gui/widgets/e-minicard.h: Made it so
- that minicard doesn't write out changes to the backend unless
- something's actually changed.
-
-Tue Sep 26 16:28:47 2000 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c: Make sure that card->name and
- card->full_name are always valid.
-
- * contact-editor/e-contact-editor.c: Removed some unused
- variables.
-
-2000-09-22 Matt Bissiri <bissiri@eecs.umich.edu>
-
- * contact-editor/e-contact-editor-fullname.c (extract_info): If
- (editor->name == NULL), store ptr to newly allocated ECardName in
- editor->name, not just in a stack variable. This fixes a crash
- which happened when you click "New", then click "Full Name...",
- then enter name, then click "OK".
-
- * backend/ebook/e-card.c (e_card_name_to_string): Add
- g_return_val_if_fail.
-
-2000-09-25 Jeffrey Stedfast <fejj@helixcode.com>
-
- * gui/widgets/Makefile.am:
- * gui/component/Makefile.am:
- * contact-editor/Makefile.am:
- * printing/Makefile.am: Look for ename in /e-util/ename instead of
- /addressbook/ename
-
- * backend/ebook/e-card.c: Updated to include e-util/ename/*.h
-
- * ename: Moved to /e-util so it could be shared
-
- * Makefile.am (SUBDIRS): took out ename
-
-2000-09-25 Nat Friedman <nat@helixcode.com>
-
- * ename/e-name-western-tables.h: Added a ton of new prefixes and
- suffixes.
-
-2000-09-22 Michael Meeks <michael@helixcode.com>
-
- * gui/component/addressbook.c (control_activate): update.
-
- * contact-editor/e-contact-editor.c (create_ui): upd.
-
-2000-09-22 Chris Toshok <toshok@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c: lots of changes. flesh out the
- remove/modify/create functions. add another flag for the property
- table, PROP_DN, which makes it easy for us to determine when we
- need to create a new DN for a record when we're modifying. also
- add a ber_func to the table for PROP_TYPE_LIST fields, which fills
- in the list of bvalues that we send to the ldap server. The
- add/modify/delete stuff hasn't been tested yet, and it hopelessly
- complex (yay ldap).
- (ldap_search_handler): act synchronous when ldap_search responds
- with -1.
- (view_destroy): use pas_book_view_notify_status_message.
- (ldap_op_process_current): same
- (ldap_op_process): same
- (poll_ldap): same
- (ldap_search_handler): same
-
-2000-09-22 Chris Toshok <toshok@helixcode.com>
-
- * backend/ebook/e-card-simple.h: add
- E_CARD_SIMPLE_FIELD_FAMILY_NAME to the enum.
-
- * backend/ebook/e-card-simple.c (field_data): add
- E_CARD_SIMPLE_FIELD_FAMILY_NAME.
- (e_card_simple_get): add getter for FAMILY_NAME.
-
-2000-09-22 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c: Made addresses be quoted printable again
- so that they will encode properly if they have carriage returns in
- them. This is possible now because of a fix in libversit.
-
-2000-09-22 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-book-view-listener.c,
- backend/ebook/e-book-view-listener.h, backend/ebook/e-book-view.c,
- backend/ebook/e-book-view.h, backend/idl/addressbook.idl,
- backend/pas/pas-book-view.c, backend/pas/pas-book-view.h: Added a
- function to set the status message associated with a given view.
- This is not yet implemented in the gui.
-
-2000-09-22 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-book.c, backend/ebook/e-book.h,
- backend/idl/addressbook.idl, backend/pas/pas-backend-file.c,
- backend/pas/pas-backend-ldap.c, backend/pas-backend.c,
- backend/pas/pas-backend.h, backend/pas/pas-book.c,
- backend/pas/pas-book.h: Added a function to query static
- capabilities (capabilities that can be reported immediately) and
- implemented them in the 2 servers.
-
- * gui/component/addressbook.c: Added a View All button and a Stop
- button. Sorted out the new directory server stuff a bit.
-
- * gui/widgets/e-addressbook-model.c,
- gui/widgets/e-addressbook-model.h: Cleaned up a bit. Added a stop
- function. Check for capabilities before deciding whether to load
- all cards when initially viewed.
-
- * gui/widgets/e-addressbook-view.c,
- gui/widgets/e-addressbook-view.h: Added stop and view all
- functions.
-
- * 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:
- Added a stop function. Check for capabilities before deciding
- whether to load all cards when initially viewed.
-
-2000-09-21 Michael Meeks <michael@helixcode.com>
-
- * gui/component/addressbook.c (control_activate): remove _UIHandler
-
-2000-09-21 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/load-pine-addressbook.c: Added a missing include
- of ctype.h.
-
- * backend/pas/pas-backend-file.c: Fixed a problem where using a
- GList was causing us to not be reentrant. We now use an EList
- here and so now this is reentrant. This should fix the "wombat
- crashes every time you run evolution" bug.
-
- * contact-editor/e-contact-editor.c: Fixed a type mismatch.
-
-2000-09-21 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/load-pine-addressbook.c: Make this work when a
- field is spread across multiple lines.
-
-2000-09-20 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Added a
- wants_html field to cards. Uses "x-mozilla-html".
-
- * contact-editor/Makefile.am: Added definition of
- EVOLUTION_DATADIR.
-
- * contact-editor/contact-editor.glade: Make Wants HTML check
- button visible.
-
- * contact-editor/e-contact-editor.c,
- contact-editor/e-contact-editor.h: Make Wants HTML check button
- active. Fix UI stuff to use XML. Set parent window of
- confirm_delete dialog.
-
- * gui/widgets/e-addressbook-view.c, gui/widgets/e-minicard.c: Set
- the parent window of the confirm_delete dialog.
-
-2000-09-20 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/widgets/e-addressbook-view.c: Fixed display of the minicards
- when the addressbook was first loading. (It was overwriting a
- string with NULL during init.)
-
-2000-09-19 Dan Winship <danw@helixcode.com>
-
- * gui/search/Makefile.am (ruledir): Use $(datadir), not
- $(prefix)/share
-
-2000-09-18 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/Makefile.am, contact-editor/Makefile.am,
- ename/Makefile.am, gui/component/Makefile.am,
- gui/widgets/Makefile.am: Added $(EXTRA_GNOME_CFLAGS) and
- $(EXTRA_GNOME_LIBS). Removed unneeded libraries.
-
- * backend/ebook/e-card.c, backend/pas/pas-backend-file.c,
- contact-editor/e-contact-editor-address.c,
- contact-editor/e-contact-editor-categories.c,
- contact-editor/e-contact-editor-categories.h,
- contact-editor/e-contact-editor-fullname.c,
- contact-editor/e-contact-editor.c,
- contact-editor/e-contact-save-as.c, ename/e-address-western.c,
- ename/test-ename-western-gtk.c,
- gui/component/addressbook-factory.c, gui/component/addressbook.c,
- gui/component/e-cardlist-model.h, gui/component/e-ldap-storage.c,
- gui/component/select-names/e-select-names-bonobo.c,
- gui/component/select-names/e-select-names-manager.c,
- gui/component/select-names/e-select-names-model.c,
- gui/component/select-names/e-select-names-table-model.c,
- gui/component/select-names/e-select-names-table-model.h,
- gui/component/select-names/e-select-names-text-model.h,
- gui/component/select-names/e-select-names.c,
- gui/component/select-names/e-select-names.h,
- gui/search/e-addressbook-search-dialog.c,
- gui/widgets/e-addressbook-model.h,
- gui/widgets/e-addressbook-view.c, gui/widgets/e-minicard-label.c,
- 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.h, gui/widgets/e-minicard.c,
- gui/widgets/test-minicard-label.c, gui/widgets/test-reflow.c,
- printing/e-contact-print.c: Fixed the #include lines to deal
- properly with gal.
-
-2000-09-15 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.h,
- contact-editor/e-contact-save-as.h,
- gui/widgets/e-addressbook-model.h,
- gui/widgets/e-minicard-view-widget.h,
- gui/widgets/e-minicard-view.h, gui/widgets/e-minicard.c,
- gui/widgets/e-minicard.h: Fixed the paths of some .h #includes.
-
- * gui/component/addressbook.c: Removed all of the code to actually
- create and display the correct view of the addressbook and moved
- it to the new class gui/widgets/e-addressbook-view.c.
-
- * gui/widgets/Makefile.am: Added everything necessary for
- e-addressbook-view.c and e-addressbook-view.h.
-
- * gui/widgets/e-addressbook-view.c,
- gui/widgets/e-addressbook-view.h: New class to deal with actual
- display of addresses and switching between card view and table
- view.
-
- * gui/widgets/e-minicard-view-widget.c: Made this deal more
- gracefully with having the book set to NULL.
-
-2000-09-16 Michael Meeks <michael@helixcode.com>
-
- * gui/component/select-names/e-select-names.c: fix broken include.
-
- * gui/component/Makefile.am (INCLUDES): define datadir.
- (evolution_addressbook_SOURCES): remove e-addressbook-model.[ch]
-
- * gui/component/addressbook.c (control_activate): use datadir.
-
-2000-09-16 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/widgets/Makefile.am (gladedir): Define.
- (glade_DATA): Install `alphabet.glade'.
- (EXTRA_DIST): Define.
-
- * gui/component/Makefile.am (glade_DATA): Remove `alphabet.glade'.
- (EXTRA_DIST): Remove `alphabet.glade.h'.
-
- * gui/widgets/Makefile.am (libeminicard_a_SOURCES): Add
- `e-addressbook-model.c' and `e-addressbook-model.h'. I hope this
- is what Chris meant to do.
-
- * gui/component/Makefile.am (INCLUDES): Add
- `-I$(top_srcdir)/addressbook/gui/widgets'.
- (evolution_addressbook_SOURCES): Remove `e-addressbook-model.c'
- and `e-addressbook-model.h'.
-
- * gui/component/select-names/e-select-names.c: #include
- "e-addressbook-model.h" from "addressbook/gui/widgets" instead of
- "addressbook/gui/component", as it has been moved there.
-
-2000-09-15 Chris Toshok <toshok@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c: split all the ldap operations
- into 2 halves, a handler, and destructor, and create a structure
- containing two function pointers and any data they need. this
- allows us queue up pending operations (since the LDAP*'s are no
- longer view specific. there's one per backend.) also, add
- support for restarting async operations if the SERVER DOWN error
- isn't communicated until sometime after the handler is called (as
- is the case with the async search stuff.)
-
-2000-09-14 Dan Winship <danw@helixcode.com>
-
- * gui/component/addressbook-factory.c (main): Call unicode_init
- for e-font stuff.
-
-2000-09-14 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/Makefile.am, gui/widgets/Makefile.am: Added
- $(GNOME_PRINT_LIBS) to all of the test files in these directories.
-
-2000-09-14 Michael Meeks <michael@helixcode.com>
-
- * gui/component/Makefile.am (evolution_addressbook_LDADD): fix path.
-
- * gui/component/addressbook.c: update include.
-
- * gui/component/addressbook-factory.c: update include.
-
- * gui/widgets/e-minicard-view.h: update include.
-
- * gui/search/e-addressbook-search-dialog.c: update include path.
-
-2000-09-13 Michael Meeks <michael@helixcode.com>
-
- * contact-editor/e-contact-editor.c (e_contact_editor_init): hack.
- (create_toolbar): ditto.
-
-2000-09-07 Michael Meeks <michael@helixcode.com>
-
- * gui/component/addressbook.c: Radicaly update UI handler code.
-
-2000-09-13 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/widgets/*, gui/minicard/*: Moved gui/minicard to
- gui/widgets, except for e-reflow.c, e-reflow.h, e-reflow-sorted.c,
- and e-reflow-sorted.h.
-
- * gui/widgets/Makefile.am: Added e-reflow to the INCLUDES list and
- libereflow.a to a bunch of LDADD lines.
-
- * gui/component/Makefile.am (evolution_addressbook_LDADD): Added
- libereflow.a here.
-
- * gui/Makefile.am (SUBDIRS): Replaced minicard with widgets.
-
-2000-09-12 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/select-names/Makefile.am: Add space after `-I'
- when invoking `orbit-idl'.
-
-2000-09-12 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/Makefile.am (EXTRA_DIST): Remove `ui.xml'.
-
-2000-09-11 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Fixed a crash error.
-
-2000-09-11 Christopher James Lahey <clahey@helixcode.com>
-
- * ename/e-address-western.c: Fixed some warnings.
-
-2000-09-11 Jesse Pavel <jpavel@helixcode.com>
-
- * ename/e-address-western.c: fixed certain address parsing
- problems.
-
-2000-09-11 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/fulladdr.glade: Made this a bit better balanced.
-
- * gui/component/addressbook.c: Make the toolbar button for find do
- the same thing that the menu item for search does.
-
- * gui/search/e-addressbook-search-dialog.c: Made the top half of
- this not expand.
-
-2000-09-11 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h:
- Removed a bunch of redundant code. Made it so that when you set
- an address label, it sets the delivery address as well. Added
- functions to set and get the delivery address.
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Added code to
- convert and address label to a delivery address.
-
- * contact-editor/Makefile.am: Added e-contact-editor-address.[ch],
- fulladdr.glade, fulladdr.glade.h.
-
- * contact-editor/contact-editor.glade,
- contact-editor/e-contact-editor-strings.h: Switched from a label
- to a button to show the parsed address.
-
- * contact-editor/e-contact-editor-address.c,
- contact-editor/e-contact-editor-address.h: New class to implement
- the parsed address dialog.
-
- * contact-editor/e-contact-editor-fullname.c,
- contact-editor/e-contact-editor-fullname.h: Added const to the
- _new function.
-
- * contact-editor/e-contact-editor.c: Implemented clicking on the
- address button.
-
- * contact-editor/fulladdr.glade, contact-editor/fulladdr.glade.h:
- New glade files for the parsed address dialog.
-
- * contact-editor/fullname-strings.h, fullname.glade: Changed these
- accellabels to labels.
-
- * ename/Makefile.am: Added e-address-western.c.
-
- * ename/e-address-western.c: Fixed some warnings.
-
-2000-09-10 Christopher James Lahey <clahey@helixcode.com>
-
- * ename/e-address-western.c: Added by Jesse.
-
-2000-09-08 Lauris Kaplinski <lauris@helixcode.com>
-
- * gui/minicard/e-minicard-label.c (e_minicard_label_construct):
- Use canvas default font
-
- * gui/minicard/e-minicard.c (e_minicard_realize): Ditto
- (get_left_width): Ditto
-
-2000-09-08 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor-categories.c: Fixed a few warnings.
-
-2000-09-02 Lauris kaplinski <lauris@helixcode.com>
-
- * contact-editor/e-contact-editor-categories.c: e_utf8 wrappers
-
- * contact-editor/e-contact-editor.c: e_utf8 wrappers
-
-2000-09-01 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/e-ldap-storage.c (load_ldap_data): Updated for the
- extra arg now needed by `evolution_storage_new_folder()'.
- (e_ldap_storage_add_server): Likewise.
-
-2000-08-31 Ettore Perazzoli <ettore@helixcode.com>
-
- * conduit/Makefile.am (INCLUDES): Add `BONOBO_GNOME_CFLAGS' and
- `-I$(top_srcdir)'.
-
-2000-08-31 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/Makefile.am: Install load-gnomecard-addressbook
- and load-pine-addressbook.
-
-2000-08-30 Lauris Kaplinski <lauris@helixcode.com>
-
- * printing/e-contact-print.c: Countless small changes for gnome-print 0.21+
-
-2000-08-30 Dan Winship <danw@helixcode.com>
-
- * gui/component/addressbook.oafinfo: Add a name to the minicard
- viewer.
-
-2000-08-29 Dan Winship <danw@helixcode.com>
-
- * backend/ebook/e-book.c:
- * backend/ebook/test-client.c:
- * backend/ebook/test-client-list.c:
- * backend/ebook/load-gnomecard-addressbook.c:
- * backend/ebook/load-pine-addressbook.c:
- * backend/pas/pas-book-factory.c:
- * conduit/address-conduit.h: Remove USING_OAF checks
-
-2000-08-28 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Use the right argument name to turn
- on grid lines.
-
-2000-08-26 JP Rosevear <jpr@helixcode.com>
-
- * gui/minicard/Makefile.am: Comment out minicard-view-test
- since its gnorba dependent
-
-2000-08-26 JP Rosevear <jpr@helixcode.com>
-
- * gui/component/addressbook-component.c: Remove gnorba stuff
-
- * gui/minicard/e-minicard-control.c (e_minicard_control_factory_init):
- ditto
-
- * gui/component/addressbook.c: ditto
-
- * gui/component/addressbook-factory.c: ditto
-
-2000-08-25 Christopher James Lahey <clahey@helixcode.com>
-
- * demo/* Removed the demo directory since it's no longer used.
-
-2000-08-26 JP Rosevear <jpr@helixcode.com>
-
- * gui/minicard/Makefile.am: Remove gnorba stuff
-
- * gui/minicard/e-minicard-control.gnorba: Kill
-
-2000-08-26 JP Rosevear <jpr@helixcode.com>
-
- * gui/component/addressbook.gnorba: Kill
-
- * gui/component/Makefile.am: Remove gnorba stuff
-
-2000-08-25 Dan Winship <danw@helixcode.com>
-
- * gui/component/Makefile.am (evolution_addressbook_LDFLAGS): Add
- -export-dynamic so libglade will be able to resolve custom widget
- callbacks.
-
-2000-08-23 Lauris Kaplinski <lauris@helixcode.com>
-
- * backend/pas/pas-backend-file.c (func_contains): Use e_utf8_strstrcase
-
- * contact-editor/e-contact-editor-fullname.c (fill_in_field): Use e_utf8 wrapper
- (extract_field): Same
-
- * contact-editor/e-contact-editor.c (full_name_clicked): Don't crash
-
- * ename/Makefile.am: Link demo with libeutil.la
-
- * ename/test-ename-western-gtk.c (full_changed_cb): Use e_utf8 wrapper
-
- * gui/component/addressbook.c (find_contact_cb): Use e_utf8 wrapper
- (search_entry_activated): Same
-
-2000-08-22 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/search/e-addressbook-search-dialog.c: Fix an error in the
- arguments to rule_context_load.
-
- * backend/ebook/e-card.c: Fix this to not mess up if the person
- passes a VCard with a carriage return in the mailing address.
-
-2000-08-14 Not Zed <NotZed@HelixCode.com>
-
- * gui/search/addresstypes.xml: Fixed fullname->full_name for
- search field.
-
- * gui/search/e-addressbook-search-dialog.c (get_widget): Check we
- actually got any parts to build the dialogue with.
-
-2000-08-13 Not Zed <NotZed@HelixCode.com>
-
- * gui/component/addressbook-component.c (owner_set_cb): Set the
- global_shell_client nastyhack when we know it.
- This is only required to link with the filter code ...
-
- * gui/component/Makefile.am (evolution_addressbook_LDADD): Added
- libfilter.a to the link line.
-
- * gui/search/Makefile.am (noinst_LIBRARIES): Change library name
- from libaddressbooksearchdialog to libaddressbooksearch, as used
- elsewhere.
-
- * gui/search/e-addressbook-search-dialog.c (get_widget):
- Implement.
- (get_query): Likewise.
- (e_addressbook_search_dialog_destroy): Unref filter stuff when
- done.
-
- * gui/component/addressbook.c (control_deactivate): Added chris's
- patch to put the meny in
-
-2000-08-22 Lauris Kaplinski <lauris@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Use e_utf8 wrappers everywhere
-
-2000-08-22 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/e-card.h: Started adding a time zone field to ECard.
-
- * gui/component/e-addressbook-model.c: Added
- e_table_model_pre_change where appropriate.
-
- * gui/minicard/e-minicard-control.c: Added a ref and unref pair.
-
-2000-08-22 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Linked in the search dialog again.
- It looks like some changes in the shell made this not work.
-
-2000-08-19 Christopher James Lahey <clahey@helixcode.com>
-
- * conduit/address-conduit.c, conduit/address-conduit.h: Changed
- this to use ECardSimple.
-
- * contact-editor/e-contact-editor.c: Fixed a memory leak.
-
- * gui/component/addressbook.c: Added stuff to the right click
- menu. Activated the new search dialog that doesn't quite work
- yet.
-
- * gui/minicard/e-minicard-view.c: Fixed some run time warnings.
-
-2000-08-15 Larry Ewing <lewing@helixcode.com>
-
- * gui/minicard/e-minicard.c (e_minicard_event): use style colors
- for the selected state. This doesn't properly redraw the minicard
- when there is a style_change event, that is next.
- (e_minicard_realize): use style colors.
-
-2000-08-14 Peter Williams <peterw@helixcode.com>
-
- * backend/pas/pas-backend-file.c: Include the proper db1/db.h
- as in RedHat 7.0 -- patch from Kenny Graunke <kwg@teleport.com>
-
-2000-08-13 Chris Toshok <toshok@helixcode.com>
-
- * conduit/Makefile.am (libaddress_conduit_la_SOURCES): add
- address-conduit.h
-
- * Makefile.am (CONDUIT_SUBDIR): only set subdir if
- ENABLE_PILOT_CONDUITS is set.
-
-2000-08-13 Chris Toshok <toshok@helixcode.com>
-
- * Makefile.am (SUBDIRS): add conduit subdir.
-
-2000-08-13 Chris Toshok <toshok@helixcode.com>
-
- * conduit/address-conduit.c (conduit_get_gpilot_conduit): add
- special oaf initialization hack so conduit can find wombat, and
- accept all cookies so that we can actually talk to oaf.
-
-2000-08-13 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-backend-file.c: Fixed a typo that cause the
- wrong field to be searched.
-
- * gui/component/select-names/e-select-names.c: Made the select
- names dialog only display entries with email addresses.
-
-2000-08-12 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/contact-editor.glade: Fixed a typo in the name of
- the first phone entry.
-
-2000-08-12 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/search/Makefile.am,
- gui/search/e-addressbook-search-dialog.c,
- gui/search/e-addressbook-search-dialog.h: A few small interface
- fixes.
-
- * gui/component/Makefile.am: Link in the addressbook search
- dialog.
-
-2000-08-12 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/Makefile.am: Added the search directory.
-
- * backend/ebook/e-book.c: Fixed a potential crash.
-
- * gui/minicard/e-reflow-sorted.h: Fixed an include line.
-
- * gui/search/.cvsignore, gui/search/Makefile.am: New files.
-
- * gui/search/e-addressbook-search-dialog.c: Fixed compilation.
-
-2000-08-12 Christopher James Lahey <clahey@helixcode.com>
-
- * printing/Makefile.am: Ettore fixed compilation.
-
-2000-08-12 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/.cvsignore: Added load-gnomecard-addressbook.
-
-2000-08-12 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/search/e-addressbook-search-dialog.c,
- gui/search/e-addressbook-search-dialog.h: Made this into a Gtk
- object.
-
-2000-08-12 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-book-view.c: Ref our book view listener.
-
- * gui/component/addressbook.c: Updated to use new minicard view
- widget.
-
- * gui/minicard/Makefile.am: Added e-minicard-view-widget.c and
- e-minicard-view-widget.h.
-
- * gui/minicard/e-minicard-view-widget.c,
- gui/minicard/e-minicard-view-widget.h: New class that's just a
- minicard view in an ECanvas.
-
- * gui/search/e-addressbook-search-dialog.c: New file for
- implementing a search dialog.
-
-2000-08-11 Chris Toshok <toshok@helixcode.com>
-
- * conduit/address-conduit.c (transmit): implement code to encode
- the first email address and send to the pilot.
- (get_phone_label_by_flag): rename find_phone_label_for_flags to
- this, and implement by calling get_phone_label_by_name.
-
-2000-08-11 Chris Toshok <toshok@helixcode.com>
-
- * conduit/address-conduit.c (ecard_from_remote_record): add code
- for handling email addresses from pilot (which stores it as a
- phone number entry. go figure.)
- (check_for_slow_setting): #if 0 out, since we don't use it (yet).
- (update_record): un #if 0 the code to handle the case where the
- pilot info has changed for a local record.
- (merge_ecard_with_remote_record): implement function, but for now
- just return the existing (desktop) record - we still don't allow
- merge from the pilot.
-
-
-2000-08-10 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/search/addresstypes.xml: Changed a couple of input field
- names.
-
-2000-08-10 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook-component.c: Remove prototype for
- `setup_ldap_storage()', which shouldn't be here anyway.
-
-2000-08-10 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/search/, gui/search/addresstypes.xml: New search dialog for
- addressbook.
-
-2000-08-10 Dan Winship <danw@helixcode.com>
-
- * gui/component/addressbook-component.c (owner_set_cb): Update for
- changed prototype, pass evolution_homedir arg to
- setup_ldap_storage.
-
- * gui/component/e-ldap-storage.c (setup_ldap_storage): Now takes
- an evolution_homedir arg, uses that to generate the path to the
- ldapservers.xml file, and stores the result in a static variable.
- (e_ldap_storage_add_server, e_ldap_storage_remove_server): Use that
- static variable rather than hardcoding the path to the file.
-
-2000-08-10 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-backend-file.c: Fixed any search to not crash on
- missing phone numbers or email addresses.
-
-2000-08-09 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/e-minicard-control.c: Added a button to save to
- your addressbook.
-
-2000-08-09 Cody Russell <bratsche@gnome.org>
-
- * gui/component/addressbook.c: Make the toolbar honor the user's
- gnomecc settings for detachable toolbars.
-
-2000-08-09 Nat Friedman <nat@helixcode.com>
-
- * ename/e-name-western-tables.h: Added some military prefixes.
-
-2000-08-09 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Fixed a warning.
-
-2000-08-09 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook.c (control_activate): Add the stock
- print icon to the print item.
-
-2000-08-09 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook.c (control_activate): Put the print
- item in the right placeholder so that it gets the right position
- in the "File" menu.
- (control_deactivate): Updated accordingly.
-
-2000-08-09 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c, gui/minicard/e-minicard.c: Changed
- e_popup_menu_run call to match the new arguments.
-
- * gui/component/addressbook.oafinfo: Fixed this file to work
- properly.
-
- * gui/minicard/e-minicard-control.c: Use the correct oafinfo ID
- here. Also cleaned up the code a bit with the help of Michael
- Meeks.
-
-2000-08-08 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/e-addressbook-model.c (e_addressbook_model_init):
- use x-evolution-any-field.
-
- * gui/component/addressbook.c (search_entry_activated): use
- x-evolution-any-field.
- (change_view_type): same.
-
- * gui/minicard/e-minicard-view.c (e_minicard_view_init): set query
- to x-evolution-any-field.
-
- * backend/pas/pas-backend-ldap.c (func_contains): support
- x-evolution-any-field for matching any evolution supported field.
-
- * backend/pas/pas-backend-file.c (compare_email): switch to using
- ECardSimple calls.
- (compare_phone): same.
- (compare_address): same.
- (entry_compare): switch to using ECardSimple calls, and support a
- 'x-evolution-any-field' wildcard field.
- (vcard_matches_search): use an ECardSimple.
-
-2000-08-07 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Removed the next and prev
- toolbar buttons since they don't do anything.
-
-2000-08-07 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/contact-editor.glade,
- contact-editor/e-contact-editor.c: Fixed the tab order to not
- repeat the web page address field.
-
-2000-08-07 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Fixed the tab order for this
- dialog.
-
-2000-08-05 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-simple.c: Fixed a warning.
-
- * backend/ebook/e-card.c: Cast to (char *) in
- e_card_load_cards_from_file since libversit isn't const correct.
-
- * backend/pas/pas-backend-file.c: Fixed a warning.
-
-2000-08-04 Michael Meeks <michael@helixcode.com>
-
- * gui/component/addressbook.c (control_activate): unref.
-
- * demo/addressbook.c (control_activate): unref.
-
-2000-08-02 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor-categories.c,
- gui/component/e-addressbook-model.c: Emit "model_pre_change"
- signal as appropriate.
-
-2000-08-02 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/e-addressbook-model.c: Adapted this to supply the
- new append_row API of ETableModel.
-
-2000-07-31 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Changed the default set of columns.
-
-2000-07-29 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/Makefile.am: Added load-gnomecard-addressbook
- compilation.
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Added
- e_card_load_cards_from_file helper function to load multiple cards
- from a single file.
-
- * backend/ebook/load-gnomecard-addressbook.c: New file to load
- vcard files. I think this is the format that gnomecard uses so if
- you copy your gnomecard file to gnomecard.vcf and then run this
- program in the same directory, it'll copy all your gnome contacts
- into evolution. It needs to be changed to take a filename as a
- parameter. Some fields (phone and address information, for
- example) aren't displayed properly, but are saved. This is new
- code, so some other than phone and address may be lost.
-
-2000-07-28 Ettore Perazzoli <ettore@helixcode.com>
-
- * backend/pas/Makefile.am: Add `pas-backend-ldap.c' and
- `pas-backend-ldap.h' to `EXTRA_DIST' so they get distributed even
- if the OpenLDAP support is not enabled.
-
-2000-07-27 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/load-pine-addressbook.c: Changed the URI to load
- to.
-
-2000-07-26 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/e-minicard-widget-test.c: Fixed a warning.
-
-2000-07-26 Chris Toshok <toshok@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c (view_destroy): wait to free the
- view until we've taken care of freeing its internals. also, close
- the ldap connection here.
- (pas_backend_ldap_connect): rename p_b_l_ensure_connected to this,
- since it's always called when we create a view.
- (pas_backend_ldap_build_all_cards_list): open an ldap connection
- in this function and close it at the end.
- (poll_ldap): make sure to call ldap_unbind to close the view's
- connection here.
- (pas_backend_ldap_search): call pas_backend_ldap_connect here -
- ldap_unbind will either be called from poll_ldap or from
- view_destroy.
- (pas_backend_ldap_get_vcard): the PASBackendLDAP no longer has an
- LDAP*.
-
-2000-07-26 Chris Toshok <toshok@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_build_all_cards_list): add support for user settable scope.
- (pas_backend_ldap_search): same.
- (pas_backend_ldap_load_uri): same.
-
-2000-07-26 Dan Winship <danw@helixcode.com>
-
- * gui/component/addressbook.oafinfo: lowercasify the
- supported_mime_types
-
-2000-07-25 Chris Toshok <toshok@helixcode.com>
-
- * backend/ebook/e-card-types.h: add enum for e-card pilot status.
-
- * conduit/address-conduit.c: #ifdef out all the archiving code with SUPPORT_ARCHIVING.
- (purge): implement correctly - deleting ecards whose pilot status is DELETED.
- (set_status): implement.
- (set_pilot_id): add gtk_main call here to change commit_card into a synchronous
- (delete_all): implement correctly - don't delete the records, just set their status to DELETED.
- (local_record_from_ecard): get the current status from the ecard.
-
- * backend/ebook/e-card.c (e_card_get_vcard): add vcard support for pilot status.
- (parse_pilot_status): new function.
- (e_card_class_init): add pilot status object arg.
- (e_card_set_arg): add pilot status support.
- (e_card_get_arg): same.
- (e_card_init): initialize pilot_status to 0.
-
-2000-07-25 Chris Toshok <toshok@helixcode.com>
-
- * conduit/address-conduit.c: add comment headers to signals that
- didn't have any.
-
-2000-07-25 Chris Toshok <toshok@helixcode.com>
-
- * conduit/address-conduit.c (start_address_server): use the user's
- Contact db. not toshok's.
-
-2000-07-25 Michael Meeks <michael@helixcode.com>
-
- * backend/ebook/load-pine-addressbook.c (book_open_cb): check we
- opened ok.
-
-2000-07-25 Seth Alves <alves@hungry.com>
-
- * ename/Makefile.am (libename_static_la_LDFLAGS): build static
- version of the library for address conduit to use
-
- * backend/ebook/Makefile.am: build a static version of the library
- to link into the conduit
-
-2000-07-25 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c: Added a #define for
- "X-EVOLUTION-PILOTID". Added a parse_pilot_id to read pilot id's
- in properly from VCards. Rearranged some field orders. Added a
- get_arg case for ARG_PILOTID. Initialize pilot_id field to 0.
-
-2000-07-24 Chris Toshok <toshok@helixcode.com>
-
- * backend/ebook/e-card.h: add pilot_id.
-
- * backend/ebook/e-card.c (e_card_get_vcard): add support for
- X-EVOLUTION-PILOTD vcard field.
- (e_card_class_init): add pilot_id arg.
- (e_card_set_arg): handle pilot_id arg.
-
-2000-07-23 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-book-view-listener.c: Remove the idle handler
- when we're destroyed.
-
- * printing/e-contact-print.c: Fixed the spacing on the card
- header.
-
-2000-07-20 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.oafinfo: Fixed the oaf info.
-
- * gui/minicard/.cvsignore, gui/minicard/Makefile.am,
- gui/minicard/e-minicard-widget-test.c: Added a test for the
- minicard widget.
-
- * gui/minicard/e-minicard-control.c: Fixed the mime type.
-
- * gui/minicard/e-minicard.c: Fixed some crashes if your parent
- isn't a minicard view.
-
- * gui/minicard/e-minicard-control.oafinfo: Removed.
-
-2000-07-20 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook-component.c (factory_fn): Update for
- the new `evolution_shell_component_new()'.
-
-2000-07-19 Fatih Demir <kabalak@gmx.net>
-
- * conduit/address-conduit-control-applet.desktop:
- Added the Turkish desktop entry.
-
-2000-07-18 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/e-minicard-control.c: Added "text/vCard" to the
- list of mime types we support.
-
-2000-07-18 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/Makefile.am: Added
- gui/minicard/e-minicard-control.c,
- gui/minicard/e-minicard-control.h,
- gui/minicard/e-minicard-widget.c, and
- gui/minicard/e-minicard-widget.h.
-
- * gui/minicard/e-minicard-control.c,
- gui/minicard/e-minicard-control.h,
- gui/minicard/e-minicard-widget.c,
- gui/minicard/e-minicard-widget.h: Got these to compile.
-
- * gui/minicard/e-minicard-control.gnorba,
- gui/minicard/e-minicard-control.oafinfo: Copied directly from
- bonobo-clock-control. These aren't done yet.
-
-2000-07-18 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/e-minicard-control.c,
- gui/minicard/e-minicard-control.h,
- gui/minicard/e-minicard-widget.c,
- gui/minicard/e-minicard-widget.h: New files for using a minicard
- as a widget or a bonobo control.
-
-2000-07-14 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/e-ldap-storage.c (ldap_server_foreach): duh.
- don't save the port in the host slot either.
-
-2000-07-13 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor-confirm-delete.glade,
- contact-editor/e-contact-editor-confirm-delete.glade.h: Added
- these.
-
-2000-07-13 Christopher James Lahey <clahey@helixcode.com>
-
- * Makefile.am: Switched the order of compilation of printing and
- contact-editor.
-
- * contact-editor/Makefile.am: Added printing libraries and a
- confirm delete dialog glade file.
-
- * contact-editor/e-contact-editor.c,
- contact-editor/e-contact-editor.h: Enabled the delete and print
- functions as well as providing a confirm delete dialog to the
- outside world.
-
- * gui/component/addressbook.c: Made the delete button on new cards
- active.
-
- * gui/minicard/Makefile.am: Added printing libraries to a number
- of test programs.
-
- * gui/minicard/e-minicard.c: Added print and delete to the right
- click menu. Made the delete button on the card editor active.
-
- * printing/e-contact-print.c, printing/e-contact-print.h: Added a
- function to print a single card.
-
-2000-07-12 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/e-ldap-storage.c (ldap_server_foreach): oops. fix
- typo that was saving the port in the rootdn spot.
- (save_ldap_data): make this a bit safer - writing to a new file
- and renaming it.
- (load_ldap_data): make this a bit smarter - if parsing the
- ldapservers.xml file fails and there's a .new file there,
- rename it.
-
-2000-07-12 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-backend-file.c: Do case insensitive compares.
-
- * addressbook/gui/component/addressbook.c: Make quick search
- search both name and company name.
-
-2000-07-12 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Add icons to the toolbars.
-
-2000-07-12 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/Makefile.am: Added installation of arrow.png.
-
- * contact-editor/e-contact-editor.c: Use EVOLUTIONDIR #define.
-
-2000-07-11 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Removed an unused function
-
-2000-07-10 Dan Winship <danw@helixcode.com>
-
- * gui/component/select-names/Makefile.am (EXTRA_DIST): add idl
- file to EXTRA_DIST
-
-2000-07-10 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook.c (control_activate): Remove the
- SelectNames test.
-
-2000-07-10 Peter Williams <peterw@curious-george.helixcode.com>
-
- * gui/component/select-names/e-select-names-model.c: (Clahey's fix)
- Make multiple addresses be concatenated correctly.
-
-2000-07-09 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c,
- gui/component/select-names/e-select-names.c,
- gui/component/select-names/e-select-names.h: Switched from ETable
- to ETableScrolled.
-
- * addressbook/gui/minicard/e-minicard.c: Don't display mailer or
- "name or org" fields.
-
-2000-07-09 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h:
- Added a field that gives the name if it exists and the company
- name otherwise.
-
- * gui/component/e-addressbook-model.c: Formatting changes.
-
- * gui/component/select-names/e-select-names-table-model.c: Added
- stripping of names and display of company name if name doesn't
- exist.
-
- * gui/component/select-names/e-select-names.c: Fixed up the
- display so that we display both name and email address.
-
-2000-07-09 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/select-names/e-select-names-model.c: Fixed a small
- off by one error that was causing an extra character to get
- deleted sometimes.
-
-2000-07-09 Anders Carlsson <andersca@gnu.org>
-
- * gui/minicard/test-reflow.c (allocate_callback): Fix off by one bug with
- scroll region setting.
- (resize): Likewise.
- (main): Put the contacts list in an EScrolledFrame instead of using a
- separate GtkScrollbar.
-
- * gui/minicard/e-reflow.c (e_reflow_event): Don't change mouse cursor and
- don't allow drags on dividers that aren't visible.
-
- * gui/component/addressbook.c (allocate_callback): Fix off by one bug with
- scroll region setting.
- (resize): Likewise.
- (create_minicard_view): Put the contacts list in an EScrolledFrame instead of
- using a separate GtkScrollbar.
-
-2000-07-09 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Removed unused do_nothing_cb
- function.
-
- * gui/component/select-names/e-select-names-manager.c,
- gui/component/select-names/e-select-names-manager.h: Made the OK
- and Cancel buttons in the ESelectNames dialog we create work
- properly.
-
- * gui/component/select-names/e-select-names-model.c,
- gui/component/select-names/e-select-names-model.h: Added
- e_select_names_model_duplicate.
-
- * gui/component/select-names/e-select-names-text-model.c: Made the
- text be set correctly if there's already data in the source when
- the text model is created.
-
- * gui/component/select-names/e-select-names.c,
- gui/component/select-names/e-select-names.h: Removed handling of
- the buttons (the user of this dialog will have to handle them.)
- Added e_select_names_get_source. Fixed some typos.
-
-2000-07-09 Not Zed <NotZed@HelixCode.com>
-
- * gui/component/addressbook.c: Link the toolbar print button to
- the print callback.
-
-2000-07-08 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/select-names/e-select-names.c
- (e_select_names_clicked): Hitting OK or Cancel at least closes the
- dialog now.
-
-2000-07-08 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_create_entry): Set the returned entry to
- use the ellipsis.
-
-2000-07-08 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook-factory.c: Include
- e-select-names-factory.h.
-
- * gui/component/select-names/e-select-names-model.c: Handle a NULL
- iterator properly in the replace function.
-
- * gui/component/select-names/e-select-names-table-model.c: Fill in
- info properly in the value_at function.
-
- * gui/component/select-names/e-select-names-text-model.c: Don't
- strlen a NULL text object.
-
- * gui/component/select-names/e-select-names.c: Close if the person
- hits ok or cancel (doesn't yet actually undo changes if Cancel is
- hit.) Handle removing addresses when they're double clicked on.
-
- * gui/component/select-names/select-names.glade,
- gui/component/select-names/select-names.glade.h: Hid some unused
- fields and changed the text at the top of the dialog.
-
-2000-07-08 Jeffrey Stedfast <fejj@helixcode.com>
-
- * gui/component/select-names/.cvsignore: Ignore dynamically
- created source files
-
-2000-07-08 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/select-names/e-select-names-bonobo.c
- (entry_get_property_fn): New function to set the properties.
-
-2000-07-08 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook-factory.c (main): Start up the factory
- for `Evolution::Addressbook::SelectNames'.
-
- * gui/component/select-names/evolution-addressbook-select-names.oafinfo:
- New.
-
- * gui/component/select-names/e-select-names-factory.c: New.
- * gui/component/select-names/e-select-names-factory.h: New.
-
- * gui/component/select-names/e-select-names-bonobo.c: New.
- * gui/component/select-names/e-select-names-bonobo.h: New.
-
- * gui/component/addressbook-factory.c (main): Call
- `e_select_names_factory_init()'.
-
- * gui/component/select-names/e-select-names-manager.c
- (e_select_names_manager_add_section): Made const-aware.
- (e_select_names_manager_create_entry): Made const-aware.
- (e_select_names_manager_activate_dialog): Made const-aware.
-
- * gui/component/select-names/Evolution-Addressbook-SelectNames.idl:
- New.
-
-2000-07-08 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/e-addressbook-model.c,
- gui/component/e-addressbook-model.h: Added an "editable" argument.
-
- * gui/component/select-names/e-select-names.c: Set our
- EAddressModel to not be editable.
-
-2000-07-07 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/select-names/e-select-names.c: Changed to line
- mode.
-
-2000-07-07 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/select-names/e-select-names-manager.c,
- gui/component/select-names/e-select-names-model.c: Implemented the
- get_cards function.
-
- * gui/component/select-names/e-select-names.c: Implemented adding
- cards through the interface.
-
-2000-07-07 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/select-names/e-select-names-manager.c: Make the
- entry widgets we create editable.
-
- * gui/component/select-names/e-select-names-model.c: Use
- e_strsplit instead of g_strsplit. Fixed an off by 1 error.
-
- * gui/component/select-names/e-select-names-table-model.c: When
- the model changes, send a model changed signal.
-
- * gui/component/select-names/e-select-names-text-model.c: Made
- changing this work correctly if it's empty. Made change signals
- propagate properly. Is a bit better about freeing iterators when
- done.
-
- * gui/component/select-names/e-select-names.c: Made the finished
- lists be in order instead of being sorted.
-
-2000-07-07 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c (new_server_cb): Since
- ELDAPServer->port is a char *, allocate a string with the number
- 389 contained.
-
- * gui/component/addressbook.c: Make the select names test test the
- new code instead of the old way of getting to an ESelectNames
- dialog.
-
- * gui/component/select-names/e-select-names-manager.c: Coded
- storing the model for each section, creating an entry and
- returning it, and for activating the dialog. Wrote a bit of the
- get_cards code, but not all of it.
-
- * gui/component/select-names/e-select-names-model.c,
- gui/component/select-names/e-select-names-model.h: Coded all of
- the code needed to make ESelectNamesTextModel work (it doesn't
- yet, but all the code should be there.) Removed
- E_SELECT_NAMES_MODEL_DATA_TYPE_SEPARATION_MATERIAL.
-
- * gui/component/select-names/e-select-names-table-model.c,
- gui/component/select-names/e-select-names-text-model.c: Changed
- these to compensate for removal of
- E_SELECT_NAMES_MODEL_DATA_TYPE_SEPARATION_MATERIAL.
-
- * gui/component/select-names/e-select-names-table-model.h,
- gui/component/select-names/e-select-names-text-model.h: Fixed some
- silly typos.
-
- * gui/component/select-names/e-select-names.c,
- gui/component/select-names/e-select-names.h: Added a parameter to
- add_section that lets you specify the source ESelectNamesModel.
-
-2000-07-06 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/e-ldap-storage.h: add scope to ELDAPServer, and
- make port a string.
-
- * gui/component/e-ldap-storage.c (load_ldap_data): don't load a
- uri, load all the bits and pieces and build up the uri when
- creating the folder, according to the openldap url format.
- (ldap_server_foreach): store out each of the individual uri
- pieces.
- (e_ldap_storage_remove_server): free the new fields.
- (get_string_value): if the text is empty, return the empty string
- instead of NULL.
-
- * gui/component/e-ldap-server-dialog.c (extract_server_info): port is a string now.
- (fill_in_server_info): port is a string now.
-
-2000-07-06 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Changed "FIXME: Save and
- Close" to "Save and Close". Removed some toolbar items that will
- never be used.
-
- * gui/component/select-names/e-select-names-model.c,
- gui/component/select-names/e-select-names-model.h: Added functions
- to allow you to modify the model (not implemented yet.)
-
- * gui/component/select-names/e-select-names-table-model.c,
- gui/component/select-names/e-select-names-table-model.h: Finished
- this. Doesn't support changing the model at all.
-
- * gui/component/select-names/e-select-names-text-model.c: Finished
- this. Changing the model by typing is done, but doesn't work
- since none of the functions in the base model are implemented.
-
-2000-07-05 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/addressbook.c (new_server_cb): call
- e_ldap_storage_add_server call.
-
- * gui/component/ldap-server-dialog.glade: add name row.
-
- * gui/component/e-ldap-server-dialog.h: remove the ELDAPServer type.
-
- * gui/component/e-ldap-server-dialog.c (extract_server_info): add
- support for the name-entry.
-
- * gui/component/e-ldap-server-dialog.c (fill_in_server_info): same.
-
- * gui/component/e-ldap-storage.h: add ELDAPServer type, and add
- prototypes for e_ldap_storage_add_server and
- e_ldap_storage_remove_server.
-
- * gui/component/e-ldap-storage.c (e_ldap_storage_add_server): new
- function, add it to our hash table, add a shell folder, and save
- out the metadata.
- (ldap_server_foreach): add the ldap server info under a
- "contactserver" node.
- (setup_ldap_storage): create our hashtable.
-
-2000-07-05 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/addressbook.c (set_prop): remove hack to read
- "uri" file from local directory.
-
- * gui/component/Makefile.am (evolution_addressbook_SOURCES): add
- e-ldap-storage.{c,h}
-
- * gui/component/addressbook-component.c (owner_set_cb): call
- setup_ldap_storage.
-
- * gui/component/e-ldap-storage.c (setup_ldap_storage): Register
- the LDAP storage and load the .xml file.
- (load_ldap_data): function to load our xml file.
- (save_ldap_data): function to save our xml file.
-
- * gui/component/e-ldap-storage.h: new file.
-
-2000-07-03 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/select-names/e-select-names-manager.c,
- gui/component/select-names/e-select-names-text-model.c,
- gui/component/select-names/e-select-names.c: Fixed more compile
- errors.
-
-2000-07-03 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/select-names/Makefile.am: Fixed compile error.
-
-2000-07-03 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/Makefile.am: Removed e-card-iterator.c,
- e-card-iterator.h, e-card-list-iterator.c, e-card-list-iterator.h,
- e-card-list.c, e-card-list.h.
-
- * backend/ebook/e-card-iterator.c,
- backend/ebook/e-card-iterator.h,
- backend/ebook/e-card-list-iterator.c,
- backend/ebook/e-card-list-iterator.h, backend/ebook/e-card-list.c,
- backend/ebook/e-card-list.h: Removed in favor or versions without
- the -card in the e-util directory since these classes are not
- specific to cards at all.
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h,
- backend/ebook/e-card.c, backend/ebook/e-card.h,
- backend/ebook/load-pine-addressbook.c, backend/ebook/test-card.c,
- backend/pas/pas-backend-file.c: Changed the references to
- e-card-list.c and friends to e-list.c and friends.
-
- * contact-editor/e-contact-editor.c: Added #include
- <e-contact-save-as.h> to fix a warning.
-
- * gui/component/Makefile.am: Moved a number of classes associated
- with the select-names object to the new select-names directory.
-
- * gui/component/addressbook.c: Changed the reference to
- e-select-names.h.
-
- * gui/component/e-select-names.c, gui/component/e-select-names.h,
- gui/component/select-names.glade,
- gui/component/select-names.glade.h: Moved these files into
- select-names/.
-
- * gui/component/select-names/.cvsignore,
- gui/component/select-names/Makefile.am,
- gui/component/select-names/e-select-names-manager.c,
- gui/component/select-names/e-select-names-manager.h,
- gui/component/select-names/e-select-names-model.c,
- gui/component/select-names/e-select-names-model.h,
- gui/component/select-names/e-select-names-table-model.c,
- gui/component/select-names/e-select-names-table-model.h,
- gui/component/select-names/e-select-names-text-model.c,
- gui/component/select-names/e-select-names-text-model.h,
- gui/component/select-names/e-select-names.c,
- gui/component/select-names/e-select-names.h,
- gui/component/select-names/recipient.glade,
- gui/component/select-names/select-names.glade,
- gui/component/select-names/select-names.glade.h: New files for
- select names dialog (e-select-names.c, e-select-names.h,
- select-names.glade, select-names.glade.h and recipient.glade moved
- from gui/component/.)
-
-2000-06-29 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook-component.c (owner_set_cb): Get an
- EvolutionShellClient instead of an Evolution_Shell to match the
- changes in libeshell.
-
-2000-06-28 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/select-names/,
- gui/component/select-names/e-select-names-manager.c,
- gui/component/select-names/e-select-names-manager.h: New select
- names manager interface (Not complete.)
-
-2000-06-26 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor-categories.c,
- addressbook/gui/component/e-cardlist-model.c: Added
- value_to_string handlers.
-
- * demo/addressbook-widget.c, demo/demo.c: Removed usage of "x" and
- "y" arguments.
-
- * addressbook/gui/component/addressbook.c: Activated Click To Add
- and set the click to add message.
-
- * addressbook/gui/component/e-addressbook-model.c: Added
- value_to_string and append_row handlers.
-
- * addressbook/gui/component/e-select-names.c: Added a column.
-
-2000-06-26 Chris Toshok <toshok@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c (poll_ldap): remove spew.
- (pas_backend_ldap_ensure_connected): duh, don't access a pointer
- we know to be NULL.
- (query_prop_to_ldap): rename map_e_card_prop_to_ldap to this.
- easier to type.
-
-2000-06-21 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/test-minicard-label.c,
- gui/minicard/test-minicard.c, gui/minicard/test-reflow.c: Remove
- usage of "x" and "y" arguments.
-
-2000-06-18 <ettore@helixcode.com>
-
- * contact-editor/Makefile.am (INCLUDES): Use
- `$(BONOBO_GNOME_CFLAGS)' so that we compile when Bonobo is not in
- the default GNOME prefix.
-
-2000-06-17 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/e-minicard-label.c,
- gui/minicard/e-minicard-label.h, gui/minicard/e-minicard.c: Made
- the left column of minicards not get any wider than the widest
- possible name.
-
-2000-06-13 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/Makefile.am (SHELL_OBJS): Removed.
- (evolution_addressbook_LDADD): Link with
- `$(top_builddir)/shell/libeshell.a'.
-
-2000-06-12 Federico Mena Quintero <federico@helixcode.com>
-
- * contact-editor/e-contact-editor-categories.c: Removed the
- ETableModel thaw handler.
- * gui/component/e-cardlist-model.c: Likewise.
-
-2000-06-11 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/e-select-names.c: Fixed the widget reparenting.
-
-2000-06-11 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/Makefile.am: Added glade files.
-
- * gui/component/addressbook.c: Added a test of the Select Names
- functionality.
-
- * gui/component/e-addressbook-model.c: Made this class_init
- function a bit cleaner.
-
- * gui/component/e-select-names.c: Tested this and fixed some
- obvious errors.
-
- * gui/component/select-names.glade: The main window shouldn't be
- visible by default.
-
-2000-06-11 Ettore Perazzoli <ettore@helixcode.com>
-
- * contact-editor/Makefile.am (contact_editor_test_LDADD): Link
- with libemiscwidgets.a.
- * gui/component/Makefile.am (evolution_addressbook_LDADD): Likewise.
- * gui/minicard/Makefile.am (minicard_test_LDADD): Likewise.
- (reflow_test_LDADD): Likewise.
- (minicard_view_test_LDADD): Likewise.
-
-2000-06-10 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/e-cardlist-model.c: Renamed a bunch of functions
- for better readability.
-
- * gui/component/e-select-names.c, gui/component/e-select-names.h:
- This should be a working dialog now.
-
- * gui/component/select-names.glade: Changed the name & creation
- function of the ETable here.
-
-2000-06-10 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/select-names.glade,
- gui/component/select-names.glade.h: Glade files for Select Names
- dialog.
-
-2000-06-10 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Do e_card_simple_sync and
- extract_info more often.
-
- * gui/component/addressbook.c: Added table printing code.
-
-2000-06-09 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook-component.c (factory_fn): Pass NULL
- for the new args @create_folder_fn and @remove_folder_fn.
-
-2000-06-08 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook-component.c (create_view): Updated for
- the new `EvolutionShellComponentCreateViewFn'. Return
- `EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE' if @type is not
- "contacts".
-
-2000-06-08 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Bind Save As to save the
- current view of the contact as a vcard.
-
-2000-06-08 Federico Mena Quintero <federico@helixcode.com>
-
- * contact-editor/e-contact-editor.c (save_card): Doh, sync the
- card simple and extract the card info.
-
-2000-06-08 Federico Mena Quintero <federico@helixcode.com>
-
- * contact-editor/e-contact-editor.h (EContactEditor): Now this
- derives from GtkObject. It follows the same strategy as the
- EventEditor in the calendar.
- (EContactEditor): Added an is_new_card field so that we can know
- whether to add() or commit() the card.
-
- * contact-editor/e-contact-editor.c (e_contact_editor_get_type):
- Derive from GtkObject.
- (e_contact_editor_class_init): Likewise.
- (e_contact_editor_class_init): Added an "is_new_card" argument.
- (e_contact_editor_set_arg): Handle ARG_IS_NEW_CARD.
- (e_contact_editor_get_arg): Likewise.
- (e_contact_editor_new): Take in an is_new_arg argument and set it
- on the object.
- (e_contact_editor_init): Load the app widget into the app field of
- the EContactEditor structure. Create its UIHandler as well.
- (e_contact_editor_class_init): New "add_card", "commit_card", and
- "editor_closed" signals.
-
- * contact-editor/test-editor.c (main): Modified for the new API.
- (editor_closed_cb): Tweaked for the new API.
- Since this test program does not use Bonobo, it doesn't work,
- though.
-
- * gui/component/addressbook.c (new_contact_cb): Use the new
- contact editor API.
- (table_double_click): Ditto.
-
- * gui/minicard/e-minicard-view.c (e_minicard_view_event): Use the
- new contact editor API.
-
- * gui/minicard/e-minicard.c (e_minicard_event): Use the new
- contact editor API.
-
-2000-06-08 Ettore Perazzoli <ettore@helixcode.com>
-
- * contact-editor/Makefile.am (contact_editor_test_LDADD): Remove
- the `$(srcdir)/' prefix from `libecontacteditor.a' because [of
- course] the library is built in the build directory, not in the
- source directory.
- * gui/minicard/Makefile.am (minicard_test_LDADD): Likewise with
- `libeminicard.a'.
- (minicard_label_test_LDADD): Likewise.
- (reflow_test_LDADD): Likewise.
- (minicard_view_test_LDADD): Likewise.
-
-2000-06-06 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Bind right click on the ETable to
- "Save to VCard."
-
-2000-06-02 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Made phone/email/address
- labels change correctly again.
-
-2000-06-02 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook-component.c: Made
- evolution-addressbook shut down when the shell is done with it.
-
-2000-06-02 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/e-minicard-view.c, gui/minicard/e-minicard.c: Made
- double click only work on the first button.
-
-2000-06-01 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/e-minicard.c: return TRUE if opening a contact
- editor so that we don't get a "new dialog" contact editor.
-
-2000-06-01 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook.c (new_contact_cb): Use the stock
- cancel button for the dialog.
- (table_double_click): Likewise.
- (find_contact_cb): Likewise.
-
-2000-05-31 Miguel de Icaza <miguel@helixcode.com>
-
- * contact-editor/contact-editor.glade: Added accelerators for
- the remaining items.
-
- Add spacing, beautify the dialogs.
-
-2000-06-01 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook.c (control_activate): Put the toolbar
- into a frame to make it look like standard GNOME toolbars. Also,
- set `GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL' so that it does not do
- evil things when its moved to the left or the right of the window.
-
-2000-05-30 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/e-cardlist-model.c,
- gui/component/e-cardlist-model.h: New files for card list.
-
-2000-05-30 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Fixed a memory leak.
-
-2000-05-30 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/alphabet.glade: Made the alphabet buttons not
- focusable.
-
- * gui/minicard/e-minicard-view.c: Made the "123" button work.
-
- * gui/minicard/e-reflow-sorted.c: Made all buttons past the last
- letter available work.
-
-2000-05-30 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/alphabet.glade: Added a bit of space around the
- alphabet bar.
-
-2000-05-30 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/Makefile.am: Added alphabet.glade and
- alphabet.glade.h.
-
- * gui/component/addressbook.c, gui/component/alphabet.glade,
- gui/component/alphabet.glade.h: Added an alphabet bar.
-
- * gui/minicard/e-minicard-view.c, gui/minicard/e-minicard-view.h,
- gui/minicard/e-reflow-sorted.c, gui/minicard/e-reflow-sorted.h:
- Added the ability to just to a particular spot in the reflow.
-
-2000-05-30 Christopher James Lahey <clahey@helixcode.com>
-
- * printing/Makefile.am: Added BONOBO_GNOME_CFLAGS to CPPFLAGS.
-
-2000-05-30 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/e-minicard-view.c: Made double clicking create a
- new card. Set the empty message.
-
- * gui/minicard/e-minicard.c: Made sorting be case insensitive.
-
- * gui/minicard/e-reflow-sorted.c, e-reflow.c, e-reflow.h: Added a
- message for when the reflow is empty.
-
- * printing/e-contact-print.c, printing/medbook.ecps: Made the
- default printout be full page. Made sorting case insensitive.
-
-2000-05-30 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-book-view-listener.c,
- backend/ebook/e-book-view-listener.h, backend/ebook/e-book-view.c,
- backend/ebook/e-book-view.h, backend/idl/addressbook.idl,
- backend/pas/pas-backend-file.c, backend/pas/pas-backend-ldap.c,
- backend/pas/pas-book-factory.c, backend/pas/pas-book-view.c,
- backend/pas/pas-book-view.h: Added "sequence_complete" signal.
-
- * printing/e-contact-print.c: Made printing wait for
- "sequence_complete" signal and made it sort.
-
-2000-05-25 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c,
- gui/component/e-addressbook-model.c,
- gui/component/e-addressbook-model.h: Added double click to open
- contact editor.
-
-2000-05-25 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Removed some columns.
-
-2000-05-25 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component/addressbook.c (addressbook_factory_new_control):
- New function.
- (addressbook_factory): Use it.
-
- * Makefile.am (evolution_addressbook_LDADD): Link with
- `evolution-shell-component.o' from the shell directory.
-
- * gui/component/addressbook-component.c: New.
- * gui/component/addressbook-component.h: New.
-
-2000-05-23 Christopher James Lahey <clahey@helixcode.com>
-
- * Makefile.am: Switched printing and gui.
-
- * backend/ebook/e-book-view-listener.h,
- backend/ebook/e-book-view.h, backend/ebook/e-book.h,
- backend/ebook/e-card-cursor.h, backend/ebook/e-card-list.h,
- backend/ebook/e-card-simple.h, backend/ebook/e-card.h: Fixed the
- #defines to work elsewhere in evolution.
-
- * gui/component/Makefile.am: Added linking to libecontactprint.
-
- * gui/component/addressbook.c: Added a menu item to print the
- current query.
-
- * printing/Makefile.am: Add linking to libebook and requirements.
- Add installation of ecps files.
-
- * printing/e-contact-print.c, printing/e-contact-print.h: Changed
- this to use real data from an EBook.
-
- * printing/test-print.c: Made this pass NULL, NULL to
- e_contact_print_dialog_new so that it will compile.
-
-2000-05-23 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-save-as.c: Fixed some memory leaks.
-
-2000-05-23 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/Makefile.am: Added e-contact-editor-save-as.c and
- e-contact-editor-save-as.h.
-
- * contact-editor/e-contact-save-as.c,
- contact-editor/e-contact-save-as.h: New files that display a save
- as dialog and then save the given card to that file.
-
- * gui/minicard/e-minicard.c: Call e_contact_save_as in a right
- click menu.
-
-2000-05-19 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor-categories.c,
- gui/component/e-addressbook-model.c: Added initialize_value and
- value_is_empty callbacks.
-
-2000-05-19 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Fixed a bug that broke
- address field support.
-
-2000-05-19 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c,
- contact-editor/e-contact-editor.h: Added support for arbitrary
- fields in the contact editor.
-
-2000-05-18 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c: Fixed e_card_name_copy and
- e_card_arbitrary_copy to deal correctly with a passed NULL.
-
- * contact-editor/Makefile.am: Removed imagesdir stuff.
-
- * contact-editor/arrow.png: Made this transparent.
-
- * contact-editor/contact-editor.glade,
- contact-editor/e-contact-editor-strings.h: Renamed some widgets
- and added custom widgets for all of the images.
-
- * contact-editor/e-contact-editor.c: Worked on making this work
- decently well with messed up glade files. Cleaned up a lot of code.
-
-2000-05-18 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c: Fixed the code to write out and read in
- arbitrary fields.
-
-2000-05-18 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h,
- backend/ebook/e-card-types.h, backend/ebook/e-card.c,
- backend/ebook/e-card.h: Implemented "MAILER" field. Added
- arbitrary field support.
-
- * contact-editor/e-contact-editor-categories.c: Fixed a warning.
-
-2000-05-16 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h:
- Added E_CARD_SIMPLE_FIELD_MAILER. Not implemented yet.
-
-2000-05-16 Chris Toshok <toshok@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c (construct_email_list): convert to use ECardSimple.
- (poll_ldap): same.
-
-2000-05-16 Chris Toshok <toshok@helixcode.com>
-
- * backend/pas/pas-book.h: add typedefs for the can_write
- functions, and add parameters to pas_book_new.
-
- * backend/pas/pas-book.c (pas_book_construct): add can_write/can_write_card params.
- (pas_book_new): same.
- (impl_Evolution_Book_can_write): new function.
- (impl_Evolution_Book_can_write_card): same.
- (pas_book_get_epv): assign the can_write/can_write_card slots in the epv.
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_can_write): new function.
- (pas_backend_ldap_can_write_card): same.
- (pas_backend_ldap_add_client): add can_write/can_write_card to pas_book_new call.
-
- * backend/pas/pas-backend-file.c (pas_backend_file_can_write_card): new function, calls can_write.
- (pas_backend_file_can_write): same.
- (can_write): return TRUE if we can write to the addressbook file.
- (pas_backend_file_add_client): add can_write/can_write_card to pas_book_new call.
-
- * backend/idl/addressbook.idl (Evolution): add can_write and
- can_write_card permission requests.
-
-2000-05-16 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c (e_card_get_vcard): Fixed a large memory leak.
-
-2000-05-16 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c (add_list_unique): Fixed another memory
- leak.
-
-2000-05-16 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-simple.c, backend/pas/pas-backend-file.c,
- contact-editor/e-contact-editor.c, ename/e-name-western.c,
- gui/component/addressbook.c, gui/minicard/e-minicard-view.c: Fixed
- some memory leaks.
-
- * backend/ebook/e-card.c: Rearranged some code.
-
-2000-05-16 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor-categories.c: Fixed a reference
- leak.
-
-2000-05-16 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor-categories.c: Fixed a compile
- error.
-
-2000-05-16 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor-categories.c: Got rid of a
- memory leak. Rearranged a couple functions.
-
- * gui/minicard/e-minicard-view.c, gui/minicard/e-minicard-view.h:
- Added some code to stop watching the EBook when the canvas is
- destroyed (apparently the canvas is destroyed before our widget is
- destroyed.)
-
-2000-05-14 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor-categories.c: Use the correct
- policy for resize.
-
-2000-05-14 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/Makefile.am: Added libeutil for e-card's support
- for categories.
-
- * backend/ebook/e-card-list.c, backend/ebook/e-card-list.h: Added
- a function to get the length.
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Added categories
- support (accessible either as "categories" or "category_list".)
-
- * contact-editor/Makefile.am: Added e-table and all of the
- categories files.
-
- * contact-editor/categories.glade,
- contact-editor/categories-strings.h,
- contact-editor/e-contact-editor-categories.c,
- contact-editor/e-contact-editor-categories.h:
-
- * contact-editor/contact-editor.glade,
- contact-editor/e-contact-editor-strings.h: Rearranged this dialog.
-
- * contact-editor/e-contact-editor.c: Rearranged dialog a bit.
- Added opening of categories dialog.
-
- * gui/component/Makefile.am: Rearranged libraries so that
- libetable would be available for the contact editor categories
- dialog.
-
- * gui/component/addressbook.c: Fix for new ETable resizing. Make
- contact editor dialog resizable.
-
- * gui/minicard/Makefile.am: Added libetable contact editor
- categories dialog.
-
- * gui/minicard/e-minicard.c: Make contact editor dialog resizable.
-
-2000-05-12 Miguel de Icaza <miguel@gnu.org>
-
- * contact-editor/fulname.glade: Use accelerators here.
-
-2000-05-13 Valek Filippov <frob@df.ru>
-
- * gui/component/ldap-server-dialog.glade: save translatable strings
- * gui/component/ldap-server-dialog.glade.h: file with strings
- * printing/e-contact-print.glade: save translatable strings
- * printing/e-contact-print.glade.h: file with strings
-
-2000-05-11 Dan Winship <danw@helixcode.com>
-
- * gui/component/addressbook.c (control_activate): Now that we
- depend on recent gnome-libs we can make the toolbar detachable
- again.
-
-2000-05-10 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Make the table view be sorted by
- name initially.
-
-2000-05-10 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-book-factory.c: Send a proper response when you
- can't find the ldap URI.
-
- * gui/component/addressbook.c: Cleaned up the open error dialog a
- bit.
-
-2000-05-10 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Added a dialog for when you can't
- open an addressbook.
-
-2000-05-10 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/Makefile.am: Added e-book-types.h, e-card-pairs.h,
- e-card-types.h.
-
- * backend/pas/Makefile.am: Added pas-backend-ldap.h.
-
- * contact-editor/Makefile.am: Added a proper EXTRA_DIST section.
- Removed some old defines.
-
- * ename/Makefile.am: Added e-name-western-tables.h.
-
- * gui/component/Makefile.am: Added e-ldap-server-dialog.h. Added
- a proper EXTRA_DIST section.
-
- * gui/minicard/e-reflow.c: Added a missed cast.
-
- * printing/Makefile.am: Added a proper EXTRA_DIST section.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Make sure that the canvas
- doesn't intercept keyboard focus.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Use new art.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/contact-editor.glade,
- contact-editor/e-contact-editor-strings.h: Replaced the Address
- button with a label and rearranged the address area a bit.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/e-minicard.c: Reenable editting.
-
- * gui/minicard/e-reflow-sorted.c: Make reflow flow on deletion.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Destroy the view object when
- leaving the minicard view.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/e-reflow-sorted.c: Fixed reflow sorting to call
- reflow_request when sorting on an item changes.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-simple.c: Make File As change if name or
- company are changed pretty much anywhere.
-
- * gui/minicard/e-minicard.c: Turned off having minicard editing
- effect anything since it's so crashy.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c: Enabled a couple more fields
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-backend-file.c: Added a default card to all new
- file backends.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/e-addressbook-model.c: Rearranged order of things
- getting destroyed.
-
- * gui/minicard/e-minicard-view.c: Rearranged order of things
- getting destroyed. Don't set attributes of non-null or destroyed
- items. Destroy parent object when destroyed. Maintain ref_count
- of items in list.
-
- * gui/minicard/e-minicard.c: Don't set attributes of non-null
- items.
-
- * gui/minicard/e-reflow-sorted.c: Maintain ref_count of items in
- list.
-
- * gui/minicard/e-reflow.c: Maintain ref_count of items in list.
- Destroy parent object when destroyed.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-simple.c: Fixed some indentation.
-
- * contact-editor/contact-editor.glade,
- contact-editor/e-contact-editor-strings.h: Changed Email to
- Primary Email.
-
- * contact-editor/e-contact-editor.c: Added checkmarks to indicate
- if data exists in the pull down menus for the phone, address, and
- email fields.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-simple.c: Fixed the string duplication
- problem. Fixed the business/home address string mix up.
-
- * gui/component/addressbook.c: Made the minicard view the default
- view.
-
-2000-05-08 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-simple.c: Fixed this up a bit. Syncing
- should work better now.
-
-2000-05-08 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/e-minicard-view.c, gui/minicard/e-minicard.c,
- gui/minicard/e-minicard.h, gui/minicard/e-reflow-sorted.c,
- gui/minicard/e-reflow-sorted.h: Made a minimal number of things be
- destroyed and recreated when updating a field.
-
-2000-05-07 <toshok@the-dot-in.helixcode.com>
-
- * gui/minicard/e-minicard.c (remodel): make sure to free the
- return value of e_card_simple_get.
-
- * gui/component/addressbook.c (teardown_table_view): destroy the
- ECardSimple here, plug memory leak.
- (create_table_view): use view->simple so we can destroy the
- ECardSimple later on.
-
-2000-05-07 Chris Toshok <toshok@helixcode.com>
-
- * ename/e-name-western.c (e_name_western_extract_middle): comment
- function, and fix an ABR.
-
-2000-05-07 Chris Toshok <toshok@helixcode.com>
-
- * ename/e-name-western.c (e_name_western_cleanup_string): comment
- function, and fix an ABR.
-
-2000-05-08 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/minicard/e-minicard.c: Added saving in minicard view.
-
-2000-05-07 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-backend-file.c: Fixed an off by 2 error.
-
-2000-05-07 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/addressbook.c (set_prop): don't create a new
- ebook. instead, unload the current uri (if there is one) and load
- the new one.
- (addressbook_factory): create the ebook once.
-
-2000-05-07 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/e-addressbook-model.c: Replaced some model_changed
- calls with row_inserted calls.
-
-2000-05-07 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-backend-file.c, backend/pas/pas-backend-ldap.c:
- Removed some code that was notifying too many clients at the wrong
- times.
-
- * gui/component/addressbook.c: Set view->book. Unreffed
- view->book. Unreffed the model instead of destroying it. Removed
- the /tmp/test.db stuff.
-
-2000-05-07 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Make the addressbook create the
- correct file uri. Added a default query. Initialize view->model
- and view->view to NULL.
-
- * gui/component/e-addressbook-model.c,
- gui/minicard/e-minicard-view.c: Only call get_book_view if both
- book and query and non-null.
-
-2000-05-06 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/addressbook.c (control_deactivate): remove the
- separator and toggle view items as well.
- (toggle_view_as_cb): callback for the "/View/Toggle View" menu
- item.
- (get_query): getter for the query string that takes into account
- the two view types.
- (set_query): setter for the query string that takes into account
- the two view types.
- (set_book): setter for the EBook type - not really a setter, since
- the book is kept in the AddressbookView, but this method actually
- sets the "book" property on the current view.
- (find_contact_cb): make use of get/set_query
- (search_entry_activated): make use of set_query.
- (control_activate): add a menu separator and an item to toggle
- between view types.
- (book_open_cb): make use of set_book.
- (ebook_create): no longer needs to return the EBook, since we set
- the book field in our view.
- (teardown_minicard_view): destructor function for the minicard
- specific ui.
- (create_minicard_view): constructor function for the minicard
- specific ui.
- (teardown_table_view): destructor function for the e-table
- specific ui.
- (create_table_view): constructor function for the e-table specific
- ui.
- (change_view_type): destroy the old and create the new view ui,
- change the label of the Toggle View menu item, and reset the book
- and query on the new view type.
- (addressbook_factory): create an all-encompassing vbox that the
- view uses to create the bonobo control, which contains 1 widget
- per ui specific view (the e-table in the table case, and another
- vbox in the minicard case.) use change_view_type to create the
- initial view.
-
-2000-05-07 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-book.c: Made a NULL callback just mean to not
- call back.
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h:
- Reordered fields. Added a get_const function to get a constant
- string that persists until the simple is destroyed.
-
- * gui/component/Makefile.am: Added e-addressbook-model.c and
- e-addressbook-model.h and all of the libraries and includes that
- they are dependent on.
-
- * gui/component/addressbook-factory.c: Initialize e cursors.
-
- * gui/component/addressbook.c: Added inactive code to display an
- ETable view of the addressbook.
-
- * gui/component/e-addressbook-model.c,
- gui/component/e-addressbook-model.h: New files to implement an
- ETable model with a EBook back end.
-
-2000-05-06 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h:
- Mostly finished ECardSimple.
-
- * contact-editor/e-contact-editor.c: Changed this to match with
- some of the changes to ECardSimple.
-
- * gui/component/addressbook.c: Changed this to look for
- "addressbook.db" in the given directory if it doesn't find the
- file "uri".
-
- * gui/minicard/e-minicard.c, gui/minicard/e-minicard.h: Changed
- this to use ECardSimple.
-
-2000-05-06 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/.cvsignore: ignore evolution-addressbook.pure
-
- * gui/component/Makefile.am: add support for generating
- evolution-addressbook.pure.
-
-2000-05-06 Chris Toshok <toshok@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_load_uri): if a
- port isn't specified in the uri default to 389.
-
-2000-05-06 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component/addressbook.c: Made this take a uri through its
- property bag.
-
-2000-05-05 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/Makefile.am: Added e-card-simple.c and
- e-card-simple.h.
-
- * backend/ebook/e-card-simple.c, backend/ebook/e-card-simple.h:
- New card wrapper class to simplify things.
-
- * contact-editor/e-contact-editor.c,
- contact-editor/e-contact-editor.h: Changed e-contact-editor to use
- ECardSimple a bit.
-
-2000-05-03 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/addressbook.c (control_deactivate): #ifdef
- HAVE_LDAP the ldap specific stuff.
- (null_cb): same.
- (control_activate): same.
-
-2000-05-02 Ettore Perazzoli <ettore@helixcode.com>
-
- * backend/ebook/Makefile.am (INCLUDES): Add
- `-I$(top_srcdir)/addressbook/ename'.
-
-2000-05-02 Matt Loper <matt@helixcode.com>
-
- * demo/Makefile.am: set G_LOG_DOMAIN.
- * printing/Makefile.am: same.
-
-2000-05-01 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-book-factory.c: Add back in the
- CORBA_Object_release.
-
- * backend/pas/pas-book.c: Properly duplicate and release the
- listener passed to us.
-
-2000-05-01 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/pas/pas-backend-file.c, backend/pas/pas-backend-ldap.c:
- Made uri slightly better managed.
-
- * backend/pas/pas-book-factory.c
- (pas_book_factory_process_request): Remove this
- CORBA_Object_release that causes things not to work. This is just
- a temporary fix until we figure out what's actually wrong.
-
- * backend/pas/pas-book.c: Fixed a copy and paste error in a warning.
-
-2000-05-01 Christopher James Lahey <clahey@helixcode.com>
-
- * Makefile.am: Switched the subdirs order since backend depends on
- ename.
-
-2000-05-01 Larry Ewing <lewing@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_remove_client):
- fix a typo in the for loop.
-
-2000-05-01 Michael Meeks <michael@helixcode.com>
-
- * backend/pas/pas-book-factory.c: include gtk.
-
-2000-04-30 Federico Mena Quintero <federico@helixcode.com>
-
- * backend/ebook/e-book-types.h (EBookStatus): Added new status
- values for the IDL stuff.
-
- * backend/pas/pas-book-factory.h (PASBookFactoryClass): New
- "last_book_gone" signal.
-
- * backend/pas/pas-book-factory.c
- (pas_book_factory_launch_backend): Better error handling.
- (pas_book_factory_process_queue): Let
- pas_book_factory_process_request() free the request.
- (pas_book_factory_process_request): Free the request here.
- Perform better error handling.
- (free_active_server_map_entry): Free an active server map entry;
- free the URI key and unref the backend value. This function was
- renamed; the old one was trying to CORBA_Object_unref() a GTK+
- object!
- (remove_backends_entry): Free a backend table entry; free the URI
- key.
- (backend_last_client_gone_cb): Remove the backend from the active
- server map and emit the "last_book_gone" signal if appropriate.
- (pas_book_factory_get_n_backends): New function to query the
- number of running backends in an addressbook factory.
-
- * backend/idl/addressbook.idl (BookListener::CallStatus): Added a
- ProtocolNotSupported code. This is for when the addressbook
- factory cannot find a provider for the requested URI.
-
- * backend/pas/pas-backend.h (PASBackendClass): New
- "last_client_gone" signal.
- (PASBackendClass): New get_uri virtual method.
-
- * backend/pas/pas-backend.c (pas_backend_load_uri): Return a
- gboolean success code.
- (pas_backend_add_client): Return a gboolean success code.
- (pas_backend_last_client_gone): New function used by backend
- implementations to notify upwards when the backend's last client
- is destroyed.
- (pas_backend_get_uri): New function to get the URI of a backend.
-
- * backend/pas/pas-backend-file.c (pas_backend_file_add_client):
- Pass the backend as the closure data to the "destroy" handler of
- the book. We cannot call pas_book_get_backend() in the callback
- since the book's private data has already been destroyed when the
- callback is invoked. Alternatively, we could move the private
- data destruction step to the book's ::finalize() method.
- (pas_backend_file_book_destroy_cb): Get the backend from the
- callback's data, not from the book.
- (pas_backend_file_remove_client): Remove the book from the list of
- clients. When all clients go away, call
- pas_backend_last_client_gone().
- (PASBackendFilePrivate): Added an uri field.
- (pas_backend_file_get_uri): Implement the get_uri method.
- (pas_backend_file_load_uri): Return a gboolean success code.
- Also, store the URI in the private structure.
- (pas_backend_file_add_client): Return a gboolean success code.
- Also, call pas_backend_last_client_gone() if appropriate.
- (pas_backend_file_destroy): Free the bf->priv->uri.
-
- * backend/pas/pas-backend-ldap.c (pas_backend_ldap_add_client):
- Pass the backend as the closure data to the "destroy" handler of
- the book. See above for rationale.
- (pas_backend_ldap_book_destroy_cb): Get the backend from the
- callback's data.
- (pas_backend_ldap_remove_client): Remove the book from the list of
- clients. When all clients go away, call
- pas_backend_last_client_gone().
- (pas_backend_ldap_load_uri): Return a gboolean success code.
- (pas_backend_ldap_add_client): Return a gboolean success code.
- Also, call pas_backend_last_client_gone() if appropriate.
- (PASBackendLDAPPrivate): New uri field.
- (pas_backend_ldap_get_uri): Implement the get_uri method.
- (pas_backend_ldap_load_uri): Store the uri in the private
- structure.
- (pas_backend_ldap_destroy): Free the bl->priv->uri.
-
-2000-04-30 Chris Toshok <toshok@helixcode.com>
-
- * gui/component/Makefile.am (evolution_addressbook_SOURCES): added
- e-ldap-server-dialog.c
- (glade_DATA): added ldap-server-dialog.glade
-
- * gui/component/ldap-server-dialog.glade: new file.
-
- * gui/component/e-ldap-server-dialog.h: new file.
-
- * gui/component/e-ldap-server-dialog.c: new file, contains logic
- associated with ldap server dialog.
-
- * gui/component/addressbook.c (control_deactivate): remove the
- directory server menu item.
- (null_cb): do nothing callback for e_book_load_uri call. should
- change to (at the very least) pop up a dialog if there was an
- error.
- (new_server_cb): new function - really just switches to a
- particular ldap server, since the information isn't saved
- anywhere.
- (control_activate): add directory server menu item.
-
-2000-04-30 Chris Toshok <toshok@helixcode.com>
-
- * backend/ebook/e-book.c (e_book_load_uri): create the book
- listener here, since it's destroyed in unload_uri.
- (e_book_construct): remove the book listener construction here.
-
-2000-04-30 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/.cvsignore: Added load-pine-addressbook.
-
-2000-04-30 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/contact-editor.glade,
- contact-editor/e-contact-editor.c, gui/minicard/e-minicard.c: Made
- some fields invisible that were visible before.
-
-2000-04-30 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c: Make file as not have the : after it if
- it's empty. If there's no name, or file_as, fill in these fields
- with defaults based on full_name or name respectively.
-
- * backend/ebook/load-pine-addressbook.c: New file to do import of
- pine .addressbook files.
-
- * backend/pas/pas-backend-file.c: Made empty fields act as the
- empty string for searches.
-
- * contact-editor/e-contact-editor.c,
- contact-editor/e-contact-editor.h: Made the File As field update
- properly as you edit the name and company fields. Added the pull
- down list of File As choices. Made sure that all fields will
- be set to NULL if they are deleted to the empty string.
-
- * gui/minicard/e-minicard.c: Use the File As field instead of the
- Full Name field for the header. Make identical compares on the
- File As field do a compare on the uid.
-
-2000-04-30 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor-fullname.c,
- contact-editor/fullname.glade: Fixed a string mismatch.
-
-2000-04-30 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/Makefile.am: Added ename includes and libs.
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Added
- e_card_name_from_string. Added header for
- e_card_delivery_address_from_string, even though it's not
- implemented yet.
-
- * contact-editor/Makefile.am: Removed the ename includes since we
- no longer use ename directly here.
-
- * contact-editor/e-contact-editor.c: Fixed this to properly save
- the address labels displayed. Updated this to use the function
- e_card_name_from_string instead of doing it by hand.
-
- * contact-editor/fullname-strings.h,
- contact-editor/fullname.glade: Deleted an unused field. Changed
- the set of prefixes and suffixes.
-
-2000-04-30 Chris Toshok <toshok@helixcode.com>
-
- * backend/pas/pas-backend-ldap.c
- (pas_backend_ldap_ensure_connected): add support for a rootdn in
- the uri.
- (pas_backend_ldap_build_all_cards_list): make use of the rootdn in
- the call to ldap_search_s.
- (pas_backend_ldap_search): same.
- (pas_backend_ldap_load_uri): get the rootdn out of the passed in uri.
-
-2000-04-29 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Added
- e_card_phone_new e_card_delivery_address_new,
- e_card_delivery_address_to_string, e_card_name_copy,
- e_card_name_new, e_card_name_to_string, and made e_card_name_free
- public. Removed some unused code.
-
- * backend/pas/pas-backend-file.c: Fixed a warning.
-
- * contact-editor/Makefile.am: Added e-contact-editor-fullname.[ch]
- and fullname.glade. Added e-name libs and includes.
-
- * contact-editor/e-contact-editor-fullname.c,
- contact-editor/e-contact-editor-fullname.h,
- contact-editor/fullname-strings.h, contact-editor/fullname.glade:
- New dialog for editing the fields of a name separately.
-
- * contact-editor/e-contact-editor.c,
- contact-editor/e-contact-editor.h: Create an
- EContactEditorFullname when you click on the Full Name button.
- Maintain a parsed name at all times.
-
- * gui/component/Makefile.am, gui/minicard/Makefile.am: Added
- e-name libs.
-
-2000-04-28 Larry Ewing <lewing@helixcode.com>
-
- * backend/pas/pas-book-factory.c (register_factory): fix the
- `USING_OAF' changes so that they work for when we are not using
- oaf.
-
-2000-04-27 Ettore Perazzoli <ettore@helixcode.com>
-
- * ename/Makefile.am
- (gnome_libs): Use `BONOBO_GNOME_LIBS'.
- (INCLUDES): Add `-I$(srcdir)/..'.
-
- * backend/pas/pas-book-factory.c
- (register_factory): New function to register the factory.
- Implementation different according to `USING_OAF'.
- (pas_book_factory_activate): Use `register_factory()'.
-
- * gui/component/addressbook.c: New #define `CONTROL_FACTORY_ID',
- varying depending on whether we are `USING_OAF'.
- (addressbook_factory_init): Use `CONTROL_FACTORY_ID'.
-
- * backend/ebook/test-client.c (init_corba): New function,
- implemented differently according to the `USING_OAF' #define.
-
- * backend/ebook/e-book.c: New #define `CARDSERVER_OAF_ID'.
- (e_book_construct): Work with OAF #if `USING_OAF'.
-
- * backend/ebook/Makefile.am (gnome_libs): Removed.
- (corbadir): Removed.
- (ebook_libs): Removed.
- (test_client_LDADD): Just add `libebook.la'.
- (test_card_LDADD): Likewise.
- (test_client_list_LDADD): Likewise.
-
- * gui/component/addressbook-factory.c
- (init_corba): New helper function, implemented differently
- according to `USING_OAF'.
- (main): Call `init_corba()'.
-
-2000-04-27 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card.c, backend/ebook/e-card.h: Added file as,
- office, manager, assistant, spouse, and anniversary fields. These
- all use "X-EVOLUTION-" fields in the VCards.
-
- * backend/pas/pas-backend-file.c: Added all the new fields (except
- anniversary) to the list of fields.
-
- * contact-editor/contact-editor.glade,
- contact-editor/e-contact-editor-strings.h: Fixed some misnamed
- fields and fixed the placement of the comments field.
-
- * contact-editor/e-contact-editor.c: Made the newly added fields
- display properly.
-
- * Makefile.am: Added ename.
-
- * ename/e-name-western.h, ename/test-ename-western-gtk.c,
- ename/test-ename-western.c: Fixed up some #includes.
-
- * ename/.cvsignore: Added .cvsignore.
-
-2000-04-26 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-types.h, backend/ebook/e-card.c,
- backend/ebook/e-card.h: Added an address label field.
-
- * contact-editor/contact-editor.glade,
- contact-editor/e-contact-editor-strings.h: Got rid of some unused
- fields.
-
- * contact-editor/e-contact-editor.c,
- contact-editor/e-contact-editor.h: Added the address label field.
- Load only. Editing these fields seems to mess things up.
-
-2000-04-26 Christopher James Lahey <clahey@helixcode.com>
-
- * contact-editor/e-contact-editor.c: Added proper handling of the
- email field.
-
-2000-04-26 Christopher James Lahey <clahey@helixcode.com>
-
- * backend/ebook/e-card-types.h, backend/ebook/e-card.c,
- gui/minicard/e-minicard.c: Prefixed the ADDR_ flags.
-
- * contact-editor/contact-editor.glade,
- contact-editor/e-contact-editor-strings.h: Edited the glade file.
- Removed all the fields that we don't use.
-
- * contact-editor/e-contact-editor.c,
- contact-editor/e-contact-editor.h: Made the phone fields work
- properly. The address and email fields are temporarily turned off
- until they can be made to work as the phone fields do.
-
-2000-04-25 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/minicard/Makefile.am (INCLUDES): Use
- `$(BONOBO_GNOME_CFLAGS)'.
-
- * backend/pas/Makefile.am (idl_flags): Add `-I $(datadir)/idl' to
- pick up IDL files in the installation prefix as well.
- (INCLUDES): Use `$(BONOBO_GNOME_CFLAGS)'.
-
- * backend/ebook/Makefile.am (ORBIT_IDL): Use `-I $(datadir)/idl'
- to get the IDLs from the installation prefix as well.
- (INCLUDES): Add `$(BONOBO_GNOME_CFLAGS)'.
- (test_client_LDADD): Use `$(BONOBO_GNOME_LIBS)' instead of
- hardcoding `-lbonobo'! Also get rid of some other useless flags,
- as `$(BONOBO_GNOME_LIBS)' really has all what we need.
- (test_client_list_LDADD): Likewise.
- (test_card_LDADD): Likewise.
-
-2000-04-18 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/minicard/Makefile.am (INCLUDES): Use "e-minicard" as the log
- domain.
-
- * gui/component/Makefile.am (INCLUDES): Use
- "evolution-addressbook" as the log domain.
-
- * backend/pas/Makefile.am: Build libpas.a, not a shared library.
- Do not install any header files.
- (INCLUDES): Remove spurious include paths.
-
- * backend/pas/*.[ch]: Fix includes.
-
- * backend/ebook/Makefile.am: Do not install the test programs.
- Fixed some include weirdness.
-
- * backend/ebook/*.[ch]: Fix includes.
-
- * contact-editor/Makefile.am (INCLUDES): Set the log domain to
- "contact-editor".
- (INCLUDES): Fix.
-
- * contact-editor/*.[ch]: Fix includes.
-
- * gui/minicard/*.[ch]: Fix includes.
-
- * ChangeLog: Started a ChangeLog here.
diff --git a/addressbook/E-CARD-NEEDED-FIELDS b/addressbook/E-CARD-NEEDED-FIELDS
deleted file mode 100644
index e227d1b130..0000000000
--- a/addressbook/E-CARD-NEEDED-FIELDS
+++ /dev/null
@@ -1,9 +0,0 @@
-I will add these fields as I get a chance to.
-
-Thanks,
- Chris Lahey
-
-X-EVOLUTION-LIST boolean if this is a mailing list.
-X-EVOLUTION-LIST-SHOW-ADDRESSES boolean whether to list all email addresses in the To: line or to treat the list kind of like a BCC.
-X-EVOLUTION-RELATED-CONTACTS EDestionationList of related contacts.
-REV last changed date. \ No newline at end of file
diff --git a/addressbook/Makefile.am b/addressbook/Makefile.am
index 9aad9c1b30..45802a5ffc 100644
--- a/addressbook/Makefile.am
+++ b/addressbook/Makefile.am
@@ -1,7 +1,18 @@
-if ENABLE_PILOT_CONDUITS
-CONDUIT_SUBDIR=conduit
-endif
-SUBDIRS = \
- backend printing gui $(CONDUIT_SUBDIR)
+SUBDIRS = util printing importers gui tools
+error_DATA = addressbook.error
+errordir = $(privdatadir)/errors
+
+@EVO_PLUGIN_RULE@
+
+EXTRA_DIST = \
+ addressbook.error.xml
+
+dist-hook:
+ cd $(distdir); rm -f $(BUILT_SOURCES)
+
+BUILT_SOURCES = $(error_DATA)
+CLEANFILES = $(BUILT_SOURCES)
+
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/addressbook.error.xml b/addressbook/addressbook.error.xml
new file mode 100644
index 0000000000..23dd3a2420
--- /dev/null
+++ b/addressbook/addressbook.error.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<error-list domain="addressbook">
+
+ <error id="ldap-init" type="error">
+ <_primary>This address book could not be opened.</_primary>
+ <_secondary>This address book server might be unreachable or the server name may be misspelled or your network connection could be down.</_secondary>
+ </error>
+
+ <error id="ldap-auth" type="error">
+ <_primary>Failed to authenticate with LDAP server.</_primary>
+ <_secondary>Check to make sure your password is spelled correctly and that you are using a supported login method. Remember that many passwords are case sensitive; your caps lock might be on.</_secondary>
+ </error>
+
+ <error id="ldap-search-base" type="error">
+ <_primary>This address book server does not have any suggested search bases.</_primary>
+ <_secondary>This LDAP server may use an older version of LDAP, which does not support this functionality or it may be misconfigured. Ask your administrator for supported search bases.</_secondary>
+ </error>
+
+ <error id="ldap-v3-schema" type="error">
+ <_primary>This server does not support LDAPv3 schema information.</_primary>
+ </error>
+
+ <error id="ldap-get-schema" type="error">
+ <_primary>Could not get schema information for LDAP server.</_primary>
+ </error>
+
+ <error id="ldap-invalid-schema" type="error">
+ <_primary>LDAP server did not respond with valid schema information.</_primary>
+ </error>
+
+ <error id="remove-addressbook" type="error">
+ <_primary>Could not remove address book.</_primary>
+ </error>
+
+ <error id="ask-delete-addressbook" type="question" default="GTK_RESPONSE_CANCEL">
+ <_primary>Delete address book '{0}'?</_primary>
+ <_secondary>This address book will be removed permanently.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_CANCEL"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="ask-delete-remote-addressbook" type="question" default="GTK_RESPONSE_CANCEL">
+ <_primary>Delete remote address book &quot;{0}&quot;?</_primary>
+ <_secondary>This will permanently remove the address book &quot;{0}&quot; from the server. Are you sure you want to proceed?</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Delete From Server" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="edit-categories" type="error">
+ <_primary>Category editor not available.</_primary>
+ </error>
+
+ <error id="generic-error" type="error">
+ <primary>{0}</primary>
+ <secondary>{1}</secondary>
+ </error>
+
+ <error id="load-error" type="error">
+ <_primary>Unable to open address book</_primary>
+ <secondary>{0}</secondary>
+ </error>
+
+ <error id="search-error" type="error">
+ <_primary>Unable to perform search.</_primary>
+ <secondary>{0}</secondary>
+ </error>
+
+ <error id="prompt-save" type="question" default="GTK_RESPONSE_YES">
+ <_primary>Would you like to save your changes?</_primary>
+ <_secondary>You have made modifications to this contact. Do you want to save these changes?</_secondary>
+ <button _label="_Discard" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button stock="gtk-save" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-move" type="question" default="GTK_RESPONSE_NO">
+ <_primary>Cannot move contact.</_primary>
+ <_secondary>You are attempting to move a contact from one address book to another but it cannot be removed from the source. Do you want to save a copy instead?</_secondary>
+ <button stock="gtk-no" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-yes" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error type="question" id="prompt-resize" default="GTK_RESPONSE_YES">
+ <_primary>The image you have selected is large. Do you want to resize and store it?</_primary>
+ <button _label="_Resize" response="GTK_RESPONSE_YES"/>
+ <button _label="_Use as it is" response="GTK_RESPONSE_NO"/>
+ <button _label="_Do not save" response="GTK_RESPONSE_CANCEL"/>
+ </error>
+
+ <error id="save-error" type="error">
+ <_primary>Unable to save {0}.</_primary>
+ <_secondary>Error saving {0} to {1}: {2}</_secondary>
+ </error>
+
+ <error id="ask-list-add-exists" type="question" default="GTK_RESPONSE_NO">
+ <_primary>Address '{0}' already exists.</_primary>
+ <_secondary>A contact already exists with this address. Would you like to add a new card with the same address anyway?</_secondary>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button stock="gtk-ok" _label="_Add" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="ask-list-add-some-mails-exist" type="question" default="GTK_RESPONSE_CANCEL">
+ <_primary>Some addresses already exist in this contact list.</_primary>
+ <_secondary>You are trying to add addresses that are part of this list already. Would you like to add them anyway?</_secondary>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="Skip duplicates" response="GTK_RESPONSE_NO"/>
+ <button _label="Add with duplicates" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="ask-list-add-list-exists" type="question" default="GTK_RESPONSE_NO">
+ <_primary>List '{0}' is already in this contact list.</_primary>
+ <_secondary>A contact list named '{0}' is already in this contact list. Would you like to add it anyway?</_secondary>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button stock="gtk-ok" _label="_Add" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="contact-delete-error-perm" type="warning">
+ <_primary>Failed to delete contact</_primary>
+ <_secondary>You do not have permission to delete contacts in this address book.</_secondary>
+ </error>
+
+ <error id="error-read-only" type="error" default="GTK_RESPONSE_YES">
+ <_primary>Cannot add new contact</_primary>
+ <!-- For Translators: {0} is the name of the address book source -->
+ <_secondary>'{0}' is a read-only address book and cannot be modified. Please select a different address book from the side bar in the Contacts view.</_secondary>
+ </error>
+
+</error-list>
diff --git a/addressbook/backend/.cvsignore b/addressbook/backend/.cvsignore
deleted file mode 100644
index 09980ae6ba..0000000000
--- a/addressbook/backend/.cvsignore
+++ /dev/null
@@ -1,6 +0,0 @@
-.deps
-.libs
-Makefile
-Makefile.in
-*.lo
-*.la
diff --git a/addressbook/backend/Makefile.am b/addressbook/backend/Makefile.am
deleted file mode 100644
index b2807b2480..0000000000
--- a/addressbook/backend/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = idl ebook pas
diff --git a/addressbook/backend/ebook/.cvsignore b/addressbook/backend/ebook/.cvsignore
deleted file mode 100644
index deec6ea2e7..0000000000
--- a/addressbook/backend/ebook/.cvsignore
+++ /dev/null
@@ -1,25 +0,0 @@
-.deps
-.libs
-.pure
-Makefile
-Makefile.in
-*.lo
-*.la
-addressbook-stubs.c
-addressbook-skels.c
-addressbook-common.c
-addressbook.h
-test-card
-test-client
-test-client-list
-load-pine-addressbook
-load-gnomecard-addressbook
-evolution-vcard-importer
-evolution-gnomecard-importer
-evolution-ldif-importer
-Evolution-Composer-stubs.c
-Evolution-Composer-skels.c
-Evolution-Composer-common.c
-Evolution-Composer.h
-GNOME_Evolution_Addressbook_VCard_Importer.oaf
-GNOME_Evolution_Addressbook_LDIF_Importer.oaf
diff --git a/addressbook/backend/ebook/GNOME_Evolution_Addressbook_LDIF_Importer.oaf.in b/addressbook/backend/ebook/GNOME_Evolution_Addressbook_LDIF_Importer.oaf.in
deleted file mode 100644
index b022dcde67..0000000000
--- a/addressbook/backend/ebook/GNOME_Evolution_Addressbook_LDIF_Importer.oaf.in
+++ /dev/null
@@ -1,29 +0,0 @@
-<oaf_info>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_LDIF_ImporterFactory"
- type="exe"
- location="evolution-ldif-importer">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory to import LDIF files into Evolution."/>
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_LDIF_Importer"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_LDIF_ImporterFactory">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/Importer:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="evolution:menu-name" type="string"
- value="LDAP Data Interchange Format (.ldif)"/>
- <oaf_attribute name="description" type="string"
- _value="Imports LDIF files into Evolution."/>
-</oaf_server>
-
-</oaf_info>
diff --git a/addressbook/backend/ebook/GNOME_Evolution_Addressbook_VCard_Importer.oaf.in b/addressbook/backend/ebook/GNOME_Evolution_Addressbook_VCard_Importer.oaf.in
deleted file mode 100644
index 9cd4699633..0000000000
--- a/addressbook/backend/ebook/GNOME_Evolution_Addressbook_VCard_Importer.oaf.in
+++ /dev/null
@@ -1,29 +0,0 @@
-<oaf_info>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_VCard_ImporterFactory"
- type="exe"
- location="evolution-vcard-importer">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory to import VCard files into Evolution."/>
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_VCard_Importer"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_VCard_ImporterFactory">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/Importer:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="evolution:menu-name" type="string"
- value="VCard (.vcf, .gcrd)"/>
- <oaf_attribute name="description" type="string"
- _value="Imports VCard files into Evolution."/>
-</oaf_server>
-
-</oaf_info>
diff --git a/addressbook/backend/ebook/Makefile.am b/addressbook/backend/ebook/Makefile.am
deleted file mode 100644
index 307ec123fd..0000000000
--- a/addressbook/backend/ebook/Makefile.am
+++ /dev/null
@@ -1,178 +0,0 @@
-noinst_PROGRAMS = test-card test-client test-client-list
-
-bin_PROGRAMS = evolution-vcard-importer \
- evolution-ldif-importer \
- load-pine-addressbook \
- load-gnomecard-addressbook
-
-CORBA_SOURCE = \
- addressbook.h \
- addressbook-common.c \
- addressbook-stubs.c \
- addressbook-skels.c \
- Evolution-Composer.h \
- Evolution-Composer-common.c \
- Evolution-Composer-skels.c \
- Evolution-Composer-stubs.c
-
-idls = \
- $(srcdir)/../idl/addressbook.idl \
- $(srcdir)/../../../composer/Evolution-Composer.idl
-
-idl_flags = `$(GNOME_CONFIG) --cflags idl` -I $(datadir)/idl
-
-$(CORBA_SOURCE): $(idls)
- $(ORBIT_IDL) -I $(srcdir) $(idls) $(idl_flags)
-
-INCLUDES = \
- -DGNOMELOCALEDIR=\""$(localedir)"\" \
- -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 \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
-
-privlib_LTLIBRARIES = libebook.la libebook-static.la
-
-libebook_la_SOURCES = \
- $(CORBA_SOURCE) \
- e-book-listener.c \
- e-book-view-listener.c \
- e-book-view.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
-
-libebookincludedir = $(includedir)/evolution/ebook
-
-libebookinclude_HEADERS = \
- e-book-listener.h \
- e-book-types.h \
- e-book-view-listener.h \
- e-book-view.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
-
-
-#
-# make a static library for use by addressbook's conduit's shared library
-#
-libebook_static_la_SOURCES = $(libebook_la_SOURCES)
-libebook_static_la_LDFLAGS = -all-static
-
-test_client_SOURCES = \
- test-client.c
-
-test_client_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS) \
- $(top_builddir)/camel/libcamel.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/e-util/ename/libename.la \
- $(top_builddir)/e-util/libeutil.la
-
-test_client_list_SOURCES = \
- test-client-list.c
-
-test_client_list_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS) \
- $(top_builddir)/camel/libcamel.la \
- $(top_builddir)/e-util/ename/libename.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/e-util/libeutil.la
-
-test_card_SOURCES = \
- test-card.c
-
-test_card_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS) \
- $(top_builddir)/camel/libcamel.la \
- $(top_builddir)/e-util/ename/libename.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/e-util/libeutil.la
-
-evolution_vcard_importer_SOURCES = \
- evolution-vcard-importer.c
-
-evolution_vcard_importer_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS) \
- $(top_builddir)/camel/libcamel.la \
- $(top_builddir)/shell/importer/libevolution-importer.la \
- $(DB3_LDADD) \
- $(top_builddir)/e-util/ename/libename.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/e-util/libeutil.la
-
-evolution_ldif_importer_SOURCES = \
- evolution-ldif-importer.c
-
-evolution_ldif_importer_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS) \
- $(top_builddir)/camel/libcamel.la \
- $(top_builddir)/shell/importer/libevolution-importer.la \
- $(DB3_LDADD) \
- $(top_builddir)/e-util/ename/libename.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/e-util/libeutil.la
-
-load_pine_addressbook_SOURCES = \
- load-pine-addressbook.c
-
-load_pine_addressbook_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS) \
- $(top_builddir)/camel/libcamel.la \
- $(top_builddir)/e-util/ename/libename.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/e-util/libeutil.la
-
-
-load_gnomecard_addressbook_SOURCES = \
- load-gnomecard-addressbook.c
-
-load_gnomecard_addressbook_LDADD = \
- libebook.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS) \
- $(top_builddir)/camel/libcamel.la \
- $(top_builddir)/e-util/ename/libename.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/e-util/libeutil.la
-
-
-BUILT_SOURCES = $(CORBA_SOURCE)
-CLEANFILES = $(BUILT_SOURCES)
-
-dist-hook:
- cd $(distdir); rm -f $(BUILT_SOURCES)
-
-oafdir = $(datadir)/oaf
-oaf_in_files = GNOME_Evolution_Addressbook_VCard_Importer.oaf.in \
- GNOME_Evolution_Addressbook_LDIF_Importer.oaf.in
-oaf_DATA = $(oaf_in_files:.oaf.in=.oaf)
-
-@XML_I18N_MERGE_OAF_RULE@
-
-# add this back when you add the file to the archive ;)
-# GNOME_Evolution_Addressbook_Pine_Importer.oafinfo
-
-EXTRA_DIST = $(oaf_in_files) $(oaf_DATA)
diff --git a/addressbook/backend/ebook/TODO b/addressbook/backend/ebook/TODO
deleted file mode 100644
index a69703cd92..0000000000
--- a/addressbook/backend/ebook/TODO
+++ /dev/null
@@ -1,2 +0,0 @@
-* Make sure open_book_progress does not use the EBook op queue; make
- sure it works.
diff --git a/addressbook/backend/ebook/e-book-listener.c b/addressbook/backend/ebook/e-book-listener.c
deleted file mode 100644
index ca366386f2..0000000000
--- a/addressbook/backend/ebook/e-book-listener.c
+++ /dev/null
@@ -1,834 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Exports the BookListener interface. Maintains a queue of messages
- * which come in on the interface.
- *
- * Author:
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#include <config.h>
-#include <gtk/gtksignal.h>
-#include "e-book-listener.h"
-
-static EBookStatus e_book_listener_convert_status (GNOME_Evolution_Addressbook_BookListener_CallStatus status);
-
-enum {
- RESPONSES_QUEUED,
- LAST_SIGNAL
-};
-
-static guint e_book_listener_signals [LAST_SIGNAL];
-
-static BonoboObjectClass *e_book_listener_parent_class;
-POA_GNOME_Evolution_Addressbook_BookListener__vepv e_book_listener_vepv;
-
-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) {
- gtk_signal_emit (GTK_OBJECT (listener), e_book_listener_signals [RESPONSES_QUEUED]);
- }
-
- 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)
-{
- 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));
-
- }
-}
-
-/* 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)
-{
- 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;
-
- resp = g_new0 (EBookListenerResponse, 1);
-
- resp->op = LinkStatusEvent;
- resp->connected = connected;
-
- e_book_listener_queue_response (listener, resp);
-}
-
-static void
-e_book_listener_queue_writable_status (EBookListener *listener,
- gboolean writable)
-{
- EBookListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
-
- resp->op = WritableStatusEvent;
- resp->writable = writable;
-
- e_book_listener_queue_response (listener, resp);
-}
-
-static void
-e_book_listener_queue_authentication_response (EBookListener *listener,
- EBookStatus status)
-{
- EBookListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
-
- resp->op = AuthenticationResponse;
- resp->status = status;
-
- e_book_listener_queue_response (listener, resp);
-}
-
-static void
-e_book_listener_queue_get_supported_fields_response (EBookListener *listener,
- EBookStatus status,
- const GNOME_Evolution_Addressbook_stringlist *fields)
-{
- EBookListenerResponse *resp;
- int i;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookListenerResponse, 1);
-
- resp->op = GetSupportedFieldsResponse;
- resp->status = status;
- resp->fields = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL);
-
- for (i = 0; i < fields->_length; i ++) {
- e_list_append (resp->fields, fields->_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 GNOME_Evolution_Addressbook_CardId id,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object_from_servant (servant));
-
- e_book_listener_queue_create_card_response (
- listener,
- e_book_listener_convert_status (status),
- id);
-}
-
-static void
-impl_BookListener_respond_remove_card (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object_from_servant (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_from_servant (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 GNOME_Evolution_Addressbook_VCard card,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object_from_servant (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_from_servant (servant));
- GNOME_Evolution_Addressbook_CardCursor cursor_copy;
-
- cursor_copy = bonobo_object_dup_ref (cursor, ev);
-
- 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);
-}
-
-static void
-impl_BookListener_respond_get_view (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const GNOME_Evolution_Addressbook_BookView book_view,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object_from_servant (servant));
- GNOME_Evolution_Addressbook_BookView book_view_copy;
-
- book_view_copy = bonobo_object_dup_ref (book_view, ev);
-
- if (ev->_major != CORBA_NO_EXCEPTION) {
- g_warning ("EBookListener: Exception while duplicating BookView.\n");
- return;
- }
-
- e_book_listener_queue_get_view_response (
- listener,
- e_book_listener_convert_status (status),
- book_view_copy);
-}
-
-static void
-impl_BookListener_respond_get_changes (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const GNOME_Evolution_Addressbook_BookView book_view,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object_from_servant (servant));
- GNOME_Evolution_Addressbook_BookView book_view_copy;
-
- book_view_copy = bonobo_object_dup_ref (book_view, ev);
-
- if (ev->_major != CORBA_NO_EXCEPTION) {
- g_warning ("EBookListener: Exception while duplicating BookView.\n");
- return;
- }
-
- e_book_listener_queue_get_changes_response (
- listener,
- e_book_listener_convert_status (status),
- book_view_copy);
-}
-
-static void
-impl_BookListener_respond_open_book (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const GNOME_Evolution_Addressbook_Book book,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object_from_servant (servant));
- GNOME_Evolution_Addressbook_Book book_copy;
-
- book_copy = bonobo_object_dup_ref (book, ev);
-
- if (ev->_major != CORBA_NO_EXCEPTION) {
- g_warning ("EBookListener: Exception while duplicating Book!\n");
- return;
- }
-
- e_book_listener_queue_open_response (
- listener,
- e_book_listener_convert_status (status),
- book_copy);
-}
-
-static void
-impl_BookListener_report_open_book_progress (PortableServer_Servant servant,
- const CORBA_char *status_message,
- const CORBA_short percent,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object_from_servant (servant));
-
- e_book_listener_queue_open_progress (
- listener, status_message, percent);
-}
-
-static void
-impl_BookListener_respond_authentication_result (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object_from_servant (servant));
-
- e_book_listener_queue_authentication_response (
- listener, status);
-}
-
-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)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object_from_servant (servant));
-
- e_book_listener_queue_get_supported_fields_response (
- listener, status, fields);
-}
-
-static void
-impl_BookListener_report_connection_status (PortableServer_Servant servant,
- const CORBA_boolean connected,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object_from_servant (servant));
-
- e_book_listener_queue_link_status (
- listener, connected);
-}
-
-static void
-impl_BookListener_report_writable (PortableServer_Servant servant,
- const CORBA_boolean writable,
- CORBA_Environment *ev)
-{
- EBookListener *listener = E_BOOK_LISTENER (bonobo_object_from_servant (servant));
-
- e_book_listener_queue_writable_status (listener, 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);
-}
-
-/**
- * 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)
-{
- 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 EBookListener *
-e_book_listener_construct (EBookListener *listener)
-{
- POA_GNOME_Evolution_Addressbook_BookListener *servant;
- CORBA_Environment ev;
- CORBA_Object obj;
-
- g_assert (listener != NULL);
- g_assert (E_IS_BOOK_LISTENER (listener));
-
- servant = (POA_GNOME_Evolution_Addressbook_BookListener *) g_new0 (BonoboObjectServant, 1);
- servant->vepv = &e_book_listener_vepv;
-
- CORBA_exception_init (&ev);
-
- POA_GNOME_Evolution_Addressbook_BookListener__init ((PortableServer_Servant) servant, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_free (servant);
- CORBA_exception_free (&ev);
-
- return NULL;
- }
-
- CORBA_exception_free (&ev);
-
- obj = bonobo_object_activate_servant (BONOBO_OBJECT (listener), servant);
- if (obj == CORBA_OBJECT_NIL) {
- g_free (servant);
-
- return NULL;
- }
-
- bonobo_object_construct (BONOBO_OBJECT (listener), obj);
-
- return listener;
-}
-
-/**
- * e_book_listener_new:
- * @book: the #EBook for which the listener is to be bound
- *
- * Creates and returns a new #EBookListener for the book.
- *
- * Returns: a new #EBookListener
- */
-EBookListener *
-e_book_listener_new ()
-{
- EBookListener *listener;
- EBookListener *retval;
-
- listener = gtk_type_new (E_BOOK_LISTENER_TYPE);
-
- retval = e_book_listener_construct (listener);
-
- if (retval == NULL) {
- g_warning ("e_book_listener_new: Error constructing "
- "EBookListener!\n");
- bonobo_object_unref (BONOBO_OBJECT (listener));
- return NULL;
- }
-
- return retval;
-}
-
-static void
-e_book_listener_init (EBookListener *listener)
-{
- listener->priv = g_new0 (EBookListenerPrivate, 1);
-}
-
-void
-e_book_listener_stop (EBookListener *listener)
-{
- g_return_if_fail (E_IS_BOOK_LISTENER (listener));
-
- listener->priv->stopped = TRUE;
-}
-
-static void
-e_book_listener_destroy (GtkObject *object)
-{
- EBookListener *listener = E_BOOK_LISTENER (object);
- 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);
-
- GTK_OBJECT_CLASS (e_book_listener_parent_class)->destroy (object);
-}
-
-POA_GNOME_Evolution_Addressbook_BookListener__epv *
-e_book_listener_get_epv (void)
-{
- POA_GNOME_Evolution_Addressbook_BookListener__epv *epv;
-
- epv = g_new0 (POA_GNOME_Evolution_Addressbook_BookListener__epv, 1);
-
- epv->notifyOpenBookProgress = impl_BookListener_report_open_book_progress;
- epv->notifyBookOpened = impl_BookListener_respond_open_book;
-
- epv->notifyCardCreated = impl_BookListener_respond_create_card;
- epv->notifyCardRemoved = impl_BookListener_respond_remove_card;
- epv->notifyCardModified = impl_BookListener_respond_modify_card;
-
- epv->notifyAuthenticationResult = impl_BookListener_respond_authentication_result;
- epv->notifySupportedFields = impl_BookListener_response_get_supported_fields;
-
- epv->notifyCardRequested = impl_BookListener_respond_get_vcard;
- epv->notifyCursorRequested = impl_BookListener_respond_get_cursor;
- 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;
-
- return epv;
-}
-
-static void
-e_book_listener_corba_class_init (void)
-{
- e_book_listener_vepv.Bonobo_Unknown_epv = bonobo_object_get_epv ();
- e_book_listener_vepv.GNOME_Evolution_Addressbook_BookListener_epv = e_book_listener_get_epv ();
-}
-
-static void
-e_book_listener_class_init (EBookListenerClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
-
- e_book_listener_parent_class = gtk_type_class (bonobo_object_get_type ());
-
- e_book_listener_signals [RESPONSES_QUEUED] =
- gtk_signal_new ("responses_queued",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EBookListenerClass, responses_queued),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, e_book_listener_signals, LAST_SIGNAL);
-
- object_class->destroy = e_book_listener_destroy;
-
- e_book_listener_corba_class_init ();
-}
-
-/**
- * e_book_listener_get_type:
- */
-GtkType
-e_book_listener_get_type (void)
-{
- static GtkType type = 0;
-
- if (! type) {
- GtkTypeInfo info = {
- "EBookListener",
- sizeof (EBookListener),
- sizeof (EBookListenerClass),
- (GtkClassInitFunc) e_book_listener_class_init,
- (GtkObjectInitFunc) e_book_listener_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (bonobo_object_get_type (), &info);
- }
-
- return type;
-}
diff --git a/addressbook/backend/ebook/e-book-listener.h b/addressbook/backend/ebook/e-book-listener.h
deleted file mode 100644
index f546c9a029..0000000000
--- a/addressbook/backend/ebook/e-book-listener.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * A client-side GtkObject which exposes the
- * Evolution:BookListener interface.
- *
- * Author:
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#ifndef __E_BOOK_LISTENER_H__
-#define __E_BOOK_LISTENER_H__
-
-#include <libgnome/gnome-defs.h>
-#include <bonobo/bonobo-object.h>
-#include <ebook/addressbook.h>
-#include <ebook/e-book-types.h>
-#include <e-util/e-list.h>
-
-BEGIN_GNOME_DECLS
-
-typedef struct _EBookListener EBookListener;
-typedef struct _EBookListenerClass EBookListenerClass;
-typedef struct _EBookListenerPrivate EBookListenerPrivate;
-
-struct _EBookListener {
- BonoboObject parent;
- EBookListenerPrivate *priv;
-};
-
-struct _EBookListenerClass {
- BonoboObjectClass parent;
-
- /*
- * Signals
- */
- void (*responses_queued) (void);
-};
-
-typedef enum {
- /* Async responses */
- OpenBookResponse,
- CreateCardResponse,
- RemoveCardResponse,
- ModifyCardResponse,
- GetCardResponse,
- GetCursorResponse,
- GetBookViewResponse,
- GetChangesResponse,
- AuthenticationResponse,
- GetSupportedFieldsResponse,
-
- /* Async events */
- LinkStatusEvent,
- WritableStatusEvent,
- OpenProgressEvent,
-} EBookListenerOperation;
-
-typedef struct {
- 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 */
- EList *fields;
-
- /* For OpenProgressEvent */
- char *msg;
- short percent;
-
- /* For LinkStatusEvent */
- gboolean connected;
-
- /* For WritableStatusEvent */
- gboolean writable;
-
- /* 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);
-GtkType e_book_listener_get_type (void);
-void e_book_listener_stop (EBookListener *listener);
-
-POA_GNOME_Evolution_Addressbook_BookListener__epv *e_book_listener_get_epv (void);
-
-#define E_BOOK_LISTENER_TYPE (e_book_listener_get_type ())
-#define E_BOOK_LISTENER(o) (GTK_CHECK_CAST ((o), E_BOOK_LISTENER_TYPE, EBookListener))
-#define E_BOOK_LISTENER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_BOOK_LISTENER_TYPE, EBookListenerClass))
-#define E_IS_BOOK_LISTENER(o) (GTK_CHECK_TYPE ((o), E_BOOK_LISTENER_TYPE))
-#define E_IS_BOOK_LISTENER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_BOOK_LISTENER_TYPE))
-
-END_GNOME_DECLS
-
-#endif /* ! __E_BOOK_LISTENER_H__ */
diff --git a/addressbook/backend/ebook/e-book-types.h b/addressbook/backend/ebook/e-book-types.h
deleted file mode 100644
index eb70a778fc..0000000000
--- a/addressbook/backend/ebook/e-book-types.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * A client-side GtkObject which exposes the
- * Evolution:BookListener interface.
- *
- * Author:
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#ifndef __E_BOOK_TYPES_H__
-#define __E_BOOK_TYPES_H__
-
-#include <libgnome/gnome-defs.h>
-
-BEGIN_GNOME_DECLS
-
-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
-} EBookStatus;
-
-typedef enum {
- E_BOOK_VIEW_STATUS_SUCCESS,
- 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
-} EBookViewStatus;
-
-typedef enum {
- E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS,
- E_BOOK_SIMPLE_QUERY_STATUS_CANCELLED,
- E_BOOK_SIMPLE_QUERY_STATUS_OTHER_ERROR
-} EBookSimpleQueryStatus;
-
-END_GNOME_DECLS
-
-#endif /* ! __E_BOOK_TYPES_H__ */
diff --git a/addressbook/backend/ebook/e-book-util.c b/addressbook/backend/ebook/e-book-util.c
deleted file mode 100644
index 06e2787f3e..0000000000
--- a/addressbook/backend/ebook/e-book-util.c
+++ /dev/null
@@ -1,761 +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 <gtk/gtkobject.h>
-#include <gtk/gtksignal.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-util.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_concat_dir_and_file(uri + offset, "addressbook.db");
- 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 {
- info->cb (NULL, info->closure);
- }
- g_free (info);
-}
-
-gboolean
-e_book_load_address_book_by_uri (EBook *book, const char *uri, EBookCallback open_response, gpointer closure)
-{
- gboolean rv;
- char *real_uri;
-
- g_return_val_if_fail (book != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK (book), FALSE);
- g_return_val_if_fail (open_response != NULL, FALSE);
-
- real_uri = e_book_expand_uri (uri);
-
- rv = e_book_load_uri (book, real_uri, open_response, closure);
-
- if (!rv) {
- g_warning ("Couldn't load addressbook %s", real_uri);
- }
-
- g_free (real_uri);
-
- return rv;
-}
-
-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 ();
- if (! e_book_load_address_book_by_uri (book, uri, got_uri_book_cb, info)) {
- gtk_object_unref (GTK_OBJECT (book));
- g_free (info);
- }
-}
-
-Bonobo_ConfigDatabase
-e_book_get_config_database (CORBA_Environment *ev)
-{
- static Bonobo_ConfigDatabase config_db;
-
- if (config_db == NULL)
- config_db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", ev);
-
- 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) {
- gtk_object_unref (GTK_OBJECT (book));
- book = common_default_book;
- }
-
- info->cb (book, info->closure);
-
- if (common_default_book == NULL) {
- common_default_book = book;
- }
-
- } else {
-
- 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 ();
- if (! e_book_load_default_book (book, got_default_book_cb, info)) {
- gtk_object_unref (GTK_OBJECT (book));
- g_free (info);
- }
-}
-
-static char *default_book_uri;
-
-static void
-set_default_book_uri_local (void)
-{
- char *filename;
-
- if (default_book_uri)
- g_free (default_book_uri);
-
- filename = gnome_util_prepend_user_home ("evolution/local/Contacts/addressbook.db");
- default_book_uri = g_strdup_printf ("file://%s", filename);
- g_free (filename);
-}
-
-static void
-set_default_book_uri_from_bonobo_conf (void)
-{
- CORBA_Environment ev;
- char *val;
- Bonobo_ConfigDatabase config_db;
-
- CORBA_exception_init (&ev);
- config_db = e_book_get_config_database (&ev);
- val = bonobo_config_get_string (config_db, "/DefaultFolders/contacts_uri", &ev);
- CORBA_exception_free (&ev);
-
- if (val) {
- default_book_uri = e_book_expand_uri (val);
- g_free (val);
- } else
- set_default_book_uri_local ();
-}
-
-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.
- */
- if (status == E_BOOK_STATUS_PROTOCOL_NOT_SUPPORTED ||
- status == E_BOOK_STATUS_NO_SUCH_BOOK) {
- set_default_book_uri_local ();
- e_book_load_default_book (book, user_response, user_closure);
- } else {
- user_response (book, status, user_closure);
- }
-}
-
-gboolean
-e_book_load_default_book (EBook *book, EBookCallback open_response, gpointer closure)
-{
- char *uri;
- gboolean rv;
- DefaultBookClosure *default_book_closure;
-
- g_return_val_if_fail (book != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK (book), FALSE);
- g_return_val_if_fail (open_response != NULL, FALSE);
-
- 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;
-
- rv = e_book_load_uri (book, uri,
- e_book_default_book_open, default_book_closure);
-
- if (!rv) {
- g_warning ("Couldn't load default addressbook");
- }
-
- return rv;
-}
-
-char*
-e_book_get_default_book_uri ()
-{
- if (!default_book_uri)
- set_default_book_uri_from_bonobo_conf ();
-
- 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 = gtk_object_get_data (GTK_OBJECT (book), "sq_pending");
- pending = g_list_prepend (pending, info);
- gtk_object_set_data (GTK_OBJECT (book), "sq_pending", pending);
-}
-
-static SimpleQueryInfo *
-book_lookup_simple_query (EBook *book, guint tag)
-{
- GList *pending = gtk_object_get_data (GTK_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 = gtk_object_get_data (GTK_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;
- }
- }
- gtk_object_set_data (GTK_OBJECT (book), "sq_pending", pending);
-}
-
-static guint
-book_issue_tag (EBook *book)
-{
- gpointer ptr = gtk_object_get_data (GTK_OBJECT (book), "sq_tag");
- guint tag = GPOINTER_TO_UINT (ptr);
- if (tag == 0)
- tag = 1;
- gtk_object_set_data (GTK_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;
- gtk_object_ref (GTK_OBJECT (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) {
- gtk_signal_disconnect (GTK_OBJECT (sq->view), sq->add_tag);
- sq->add_tag = 0;
- }
-
- if (sq->seq_complete_tag) {
- gtk_signal_disconnect (GTK_OBJECT (sq->view), sq->seq_complete_tag);
- sq->seq_complete_tag = 0;
- }
-
- if (sq->view) {
- gtk_object_unref (GTK_OBJECT (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)
- gtk_object_unref (GTK_OBJECT (sq->book));
-
- g_list_foreach (sq->cards, (GFunc) gtk_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) gtk_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;
- gtk_object_ref (GTK_OBJECT (book_view));
-
- sq->add_tag = gtk_signal_connect (GTK_OBJECT (sq->view),
- "card_added",
- GTK_SIGNAL_FUNC (simple_query_card_added_cb),
- sq);
- sq->seq_complete_tag = gtk_signal_connect (GTK_OBJECT (sq->view),
- "sequence_complete",
- GTK_SIGNAL_FUNC (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);
-}
diff --git a/addressbook/backend/ebook/e-book-util.h b/addressbook/backend/ebook/e-book-util.h
deleted file mode 100644
index c1c07564cd..0000000000
--- a/addressbook/backend/ebook/e-book-util.h
+++ /dev/null
@@ -1,93 +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 <libgnome/gnome-defs.h>
-#include "e-book.h"
-#include <bonobo-conf/bonobo-config-database.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-moniker-util.h>
-
-BEGIN_GNOME_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);
-
-gboolean 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);
-gboolean e_book_load_default_book (EBook *book,
- EBookCallback open_response,
- gpointer closure);
-char *e_book_get_default_book_uri (void);
-
-/* Bonoboconf database interface. */
-Bonobo_ConfigDatabase e_book_get_config_database (CORBA_Environment *ev);
-
-/* 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);
-
-END_GNOME_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
deleted file mode 100644
index ce46fd1100..0000000000
--- a/addressbook/backend/ebook/e-book-view-listener.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Exports the BookViewListener interface. Maintains a queue of messages
- * which come in on the interface.
- *
- * Author:
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#include <config.h>
-#include <gtk/gtksignal.h>
-#include "e-book-view-listener.h"
-#include "e-book-view.h"
-#include "e-card.h"
-
-static EBookViewStatus e_book_view_listener_convert_status (GNOME_Evolution_Addressbook_BookViewListener_CallStatus status);
-
-enum {
- RESPONSES_QUEUED,
- LAST_SIGNAL
-};
-
-static guint e_book_view_listener_signals [LAST_SIGNAL];
-
-static BonoboObjectClass *e_book_view_listener_parent_class;
-POA_GNOME_Evolution_Addressbook_BookViewListener__vepv e_book_view_listener_vepv;
-
-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) {
- gtk_signal_emit (GTK_OBJECT (listener), e_book_view_listener_signals [RESPONSES_QUEUED]);
- }
-
- 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)
-{
- if (response == NULL)
- return;
-
- if (listener->priv->stopped) {
- /* Free response and return */
- g_free (response->id);
- g_list_foreach (response->cards, (GFunc) gtk_object_unref, NULL);
- g_list_free (response->cards);
- 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));
- }
-}
-
-/* Add, Remove, Modify */
-static void
-e_book_view_listener_queue_status_event (EBookViewListener *listener,
- EBookViewListenerOperation op,
- EBookViewStatus status)
-{
- EBookViewListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookViewListenerResponse, 1);
-
- resp->op = op;
- resp->status = status;
- resp->id = NULL;
- resp->cards = NULL;
- resp->message = NULL;
-
- e_book_view_listener_queue_response (listener, resp);
-}
-
-/* Add, Remove, Modify */
-static void
-e_book_view_listener_queue_id_event (EBookViewListener *listener,
- EBookViewListenerOperation op,
- const char *id)
-{
- EBookViewListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookViewListenerResponse, 1);
-
- resp->op = op;
- resp->status = E_BOOK_VIEW_STATUS_SUCCESS;
- resp->id = g_strdup (id);
- resp->cards = NULL;
- resp->message = NULL;
-
- e_book_view_listener_queue_response (listener, resp);
-}
-
-/* Add, Remove, Modify */
-static void
-e_book_view_listener_queue_sequence_event (EBookViewListener *listener,
- EBookViewListenerOperation op,
- const GNOME_Evolution_Addressbook_VCardList *cards)
-{
- EBookViewListenerResponse *resp;
- int i;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookViewListenerResponse, 1);
-
- resp->op = op;
- resp->status = E_BOOK_VIEW_STATUS_SUCCESS;
- resp->id = NULL;
- resp->cards = NULL;
- resp->message = NULL;
-
- for ( i = 0; i < cards->_length; i++ ) {
- resp->cards = g_list_append(resp->cards, e_card_new(cards->_buffer[i]));
- }
-
- e_book_view_listener_queue_response (listener, resp);
-}
-
-/* Status Message */
-static void
-e_book_view_listener_queue_message_event (EBookViewListener *listener,
- EBookViewListenerOperation op,
- const char *message)
-{
- EBookViewListenerResponse *resp;
-
- if (listener->priv->stopped)
- return;
-
- resp = g_new0 (EBookViewListenerResponse, 1);
-
- resp->op = op;
- resp->status = E_BOOK_VIEW_STATUS_SUCCESS;
- resp->id = NULL;
- resp->cards = NULL;
- 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)
-{
- EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object_from_servant (servant));
-
- e_book_view_listener_queue_sequence_event (
- listener, CardAddedEvent, cards);
-}
-
-static void
-impl_BookViewListener_notify_card_removed (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_CardId id,
- CORBA_Environment *ev)
-{
- EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object_from_servant (servant));
-
- e_book_view_listener_queue_id_event (
- listener, CardRemovedEvent, (const char *) id);
-}
-
-static void
-impl_BookViewListener_notify_card_changed (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_VCardList *cards,
- CORBA_Environment *ev)
-{
- EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object_from_servant (servant));
-
- e_book_view_listener_queue_sequence_event (
- listener, CardModifiedEvent, cards);
-}
-
-static void
-impl_BookViewListener_notify_sequence_complete (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookViewListener_CallStatus status,
- CORBA_Environment *ev)
-{
- EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object_from_servant (servant));
-
- 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)
-{
- EBookViewListener *listener = E_BOOK_VIEW_LISTENER (bonobo_object_from_servant (servant));
-
- e_book_view_listener_queue_message_event (listener, StatusMessageEvent, message);
-}
-
-/**
- * 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;
-}
-
-static EBookViewStatus
-e_book_view_listener_convert_status (const GNOME_Evolution_Addressbook_BookViewListener_CallStatus status)
-{
- switch (status) {
- case GNOME_Evolution_Addressbook_BookViewListener_Success:
- return E_BOOK_VIEW_STATUS_SUCCESS;
- case GNOME_Evolution_Addressbook_BookViewListener_SearchTimeLimitExceeded:
- return E_BOOK_VIEW_STATUS_TIME_LIMIT_EXCEEDED;
- case GNOME_Evolution_Addressbook_BookViewListener_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;
- default:
- g_warning ("e_book_view_listener_convert_status: Unknown status "
- "from card server: %d\n", (int) status);
- return E_BOOK_VIEW_STATUS_UNKNOWN;
-
- }
-}
-
-static EBookViewListener *
-e_book_view_listener_construct (EBookViewListener *listener)
-{
- POA_GNOME_Evolution_Addressbook_BookViewListener *servant;
- CORBA_Environment ev;
- CORBA_Object obj;
-
- g_assert (listener != NULL);
- g_assert (E_IS_BOOK_VIEW_LISTENER (listener));
-
- servant = (POA_GNOME_Evolution_Addressbook_BookViewListener *) g_new0 (BonoboObjectServant, 1);
- servant->vepv = &e_book_view_listener_vepv;
-
- CORBA_exception_init (&ev);
-
- POA_GNOME_Evolution_Addressbook_BookViewListener__init ((PortableServer_Servant) servant, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_free (servant);
- CORBA_exception_free (&ev);
-
- return NULL;
- }
-
- CORBA_exception_free (&ev);
-
- obj = bonobo_object_activate_servant (BONOBO_OBJECT (listener), servant);
- if (obj == CORBA_OBJECT_NIL) {
- g_free (servant);
-
- return NULL;
- }
-
- bonobo_object_construct (BONOBO_OBJECT (listener), obj);
-
- return listener;
-}
-
-/**
- * e_book_view_listener_new:
- * @book: the #EBookView for which the listener is to be bound
- *
- * Creates and returns a new #EBookViewListener for the book.
- *
- * Returns: a new #EBookViewListener
- */
-EBookViewListener *
-e_book_view_listener_new ()
-{
- EBookViewListener *listener;
- EBookViewListener *retval;
-
- listener = gtk_type_new (E_BOOK_VIEW_LISTENER_TYPE);
-
- retval = e_book_view_listener_construct (listener);
-
- if (retval == NULL) {
- g_warning ("e_book_view_listener_new: Error constructing "
- "EBookViewListener!\n");
- bonobo_object_unref (BONOBO_OBJECT (listener));
- return NULL;
- }
-
- return retval;
-}
-
-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;
-}
-
-void
-e_book_view_listener_stop (EBookViewListener *listener)
-{
- g_return_if_fail (E_IS_BOOK_VIEW_LISTENER (listener));
- listener->priv->stopped = TRUE;
-}
-
-static void
-e_book_view_listener_destroy (GtkObject *object)
-{
- EBookViewListener *listener = E_BOOK_VIEW_LISTENER (object);
- 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_free(resp->id);
-
- g_list_foreach(resp->cards, (GFunc) gtk_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;
-
- GTK_OBJECT_CLASS (e_book_view_listener_parent_class)->destroy (object);
-}
-
-POA_GNOME_Evolution_Addressbook_BookViewListener__epv *
-e_book_view_listener_get_epv (void)
-{
- POA_GNOME_Evolution_Addressbook_BookViewListener__epv *epv;
-
- epv = g_new0 (POA_GNOME_Evolution_Addressbook_BookViewListener__epv, 1);
-
- epv->notifyCardChanged = impl_BookViewListener_notify_card_changed;
- epv->notifyCardRemoved = impl_BookViewListener_notify_card_removed;
- epv->notifyCardAdded = impl_BookViewListener_notify_card_added;
- epv->notifySequenceComplete = impl_BookViewListener_notify_sequence_complete;
- epv->notifyStatusMessage = impl_BookViewListener_notify_status_message;
-
- return epv;
-}
-
-static void
-e_book_view_listener_corba_class_init (void)
-{
- e_book_view_listener_vepv.Bonobo_Unknown_epv = bonobo_object_get_epv ();
- e_book_view_listener_vepv.GNOME_Evolution_Addressbook_BookViewListener_epv = e_book_view_listener_get_epv ();
-}
-
-static void
-e_book_view_listener_class_init (EBookViewListenerClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
-
- e_book_view_listener_parent_class = gtk_type_class (bonobo_object_get_type ());
-
- e_book_view_listener_signals [RESPONSES_QUEUED] =
- gtk_signal_new ("responses_queued",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EBookViewListenerClass, responses_queued),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, e_book_view_listener_signals, LAST_SIGNAL);
-
- object_class->destroy = e_book_view_listener_destroy;
-
- e_book_view_listener_corba_class_init ();
-}
-
-/**
- * e_book_view_listener_get_type:
- */
-GtkType
-e_book_view_listener_get_type (void)
-{
- static GtkType type = 0;
-
- if (! type) {
- GtkTypeInfo info = {
- "EBookViewListener",
- sizeof (EBookViewListener),
- sizeof (EBookViewListenerClass),
- (GtkClassInitFunc) e_book_view_listener_class_init,
- (GtkObjectInitFunc) e_book_view_listener_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (bonobo_object_get_type (), &info);
- }
-
- return type;
-}
diff --git a/addressbook/backend/ebook/e-book-view-listener.h b/addressbook/backend/ebook/e-book-view-listener.h
deleted file mode 100644
index 284c880ed1..0000000000
--- a/addressbook/backend/ebook/e-book-view-listener.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * A client-side GtkObject which exposes the
- * Evolution:BookViewListener interface.
- *
- * Author:
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#ifndef __E_BOOK_VIEW_LISTENER_H__
-#define __E_BOOK_VIEW_LISTENER_H__
-
-#include <libgnome/gnome-defs.h>
-#include <bonobo/bonobo-object.h>
-#include <ebook/e-book-types.h>
-#include <ebook/addressbook.h>
-
-BEGIN_GNOME_DECLS
-
-typedef struct _EBookViewListener EBookViewListener;
-typedef struct _EBookViewListenerClass EBookViewListenerClass;
-typedef struct _EBookViewListenerPrivate EBookViewListenerPrivate;
-
-struct _EBookViewListener {
- BonoboObject parent;
- EBookViewListenerPrivate *priv;
-};
-
-struct _EBookViewListenerClass {
- BonoboObjectClass parent;
-
- /*
- * Signals
- */
- void (*responses_queued) (void);
-};
-
-typedef enum {
- /* Async events */
- CardAddedEvent,
- CardRemovedEvent,
- CardModifiedEvent,
- SequenceCompleteEvent,
- StatusMessageEvent,
-} EBookViewListenerOperation;
-
-typedef struct {
- EBookViewListenerOperation op;
-
- /* For SequenceComplete */
- EBookViewStatus status;
-
- /* For CardRemovedEvent */
- char *id;
-
- /* For Card[Added|Modified]Event */
- GList *cards; /* Of type ECard. */
-
- /* 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);
-GtkType e_book_view_listener_get_type (void);
-void e_book_view_listener_stop (EBookViewListener *listener);
-
-POA_GNOME_Evolution_Addressbook_BookViewListener__epv *e_book_view_listener_get_epv (void);
-
-#define E_BOOK_VIEW_LISTENER_TYPE (e_book_view_listener_get_type ())
-#define E_BOOK_VIEW_LISTENER(o) (GTK_CHECK_CAST ((o), E_BOOK_VIEW_LISTENER_TYPE, EBookViewListener))
-#define E_BOOK_VIEW_LISTENER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_BOOK_VIEW_LISTENER_TYPE, EBookViewListenerClass))
-#define E_IS_BOOK_VIEW_LISTENER(o) (GTK_CHECK_TYPE ((o), E_BOOK_VIEW_LISTENER_TYPE))
-#define E_IS_BOOK_VIEW_LISTENER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_BOOK_VIEW_LISTENER_TYPE))
-
-END_GNOME_DECLS
-
-#endif /* ! __E_BOOK_VIEW_LISTENER_H__ */
diff --git a/addressbook/backend/ebook/e-book-view.c b/addressbook/backend/ebook/e-book-view.c
deleted file mode 100644
index 3dd5f4c703..0000000000
--- a/addressbook/backend/ebook/e-book-view.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/* -*- 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 <gtk/gtksignal.h>
-#include <gtk/gtkmarshal.h>
-
-#include "addressbook.h"
-#include "e-card-cursor.h"
-#include "e-book-view-listener.h"
-#include "e-book-view.h"
-#include "e-book.h"
-
-GtkObjectClass *e_book_view_parent_class;
-
-struct _EBookViewPrivate {
- GNOME_Evolution_Addressbook_BookView corba_book_view;
-
- EBook *book;
-
- EBookViewListener *listener;
-
- int responses_queued_id;
-};
-
-enum {
- CARD_CHANGED,
- CARD_REMOVED,
- CARD_ADDED,
- SEQUENCE_COMPLETE,
- STATUS_MESSAGE,
- LAST_SIGNAL
-};
-
-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);
-
- gtk_signal_emit (GTK_OBJECT (book_view), e_book_view_signals [CARD_ADDED],
- resp->cards);
-
- g_list_foreach (resp->cards, (GFunc) gtk_object_unref, NULL);
- g_list_free (resp->cards);
-}
-
-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);
-
- gtk_signal_emit (GTK_OBJECT (book_view), e_book_view_signals [CARD_CHANGED],
- resp->cards);
-
- g_list_foreach (resp->cards, (GFunc) gtk_object_unref, NULL);
- g_list_free (resp->cards);
-}
-
-static void
-e_book_view_do_removed_event (EBookView *book_view,
- EBookViewListenerResponse *resp)
-{
- gtk_signal_emit (GTK_OBJECT (book_view), e_book_view_signals [CARD_REMOVED],
- resp->id);
-
- g_free(resp->id);
-}
-
-static void
-e_book_view_do_complete_event (EBookView *book_view,
- EBookViewListenerResponse *resp)
-{
- gtk_signal_emit (GTK_OBJECT (book_view), e_book_view_signals [SEQUENCE_COMPLETE], resp->status);
-}
-
-static void
-e_book_view_do_status_message_event (EBookView *book_view,
- EBookViewListenerResponse *resp)
-{
- gtk_signal_emit (GTK_OBJECT (book_view), e_book_view_signals [STATUS_MESSAGE],
- resp->message);
- g_free(resp->message);
-}
-
-
-/*
- * Reading notices out of the EBookViewListener's queue.
- */
-static void
-e_book_view_check_listener_queue (EBookViewListener *listener, EBookView *book_view)
-{
- EBookViewListenerResponse *resp;
-
- resp = e_book_view_listener_pop_response (listener);
-
- if (resp == NULL)
- return;
-
- switch (resp->op) {
- case CardAddedEvent:
- e_book_view_do_added_event (book_view, resp);
- break;
- case CardModifiedEvent:
- e_book_view_do_modified_event (book_view, resp);
- break;
- case CardRemovedEvent:
- e_book_view_do_removed_event (book_view, resp);
- break;
- case SequenceCompleteEvent:
- e_book_view_do_complete_event (book_view, resp);
- break;
- case StatusMessageEvent:
- e_book_view_do_status_message_event (book_view, resp);
- break;
- default:
- g_error ("EBookView: Unknown operation %d in listener queue!\n",
- resp->op);
- break;
- }
-
- g_free (resp);
-}
-
-static gboolean
-e_book_view_construct (EBookView *book_view, GNOME_Evolution_Addressbook_BookView corba_book_view, EBookViewListener *listener)
-{
- CORBA_Environment ev;
- g_return_val_if_fail (book_view != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK_VIEW (book_view), FALSE);
-
- /*
- * Copy in the corba_book_view.
- */
- CORBA_exception_init (&ev);
-
- book_view->priv->corba_book_view = bonobo_object_dup_ref(corba_book_view, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_view_construct: Exception duplicating corba_book_view.\n");
- CORBA_exception_free (&ev);
- book_view->priv->corba_book_view = NULL;
- return FALSE;
- }
-
- CORBA_exception_free (&ev);
-
- /*
- * Create our local BookListener interface.
- */
- book_view->priv->listener = listener;
- book_view->priv->responses_queued_id = gtk_signal_connect (GTK_OBJECT (book_view->priv->listener), "responses_queued",
- e_book_view_check_listener_queue, book_view);
-
- bonobo_object_ref(BONOBO_OBJECT(book_view->priv->listener));
-
- return TRUE;
-}
-
-/**
- * e_book_view_new:
- */
-EBookView *
-e_book_view_new (GNOME_Evolution_Addressbook_BookView corba_book_view, EBookViewListener *listener)
-{
- EBookView *book_view;
-
- book_view = gtk_type_new (E_BOOK_VIEW_TYPE);
-
- if (! e_book_view_construct (book_view, corba_book_view, listener)) {
- gtk_object_unref (GTK_OBJECT (book_view));
- return NULL;
- }
-
- return book_view;
-}
-
-void
-e_book_view_set_book (EBookView *book_view, EBook *book)
-{
- g_return_if_fail (book_view && E_IS_BOOK_VIEW (book_view));
- g_return_if_fail (book && E_IS_BOOK (book));
- g_return_if_fail (book_view->priv->book == NULL);
-
- book_view->priv->book = book;
- gtk_object_ref (GTK_OBJECT (book));
-}
-
-void
-e_book_view_stop (EBookView *book_view)
-{
- g_return_if_fail (book_view && E_IS_BOOK_VIEW (book_view));
- if (book_view->priv->listener)
- e_book_view_listener_stop (book_view->priv->listener);
-}
-
-static void
-e_book_view_init (EBookView *book_view)
-{
- book_view->priv = g_new0 (EBookViewPrivate, 1);
- 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;
-}
-
-static void
-e_book_view_destroy (GtkObject *object)
-{
- EBookView *book_view = E_BOOK_VIEW (object);
- CORBA_Environment ev;
-
- if (book_view->priv->book) {
- gtk_object_unref (GTK_OBJECT (book_view->priv->book));
- }
-
- if (book_view->priv->corba_book_view) {
- CORBA_exception_init (&ev);
-
- bonobo_object_release_unref (book_view->priv->corba_book_view, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("EBookView: Exception while releasing BookView\n");
- }
-
- CORBA_exception_free (&ev);
- }
-
- if (book_view->priv->listener) {
- if (book_view->priv->responses_queued_id)
- gtk_signal_disconnect(GTK_OBJECT(book_view->priv->listener),
- book_view->priv->responses_queued_id);
- e_book_view_listener_stop (book_view->priv->listener);
- bonobo_object_unref (BONOBO_OBJECT(book_view->priv->listener));
- }
-
- g_free (book_view->priv);
-
- if (GTK_OBJECT_CLASS (e_book_view_parent_class)->destroy)
- GTK_OBJECT_CLASS (e_book_view_parent_class)->destroy (object);
-}
-
-static void
-e_book_view_class_init (EBookViewClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
-
- e_book_view_parent_class = gtk_type_class (gtk_object_get_type ());
-
- e_book_view_signals [CARD_CHANGED] =
- gtk_signal_new ("card_changed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EBookViewClass, card_changed),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_POINTER);
-
- e_book_view_signals [CARD_ADDED] =
- gtk_signal_new ("card_added",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EBookViewClass, card_added),
- gtk_marshal_NONE__STRING,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_STRING);
-
- e_book_view_signals [CARD_REMOVED] =
- gtk_signal_new ("card_removed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EBookViewClass, card_removed),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_POINTER);
-
- e_book_view_signals [SEQUENCE_COMPLETE] =
- gtk_signal_new ("sequence_complete",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EBookViewClass, sequence_complete),
- gtk_marshal_NONE__ENUM,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_ENUM);
-
- e_book_view_signals [STATUS_MESSAGE] =
- gtk_signal_new ("status_message",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EBookViewClass, status_message),
- gtk_marshal_NONE__STRING,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_STRING);
-
- gtk_object_class_add_signals (object_class, e_book_view_signals,
- LAST_SIGNAL);
-
- klass->card_changed = NULL;
- klass->card_added = NULL;
- klass->card_removed = NULL;
- klass->sequence_complete = NULL;
- klass->status_message = NULL;
-
- object_class->destroy = e_book_view_destroy;
-}
-
-/**
- * e_book_view_get_type:
- */
-GtkType
-e_book_view_get_type (void)
-{
- static GtkType type = 0;
-
- if (! type) {
- GtkTypeInfo info = {
- "EBookView",
- sizeof (EBookView),
- sizeof (EBookViewClass),
- (GtkClassInitFunc) e_book_view_class_init,
- (GtkObjectInitFunc) e_book_view_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (gtk_object_get_type (), &info);
- }
-
- return type;
-}
diff --git a/addressbook/backend/ebook/e-book-view.h b/addressbook/backend/ebook/e-book-view.h
deleted file mode 100644
index 2e055ddec9..0000000000
--- a/addressbook/backend/ebook/e-book-view.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- 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.
- */
-
-#ifndef __E_BOOK_VIEW_H__
-#define __E_BOOK_VIEW_H__
-
-#include <libgnome/gnome-defs.h>
-
-#include <ebook/e-card.h>
-#include <ebook/e-book-view-listener.h>
-
-BEGIN_GNOME_DECLS
-
-typedef struct _EBookView EBookView;
-typedef struct _EBookViewClass EBookViewClass;
-typedef struct _EBookViewPrivate EBookViewPrivate;
-
-struct _EBook; /* Forward reference */
-
-struct _EBookView {
- GtkObject parent;
- EBookViewPrivate *priv;
-};
-
-struct _EBookViewClass {
- GtkObjectClass parent;
-
- /*
- * Signals.
- */
- void (* card_changed) (EBookView *book_view, const GList *cards);
- void (* card_removed) (EBookView *book_view, const char *id);
- void (* card_added) (EBookView *book_view, const GList *cards);
- void (* sequence_complete) (EBookView *book_view, EBookViewStatus status);
- void (* status_message) (EBookView *book_view, const char *message);
-};
-
-/* Creating a new addressbook. */
-EBookView *e_book_view_new (GNOME_Evolution_Addressbook_BookView corba_book_view, EBookViewListener *listener);
-
-GtkType e_book_view_get_type (void);
-
-void e_book_view_set_book (EBookView *book_view, struct _EBook *book);
-
-void e_book_view_stop (EBookView *book_view);
-
-#define E_BOOK_VIEW_TYPE (e_book_view_get_type ())
-#define E_BOOK_VIEW(o) (GTK_CHECK_CAST ((o), E_BOOK_VIEW_TYPE, EBookView))
-#define E_BOOK_VIEW_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_BOOK_VIEW_TYPE, EBookViewClass))
-#define E_IS_BOOK_VIEW(o) (GTK_CHECK_TYPE ((o), E_BOOK_VIEW_TYPE))
-#define E_IS_BOOK_VIEW_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_BOOK_VIEW_TYPE))
-
-END_GNOME_DECLS
-
-#endif /* ! __E_BOOK_VIEW_H__ */
diff --git a/addressbook/backend/ebook/e-book.c b/addressbook/backend/ebook/e-book.c
deleted file mode 100644
index cad203ad44..0000000000
--- a/addressbook/backend/ebook/e-book.c
+++ /dev/null
@@ -1,1569 +0,0 @@
-/* -*- 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 <gtk/gtksignal.h>
-#include <gtk/gtkmarshal.h>
-#include <libgnome/gnome-defs.h>
-#include <liboaf/liboaf.h>
-
-#include "addressbook.h"
-#include "e-card-cursor.h"
-#include "e-book-listener.h"
-#include "e-book.h"
-#include "e-util/e-component-listener.h"
-
-GtkObjectClass *e_book_parent_class;
-
-#define CARDSERVER_OAF_ID "OAFIID:GNOME_Evolution_Wombat_ServerFactory"
-
-typedef enum {
- URINotLoaded,
- URILoading,
- URILoaded
-} EBookLoadState;
-
-struct _EBookPrivate {
- GList *book_factories;
- GList *iter;
-
- 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;
-
- gchar *uri;
-};
-
-enum {
- OPEN_PROGRESS,
- WRITABLE_STATUS,
- LINK_STATUS,
- BACKEND_DIED,
- LAST_SIGNAL
-};
-
-static guint e_book_signals [LAST_SIGNAL];
-
-typedef struct {
- guint tag;
- gboolean active;
- gpointer cb;
- gpointer closure;
- EBookViewListener *listener;
-} EBookOp;
-
-/*
- * 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);
-}
-
-static guint
-e_book_queue_op (EBook *book,
- gpointer cb,
- gpointer closure,
- EBookViewListener *listener)
-{
- EBookOp *op;
-
- op = g_new0 (EBookOp, 1);
- op->tag = book->priv->op_tag++;
- op->active = TRUE;
- op->cb = cb;
- op->closure = closure;
- op->listener = listener;
-
- if (op->listener)
- bonobo_object_ref (BONOBO_OBJECT (op->listener));
-
- book->priv->pending_ops =
- g_list_append (book->priv->pending_ops, op);
-
- return op->tag;
-}
-
-/*
- * Local response queue management.
- */
-static void
-e_book_unqueue_op (EBook *book)
-{
- EBookOp *op;
- GList *removed;
-
- removed = g_list_last (book->priv->pending_ops);
-
- 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--;
- }
-}
-
-static EBookOp *
-e_book_pop_op (EBook *book)
-{
- GList *popped;
- EBookOp *op;
-
- if (book->priv->pending_ops == NULL)
- return NULL;
-
- op = book->priv->pending_ops->data;
-
- popped = book->priv->pending_ops;
- book->priv->pending_ops =
- g_list_remove_link (book->priv->pending_ops,
- book->priv->pending_ops);
-
- g_list_free_1 (popped);
-
- return op;
-}
-
-static gboolean
-e_book_cancel_op (EBook *book, guint tag)
-{
- GList *iter;
- gboolean cancelled = 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;
- }
- }
-
- return cancelled;
-}
-
-static void
-e_book_do_response_create_card (EBook *book,
- EBookListenerResponse *resp)
-{
- EBookOp *op;
-
- op = e_book_pop_op (book);
-
- if (op == NULL) {
- g_warning ("e_book_do_response_create_card: Cannot find operation "
- "in local op queue!\n");
- return;
- }
-
- if (op->cb)
- ((EBookIdCallback) op->cb) (book, resp->status, resp->id, op->closure);
- g_free (resp->id);
- e_book_op_free (op);
-}
-
-static void
-e_book_do_response_generic (EBook *book,
- EBookListenerResponse *resp)
-{
- EBookOp *op;
-
- op = e_book_pop_op (book);
-
- if (op == NULL) {
- g_warning ("e_book_do_response_generic: Cannot find operation "
- "in local op queue!\n");
- }
-
- if (op->cb)
- ((EBookCallback) op->cb) (book, resp->status, op->closure);
-
- e_book_op_free (op);
-}
-
-static void
-e_book_do_response_get_vcard (EBook *book,
- EBookListenerResponse *resp)
-{
- EBookOp *op;
- ECard *card;
-
- op = e_book_pop_op (book);
-
- if (op == NULL) {
- g_warning ("e_book_do_response_get_vcard: Cannot find operation "
- "in local op queue!\n");
- return;
- }
- if (resp->vcard != NULL) {
-
- card = e_card_new(resp->vcard);
-
- 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);
- }
-
- gtk_object_unref(GTK_OBJECT(card));
- } else {
- ((EBookCursorCallback) op->cb) (book, resp->status, NULL, op->closure);
- }
- } else {
- ((EBookCardCallback) op->cb) (book, resp->status, NULL, op->closure);
- }
-
- g_free (resp->vcard);
- e_book_op_free (op);
-}
-
-static void
-e_book_do_response_get_cursor (EBook *book,
- EBookListenerResponse *resp)
-{
- CORBA_Environment ev;
- EBookOp *op;
- ECardCursor *cursor;
-
- op = e_book_pop_op (book);
-
- if (op == NULL) {
- g_warning ("e_book_do_response_get_cursor: Cannot find operation "
- "in local op queue!\n");
- return;
- }
-
- cursor = e_card_cursor_new(resp->cursor);
-
- 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);
- }
-
- /*
- * Release the remote GNOME_Evolution_Addressbook_Book in the PAS.
- */
- CORBA_exception_init (&ev);
-
- bonobo_object_release_unref (resp->cursor, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_do_response_get_cursor: Exception releasing "
- "remote GNOME_Evolution_Addressbook_CardCursor interface!\n");
- }
-
- CORBA_exception_free (&ev);
-
- gtk_object_unref(GTK_OBJECT(cursor));
- } else {
- ((EBookCursorCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure);
- }
-
- e_book_op_free (op);
-}
-
-static void
-e_book_do_response_get_view (EBook *book,
- EBookListenerResponse *resp)
-{
- CORBA_Environment ev;
- EBookOp *op;
- EBookView *book_view;
-
- op = e_book_pop_op (book);
-
- if (op == NULL) {
- g_warning ("e_book_do_response_get_view: Cannot find operation "
- "in local op queue!\n");
- return;
- }
-
- 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);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_do_response_get_view: Exception releasing "
- "remote GNOME_Evolution_Addressbook_BookView interface!\n");
- }
-
- CORBA_exception_free (&ev);
-
- gtk_object_unref(GTK_OBJECT(book_view));
- } else {
- e_book_view_listener_stop (op->listener);
- ((EBookBookViewCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure);
- }
-
- e_book_op_free (op);
-}
-
-static void
-e_book_do_response_get_changes (EBook *book,
- EBookListenerResponse *resp)
-{
- CORBA_Environment ev;
- EBookOp *op;
- EBookView *book_view;
-
- op = e_book_pop_op (book);
-
- if (op == NULL) {
- g_warning ("e_book_do_response_get_changes: Cannot find operation "
- "in local op queue!\n");
- return;
- }
-
- book_view = e_book_view_new (resp->book_view, op->listener);
-
- 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);
- }
-
- /*
- * Release the remote GNOME_Evolution_Addressbook_BookView in the PAS.
- */
- CORBA_exception_init (&ev);
-
- bonobo_object_release_unref (resp->book_view, &ev);
-
- 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_free (&ev);
-
- gtk_object_unref(GTK_OBJECT(book_view));
- } else {
- e_book_view_listener_stop (op->listener);
- ((EBookBookViewCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure);
- }
-
- e_book_op_free (op);
-}
-
-static void
-backend_died_cb (EComponentListener *cl, gpointer user_data)
-{
- EBook *book = user_data;
-
- book->priv->load_state = URINotLoaded;
- gtk_signal_emit (GTK_OBJECT (book), e_book_signals [BACKEND_DIED]);
-}
-
-static void
-e_book_do_response_open (EBook *book,
- EBookListenerResponse *resp)
-{
- 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, 0);
- gtk_signal_connect (GTK_OBJECT (book->priv->comp_listener), "component_died",
- GTK_SIGNAL_FUNC (backend_died_cb), book);
- }
-
- op = e_book_pop_op (book);
-
- if (op == NULL) {
- g_warning ("e_book_do_response_open: Cannot find operation "
- "in local op queue!\n");
- return;
- }
-
- if (op->cb)
- ((EBookCallback) op->cb) (book, resp->status, op->closure);
- e_book_op_free (op);
-}
-
-static void
-e_book_do_progress_event (EBook *book,
- EBookListenerResponse *resp)
-{
- gtk_signal_emit (GTK_OBJECT (book), e_book_signals [OPEN_PROGRESS],
- resp->msg, resp->percent);
-
- g_free (resp->msg);
-}
-
-static void
-e_book_do_link_event (EBook *book,
- EBookListenerResponse *resp)
-{
- gtk_signal_emit (GTK_OBJECT (book), e_book_signals [LINK_STATUS],
- resp->connected);
-}
-
-static void
-e_book_do_writable_event (EBook *book,
- EBookListenerResponse *resp)
-{
- gtk_signal_emit (GTK_OBJECT (book), e_book_signals [WRITABLE_STATUS],
- resp->writable);
-}
-
-static void
-e_book_do_response_get_supported_fields (EBook *book,
- EBookListenerResponse *resp)
-{
- EBookOp *op;
-
- op = e_book_pop_op (book);
-
- if (op == NULL) {
- g_warning ("e_book_do_response_get_supported_fields: Cannot find operation "
- "in local op queue!\n");
- return;
- }
-
- if (op->cb) {
- if (op->active)
- ((EBookFieldsCallback) op->cb) (book, resp->status, resp->fields, op->closure);
- else
- ((EBookFieldsCallback) op->cb) (book, E_BOOK_STATUS_CANCELLED, NULL, op->closure);
- }
-
- e_book_op_free (op);
-}
-
-/*
- * Reading notices out of the EBookListener's queue.
- */
-static void
-e_book_check_listener_queue (EBookListener *listener, EBook *book)
-{
- EBookListenerResponse *resp;
-
- resp = e_book_listener_pop_response (listener);
-
- if (resp == NULL)
- 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 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);
- }
-
- g_free (resp);
-}
-
-/**
- * e_book_load_uri:
- */
-
-typedef struct {
- char *uri;
- EBookCallback open_response;
- gpointer closure;
-} EBookLoadURIData;
-
-static void e_book_load_uri_from_factory (EBook *book,
- GNOME_Evolution_Addressbook_BookFactory factory,
- EBookLoadURIData *load_uri_data);
-
-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);
- }
- 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);
- }
-}
-
-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);
-
- cb (book, status, closure);
- }
- else {
- e_book_load_uri_step (book, status, data);
- }
-}
-
-static void
-e_book_load_uri_from_factory (EBook *book,
- GNOME_Evolution_Addressbook_BookFactory factory,
- EBookLoadURIData *load_uri_data)
-{
- CORBA_Environment ev;
-
- 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);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_load_uri: CORBA exception while opening addressbook!\n");
- e_book_unqueue_op (book);
- CORBA_exception_free (&ev);
- e_book_load_uri_step (book, E_BOOK_STATUS_OTHER_ERROR, load_uri_data);
- }
-
- CORBA_exception_free (&ev);
-
-}
-
-static gboolean
-activate_factories_for_uri (EBook *book, const char *uri)
-{
- CORBA_Environment ev;
- OAF_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");
- 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
- );
-
- CORBA_exception_init (&ev);
-
- info_list = oaf_query (query, NULL, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("Eeek! Cannot perform OAF 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);
- CORBA_exception_free (&ev);
- goto shutdown;
- }
-
- CORBA_exception_free (&ev);
-
- for (i = 0; i < info_list->_length; i ++) {
- const OAF_ServerInfo *info;
- GNOME_Evolution_Addressbook_BookFactory factory;
-
- info = info_list->_buffer + i;
-
- factory = oaf_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
- book->priv->book_factories = g_list_append (book->priv->book_factories,
- factory);
- }
-
- if (!book->priv->book_factories) {
- g_warning ("Couldn't activate any book factories.");
- goto shutdown;
- }
-
- retval = TRUE;
-
- shutdown:
- if (info_list)
- CORBA_free (info_list);
- g_free (query);
- g_free (protocol);
-
- return retval;
-}
-
-gboolean
-e_book_load_uri (EBook *book,
- const char *uri,
- EBookCallback open_response,
- gpointer closure)
-{
- EBookLoadURIData *load_uri_data;
- GNOME_Evolution_Addressbook_BookFactory factory;
-
- g_return_val_if_fail (book != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK (book), FALSE);
- g_return_val_if_fail (uri != NULL, FALSE);
- g_return_val_if_fail (open_response != NULL, FALSE);
-
- 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");
- return FALSE;
- }
-
- /* try to find a list of factories that can handle the protocol */
- if (!activate_factories_for_uri (book, uri)) {
- open_response (NULL, E_BOOK_STATUS_PROTOCOL_NOT_SUPPORTED, closure);
- 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");
- return FALSE;
- }
-
- gtk_signal_connect (GTK_OBJECT (book->priv->listener), "responses_queued",
- e_book_check_listener_queue, book);
-
- load_uri_data = g_new (EBookLoadURIData, 1);
- load_uri_data->open_response = open_response;
- load_uri_data->closure = closure;
-
- /* initialize the iterator, and load from the first one*/
- book->priv->iter = book->priv->book_factories;
-
- factory = book->priv->iter->data;
-
- e_book_load_uri_from_factory (book, factory, load_uri_data);
-
- book->priv->load_state = URILoading;
-
- /* Now we play the waiting game. */
-
- return TRUE;
-}
-
-/**
- * e_book_unload_uri:
- */
-void
-e_book_unload_uri (EBook *book)
-{
- CORBA_Environment ev;
-
- g_return_if_fail (book != NULL);
- g_return_if_fail (E_IS_BOOK (book));
-
- /*
- * 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;
- }
-
- /*
- * 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_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 = URINotLoaded;
-}
-
-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)
-{
- CORBA_Environment ev;
- char *temp;
- char *ret_val;
-
- CORBA_exception_init (&ev);
-
- if (book->priv->load_state != URILoaded) {
- 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("");
- }
-
- ret_val = g_strdup(temp);
- CORBA_free(temp);
-
- CORBA_exception_free (&ev);
-
- return ret_val;
-}
-
-guint
-e_book_get_supported_fields (EBook *book,
- EBookFieldsCallback cb,
- gpointer closure)
-{
- CORBA_Environment ev;
- guint tag;
-
- CORBA_exception_init (&ev);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_unload_uri: No URI is loaded!\n");
- return 0;
- }
-
- tag = e_book_queue_op (book, cb, closure, NULL);
-
- GNOME_Evolution_Addressbook_Book_getSupportedFields(book->priv->corba_book, &ev);
-
- 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;
- }
-
- CORBA_exception_free (&ev);
-
- return tag;
-}
-
-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);
-
- book->priv->book_factories = NULL;
-
- return TRUE;
-}
-
-/**
- * e_book_new:
- */
-EBook *
-e_book_new (void)
-{
- EBook *book;
-
- book = gtk_type_new (E_BOOK_TYPE);
-
- if (! e_book_construct (book)) {
- gtk_object_unref (GTK_OBJECT (book));
- return NULL;
- }
-
- return book;
-}
-
-/* User authentication. */
-
-void
-e_book_authenticate_user (EBook *book,
- const char *user,
- const char *passwd,
- const char *auth_method,
- EBookCallback cb,
- gpointer closure)
-{
- CORBA_Environment ev;
-
- g_return_if_fail (book != NULL);
- g_return_if_fail (E_IS_BOOK (book));
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_authenticate_user: No URI loaded!\n");
- return;
- }
-
- CORBA_exception_init (&ev);
-
- e_book_queue_op (book, cb, closure, NULL);
-
- GNOME_Evolution_Addressbook_Book_authenticateUser (book->priv->corba_book,
- user,
- passwd,
- auth_method,
- &ev);
-
- 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;
- }
-
- CORBA_exception_free (&ev);
-}
-
-/* Fetching cards */
-
-/**
- * e_book_get_card:
- */
-guint
-e_book_get_card (EBook *book,
- const char *id,
- EBookCardCallback cb,
- gpointer closure)
-{
- CORBA_Environment ev;
- guint tag;
-
- g_return_val_if_fail (book != NULL, 0);
- g_return_val_if_fail (E_IS_BOOK (book), 0);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_get_card: No URI loaded!\n");
- return 0;
- }
-
- CORBA_exception_init (&ev);
-
- tag = e_book_queue_op (book, cb, closure, NULL);
-
- GNOME_Evolution_Addressbook_Book_getVCard (book->priv->corba_book, (const GNOME_Evolution_Addressbook_VCard) id, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_get_card: Exception "
- "getting card!\n");
- CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
- return 0;
- }
-
- CORBA_exception_free (&ev);
-
- return tag;
-}
-
-/* Deleting cards. */
-
-/**
- * e_book_remove_card:
- */
-gboolean
-e_book_remove_card (EBook *book,
- ECard *card,
- EBookCallback cb,
- gpointer closure)
-{
- const char *id;
-
- 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);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_remove_card: No URI loaded!\n");
- return FALSE;
- }
-
- id = e_card_get_id (card);
- g_assert (id != NULL);
-
- return e_book_remove_card_by_id (book, id, cb, closure);
-}
-
-/**
- * e_book_remove_card_by_id:
- */
-gboolean
-e_book_remove_card_by_id (EBook *book,
- const char *id,
- EBookCallback cb,
- gpointer closure)
-
-{
- 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 (id != NULL, FALSE);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_remove_card_by_id: No URI loaded!\n");
- return FALSE;
- }
-
- CORBA_exception_init (&ev);
-
- e_book_queue_op (book, cb, closure, NULL);
-
- GNOME_Evolution_Addressbook_Book_removeCard (
- book->priv->corba_book, (const GNOME_Evolution_Addressbook_CardId) id, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_remove_card_by_id: CORBA exception "
- "talking to PAS!\n");
- CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
- return FALSE;
- }
-
- CORBA_exception_free (&ev);
-
- return TRUE;
-}
-
-/* Adding cards. */
-
-/**
- * e_book_add_card:
- */
-gboolean
-e_book_add_card (EBook *book,
- ECard *card,
- EBookIdCallback 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);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_add_card: No URI loaded!\n");
- return FALSE;
- }
-
- vcard = e_card_get_vcard_assume_utf8 (card);
-
- if (vcard == NULL) {
- g_warning ("e_book_add_card: Cannot convert card to VCard string!\n");
- return FALSE;
- }
-
- retval = e_book_add_vcard (book, vcard, cb, closure);
-
- g_free (vcard);
-
- if (card->book && card->book != book)
- gtk_object_unref (GTK_OBJECT (card->book));
- card->book = book;
- gtk_object_ref (GTK_OBJECT (card->book));
-
- return retval;
-}
-
-/**
- * e_book_add_vcard:
- */
-gboolean
-e_book_add_vcard (EBook *book,
- const char *vcard,
- EBookIdCallback cb,
- gpointer closure)
-{
- 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);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_add_vcard: No URI loaded!\n");
- return FALSE;
- }
-
- CORBA_exception_init (&ev);
-
- e_book_queue_op (book, (EBookCallback) cb, closure, NULL);
-
- GNOME_Evolution_Addressbook_Book_addCard (
- book->priv->corba_book, (const GNOME_Evolution_Addressbook_VCard) vcard, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_add_vcard: Exception adding card to PAS!\n");
- CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
- return FALSE;
- }
-
- CORBA_exception_free (&ev);
-
- return TRUE;
-}
-
-/* Modifying cards. */
-
-/**
- * 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);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_commit_card: No URI loaded!\n");
- return FALSE;
- }
-
- vcard = e_card_get_vcard_assume_utf8 (card);
-
- if (vcard == NULL) {
- g_warning ("e_book_commit_card: Error "
- "getting VCard for card!\n");
- return FALSE;
- }
-
- retval = e_book_commit_vcard (book, vcard, cb, closure);
-
- g_free (vcard);
-
- if (card->book && card->book != book)
- gtk_object_unref (GTK_OBJECT (card->book));
- card->book = book;
- gtk_object_ref (GTK_OBJECT (card->book));
-
- return retval;
-}
-
-/**
- * e_book_commit_vcard:
- */
-gboolean
-e_book_commit_vcard (EBook *book,
- const char *vcard,
- EBookCallback cb,
- gpointer closure)
-{
- 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);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_commit_vcard: No URI loaded!\n");
- return FALSE;
- }
-
- CORBA_exception_init (&ev);
-
- e_book_queue_op (book, cb, closure, NULL);
-
- GNOME_Evolution_Addressbook_Book_modifyCard (
- book->priv->corba_book, (const GNOME_Evolution_Addressbook_VCard) vcard, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_commit_vcard: Exception "
- "modifying card in PAS!\n");
- CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
- return FALSE;
- }
-
- CORBA_exception_free (&ev);
-
- return TRUE;
-}
-
-/**
- * e_book_check_connection:
- */
-gboolean
-e_book_check_connection (EBook *book)
-{
- CORBA_Environment ev;
-
- g_return_val_if_fail (book != NULL, FALSE);
- g_return_val_if_fail (E_IS_BOOK (book), FALSE);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_check_connection: No URI loaded!\n");
- return FALSE;
- }
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_Book_checkConnection (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;
- }
-
- CORBA_exception_free (&ev);
-
- return TRUE;
-}
-
-guint
-e_book_get_cursor (EBook *book,
- gchar *query,
- EBookCursorCallback cb,
- gpointer closure)
-{
- CORBA_Environment ev;
- guint tag;
-
- g_return_val_if_fail (book != NULL, 0);
- g_return_val_if_fail (E_IS_BOOK (book), 0);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_check_connection: No URI loaded!\n");
- return 0;
- }
-
- CORBA_exception_init (&ev);
-
- tag = e_book_queue_op (book, cb, closure, NULL);
-
- GNOME_Evolution_Addressbook_Book_getCursor (book->priv->corba_book, query, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_get_all_cards: Exception "
- "querying list of cards!\n");
- CORBA_exception_free (&ev);
- e_book_unqueue_op (book);
- return 0;
- }
-
- CORBA_exception_free (&ev);
-
- return tag;
-}
-
-guint
-e_book_get_book_view (EBook *book,
- const gchar *query,
- EBookBookViewCallback cb,
- gpointer closure)
-{
- 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);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_get_book_view: No URI loaded!\n");
- return 0;
- }
-
- 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);
-
- 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;
- }
-
- CORBA_exception_free (&ev);
-
- return tag;
-}
-
-guint
-e_book_get_completion_view (EBook *book,
- const gchar *query,
- EBookBookViewCallback cb,
- gpointer closure)
-{
- 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);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_get_completion_view: No URI loaded!\n");
- return 0;
- }
-
- listener = e_book_view_listener_new();
-
- CORBA_exception_init (&ev);
-
- tag = e_book_queue_op (book, cb, closure, listener);
-
- GNOME_Evolution_Addressbook_Book_getCompletionView (book->priv->corba_book,
- bonobo_object_corba_objref(BONOBO_OBJECT(listener)),
- query, &ev);
-
- 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;
-}
-
-guint
-e_book_get_changes (EBook *book,
- gchar *changeid,
- EBookBookViewCallback cb,
- gpointer closure)
-{
- 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);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_get_changes: No URI loaded!\n");
- 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_getChanges (book->priv->corba_book, bonobo_object_corba_objref(BONOBO_OBJECT(listener)), changeid, &ev);
-
- 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;
- }
-
- CORBA_exception_free (&ev);
-
- return tag;
-}
-
-/**
- * e_book_cancel
- */
-
-void
-e_book_cancel (EBook *book, guint tag)
-{
- 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)
-{
- CORBA_Environment ev;
- char *retval;
- char *name;
-
- g_return_val_if_fail (book != NULL, NULL);
- g_return_val_if_fail (E_IS_BOOK (book), NULL);
-
- if (book->priv->load_state != URILoaded) {
- g_warning ("e_book_get_name: No URI loaded!\n");
- return NULL;
- }
-
- CORBA_exception_init (&ev);
-
- name = GNOME_Evolution_Addressbook_Book_getName (book->priv->corba_book, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("e_book_get_name: Exception getting name from PAS!\n");
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- CORBA_exception_free (&ev);
-
- if (name == NULL) {
- g_warning ("e_book_get_name: Got NULL name from PAS!\n");
- return NULL;
- }
-
- retval = g_strdup (name);
- CORBA_free (name);
-
- return retval;
-}
-
-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->uri = NULL;
-}
-
-static void
-e_book_destroy (GtkObject *object)
-{
- EBook *book = E_BOOK (object);
- CORBA_Environment ev;
- GList *l;
-
- if (book->priv->load_state == URILoaded)
- e_book_unload_uri (book);
-
- CORBA_exception_init (&ev);
-
- for (l = book->priv->book_factories; l; l = l->next) {
- CORBA_Object_release ((CORBA_Object)l->data, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("EBook: Exception while releasing BookFactory\n");
-
- CORBA_exception_free (&ev);
- CORBA_exception_init (&ev);
- }
- }
-
- if (book->priv->comp_listener) {
- gtk_signal_disconnect_by_data (GTK_OBJECT (book->priv->comp_listener), book);
- gtk_object_unref (GTK_OBJECT (book->priv->comp_listener));
- book->priv->comp_listener = NULL;
- }
-
- g_free (book->priv->uri);
-
- g_free (book->priv);
-
- GTK_OBJECT_CLASS (e_book_parent_class)->destroy (object);
-}
-
-static void
-e_book_class_init (EBookClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
-
- e_book_parent_class = gtk_type_class (gtk_object_get_type ());
-
- e_book_signals [LINK_STATUS] =
- gtk_signal_new ("link_status",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EBookClass, link_status),
- gtk_marshal_NONE__BOOL,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_BOOL);
-
- e_book_signals [WRITABLE_STATUS] =
- gtk_signal_new ("writable_status",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EBookClass, writable_status),
- gtk_marshal_NONE__BOOL,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_BOOL);
-
- e_book_signals [BACKEND_DIED] =
- gtk_signal_new ("backend_died",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EBookClass, backend_died),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, e_book_signals,
- LAST_SIGNAL);
-
- object_class->destroy = e_book_destroy;
-}
-
-/**
- * e_book_get_type:
- */
-GtkType
-e_book_get_type (void)
-{
- static GtkType type = 0;
-
- if (! type) {
- GtkTypeInfo info = {
- "EBook",
- sizeof (EBook),
- sizeof (EBookClass),
- (GtkClassInitFunc) e_book_class_init,
- (GtkObjectInitFunc) e_book_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (gtk_object_get_type (), &info);
- }
-
- return type;
-}
diff --git a/addressbook/backend/ebook/e-book.h b/addressbook/backend/ebook/e-book.h
deleted file mode 100644
index be90f52c04..0000000000
--- a/addressbook/backend/ebook/e-book.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/* -*- 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.
- */
-
-#ifndef __E_BOOK_H__
-#define __E_BOOK_H__
-
-#include <libgnome/gnome-defs.h>
-
-#include <ebook/e-card.h>
-#include <ebook/e-card-cursor.h>
-#include <ebook/e-book-view.h>
-#include <ebook/e-book-types.h>
-
-BEGIN_GNOME_DECLS
-
-typedef struct _EBook EBook;
-typedef struct _EBookClass EBookClass;
-typedef struct _EBookPrivate EBookPrivate;
-
-struct _EBook {
- GtkObject parent;
- EBookPrivate *priv;
-};
-
-struct _EBookClass {
- GtkObjectClass parent;
-
- /*
- * 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);
-
-/* Creating a new addressbook. */
-EBook *e_book_new (void);
-
-gboolean e_book_load_uri (EBook *book,
- const char *uri,
- EBookCallback open_response,
- gpointer closure);
-void e_book_unload_uri (EBook *book);
-
-const char *e_book_get_uri (EBook *book);
-
-char *e_book_get_static_capabilities (EBook *book);
-
-guint e_book_get_supported_fields (EBook *book,
- EBookFieldsCallback cb,
- gpointer closure);
-
-
-/* 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);
-
-/* 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);
-
-/* Cancel a pending operation. */
-void e_book_cancel (EBook *book,
- guint tag);
-
-
-/* Getting the name of the repository. */
-char *e_book_get_name (EBook *book);
-
-GtkType e_book_get_type (void);
-
-#define E_BOOK_TYPE (e_book_get_type ())
-#define E_BOOK(o) (GTK_CHECK_CAST ((o), E_BOOK_TYPE, EBook))
-#define E_BOOK_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_BOOK_TYPE, EBookClass))
-#define E_IS_BOOK(o) (GTK_CHECK_TYPE ((o), E_BOOK_TYPE))
-#define E_IS_BOOK_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_BOOK_TYPE))
-
-END_GNOME_DECLS
-
-#endif /* ! __E_BOOK_H__ */
diff --git a/addressbook/backend/ebook/e-card-compare.c b/addressbook/backend/ebook/e-card-compare.c
deleted file mode 100644
index b8866e7e81..0000000000
--- a/addressbook/backend/ebook/e-card-compare.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-card-compare.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 <gal/unicode/gunicode.h>
-#include "e-book-util.h"
-#include "e-card-compare.h"
-
-/* This is an "optimistic" combiner: the best of the two outcomes is
- selected. */
-static ECardMatchType
-combine_comparisons (ECardMatchType prev,
- ECardMatchType new_info)
-{
- if (new_info == E_CARD_MATCH_NOT_APPLICABLE)
- return prev;
- return (ECardMatchType) MAX ((gint) prev, (gint) new_info);
-}
-
-
-/*** Name comparisons ***/
-
-/* This *so* doesn't belong here... at least not implemented in a
- sucky way like this. But it can be fixed later. */
-
-/* This is very Anglocentric. */
-static gchar *name_synonyms[][2] = {
- { "jon", "john" }, /* Ah, the hacker's perogative */
- { "joseph", "joe" },
- { "robert", "bob" },
- { "gene", "jean" },
- { "jesse", "jessie" },
- { "ian", "iain" },
- { "richard", "dick" },
- { "william", "bill" },
- { "william", "will" },
- { "anthony", "tony" },
- { "michael", "mike" },
- { "eric", "erik" },
- { "elizabeth", "liz" },
- { "jeff", "geoff" },
- { "jeff", "geoffrey" },
- { "tom", "thomas" },
- { "dave", "david" },
- { "jim", "james" },
- { "abigal", "abby" },
- { "amanda", "amy" },
- { "amanda", "manda" },
- { "jennifer", "jenny" },
- { "christopher", "chris" },
- { "rebecca", "becca" },
- { "rebecca", "becky" },
- { "anderson", "andersen" },
- { "johnson", "johnsen" },
- /* We could go on and on... */
- /* We should add soundex here. */
- { NULL, NULL }
-};
-
-static gboolean
-name_fragment_match (const gchar *a, const gchar *b, gboolean strict)
-{
- gint len;
-
- if (!(a && b && *a && *b))
- return FALSE;
-
- /* If we are in 'strict' mode, b must match the beginning of a.
- So "Robert", "Rob" would match, but "Robert", "Robbie" wouldn't.
-
- If strict is FALSE, it is sufficient for the strings to share
- some leading characters. In this case, "Robert" and "Robbie"
- would match, as would "Dave" and "Dan". */
-
- if (strict) {
- len = g_utf8_strlen (b, -1);
- } else {
- len = MIN (g_utf8_strlen (a, -1), g_utf8_strlen (b, -1));
- }
-
- return !g_utf8_strncasecmp (a, b, len);
-}
-
-static gboolean
-name_fragment_match_with_synonyms (const gchar *a, const gchar *b, gboolean strict)
-{
- gint i;
-
- if (!(a && b && *a && *b))
- return FALSE;
-
- if (name_fragment_match (a, b, strict))
- return TRUE;
-
- /* Check for nicknames. Yes, the linear search blows. */
- for (i=0; name_synonyms[i][0]; ++i) {
-
- if (!g_utf8_strcasecmp (name_synonyms[i][0], a)
- && !g_utf8_strcasecmp (name_synonyms[i][1], b))
- return TRUE;
-
- if (!g_utf8_strcasecmp (name_synonyms[i][0], b)
- && !g_utf8_strcasecmp (name_synonyms[i][1], a))
- return TRUE;
- }
-
- return FALSE;
-}
-
-ECardMatchType
-e_card_compare_name_to_string (ECard *card, const gchar *str)
-{
- return e_card_compare_name_to_string_full (card, 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)
-{
- 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 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);
-
- str_cpy = s = g_strdup (str);
- while (*s) {
- if (*s == ',' || *s == '"')
- *s = ' ';
- ++s;
- }
- 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);
-
- fragment_count = 0;
- for (i = 0; givenv && givenv[i]; ++i)
- ++fragment_count;
- for (i = 0; addv && addv[i]; ++i)
- ++fragment_count;
- for (i = 0; familyv && familyv[i]; ++i)
- ++fragment_count;
-
- for (i = 0; namev[i] && this_part_match != E_CARD_MATCH_PART_NONE; ++i) {
-
- if (*namev[i]) {
-
- this_part_match = E_CARD_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) {
- 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;
-
- /* We remove a piece of a name once it has been matched against, so
- that "john john" won't match "john doe". */
- g_free (givenv[j]);
- givenv[j] = g_strdup ("");
- break;
- }
- }
- }
-
- if (addv && this_part_match == E_CARD_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;
-
- g_free (addv[j]);
- addv[j] = g_strdup ("");
- break;
- }
- }
- }
-
- if (familyv && this_part_match == E_CARD_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)
- : !g_utf8_strcasecmp (familyv[j], namev[i])) {
-
- this_part_match = E_CARD_MATCH_PART_FAMILY_NAME;
-
- g_free (familyv[j]);
- familyv[j] = g_strdup ("");
- break;
- }
- }
- }
-
- if (this_part_match != E_CARD_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)
- first_matched_part = this_part_match;
- }
- }
- }
-
- match_type = E_CARD_MATCH_NONE;
-
- if (this_part_match != E_CARD_MATCH_PART_NONE) {
-
- if (match_count > 0)
- match_type = E_CARD_MATCH_VAGUE;
-
- if (fragment_count == match_count) {
-
- match_type = E_CARD_MATCH_EXACT;
-
- } else if (fragment_count == match_count + 1) {
-
- match_type = E_CARD_MATCH_PARTIAL;
-
- }
- }
-
- if (matched_parts_out)
- *matched_parts_out = matched_parts;
- if (first_matched_part_out)
- *first_matched_part_out = first_matched_part;
- if (matched_character_count_out)
- *matched_character_count_out = matched_character_count;
-
- g_strfreev (namev);
- g_strfreev (givenv);
- g_strfreev (addv);
- g_strfreev (familyv);
-
- return match_type;
-}
-
-ECardMatchType
-e_card_compare_name (ECard *card1, ECard *card2)
-{
- ECardName *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);
-
- a = card1->name;
- b = card2->name;
-
- if (a == NULL || b == NULL)
- return E_CARD_MATCH_NOT_APPLICABLE;
-
- if (a->given && b->given) {
- ++possible;
- if (name_fragment_match_with_synonyms (a->given, b->given, FALSE /* both inputs are complete */)) {
- ++matches;
- given_match = TRUE;
- }
- }
-
- if (a->additional && b->additional) {
- ++possible;
- if (name_fragment_match_with_synonyms (a->additional, b->additional, FALSE /* both inputs are complete */)) {
- ++matches;
- additional_match = TRUE;
- }
- }
-
- if (a->family && b->family) {
- ++possible;
- /* We don't allow "loose matching" (i.e. John vs. Jon) on family names */
- if (! g_utf8_strcasecmp (a->family, b->family)) {
- ++matches;
- family_match = TRUE;
- }
- }
-
- /* Now look at the # of matches and try to intelligently map
- an E_CARD_MATCH_* type to it. Special consideration is given
- to family-name matches. */
-
- if (possible == 0)
- return E_CARD_MATCH_NOT_APPLICABLE;
-
- if (possible == 1)
- return family_match ? E_CARD_MATCH_VAGUE : E_CARD_MATCH_NONE;
-
- if (possible == matches)
- return family_match ? E_CARD_MATCH_EXACT : E_CARD_MATCH_PARTIAL;
-
- if (possible == matches+1)
- return family_match ? E_CARD_MATCH_VAGUE : E_CARD_MATCH_NONE;
-
- return E_CARD_MATCH_NONE;
-}
-
-
-/*** Nickname Comparisons ***/
-
-ECardMatchType
-e_card_compare_nickname (ECard *card1, ECard *card2)
-{
- 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);
-
- return E_CARD_MATCH_NOT_APPLICABLE;
-}
-
-
-
-/*** E-mail Comparisons ***/
-
-static gboolean
-match_email_username (const gchar *addr1, const gchar *addr2)
-{
- gint c1, c2;
- if (addr1 == NULL || addr2 == NULL)
- return FALSE;
-
- while (*addr1 && *addr2 && *addr1 != '@' && *addr2 != '@') {
- c1 = isupper (*addr1) ? tolower (*addr1) : *addr1;
- c2 = isupper (*addr2) ? tolower (*addr2) : *addr2;
- if (c1 != c2)
- return FALSE;
- ++addr1;
- ++addr2;
- }
-
- return *addr1 == *addr2;
-}
-
-static gboolean
-match_email_hostname (const gchar *addr1, const gchar *addr2)
-{
- gint c1, c2;
- gboolean seen_at1, seen_at2;
- if (addr1 == NULL || addr2 == NULL)
- return FALSE;
-
- /* Walk to the end of each string. */
- seen_at1 = FALSE;
- if (*addr1) {
- while (*addr1) {
- if (*addr1 == '@')
- seen_at1 = TRUE;
- ++addr1;
- }
- --addr1;
- }
-
- seen_at2 = FALSE;
- if (*addr2) {
- while (*addr2) {
- if (*addr2 == '@')
- seen_at2 = TRUE;
- ++addr2;
- }
- --addr2;
- }
-
- if (!seen_at1 && !seen_at2)
- return TRUE;
- if (!seen_at1 || !seen_at2)
- return FALSE;
-
- while (*addr1 != '@' && *addr2 != '@') {
- c1 = isupper (*addr1) ? tolower (*addr1) : *addr1;
- c2 = isupper (*addr2) ? tolower (*addr2) : *addr2;
- if (c1 != c2)
- return FALSE;
- --addr1;
- --addr2;
- }
-
- /* This will match bob@foo.ximian.com and bob@ximian.com */
- return *addr1 == '.' || *addr2 == '.';
-}
-
-static ECardMatchType
-compare_email_addresses (const gchar *addr1, const gchar *addr2)
-{
- if (addr1 == NULL || *addr1 == 0 ||
- addr2 == NULL || *addr2 == 0)
- return E_CARD_MATCH_NOT_APPLICABLE;
-
- if (match_email_username (addr1, addr2))
- return match_email_hostname (addr1, addr2) ? E_CARD_MATCH_EXACT : E_CARD_MATCH_VAGUE;
-
- return E_CARD_MATCH_NONE;
-}
-
-ECardMatchType
-e_card_compare_email (ECard *card1, ECard *card2)
-{
- EIterator *i1, *i2;
- ECardMatchType match = E_CARD_MATCH_NOT_APPLICABLE;
-
- 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 (card1->email == NULL || card2->email == NULL)
- return E_CARD_MATCH_NOT_APPLICABLE;
-
- i1 = e_list_get_iterator (card1->email);
- i2 = e_list_get_iterator (card2->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);
-
- e_iterator_reset (i2);
- while (e_iterator_is_valid (i2) && match != E_CARD_MATCH_EXACT) {
- const gchar *addr2 = (const gchar *) e_iterator_get (i2);
-
- match = combine_comparisons (match, compare_email_addresses (addr1, addr2));
-
- e_iterator_next (i2);
- }
-
- e_iterator_next (i1);
- }
-
- gtk_object_unref (GTK_OBJECT (i1));
- gtk_object_unref (GTK_OBJECT (i2));
-
- return match;
-}
-
-ECardMatchType
-e_card_compare_address (ECard *card1, ECard *card2)
-{
- 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);
-
- /* Unimplemented */
-
- return E_CARD_MATCH_NOT_APPLICABLE;
-}
-
-ECardMatchType
-e_card_compare_telephone (ECard *card1, ECard *card2)
-{
- 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);
-
- /* Unimplemented */
-
- return E_CARD_MATCH_NOT_APPLICABLE;
-}
-
-ECardMatchType
-e_card_compare (ECard *card1, ECard *card2)
-{
- ECardMatchType 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);
-
- 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));
-
- return result;
-}
-
-typedef struct _MatchSearchInfo MatchSearchInfo;
-struct _MatchSearchInfo {
- ECard *card;
- GList *avoid;
- ECardMatchQueryCallback cb;
- gpointer closure;
-};
-
-static void
-match_search_info_free (MatchSearchInfo *info)
-{
- if (info) {
- gtk_object_unref (GTK_OBJECT (info->card));
-
- /* This should already have been deallocated, but just in case... */
- if (info->avoid) {
- g_list_foreach (info->avoid, (GFunc) gtk_object_unref, NULL);
- g_list_free (info->avoid);
- info->avoid = NULL;
- }
-
- g_free (info);
- }
-}
-
-static void
-simple_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
-{
- MatchSearchInfo *info = (MatchSearchInfo *) closure;
- ECardMatchType best_match = E_CARD_MATCH_NONE;
- ECard *best_card = NULL;
- GList *remaining_cards = NULL;
- const GList *i;
-
- if (status != E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS) {
- info->cb (info->card, NULL, E_CARD_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);
- 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))) {
- avoid = TRUE;
- break;
- }
- }
- if (!avoid)
- remaining_cards = g_list_prepend (remaining_cards, this_card);
- }
-
- remaining_cards = g_list_reverse (remaining_cards);
-
- 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);
- if ((gint)this_match > (gint)best_match) {
- best_match = this_match;
- best_card = this_card;
- }
- }
-
- g_list_free (remaining_cards);
-
- info->cb (info->card, best_card, best_match, info->closure);
- match_search_info_free (info);
-}
-
-#define MAX_QUERY_PARTS 10
-static void
-use_common_book_cb (EBook *book, gpointer closure)
-{
- MatchSearchInfo *info = (MatchSearchInfo *) closure;
- ECard *card = info->card;
- 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);
- 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
-
- if (card->name->given && strlen (card->name->given) > 1)
- query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", card->name->given);
-
- if (card->name->additional && strlen (card->name->additional) > 1)
- query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", card->name->additional);
-
- if (card->name->family && strlen (card->name->family) > 1)
- query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", card->name->family);
-
-
- 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));
- if (addr && *addr) {
- gchar *s = addr;
- while (*s) {
- if (*s == '@') {
- *s = '\0';
- break;
- }
- ++s;
- }
- query_parts[p++] = g_strdup_printf ("(beginswith \"email\" \"%s\")", addr);
- g_free (addr);
- }
- e_iterator_next (iter);
- }
- }
-
-
-
- /* Build up our full query from the parts. */
- query_parts[p] = NULL;
- qj = g_strjoinv (" ", query_parts);
- for(i = 0; query_parts[i] != NULL; i++)
- g_free(query_parts[i]);
- if (p > 0) {
- query = g_strdup_printf ("(or %s)", qj);
- g_free (qj);
- } else {
- query = qj;
- }
-
- e_book_simple_query (book, query, simple_query_cb, info);
-
- g_free (query);
-}
-
-void
-e_card_locate_match (ECard *card, ECardMatchQueryCallback cb, gpointer closure)
-{
- MatchSearchInfo *info;
-
- g_return_if_fail (card && E_IS_CARD (card));
- g_return_if_fail (cb != NULL);
-
- info = g_new (MatchSearchInfo, 1);
- info->card = card;
- gtk_object_ref (GTK_OBJECT (card));
- info->cb = cb;
- info->closure = closure;
- info->avoid = NULL;
-
- e_book_use_default_book (use_common_book_cb, info);
-}
-
-/**
- * e_card_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.
- * @cb: The function to call.
- * @closure: The closure to add to the call.
- *
- * Look for the best match and return it using the ECardMatchQueryCallback.
- **/
-void
-e_card_locate_match_full (EBook *book, ECard *card, GList *avoid, ECardMatchQueryCallback cb, gpointer closure)
-{
- MatchSearchInfo *info;
-
- g_return_if_fail (card && E_IS_CARD (card));
- g_return_if_fail (cb != NULL);
-
- info = g_new (MatchSearchInfo, 1);
- info->card = card;
- gtk_object_ref (GTK_OBJECT (card));
- info->cb = cb;
- info->closure = closure;
- info->avoid = g_list_copy (avoid);
- g_list_foreach (info->avoid, (GFunc) gtk_object_ref, NULL);
-
- if (book)
- use_common_book_cb (book, info);
- else
- e_book_use_default_book (use_common_book_cb, info);
-}
-
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 171f83d736..0000000000
--- a/addressbook/backend/ebook/e-card-cursor.c
+++ /dev/null
@@ -1,235 +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 <gtk/gtkobject.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 GtkObjectClass *parent_class;
-
-/*
- * Implemented GtkObject::destroy
- */
-static void
-e_card_cursor_destroy (GtkObject *object)
-{
- ECardCursor *cursor = E_CARD_CURSOR (object);
- 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);
-
- if ( cursor->priv )
- g_free ( cursor->priv );
-
- GTK_OBJECT_CLASS (parent_class)->destroy (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)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
-
- parent_class = gtk_type_class (gtk_object_get_type ());
-
- object_class->destroy = e_card_cursor_destroy;
-}
-
-static void
-e_card_cursor_init (ECardCursor *cursor)
-{
- cursor->priv = g_new(ECardCursorPrivate, 1);
- cursor->priv->corba_cursor = CORBA_OBJECT_NIL;
-}
-
-GtkType
-e_card_cursor_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type){
- GtkTypeInfo info = {
- "ECardCursor",
- sizeof (ECardCursor),
- sizeof (ECardCursorClass),
- (GtkClassInitFunc) e_card_cursor_class_init,
- (GtkObjectInitFunc) e_card_cursor_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (gtk_object_get_type (), &info);
- }
-
- 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 GtkType 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 = gtk_type_new (e_card_cursor_get_type ());
-
- 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 d6e7625941..0000000000
--- a/addressbook/backend/ebook/e-card-cursor.h
+++ /dev/null
@@ -1,52 +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 <gtk/gtkobject.h>
-#include <libgnome/gnome-defs.h>
-#include <ebook/addressbook.h>
-#include <ebook/e-card.h>
-
-BEGIN_GNOME_DECLS
-
-typedef struct _ECardCursor ECardCursor;
-typedef struct _ECardCursorPrivate ECardCursorPrivate;
-typedef struct _ECardCursorClass ECardCursorClass;
-
-struct _ECardCursor {
- GtkObject parent;
- ECardCursorPrivate *priv;
-};
-
-struct _ECardCursorClass {
- GtkObjectClass 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);
-
-GtkType 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);
-#define E_CARD_CURSOR_TYPE (e_card_cursor_get_type ())
-#define E_CARD_CURSOR(o) (GTK_CHECK_CAST ((o), E_CARD_CURSOR_TYPE, ECardCursor))
-#define E_CARD_CURSOR_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_CARD_CURSOR_TYPE, ECardCursorClass))
-#define E_IS_CARD_CURSOR(o) (GTK_CHECK_TYPE ((o), E_CARD_CURSOR_TYPE))
-#define E_IS_CARD_CURSOR_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CARD_CURSOR_TYPE))
-
-END_GNOME_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 7f0dd263b4..0000000000
--- a/addressbook/backend/ebook/e-card-simple.c
+++ /dev/null
@@ -1,1280 +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 <gtk/gtkobject.h>
-#include <gal/util/e-unicode-i18n.h>
-#include <gal/util/e-util.h>
-
-#include <libversit/vcc.h>
-#include "e-card-simple.h"
-
-/* Object argument IDs */
-enum {
- ARG_0,
- ARG_CARD,
-};
-
-
-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_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_destroy (GtkObject *object);
-static void e_card_simple_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_card_simple_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-
-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.
- **/
-GtkType
-e_card_simple_get_type (void)
-{
- static GtkType simple_type = 0;
-
- if (!simple_type) {
- GtkTypeInfo simple_info = {
- "ECardSimple",
- sizeof (ECardSimple),
- sizeof (ECardSimpleClass),
- (GtkClassInitFunc) e_card_simple_class_init,
- (GtkObjectInitFunc) e_card_simple_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- simple_type = gtk_type_unique (gtk_object_get_type (), &simple_info);
- }
-
- 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 = E_CARD_SIMPLE(gtk_type_new(e_card_simple_get_type()));
- gtk_object_set(GTK_OBJECT(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)
-{
- GtkObjectClass *object_class;
-
- object_class = GTK_OBJECT_CLASS(klass);
-
- gtk_object_add_arg_type ("ECardSimple::card",
- GTK_TYPE_OBJECT, GTK_ARG_READWRITE, ARG_CARD);
-
- object_class->destroy = e_card_simple_destroy;
- object_class->get_arg = e_card_simple_get_arg;
- object_class->set_arg = e_card_simple_set_arg;
-}
-
-/*
- * ECardSimple lifecycle management and vcard loading/saving.
- */
-
-static void
-e_card_simple_destroy (GtkObject *object)
-{
- ECardSimple *simple;
- int i;
-
- simple = E_CARD_SIMPLE (object);
-
- if (simple->card)
- gtk_object_unref(GTK_OBJECT(simple->card));
- 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++)
- e_card_phone_unref (simple->phone[i]);
- for(i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i++)
- g_free(simple->email[i]);
- for(i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++)
- e_card_address_label_unref(simple->address[i]);
- for(i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++)
- e_card_delivery_address_unref(simple->delivery[i]);
-}
-
-
-/* Set_arg handler for the simple */
-static void
-e_card_simple_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- ECardSimple *simple;
-
- simple = E_CARD_SIMPLE (object);
-
- switch (arg_id) {
- case ARG_CARD:
- if (simple->card)
- gtk_object_unref(GTK_OBJECT(simple->card));
- g_list_foreach(simple->temp_fields, (GFunc) g_free, NULL);
- g_list_free(simple->temp_fields);
- simple->temp_fields = NULL;
- if (GTK_VALUE_OBJECT(*arg))
- simple->card = E_CARD(GTK_VALUE_OBJECT(*arg));
- else
- simple->card = NULL;
- if(simple->card)
- gtk_object_ref(GTK_OBJECT(simple->card));
- fill_in_info(simple);
- break;
- default:
- return;
- }
-}
-
-/* Get_arg handler for the simple */
-static void
-e_card_simple_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- ECardSimple *simple;
-
- simple = E_CARD_SIMPLE (object);
-
- switch (arg_id) {
- case ARG_CARD:
- e_card_simple_sync_card(simple);
- GTK_VALUE_OBJECT (*arg) = (GtkObject *) simple->card;
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- 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;
-
- gtk_object_get(GTK_OBJECT(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;
- }
- }
- }
- gtk_object_unref(GTK_OBJECT(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;
- }
- }
- }
- gtk_object_unref(GTK_OBJECT(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;
- }
- }
- }
- gtk_object_unref(GTK_OBJECT(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;
- }
- }
- }
- gtk_object_unref(GTK_OBJECT(iterator));
- 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;
-
- gtk_object_get(GTK_OBJECT(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;
- }
- }
- }
- }
- gtk_object_unref(GTK_OBJECT(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;
- }
- }
- }
- gtk_object_unref(GTK_OBJECT(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;
- }
- }
- }
- }
- gtk_object_unref(GTK_OBJECT(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;
- }
- }
- }
- }
- gtk_object_unref(GTK_OBJECT(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);
- 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);
- 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;
- const char *string;
- ECardDate *date;
- ECardName *name;
- switch(type) {
- case E_CARD_SIMPLE_INTERNAL_TYPE_STRING:
- if (simple->card) {
- gtk_object_get(GTK_OBJECT(simple->card),
- field_data[field].ecard_field, &string,
- NULL);
- return g_strdup(string);
- } else
- return NULL;
- case E_CARD_SIMPLE_INTERNAL_TYPE_DATE:
- if (simple->card) {
- gtk_object_get(GTK_OBJECT(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;
- gtk_object_get (GTK_OBJECT (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;
-
- gtk_object_get(GTK_OBJECT(simple->card),
- "file_as", &string,
- NULL);
- if (string && *string)
- return g_strdup(string);
- gtk_object_get(GTK_OBJECT(simple->card),
- "full_name", &string,
- NULL);
- if (string && *string)
- return g_strdup(string);
- gtk_object_get(GTK_OBJECT(simple->card),
- "org", &string,
- NULL);
- if (string && *string)
- return g_strdup(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) {
- gtk_object_get (GTK_OBJECT(simple->card),
- "name", &name,
- NULL);
- return g_strdup (name->family);
- } else
- return NULL;
- case E_CARD_SIMPLE_FIELD_GIVEN_NAME:
- if (simple->card) {
- gtk_object_get (GTK_OBJECT(simple->card),
- "name", &name,
- NULL);
- return g_strdup (name->given);
- } else
- return NULL;
- case E_CARD_SIMPLE_FIELD_ADDITIONAL_NAME:
- if (simple->card) {
- gtk_object_get (GTK_OBJECT(simple->card),
- "name", &name,
- NULL);
- return g_strdup (name->additional);
- } else
- return NULL;
- case E_CARD_SIMPLE_FIELD_NAME_SUFFIX:
- if (simple->card) {
- gtk_object_get (GTK_OBJECT(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) {
- gtk_object_get (GTK_OBJECT (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("");
- gtk_object_get (GTK_OBJECT (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);
- gtk_object_set(GTK_OBJECT(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:
- gtk_object_set(GTK_OBJECT(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;
- gtk_object_set (GTK_OBJECT (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 U_(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 U_(field_data[field].short_name);
-}
-
-void e_card_simple_arbitrary_foreach (ECardSimple *simple,
- ECardSimpleArbitraryCallback *callback,
- gpointer closure)
-{
- if (simple->card) {
- EList *list;
- EIterator *iterator;
- gtk_object_get(GTK_OBJECT(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);
- }
- 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;
- gtk_object_get(GTK_OBJECT(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;
- }
- 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;
- gtk_object_get(GTK_OBJECT(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);
- e_card_arbitrary_unref(new_arb);
- }
-}
-
-void
-e_card_simple_set_name (ECardSimple *simple, ECardName *name)
-{
- int style;
- style = file_as_get_style(simple);
- gtk_object_set (GTK_OBJECT (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 53c1d13164..0000000000
--- a/addressbook/backend/ebook/e-card-simple.h
+++ /dev/null
@@ -1,233 +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 <gtk/gtk.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) (GTK_CHECK_CAST ((obj), E_TYPE_CARD_SIMPLE, ECardSimple))
-#define E_CARD_SIMPLE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_CARD_SIMPLE, ECardSimpleClass))
-#define E_IS_CARD_SIMPLE(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_CARD_SIMPLE))
-#define E_IS_CARD_SIMPLE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_CARD_SIMPLE))
-
-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,
- /* If you add after FBURL, make sure to move LAST_SIMPLE_STRING */
- E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING = E_CARD_SIMPLE_FIELD_FBURL,
- 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 {
- GtkObject 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 {
- GtkObjectClass 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);
-
-/* Standard Gtk function */
-GtkType 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 762b5f2141..0000000000
--- a/addressbook/backend/ebook/e-card.c
+++ /dev/null
@@ -1,2865 +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/util/e-i18n.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 <gtk/gtkobject.h>
-#include <bonobo/bonobo-object-client.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"
-#include "e-destination.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 argument IDs */
-enum {
- ARG_0,
- ARG_FILE_AS,
- ARG_FULL_NAME,
- ARG_NAME,
- ARG_ADDRESS,
- ARG_ADDRESS_LABEL,
- ARG_PHONE,
- ARG_EMAIL,
- ARG_BIRTH_DATE,
- ARG_URL,
- ARG_ORG,
- ARG_ORG_UNIT,
- ARG_OFFICE,
- ARG_TITLE,
- ARG_ROLE,
- ARG_MANAGER,
- ARG_ASSISTANT,
- ARG_NICKNAME,
- ARG_SPOUSE,
- ARG_ANNIVERSARY,
- ARG_MAILER,
- ARG_CALURI,
- ARG_FBURL,
- ARG_NOTE,
- ARG_RELATED_CONTACTS,
- ARG_CATEGORIES,
- ARG_CATEGORY_LIST,
- ARG_WANTS_HTML,
- ARG_WANTS_HTML_SET,
- ARG_EVOLUTION_LIST,
- ARG_EVOLUTION_LIST_SHOW_ADDRESSES,
- ARG_ARBITRARY,
- ARG_ID,
- ARG_LAST_USE,
- ARG_USE_SCORE,
-};
-
-static void parse(ECard *card, VObject *vobj, char *default_charset);
-static void e_card_init (ECard *card);
-static void e_card_class_init (ECardClass *klass);
-
-static void e_card_destroy (GtkObject *object);
-static void e_card_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_card_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-
-static void assign_string(VObject *vobj, char *default_charset, char **string);
-
-char *e_v_object_get_child_value(VObject *vobj, char *name, char *default_charset);
-
-static void parse_bday(ECard *card, VObject *object, char *default_charset);
-static void parse_full_name(ECard *card, VObject *object, char *default_charset);
-static void parse_file_as(ECard *card, VObject *object, char *default_charset);
-static void parse_name(ECard *card, VObject *object, char *default_charset);
-static void parse_email(ECard *card, VObject *object, char *default_charset);
-static void parse_phone(ECard *card, VObject *object, char *default_charset);
-static void parse_address(ECard *card, VObject *object, char *default_charset);
-static void parse_address_label(ECard *card, VObject *object, char *default_charset);
-static void parse_url(ECard *card, VObject *object, char *default_charset);
-static void parse_org(ECard *card, VObject *object, char *default_charset);
-static void parse_office(ECard *card, VObject *object, char *default_charset);
-static void parse_title(ECard *card, VObject *object, char *default_charset);
-static void parse_role(ECard *card, VObject *object, char *default_charset);
-static void parse_manager(ECard *card, VObject *object, char *default_charset);
-static void parse_assistant(ECard *card, VObject *object, char *default_charset);
-static void parse_nickname(ECard *card, VObject *object, char *default_charset);
-static void parse_spouse(ECard *card, VObject *object, char *default_charset);
-static void parse_anniversary(ECard *card, VObject *object, char *default_charset);
-static void parse_mailer(ECard *card, VObject *object, char *default_charset);
-static void parse_caluri(ECard *card, VObject *object, char *default_charset);
-static void parse_fburl(ECard *card, VObject *object, char *default_charset);
-static void parse_note(ECard *card, VObject *object, char *default_charset);
-static void parse_related_contacts(ECard *card, VObject *object, char *default_charset);
-static void parse_categories(ECard *card, VObject *object, char *default_charset);
-static void parse_wants_html(ECard *card, VObject *object, char *default_charset);
-static void parse_list(ECard *card, VObject *object, char *default_charset);
-static void parse_list_show_addresses(ECard *card, VObject *object, char *default_charset);
-static void parse_arbitrary(ECard *card, VObject *object, char *default_charset);
-static void parse_id(ECard *card, VObject *object, char *default_charset);
-static void parse_last_use(ECard *card, VObject *object, char *default_charset);
-static void parse_use_score(ECard *card, VObject *object, 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, 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 },
- { 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.
- **/
-GtkType
-e_card_get_type (void)
-{
- static GtkType card_type = 0;
-
- if (!card_type) {
- GtkTypeInfo card_info = {
- "ECard",
- sizeof (ECard),
- sizeof (ECardClass),
- (GtkClassInitFunc) e_card_class_init,
- (GtkObjectInitFunc) e_card_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- card_type = gtk_type_unique (gtk_object_get_type (), &card_info);
- }
-
- return card_type;
-}
-
-ECard *
-e_card_new_with_default_charset (char *vcard, char *default_charset)
-{
- ECard *card = E_CARD(gtk_type_new(e_card_get_type()));
- 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 (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;
- gtk_object_ref (GTK_OBJECT (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_julian (&today) - g_date_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_day (&today);
- card->last_use->month = g_date_month (&today);
- card->last_use->year = g_date_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)
- gtk_object_unref (GTK_OBJECT (card->book));
- card->book = book;
- if (card->book)
- gtk_object_ref (GTK_OBJECT (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");
- for (; *v; v++) {
- if (*v == '\n') {
- addProp(prop, VCQuotedPrintableProp);
- return prop;
- }
- }
- 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");
- }
- gtk_object_unref(GTK_OBJECT(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);
- }
- gtk_object_unref(GTK_OBJECT(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);
- }
- gtk_object_unref(GTK_OBJECT(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);
- }
- gtk_object_unref(GTK_OBJECT(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->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, 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, 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, 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, char *default_charset)
-{
- char *next_email;
- EList *list;
-
- assign_string(vobj, default_charset, &next_email);
- gtk_object_get(GTK_OBJECT(card),
- "email", &list,
- NULL);
- e_list_append(list, next_email);
- g_free (next_email);
-}
-
-/* Deal with charset */
-static void
-parse_bday(ECard *card, VObject *vobj, 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, 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);
-
- gtk_object_get(GTK_OBJECT(card),
- "phone", &list,
- NULL);
- e_list_append(list, next_phone);
- e_card_phone_unref (next_phone);
-}
-
-static void
-parse_address(ECard *card, VObject *vobj, 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);
-
- gtk_object_get(GTK_OBJECT(card),
- "address", &list,
- NULL);
- e_list_append(list, next_addr);
- e_card_delivery_address_unref (next_addr);
-}
-
-static void
-parse_address_label(ECard *card, VObject *vobj, 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);
-
- gtk_object_get(GTK_OBJECT(card),
- "address_label", &list,
- NULL);
- e_list_append(list, next_addr);
- e_card_address_label_unref (next_addr);
-}
-
-static void
-parse_url(ECard *card, VObject *vobj, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, char *default_charset)
-{
- g_free(card->caluri);
- assign_string(vobj, default_charset, &(card->caluri));
-}
-
-static void
-parse_fburl(ECard *card, VObject *vobj, char *default_charset)
-{
- g_free(card->fburl);
- assign_string(vobj, default_charset, &(card->fburl));
-}
-
-static void
-parse_note(ECard *card, VObject *vobj, char *default_charset)
-{
- g_free(card->note);
- assign_string(vobj, default_charset, &(card->note));
-}
-
-static void
-parse_related_contacts(ECard *card, VObject *vobj, 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);
- gtk_object_unref(GTK_OBJECT(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;
- gtk_object_get(GTK_OBJECT(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_free(copy);
-}
-
-/* Deal with charset */
-static void
-parse_categories(ECard *card, VObject *vobj, 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, 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, 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, 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, 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));
-
- gtk_object_get(GTK_OBJECT(card),
- "arbitrary", &list,
- NULL);
- e_list_append(list, arbitrary);
- e_card_arbitrary_unref(arbitrary);
-}
-
-static void
-parse_id(ECard *card, VObject *vobj, 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, char *default_charset)
-{
- if ( vObjectValueType (vobj) ) {
- char *str = fakeCString (vObjectUStringZValue (vobj));
- if ( card->last_use )
- 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, 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, char *default_charset)
-{
- ParsePropertyFunc function = g_hash_table_lookup(E_CARD_CLASS(GTK_OBJECT(card)->klass)->attribute_jump_table, vObjectName(vobj));
- if ( function )
- function(card, vobj, default_charset);
-}
-
-static void
-parse(ECard *card, VObject *vobj, 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;
- GtkObjectClass *object_class;
-
- object_class = GTK_OBJECT_CLASS(klass);
-
- 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);
- }
-
- gtk_object_add_arg_type ("ECard::file_as",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_FILE_AS);
- gtk_object_add_arg_type ("ECard::full_name",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_FULL_NAME);
- gtk_object_add_arg_type ("ECard::name",
- GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_NAME);
- gtk_object_add_arg_type ("ECard::address",
- GTK_TYPE_OBJECT, GTK_ARG_READABLE, ARG_ADDRESS);
- gtk_object_add_arg_type ("ECard::address_label",
- GTK_TYPE_OBJECT, GTK_ARG_READABLE, ARG_ADDRESS_LABEL);
- gtk_object_add_arg_type ("ECard::phone",
- GTK_TYPE_OBJECT, GTK_ARG_READABLE, ARG_PHONE);
- gtk_object_add_arg_type ("ECard::email",
- GTK_TYPE_OBJECT, GTK_ARG_READABLE, ARG_EMAIL);
- gtk_object_add_arg_type ("ECard::birth_date",
- GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_BIRTH_DATE);
- gtk_object_add_arg_type ("ECard::url",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_URL);
- gtk_object_add_arg_type ("ECard::org",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_ORG);
- gtk_object_add_arg_type ("ECard::org_unit",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_ORG_UNIT);
- gtk_object_add_arg_type ("ECard::office",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_OFFICE);
- gtk_object_add_arg_type ("ECard::title",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TITLE);
- gtk_object_add_arg_type ("ECard::role",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_ROLE);
- gtk_object_add_arg_type ("ECard::manager",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_MANAGER);
- gtk_object_add_arg_type ("ECard::assistant",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_ASSISTANT);
- gtk_object_add_arg_type ("ECard::nickname",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_NICKNAME);
- gtk_object_add_arg_type ("ECard::spouse",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_SPOUSE);
- gtk_object_add_arg_type ("ECard::anniversary",
- GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_ANNIVERSARY);
- gtk_object_add_arg_type ("ECard::mailer",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_MAILER);
- gtk_object_add_arg_type ("ECard::caluri",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_CALURI);
- gtk_object_add_arg_type ("ECard::fburl",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_FBURL);
- gtk_object_add_arg_type ("ECard::note",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_NOTE);
- gtk_object_add_arg_type ("ECard::related_contacts",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_RELATED_CONTACTS);
- gtk_object_add_arg_type ("ECard::categories",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_CATEGORIES);
- gtk_object_add_arg_type ("ECard::category_list",
- GTK_TYPE_OBJECT, GTK_ARG_READWRITE, ARG_CATEGORY_LIST);
- gtk_object_add_arg_type ("ECard::wants_html",
- GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_WANTS_HTML);
- gtk_object_add_arg_type ("ECard::wants_html_set",
- GTK_TYPE_BOOL, GTK_ARG_READABLE, ARG_WANTS_HTML);
- gtk_object_add_arg_type ("ECard::list",
- GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_EVOLUTION_LIST);
- gtk_object_add_arg_type ("ECard::list_show_addresses",
- GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_EVOLUTION_LIST_SHOW_ADDRESSES);
- gtk_object_add_arg_type ("ECard::arbitrary",
- GTK_TYPE_OBJECT, GTK_ARG_READWRITE, ARG_ARBITRARY);
- gtk_object_add_arg_type ("ECard::id",
- GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_ID);
- gtk_object_add_arg_type ("ECard::last_use",
- GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_LAST_USE);
- gtk_object_add_arg_type ("ECard::use_score",
- GTK_TYPE_FLOAT, GTK_ARG_READWRITE, ARG_USE_SCORE);
-
-
- object_class->destroy = e_card_destroy;
- object_class->get_arg = e_card_get_arg;
- object_class->set_arg = e_card_set_arg;
-}
-
-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_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;
- }
- gtk_object_unref (GTK_OBJECT (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_strcasecmp (e_iterator_get (iter), email))
- goto finished;
- ++count;
- }
- count = -1;
-
- finished:
- gtk_object_unref (GTK_OBJECT (iter));
-
- return count;
-}
-
-/*
- * ECard lifecycle management and vCard loading/saving.
- */
-
-static void
-e_card_destroy (GtkObject *object)
-{
- ECard *card = E_CARD(object);
- g_free(card->id);
- if (card->book)
- gtk_object_unref (GTK_OBJECT (card->book));
- g_free(card->file_as);
- g_free(card->fname);
- e_card_name_unref(card->name);
- g_free(card->bday);
-
- g_free(card->url);
- g_free(card->org);
- g_free(card->org_unit);
- g_free(card->office);
- g_free(card->title);
- g_free(card->role);
- g_free(card->manager);
- g_free(card->assistant);
- g_free(card->nickname);
- g_free(card->spouse);
- g_free(card->anniversary);
- g_free(card->caluri);
- g_free(card->fburl);
- g_free(card->note);
- g_free(card->related_contacts);
-
- if (card->categories)
- gtk_object_unref(GTK_OBJECT(card->categories));
- if (card->email)
- gtk_object_unref(GTK_OBJECT(card->email));
- if (card->phone)
- gtk_object_unref(GTK_OBJECT(card->phone));
- if (card->address)
- gtk_object_unref(GTK_OBJECT(card->address));
- if (card->address_label)
- gtk_object_unref(GTK_OBJECT(card->address_label));
-}
-
-
-/* Set_arg handler for the card */
-static void
-e_card_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- ECard *card;
-
- card = E_CARD (object);
-
- switch (arg_id) {
- case ARG_FILE_AS:
- g_free(card->file_as);
- card->file_as = g_strdup(GTK_VALUE_STRING(*arg));
- if (card->file_as == NULL)
- card->file_as = g_strdup("");
- break;
-
- case ARG_FULL_NAME:
- g_free(card->fname);
- card->fname = g_strdup(GTK_VALUE_STRING(*arg));
- 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 ARG_NAME:
- e_card_name_unref (card->name);
- card->name = e_card_name_ref(GTK_VALUE_POINTER(*arg));
- 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 ARG_CATEGORIES:
- if (card->categories)
- gtk_object_unref(GTK_OBJECT(card->categories));
- card->categories = NULL;
- if (GTK_VALUE_STRING(*arg))
- do_parse_categories(card, GTK_VALUE_STRING(*arg));
- break;
- case ARG_CATEGORY_LIST:
- if (card->categories)
- gtk_object_unref(GTK_OBJECT(card->categories));
- card->categories = E_LIST(GTK_VALUE_OBJECT(*arg));
- if (card->categories)
- gtk_object_ref(GTK_OBJECT(card->categories));
- break;
- case ARG_BIRTH_DATE:
- g_free(card->bday);
- if (GTK_VALUE_POINTER (*arg)) {
- card->bday = g_new (ECardDate, 1);
- memcpy (card->bday, GTK_VALUE_POINTER (*arg), sizeof (ECardDate));
- } else {
- card->bday = NULL;
- }
- break;
- case ARG_URL:
- g_free(card->url);
- card->url = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_ORG:
- g_free(card->org);
- card->org = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_ORG_UNIT:
- g_free(card->org_unit);
- card->org_unit = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_OFFICE:
- g_free(card->office);
- card->office = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_TITLE:
- g_free(card->title);
- card->title = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_ROLE:
- g_free(card->role);
- card->role = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_MANAGER:
- g_free(card->manager);
- card->manager = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_ASSISTANT:
- g_free(card->assistant);
- card->assistant = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_NICKNAME:
- g_free(card->nickname);
- card->nickname = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_SPOUSE:
- g_free(card->spouse);
- card->spouse = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_ANNIVERSARY:
- g_free(card->anniversary);
- if (GTK_VALUE_POINTER (*arg)) {
- card->anniversary = g_new (ECardDate, 1);
- memcpy (card->anniversary, GTK_VALUE_POINTER (*arg), sizeof (ECardDate));
- } else {
- card->anniversary = NULL;
- }
- break;
- case ARG_MAILER:
- g_free(card->mailer);
- card->mailer = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_CALURI:
- g_free(card->caluri);
- card->caluri = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_FBURL:
- g_free(card->fburl);
- card->fburl = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_NOTE:
- g_free (card->note);
- card->note = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_RELATED_CONTACTS:
- g_free (card->related_contacts);
- card->related_contacts = g_strdup(GTK_VALUE_STRING(*arg));
- break;
- case ARG_WANTS_HTML:
- card->wants_html = GTK_VALUE_BOOL(*arg);
- card->wants_html_set = TRUE;
- break;
- case ARG_ARBITRARY:
- if (card->arbitrary)
- gtk_object_unref(GTK_OBJECT(card->arbitrary));
- card->arbitrary = E_LIST(GTK_VALUE_OBJECT(*arg));
- if (card->arbitrary)
- gtk_object_ref(GTK_OBJECT(card->arbitrary));
- break;
- case ARG_ID:
- g_free(card->id);
- card->id = g_strdup(GTK_VALUE_STRING(*arg));
- if (card->id == NULL)
- card->id = g_strdup ("");
- break;
- case ARG_LAST_USE:
- g_free(card->last_use);
- if (GTK_VALUE_POINTER (*arg)) {
- card->last_use = g_new (ECardDate, 1);
- memcpy (card->last_use, GTK_VALUE_POINTER (*arg), sizeof (ECardDate));
- } else {
- card->last_use = NULL;
- }
- break;
- case ARG_USE_SCORE:
- card->raw_use_score = GTK_VALUE_FLOAT(*arg);
- break;
- case ARG_EVOLUTION_LIST:
- card->list = GTK_VALUE_BOOL(*arg);
- break;
- case ARG_EVOLUTION_LIST_SHOW_ADDRESSES:
- card->list_show_addresses = GTK_VALUE_BOOL(*arg);
- break;
- default:
- return;
- }
-}
-
-/* Get_arg handler for the card */
-static void
-e_card_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- ECard *card;
-
- card = E_CARD (object);
-
- switch (arg_id) {
- case ARG_FILE_AS:
- GTK_VALUE_STRING (*arg) = card->file_as;
- break;
- case ARG_FULL_NAME:
- GTK_VALUE_STRING (*arg) = card->fname;
- break;
- case ARG_NAME:
- GTK_VALUE_POINTER(*arg) = card->name;
- break;
- case ARG_ADDRESS:
- if (!card->address)
- card->address = e_list_new((EListCopyFunc) e_card_delivery_address_ref,
- (EListFreeFunc) e_card_delivery_address_unref,
- NULL);
- GTK_VALUE_OBJECT(*arg) = GTK_OBJECT(card->address);
- break;
- case ARG_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);
- GTK_VALUE_OBJECT(*arg) = GTK_OBJECT(card->address_label);
- break;
- case ARG_PHONE:
- if (!card->phone)
- card->phone = e_list_new((EListCopyFunc) e_card_phone_ref,
- (EListFreeFunc) e_card_phone_unref,
- NULL);
- GTK_VALUE_OBJECT(*arg) = GTK_OBJECT(card->phone);
- break;
- case ARG_EMAIL:
- if (!card->email)
- card->email = e_list_new((EListCopyFunc) g_strdup,
- (EListFreeFunc) g_free,
- NULL);
- GTK_VALUE_OBJECT(*arg) = GTK_OBJECT(card->email);
- break;
- case ARG_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;
- GTK_VALUE_STRING(*arg) = g_strjoinv(", ", strs);
- g_free(strs);
- }
- break;
- case ARG_CATEGORY_LIST:
- if (!card->categories)
- card->categories = e_list_new((EListCopyFunc) g_strdup,
- (EListFreeFunc) g_free,
- NULL);
- GTK_VALUE_OBJECT(*arg) = GTK_OBJECT(card->categories);
- break;
- case ARG_BIRTH_DATE:
- GTK_VALUE_POINTER(*arg) = card->bday;
- break;
- case ARG_URL:
- GTK_VALUE_STRING(*arg) = card->url;
- break;
- case ARG_ORG:
- GTK_VALUE_STRING(*arg) = card->org;
- break;
- case ARG_ORG_UNIT:
- GTK_VALUE_STRING(*arg) = card->org_unit;
- break;
- case ARG_OFFICE:
- GTK_VALUE_STRING(*arg) = card->office;
- break;
- case ARG_TITLE:
- GTK_VALUE_STRING(*arg) = card->title;
- break;
- case ARG_ROLE:
- GTK_VALUE_STRING(*arg) = card->role;
- break;
- case ARG_MANAGER:
- GTK_VALUE_STRING(*arg) = card->manager;
- break;
- case ARG_ASSISTANT:
- GTK_VALUE_STRING(*arg) = card->assistant;
- break;
- case ARG_NICKNAME:
- GTK_VALUE_STRING(*arg) = card->nickname;
- break;
- case ARG_SPOUSE:
- GTK_VALUE_STRING(*arg) = card->spouse;
- break;
- case ARG_ANNIVERSARY:
- GTK_VALUE_POINTER(*arg) = card->anniversary;
- break;
- case ARG_MAILER:
- GTK_VALUE_STRING(*arg) = card->mailer;
- break;
- case ARG_CALURI:
- GTK_VALUE_STRING(*arg) = card->caluri;
- break;
- case ARG_FBURL:
- GTK_VALUE_STRING(*arg) = card->fburl;
- break;
- case ARG_NOTE:
- GTK_VALUE_STRING(*arg) = card->note;
- break;
- case ARG_RELATED_CONTACTS:
- GTK_VALUE_STRING(*arg) = card->related_contacts;
- break;
- case ARG_WANTS_HTML:
- GTK_VALUE_BOOL(*arg) = card->wants_html;
- break;
- case ARG_WANTS_HTML_SET:
- GTK_VALUE_BOOL(*arg) = card->wants_html_set;
- break;
- case ARG_ARBITRARY:
- if (!card->arbitrary)
- card->arbitrary = e_list_new((EListCopyFunc) e_card_arbitrary_ref,
- (EListFreeFunc) e_card_arbitrary_unref,
- NULL);
-
- GTK_VALUE_OBJECT(*arg) = GTK_OBJECT(card->arbitrary);
- break;
- case ARG_ID:
- GTK_VALUE_STRING(*arg) = card->id;
- break;
- case ARG_LAST_USE:
- GTK_VALUE_POINTER(*arg) = card->last_use;
- break;
-
- case ARG_USE_SCORE:
- GTK_VALUE_FLOAT(*arg) = e_card_get_use_score (card);
- break;
- case ARG_EVOLUTION_LIST:
- GTK_VALUE_BOOL(*arg) = card->list;
- break;
- case ARG_EVOLUTION_LIST_SHOW_ADDRESSES:
- GTK_VALUE_BOOL(*arg) = card->list_show_addresses;
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- 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->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, char *default_charset)
-{
- VObject *vobj = Parse_MIME_FromFileName((char *) filename);
- GList *list = NULL;
- while(vobj) {
- VObject *next;
- ECard *card = E_CARD(gtk_type_new(e_card_get_type()));
- 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, char *default_charset)
-{
- VObject *vobj = Parse_MIME(str, strlen (str));
- GList *list = NULL;
- while(vobj) {
- VObject *next;
- ECard *card = E_CARD(gtk_type_new(e_card_get_type()));
- 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) {
- gtk_object_unref (GTK_OBJECT (card->address));
- card->address = NULL;
- }
-
- if (card->address_label && e_list_length (card->address_label) == 0) {
- gtk_object_unref (GTK_OBJECT (card->address_label));
- card->address_label = NULL;
- }
-
- if (card->phone && e_list_length (card->phone) == 0) {
- gtk_object_unref (GTK_OBJECT (card->phone));
- card->phone = NULL;
- }
-
- if (card->email && e_list_length (card->email) == 0) {
- gtk_object_unref (GTK_OBJECT (card->email));
- card->email = NULL;
- }
-
- if (card->categories && e_list_length (card->categories) == 0) {
- gtk_object_unref (GTK_OBJECT (card->categories));
- card->categories = NULL;
- }
-
- if (card->arbitrary && e_list_length (card->arbitrary) == 0) {
- gtk_object_unref (GTK_OBJECT (card->arbitrary));
- card->arbitrary = NULL;
- }
-}
-
-static void
-assign_string(VObject *vobj, char *default_charset, char **string)
-{
- int type = vObjectValueType(vobj);
- char *str;
- char *charset = default_charset;
- gboolean free_charset = FALSE;
- VObject *charset_obj;
-
- if ((charset_obj = isAPropertyOf (vobj, "CHARSET"))) {
- switch (vObjectValueType (charset_obj)) {
- case VCVT_STRINGZ:
- charset = (char *) vObjectStringZValue(charset_obj);
- break;
- case VCVT_USTRINGZ:
- charset = fakeCString (vObjectUStringZValue (charset_obj));
- free_charset = TRUE;
- 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 (free_charset) {
- free (charset);
- }
-}
-
-
-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, char *default_charset)
-{
- char *ret_val;
- VObjectIterator iterator;
- gboolean free_charset = FALSE;
- VObject *charset_obj;
-
- if ((charset_obj = isAPropertyOf (vobj, "CHARSET"))) {
- switch (vObjectValueType (charset_obj)) {
- case VCVT_STRINGZ:
- default_charset = (char *) vObjectStringZValue(charset_obj);
- break;
- case VCVT_USTRINGZ:
- default_charset = fakeCString (vObjectUStringZValue (charset_obj));
- free_charset = TRUE;
- 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 (free_charset)
- free (default_charset);
-
- 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);
- }
- }
-}
-
-#include <Evolution-Composer.h>
-
-#define COMPOSER_OAFID "OAFIID:GNOME_Evolution_Mail_Composer"
-
-void
-e_card_list_send (GList *cards, ECardDisposition disposition)
-{
- BonoboObjectClient *bonobo_server;
- GNOME_Evolution_Composer composer_server;
- CORBA_Environment ev;
-
- if (cards == NULL)
- return;
-
- /* First, I obtain an object reference that represents the Composer. */
- bonobo_server = bonobo_object_activate (COMPOSER_OAFID, 0);
-
- g_return_if_fail (bonobo_server != NULL);
-
- composer_server = bonobo_object_corba_objref (BONOBO_OBJECT (bonobo_server));
-
- CORBA_exception_init (&ev);
-
- if (disposition == E_CARD_DISPOSITION_AS_TO) {
- GNOME_Evolution_Composer_RecipientList *to_list, *cc_list, *bcc_list;
- CORBA_char *subject;
- int to_i, bcc_i;
- GList *iter;
- 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)) {
- gint len = card->email ? e_list_length (card->email) : 0;
- if (e_card_evolution_list_show_addresses (card))
- to_length += len;
- else
- bcc_length += len;
- } else {
- if (card->email != NULL)
- ++to_length;
- }
- }
-
- /* Now I have to make a CORBA sequences that represents a recipient list with
- the right number of entries, for the cards. */
- to_list = GNOME_Evolution_Composer_RecipientList__alloc ();
- to_list->_maximum = to_length;
- to_list->_length = to_length;
- if (to_length > 0) {
- to_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (to_length);
- }
-
- cc_list = GNOME_Evolution_Composer_RecipientList__alloc ();
- cc_list->_maximum = cc_list->_length = 0;
-
- bcc_list = GNOME_Evolution_Composer_RecipientList__alloc ();
- bcc_list->_maximum = bcc_length;
- bcc_list->_length = bcc_length;
- if (bcc_length > 0) {
- bcc_list->_buffer = CORBA_sequence_GNOME_Evolution_Composer_Recipient_allocbuf (bcc_length);
- }
-
- to_i = 0;
- bcc_i = 0;
- while (cards != NULL) {
- ECard *card = cards->data;
- EIterator *iterator;
- gchar *name, *addr;
- gboolean is_list, is_hidden, free_name_addr;
- GNOME_Evolution_Composer_Recipient *recipient;
-
- if (card->email != NULL) {
-
- is_list = e_card_evolution_list (card);
- is_hidden = is_list && !e_card_evolution_list_show_addresses (card);
-
- for (iterator = e_list_get_iterator (card->email); e_iterator_is_valid (iterator); e_iterator_next (iterator)) {
-
- if (is_hidden) {
- recipient = &(bcc_list->_buffer[bcc_i]);
- ++bcc_i;
- } else {
- recipient = &(to_list->_buffer[to_i]);
- ++to_i;
- }
-
- name = "";
- addr = "";
- free_name_addr = FALSE;
- 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));
- if (dest != NULL) {
- name = g_strdup (e_destination_get_name (dest));
- addr = g_strdup (e_destination_get_email (dest));
- free_name_addr = TRUE;
- gtk_object_unref (GTK_OBJECT (dest));
- }
-
- } else { /* is just a plain old card */
- if (card->name)
- name = e_card_name_to_string (card->name);
- addr = g_strdup ((char *) e_iterator_get (iterator));
- free_name_addr = TRUE;
- }
- }
-
- recipient->name = CORBA_string_dup (name ? name : "");
- recipient->address = CORBA_string_dup (addr ? addr : "");
-
- if (free_name_addr) {
- g_free ((gchar *) name);
- g_free ((gchar *) addr);
- }
-
- /* If this isn't a list, we quit after the first (i.e. the default) address. */
- if (!is_list)
- break;
-
- }
- gtk_object_unref (GTK_OBJECT (iterator));
- }
-
- cards = g_list_next (cards);
- }
-
- subject = CORBA_string_dup ("");
-
- GNOME_Evolution_Composer_setHeaders (composer_server, "", to_list, cc_list, bcc_list, subject, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_printerr ("gui/e-meeting-edit.c: I couldn't set the composer headers via CORBA! Aagh.\n");
- CORBA_exception_free (&ev);
- return;
- }
-
- CORBA_free (to_list);
- CORBA_free (cc_list);
- CORBA_free (bcc_list);
- CORBA_free (subject);
- }
-
- if (disposition == E_CARD_DISPOSITION_AS_ATTACHMENT) {
- CORBA_char *content_type, *filename, *description;
- GNOME_Evolution_Composer_AttachmentData *attach_data;
- CORBA_boolean show_inline;
- char *tempstr;
-
- GNOME_Evolution_Composer_RecipientList *to_list, *cc_list, *bcc_list;
- CORBA_char *subject;
-
- content_type = CORBA_string_dup ("text/x-vcard");
- filename = CORBA_string_dup ("");
-
- if (cards->next) {
- description = CORBA_string_dup (_("Multiple VCards"));
- } else {
- char *file_as;
-
- gtk_object_get(GTK_OBJECT(cards->data),
- "file_as", &file_as,
- NULL);
-
- tempstr = g_strdup_printf (_("VCard for %s"), file_as);
- description = CORBA_string_dup (tempstr);
- g_free (tempstr);
- }
-
- show_inline = FALSE;
-
- tempstr = e_card_list_get_vcard (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);
- strcpy (attach_data->_buffer, tempstr);
- g_free (tempstr);
-
- GNOME_Evolution_Composer_attachData (composer_server,
- content_type, filename, description,
- show_inline, attach_data,
- &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_printerr ("gui/e-meeting-edit.c: I couldn't attach data to the composer via CORBA! Aagh.\n");
- CORBA_exception_free (&ev);
- return;
- }
-
- CORBA_free (content_type);
- CORBA_free (filename);
- CORBA_free (description);
- CORBA_free (attach_data);
-
- to_list = GNOME_Evolution_Composer_RecipientList__alloc ();
- to_list->_maximum = to_list->_length = 0;
-
- cc_list = GNOME_Evolution_Composer_RecipientList__alloc ();
- cc_list->_maximum = cc_list->_length = 0;
-
- bcc_list = GNOME_Evolution_Composer_RecipientList__alloc ();
- bcc_list->_maximum = bcc_list->_length = 0;
-
- if (!cards || cards->next) {
- subject = CORBA_string_dup ("Contact information");
- } else {
- ECard *card = cards->data;
- const gchar *tempstr2;
-
- tempstr2 = NULL;
- gtk_object_get(GTK_OBJECT(card),
- "file_as", &tempstr2,
- NULL);
- if (!tempstr2 || !*tempstr2)
- gtk_object_get(GTK_OBJECT(card),
- "full_name", &tempstr2,
- NULL);
- if (!tempstr2 || !*tempstr2)
- gtk_object_get(GTK_OBJECT(card),
- "org", &tempstr2,
- NULL);
- if (!tempstr2 || !*tempstr2) {
- EList *list;
- EIterator *iterator;
- gtk_object_get(GTK_OBJECT(card),
- "email", &list,
- NULL);
- iterator = e_list_get_iterator (list);
- if (e_iterator_is_valid (iterator)) {
- tempstr2 = e_iterator_get (iterator);
- }
- gtk_object_unref (GTK_OBJECT (iterator));
- }
-
- if (!tempstr2 || !*tempstr2)
- tempstr = g_strdup_printf ("Contact information");
- else
- tempstr = g_strdup_printf ("Contact information for %s", tempstr2);
- subject = CORBA_string_dup (tempstr);
- g_free (tempstr);
- }
-
- GNOME_Evolution_Composer_setHeaders (composer_server, "", to_list, cc_list, bcc_list, subject, &ev);
-
- CORBA_free (to_list);
- CORBA_free (cc_list);
- CORBA_free (bcc_list);
- CORBA_free (subject);
- }
-
- GNOME_Evolution_Composer_show (composer_server, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_printerr ("gui/e-meeting-edit.c: I couldn't show the composer via CORBA! Aagh.\n");
- CORBA_exception_free (&ev);
- return;
- }
-
- CORBA_exception_free (&ev);
-}
-
-void
-e_card_send (ECard *card, ECardDisposition disposition)
-{
- GList *list;
- list = g_list_prepend (NULL, card);
- e_card_list_send (list, disposition);
- g_list_free (list);
-}
-
-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 e9b3701149..0000000000
--- a/addressbook/backend/ebook/e-card.h
+++ /dev/null
@@ -1,218 +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 <gtk/gtkobject.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) (GTK_CHECK_CAST ((obj), E_TYPE_CARD, ECard))
-#define E_CARD_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_CARD, ECardClass))
-#define E_IS_CARD(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_CARD))
-#define E_IS_CARD_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_CARD))
-
-typedef struct _ECard ECard;
-typedef struct _ECardClass ECardClass;
-
-struct _EBook; /* Forward reference */
-
-struct _ECard {
- GtkObject 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 */
-
- 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 {
- GtkObjectClass parent_class;
- GHashTable *attribute_jump_table;
-};
-
-
-/* Simple functions */
-ECard *e_card_new (char *vcard); /* Assumes utf8 */
-ECard *e_card_new_with_default_charset (char *vcard,
- 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,
- 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,
- char *default_charset);
-void e_card_free_empty_lists (ECard *card);
-
-enum _ECardDisposition {
- E_CARD_DISPOSITION_AS_ATTACHMENT,
- E_CARD_DISPOSITION_AS_TO,
-};
-typedef enum _ECardDisposition ECardDisposition;
-void e_card_send (ECard *card,
- ECardDisposition disposition);
-void e_card_list_send (GList *cards,
- ECardDisposition disposition);
-
-/* 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);
-
-
-/* Standard Gtk function */
-GtkType e_card_get_type (void);
-
-#endif /* ! __E_CARD_H__ */
diff --git a/addressbook/backend/ebook/e-destination.c b/addressbook/backend/ebook/e-destination.c
deleted file mode 100644
index 25932c29e6..0000000000
--- a/addressbook/backend/ebook/e-destination.c
+++ /dev/null
@@ -1,1693 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-destination.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-destination.h"
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <gtk/gtkobject.h>
-#include <gtk/gtkmain.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include "e-book.h"
-#include "e-book-util.h"
-#include <gal/widgets/e-unicode.h>
-#include <gnome-xml/parser.h>
-#include <gnome-xml/xmlmemory.h>
-#include <camel/camel-internet-address.h>
-
-#define d(x) x
-
-enum {
- CHANGED,
- CARDIFIED,
- LAST_SIGNAL
-};
-
-guint e_destination_signals[LAST_SIGNAL] = { 0 };
-
-struct _EDestinationPrivate {
- gchar *raw;
-
- gchar *book_uri;
- gchar *card_uid;
- ECard *card;
- gint card_email_num;
-
- ECard *old_card;
- gint old_card_email_num;
- gchar *old_textrep;
-
- 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 has_been_cardified : 1;
- guint allow_cardify : 1;
- guint cannot_cardify : 1;
- guint auto_recipient : 1;
- guint pending_cardification;
-
- guint pending_change : 1;
-
- EBook *cardify_book;
-
- gint freeze_count;
-};
-
-static void e_destination_clear_card (EDestination *);
-static void e_destination_clear_strings (EDestination *);
-
-static GtkObjectClass *parent_class;
-
-static void
-e_destination_destroy (GtkObject *obj)
-{
- EDestination *dest = E_DESTINATION (obj);
-
- e_destination_clear (dest);
-
- if (dest->priv->old_card)
- gtk_object_unref (GTK_OBJECT (dest->priv->old_card));
-
- if (dest->priv->cardify_book)
- gtk_object_unref (GTK_OBJECT (dest->priv->cardify_book));
-
- g_free (dest->priv->old_textrep);
-
- g_free (dest->priv);
-
- if (parent_class->destroy)
- parent_class->destroy (obj);
-}
-
-static void
-e_destination_class_init (EDestinationClass *klass)
-{
- GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
-
- parent_class = GTK_OBJECT_CLASS (gtk_type_class (GTK_TYPE_OBJECT));
-
- object_class->destroy = e_destination_destroy;
-
- e_destination_signals[CHANGED] =
- gtk_signal_new ("changed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EDestinationClass, changed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- e_destination_signals[CARDIFIED] =
- gtk_signal_new ("cardified",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EDestinationClass, cardified),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, e_destination_signals, LAST_SIGNAL);
-}
-
-static void
-e_destination_init (EDestination *dest)
-{
- dest->priv = g_new0 (struct _EDestinationPrivate, 1);
-
- dest->priv->allow_cardify = TRUE;
- dest->priv->cannot_cardify = FALSE;
- dest->priv->auto_recipient = FALSE;
- dest->priv->pending_cardification = 0;
-}
-
-GtkType
-e_destination_get_type (void)
-{
- static GtkType dest_type = 0;
-
- if (!dest_type) {
- GtkTypeInfo dest_info = {
- "EDestination",
- sizeof (EDestination),
- sizeof (EDestinationClass),
- (GtkClassInitFunc) e_destination_class_init,
- (GtkObjectInitFunc) e_destination_init,
- NULL, NULL, /* reserved */
- (GtkClassInitFunc) NULL
- };
-
- dest_type = gtk_type_unique (gtk_object_get_type (), &dest_info);
- }
-
- return dest_type;
-}
-
-EDestination *
-e_destination_new (void)
-{
- return E_DESTINATION (gtk_type_new (E_TYPE_DESTINATION));
-}
-
-static void
-e_destination_freeze (EDestination *dest)
-{
- g_return_if_fail (E_IS_DESTINATION (dest));
- g_return_if_fail (dest->priv->freeze_count >= 0);
-
- dest->priv->freeze_count++;
-}
-
-static void
-e_destination_thaw (EDestination *dest)
-{
- g_return_if_fail (E_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)
- e_destination_changed (dest);
-}
-
-void
-e_destination_changed (EDestination *dest)
-{
- if (dest->priv->freeze_count == 0) {
- gtk_signal_emit (GTK_OBJECT (dest), e_destination_signals[CHANGED]);
- dest->priv->pending_change = FALSE;
- dest->priv->cannot_cardify = FALSE;
-
- } else {
- dest->priv->pending_change = TRUE;
- }
-}
-
-EDestination *
-e_destination_copy (const EDestination *dest)
-{
- EDestination *new_dest;
- GList *iter;
-
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
-
- new_dest = e_destination_new ();
-
- new_dest->priv->book_uri = g_strdup (dest->priv->book_uri);
- new_dest->priv->card_uid = g_strdup (dest->priv->card_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->card_email_num = dest->priv->card_email_num;
- new_dest->priv->old_card_email_num = dest->priv->old_card_email_num;
- new_dest->priv->old_textrep = g_strdup (dest->priv->old_textrep);
-
- new_dest->priv->card = dest->priv->card;
- if (new_dest->priv->card)
- gtk_object_ref (GTK_OBJECT (new_dest->priv->card));
-
- new_dest->priv->old_card = dest->priv->old_card;
- if (new_dest->priv->old_card)
- gtk_object_ref (GTK_OBJECT (new_dest->priv->old_card));
-
- 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,
- e_destination_copy (E_DESTINATION (iter->data)));
- }
-
- return new_dest;
-}
-
-static void
-e_destination_clear_card (EDestination *dest)
-{
- if (dest->priv->card) {
- if (dest->priv->old_card)
- gtk_object_unref (GTK_OBJECT (dest->priv->old_card));
-
- dest->priv->old_card = dest->priv->card;
- dest->priv->old_card_email_num = dest->priv->card_email_num;
-
- g_free (dest->priv->old_textrep);
- dest->priv->old_textrep = g_strdup (e_destination_get_textrep (dest));
- }
-
- g_free (dest->priv->book_uri);
- dest->priv->book_uri = NULL;
- g_free (dest->priv->card_uid);
- dest->priv->card_uid = NULL;
-
- dest->priv->card = NULL;
- dest->priv->card_email_num = -1;
-
- g_list_foreach (dest->priv->list_dests, (GFunc) gtk_object_unref, NULL);
- g_list_free (dest->priv->list_dests);
- dest->priv->list_dests = NULL;
-
- dest->priv->allow_cardify = TRUE;
- dest->priv->cannot_cardify = FALSE;
-
- e_destination_cancel_cardify (dest);
-
- e_destination_changed (dest);
-}
-
-static void
-e_destination_clear_strings (EDestination *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;
-
- e_destination_changed (dest);
-}
-
-void
-e_destination_clear (EDestination *dest)
-{
- g_return_if_fail (dest && E_IS_DESTINATION (dest));
-
- e_destination_freeze (dest);
-
- e_destination_clear_card (dest);
- e_destination_clear_strings (dest);
-
- e_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
-e_destination_is_empty (const EDestination *dest)
-
-{
- struct _EDestinationPrivate *p;
-
- g_return_val_if_fail (E_IS_DESTINATION (dest), TRUE);
-
- p = dest->priv;
-
- return !(p->card != NULL
- || (p->book_uri && *p->book_uri)
- || (p->card_uid && *p->card_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
-e_destination_is_valid (const EDestination *dest)
-{
- const char *email;
-
- g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE);
-
- if (e_destination_from_card (dest))
- return TRUE;
-
- email = e_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
-e_destination_equal (const EDestination *a, const EDestination *b)
-{
- const struct _EDestinationPrivate *pa, *pb;
- const char *na, *nb;
-
- g_return_val_if_fail (E_IS_DESTINATION (a), FALSE);
- g_return_val_if_fail (E_IS_DESTINATION (b), FALSE);
-
- if (a == b)
- return TRUE;
-
- pa = a->priv;
- pb = b->priv;
-
- /* Check equality of cards. */
- if (pa->card || pb->card) {
- if (! (pa->card && pb->card))
- return FALSE;
-
- if (pa->card == pb->card || !strcmp (e_card_get_id (pa->card), e_card_get_id (pb->card)))
- return TRUE;
-
- return FALSE;
- }
-
- /* Just in case name returns NULL */
- na = e_destination_get_name (a);
- nb = e_destination_get_name (b);
- if ((na || nb) && !(na && nb && ! g_utf8_strcasecmp (na, nb)))
- return FALSE;
-
- if (!g_strcasecmp (e_destination_get_email (a), e_destination_get_email (b)))
- return TRUE;
-
- return FALSE;
-}
-
-void
-e_destination_set_card (EDestination *dest, ECard *card, gint email_num)
-{
- g_return_if_fail (dest && E_IS_DESTINATION (dest));
- g_return_if_fail (card && E_IS_CARD (card));
-
- if (dest->priv->card != card || dest->priv->card_email_num != email_num) {
- /* We have to freeze/thaw around these operations so that the 'changed'
- signals don't cause the EDestination's internal state to be altered
- before we can finish setting ->card && ->card_email_num. */
- e_destination_freeze (dest);
- e_destination_clear (dest);
-
- dest->priv->card = card;
- gtk_object_ref (GTK_OBJECT (dest->priv->card));
-
- dest->priv->card_email_num = email_num;
-
- e_destination_changed (dest);
- e_destination_thaw (dest);
- }
-}
-
-void
-e_destination_set_book_uri (EDestination *dest, const gchar *uri)
-{
- g_return_if_fail (dest && E_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);
-
- /* If we already have a card, remove it unless it's uri matches the one
- we just set. */
- if (dest->priv->card) {
- EBook *book = e_card_get_book (dest->priv->card);
- if ((!book) || strcmp (uri, e_book_get_uri (book))) {
- gtk_object_unref (GTK_OBJECT (dest->priv->card));
- dest->priv->card = NULL;
- }
- }
-
- e_destination_changed (dest);
- }
-}
-
-void
-e_destination_set_card_uid (EDestination *dest, const gchar *uid, gint email_num)
-{
- g_return_if_fail (dest && E_IS_DESTINATION (dest));
- g_return_if_fail (uid != NULL);
-
- if (dest->priv->card_uid == NULL
- || strcmp (dest->priv->card_uid, uid)
- || dest->priv->card_email_num != email_num) {
-
- g_free (dest->priv->card_uid);
- dest->priv->card_uid = g_strdup (uid);
- dest->priv->card_email_num = email_num;
-
- /* If we already have a card, remove it unless it's uri matches the one
- we just set. */
- if (dest->priv->card && strcmp (uid, e_card_get_id (dest->priv->card))) {
- gtk_object_unref (GTK_OBJECT (dest->priv->card));
- dest->priv->card = NULL;
- }
-
- e_destination_changed (dest);
- }
-}
-
-void
-e_destination_set_name (EDestination *dest, const gchar *name)
-{
- gboolean changed = FALSE;
-
- g_return_if_fail (E_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;
- e_destination_changed (dest);
- }
-}
-
-void
-e_destination_set_email (EDestination *dest, const gchar *email)
-{
- gboolean changed = FALSE;
-
- g_return_if_fail (E_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;
- e_destination_changed (dest);
- }
-}
-
-void
-e_destination_set_html_mail_pref (EDestination *dest, gboolean x)
-{
- g_return_if_fail (dest && E_IS_DESTINATION (dest));
-
- dest->priv->html_mail_override = TRUE;
- if (dest->priv->wants_html_mail != x) {
- dest->priv->wants_html_mail = x;
- e_destination_changed (dest);
- }
-}
-
-gboolean
-e_destination_contains_card (const EDestination *dest)
-{
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), FALSE);
- return dest->priv->card != NULL;
-}
-
-gboolean
-e_destination_from_card (const EDestination *dest)
-{
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), FALSE);
- return dest->priv->card != NULL || dest->priv->book_uri != NULL || dest->priv->card_uid != NULL;
-}
-
-gboolean
-e_destination_is_auto_recipient (const EDestination *dest)
-{
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), FALSE);
-
- return dest->priv->auto_recipient;
-}
-
-void
-e_destination_set_auto_recipient (EDestination *dest, gboolean value)
-{
- g_return_if_fail (dest && E_IS_DESTINATION (dest));
-
- dest->priv->auto_recipient = value;
-}
-
-typedef struct _UseCard UseCard;
-struct _UseCard {
- EDestination *dest;
- EDestinationCardCallback cb;
- gpointer closure;
-};
-
-static void
-use_card_cb (ECard *card, gpointer closure)
-{
- UseCard *uc = (UseCard *) closure;
-
- if (card != NULL && uc->dest->priv->card == NULL) {
- uc->dest->priv->card = card;
- gtk_object_ref (GTK_OBJECT (uc->dest->priv->card));
- e_destination_changed (uc->dest);
- }
-
- if (uc->cb) {
- uc->cb (uc->dest, uc->dest->priv->card, uc->closure);
- }
-
- /* We held a copy of the destination during the callback. */
- gtk_object_unref (GTK_OBJECT (uc->dest));
- g_free (uc);
-}
-
-void
-e_destination_use_card (EDestination *dest, EDestinationCardCallback cb, gpointer closure)
-{
- g_return_if_fail (dest && E_IS_DESTINATION (dest));
-
- if (dest->priv->card != NULL) {
- if (cb)
- cb (dest, dest->priv->card, closure);
- } else if (dest->priv->book_uri != NULL && dest->priv->card_uid != NULL) {
- UseCard *uc = g_new (UseCard, 1);
-
- uc->dest = dest;
- /* Hold a reference to the destination during the callback. */
- gtk_object_ref (GTK_OBJECT (uc->dest));
- uc->cb = cb;
- uc->closure = closure;
- e_card_load_uri (dest->priv->book_uri, dest->priv->card_uid, use_card_cb, uc);
- } else {
- if (cb)
- cb (dest, NULL, closure);
- }
-}
-
-ECard *
-e_destination_get_card (const EDestination *dest)
-{
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
-
- return dest->priv->card;
-}
-
-const gchar *
-e_destination_get_card_uid (const EDestination *dest)
-{
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
-
- if (dest->priv->card_uid)
- return dest->priv->card_uid;
-
- if (dest->priv->card)
- return e_card_get_id (dest->priv->card);
-
- return NULL;
-}
-
-const gchar *
-e_destination_get_book_uri (const EDestination *dest)
-{
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
-
- if (dest->priv->book_uri)
- return dest->priv->book_uri;
-
- if (dest->priv->card) {
- EBook *book = e_card_get_book (dest->priv->card);
-
- if (book) {
- return e_book_get_uri (book);
- }
- }
-
- return NULL;
-}
-
-gint
-e_destination_get_email_num (const EDestination *dest)
-{
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), -1);
-
- if (dest->priv->card == NULL && (dest->priv->book_uri == NULL || dest->priv->card_uid == NULL))
- return -1;
-
- return dest->priv->card_email_num;
-}
-
-const gchar *
-e_destination_get_name (const EDestination *dest)
-{
- struct _EDestinationPrivate *priv;
-
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
-
- priv = (struct _EDestinationPrivate *)dest->priv; /* cast out const */
-
- if (priv->name == NULL) {
- if (priv->card != NULL) {
- priv->name = e_card_name_to_string (priv->card->name);
-
- if (priv->name == NULL || *priv->name == '\0') {
- g_free (priv->name);
- priv->name = g_strdup (priv->card->file_as);
- }
-
- if (priv->name == NULL || *priv->name == '\0') {
- g_free (priv->name);
- if (e_card_evolution_list (priv->card))
- priv->name = g_strdup (_("Unnamed List"));
- else
- priv->name = g_strdup (e_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 *
-e_destination_get_email (const EDestination *dest)
-{
- struct _EDestinationPrivate *priv;
-
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
-
- priv = (struct _EDestinationPrivate *)dest->priv; /* cast out const */
-
- if (priv->email == NULL) {
- if (priv->card != NULL) {
- /* Pull the address out of the card. */
- if (priv->card->email) {
- EIterator *iter = e_list_get_iterator (priv->card->email);
- int n = priv->card_email_num;
-
- if (n >= 0) {
- while (n > 0) {
- e_iterator_next (iter);
- n--;
- }
-
- if (e_iterator_is_valid (iter)) {
- gconstpointer ptr = e_iterator_get (iter);
- priv->email = g_strdup ((char *) ptr);
- }
- }
- }
- } 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 *
-e_destination_get_address (const EDestination *dest)
-{
- struct _EDestinationPrivate *priv;
-
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
-
- priv = (struct _EDestinationPrivate *)dest->priv; /* cast out const */
-
- if (priv->addr == NULL) {
- CamelInternetAddress *addr = camel_internet_address_new ();
-
- if (e_destination_is_evolution_list (dest)) {
- GList *iter = dest->priv->list_dests;
-
- while (iter) {
- EDestination *list_dest = E_DESTINATION (iter->data);
-
- if (!e_destination_is_empty (list_dest)) {
- camel_internet_address_add (addr,
- e_destination_get_name (list_dest),
- e_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,
- e_destination_get_name (dest),
- e_destination_get_email (dest));
-
- priv->addr = camel_address_encode (CAMEL_ADDRESS (addr));
- }
-
- camel_object_unref (CAMEL_OBJECT (addr));
- }
-
- return priv->addr;
-}
-
-void
-e_destination_set_raw (EDestination *dest, const gchar *raw)
-{
- g_return_if_fail (E_IS_DESTINATION (dest));
- g_return_if_fail (raw != NULL);
-
- if (dest->priv->raw == NULL || strcmp (dest->priv->raw, raw)) {
- e_destination_freeze (dest);
-
- e_destination_clear (dest);
- dest->priv->raw = g_strdup (raw);
- e_destination_changed (dest);
-
- e_destination_thaw (dest);
- }
-}
-
-const gchar *
-e_destination_get_textrep (const EDestination *dest)
-{
- const char *name, *email;
-
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
-
- if (dest->priv->raw)
- return dest->priv->raw;
-
- name = e_destination_get_name (dest);
- email = e_destination_get_email (dest);
-
- if (e_destination_from_card (dest) && name != NULL)
- 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
-e_destination_is_evolution_list (const EDestination *dest)
-{
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), FALSE);
-
- if (dest->priv->list_dests == NULL
- && dest->priv->card != NULL
- && dest->priv->card->email != NULL
- && e_card_evolution_list (dest->priv->card)) {
-
- EIterator *iter = e_list_get_iterator (dest->priv->card->email);
-
- e_iterator_reset (iter);
- while (e_iterator_is_valid (iter)) {
- const char *dest_xml = (const char *) e_iterator_get (iter);
- EDestination *list_dest = e_destination_import (dest_xml);
-
- if (list_dest)
- dest->priv->list_dests = g_list_append (dest->priv->list_dests, list_dest);
- e_iterator_next (iter);
- }
- }
-
- return dest->priv->list_dests != NULL;
-}
-
-gboolean
-e_destination_list_show_addresses (const EDestination *dest)
-{
- g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE);
-
- if (dest->priv->card != NULL)
- return e_card_evolution_list_show_addresses (dest->priv->card);
-
- return dest->priv->show_addresses;
-}
-
-gboolean
-e_destination_get_html_mail_pref (const EDestination *dest)
-{
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), FALSE);
-
- if (dest->priv->html_mail_override || dest->priv->card == NULL)
- return dest->priv->wants_html_mail;
-
- return dest->priv->card->wants_html;
-}
-
-gboolean
-e_destination_allow_cardification (const EDestination *dest)
-{
- g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE);
-
- return dest->priv->allow_cardify;
-}
-
-void
-e_destination_set_allow_cardification (EDestination *dest, gboolean x)
-{
- g_return_if_fail (E_IS_DESTINATION (dest));
-
- dest->priv->allow_cardify = x;
-}
-
-static void
-set_cardify_book (EDestination *dest, EBook *book)
-{
- if (dest->priv->cardify_book && dest->priv->cardify_book != book) {
- gtk_object_unref (GTK_OBJECT (dest->priv->cardify_book));
- }
-
- dest->priv->cardify_book = book;
-
- if (book)
- gtk_object_ref (GTK_OBJECT (book));
-}
-
-static void
-name_and_email_simple_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
-{
- EDestination *dest = E_DESTINATION (closure);
-
- if (status == E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS && g_list_length ((GList *) cards) == 1) {
- ECard *card = E_CARD (cards->data);
- const char *email = e_destination_get_email (dest);
- int email_num = 0;
-
- if (e_destination_is_valid (dest) && email && *email) {
- email_num = e_card_email_find_number (card, e_destination_get_email (dest));
- }
-
- if (email_num >= 0) {
- const char *book_uri;
-
- book_uri = e_book_get_uri (book);
-
- dest->priv->has_been_cardified = TRUE;
- e_destination_set_card (dest, card, email_num);
- e_destination_set_book_uri (dest, book_uri);
- gtk_signal_emit (GTK_OBJECT (dest), e_destination_signals[CARDIFIED]);
- }
- }
-
- if (!dest->priv->has_been_cardified) {
- dest->priv->cannot_cardify = TRUE;
- }
-
- gtk_object_unref (GTK_OBJECT (dest)); /* drop the reference held by the query */
-}
-
-
-static void
-nickname_simple_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
-{
- EDestination *dest = E_DESTINATION (closure);
-
- if (status == E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS) {
- if (g_list_length ((GList *) cards) == 1) {
- const char *book_uri;
-
- book_uri = e_book_get_uri (book);
-
- dest->priv->has_been_cardified = TRUE;
- e_destination_set_card (dest, E_CARD (cards->data), 0); /* Uses primary e-mail by default. */
- e_destination_set_book_uri (dest, book_uri);
- gtk_signal_emit (GTK_OBJECT (dest), e_destination_signals[CARDIFIED]);
-
- gtk_object_unref (GTK_OBJECT (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 */
-
- e_book_name_and_email_query (book,
- e_destination_get_textrep (dest),
- NULL,
- name_and_email_simple_query_cb,
- dest);
- }
- } else {
- /* Something went wrong with the query: drop our ref to the destination and return. */
- gtk_object_unref (GTK_OBJECT (dest));
- }
-}
-
-static void
-launch_cardify_query (EDestination *dest)
-{
- if (! e_destination_is_valid (dest)) {
- /* If it doesn't look like an e-mail address, see if it is a nickname. */
- e_book_nickname_query (dest->priv->cardify_book,
- e_destination_get_textrep (dest),
- nickname_simple_query_cb,
- dest);
-
- } else {
- e_book_name_and_email_query (dest->priv->cardify_book,
- e_destination_get_name (dest),
- e_destination_get_email (dest),
- name_and_email_simple_query_cb,
- dest);
- }
-}
-
-static void
-use_default_book_cb (EBook *book, gpointer closure)
-{
- EDestination *dest = E_DESTINATION (closure);
- if (dest->priv->cardify_book == NULL) {
- dest->priv->cardify_book = book;
- gtk_object_ref (GTK_OBJECT (book));
- }
-
- launch_cardify_query (dest);
-}
-
-
-static gboolean
-e_destination_reverting_is_a_good_idea (EDestination *dest)
-{
- const char *textrep;
- int len, old_len;
-
- g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE);
- if (dest->priv->old_textrep == NULL)
- return FALSE;
-
- textrep = e_destination_get_textrep (dest);
-
- len = g_utf8_strlen (textrep, -1);
- old_len = g_utf8_strlen (dest->priv->old_textrep, -1);
-
- if (len <= old_len/2)
- return FALSE;
-
- return TRUE;
-}
-
-void
-e_destination_cardify (EDestination *dest, EBook *book)
-{
- g_return_if_fail (E_IS_DESTINATION (dest));
- g_return_if_fail (book == NULL || E_IS_BOOK (book));
-
- if (e_destination_is_evolution_list (dest))
- return;
-
- if (e_destination_contains_card (dest))
- return;
-
- if (!dest->priv->allow_cardify)
- return;
-
- if (dest->priv->cannot_cardify)
- return;
-
- e_destination_cancel_cardify (dest);
-
- /* In some cases, we can revert to the previous card. */
- if (!e_destination_is_valid (dest)
- && e_destination_reverting_is_a_good_idea (dest)
- && e_destination_revert (dest)) {
- return;
- }
-
- set_cardify_book (dest, book);
-
- /* Handle the case of an EDestination containing a card URL */
- if (e_destination_contains_card (dest)) {
- e_destination_use_card (dest, NULL, NULL);
- return;
- }
-
- /* If we have a book ready, proceed. We hold a reference to ourselves
- until our query is complete. */
- gtk_object_ref (GTK_OBJECT (dest));
- if (dest->priv->cardify_book != NULL) {
- launch_cardify_query (dest);
- } else {
- e_book_use_default_book (use_default_book_cb, dest);
- }
-}
-
-static int
-do_cardify_delayed (gpointer ptr)
-{
- EDestination *dest = E_DESTINATION (ptr);
-
- e_destination_cardify (dest, dest->priv->cardify_book);
- return FALSE;
-}
-
-void
-e_destination_cardify_delayed (EDestination *dest, EBook *book, gint delay)
-{
- g_return_if_fail (E_IS_DESTINATION (dest));
- g_return_if_fail (book == NULL || E_IS_BOOK (book));
-
- if (delay < 0)
- delay = 500;
-
- e_destination_cancel_cardify (dest);
-
- set_cardify_book (dest, book);
-
- dest->priv->pending_cardification = gtk_timeout_add (delay, do_cardify_delayed, dest);
-}
-
-void
-e_destination_cancel_cardify (EDestination *dest)
-{
- g_return_if_fail (E_IS_DESTINATION (dest));
-
- if (dest->priv->pending_cardification) {
- gtk_timeout_remove (dest->priv->pending_cardification);
- dest->priv->pending_cardification = 0;
- }
-}
-
-gboolean
-e_destination_uncardify (EDestination *dest)
-{
- char *email;
-
- g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE);
-
- if (!e_destination_contains_card (dest))
- return FALSE;
-
- email = g_strdup (e_destination_get_email (dest));
-
- if (email == NULL)
- return FALSE;
-
- e_destination_freeze (dest);
- e_destination_clear (dest);
- e_destination_set_raw (dest, email);
- g_free (email);
- e_destination_thaw (dest);
-
- return TRUE;
-}
-
-gboolean
-e_destination_revert (EDestination *dest)
-{
- g_return_val_if_fail (E_IS_DESTINATION (dest), FALSE);
-
- if (dest->priv->old_card) {
- ECard *card;
- int card_email_num;
-
- card = dest->priv->old_card;
- card_email_num = dest->priv->old_card_email_num;
-
- dest->priv->old_card = NULL;
- g_free (dest->priv->old_textrep);
- dest->priv->old_textrep = NULL;
-
- e_destination_freeze (dest);
- e_destination_clear (dest);
- e_destination_set_card (dest, card, card_email_num);
- e_destination_thaw (dest);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-/*
- * Destination import/export
- */
-
-gchar *
-e_destination_get_address_textv (EDestination **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 (E_IS_DESTINATION (destv[len]), NULL);
- len++;
- }
-
- strv = g_new0 (char *, len + 1);
- for (i = 0, j = 0; destv[i]; i++) {
- if (!e_destination_is_empty (destv[i])) {
- const char *addr = e_destination_get_address (destv[i]);
- strv[j++] = addr ? (char *) addr : "";
- }
- }
-
- str = g_strjoinv (", ", strv);
-
- g_free (strv);
-
- return str;
-}
-
-xmlNodePtr
-e_destination_xml_encode (const EDestination *dest)
-{
- xmlNodePtr dest_node;
- const char *str;
-
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
-
- dest_node = xmlNewNode (NULL, "destination");
-
- str = e_destination_get_name (dest);
- if (str)
- xmlNewTextChild (dest_node, NULL, "name", str);
-
- if (!e_destination_is_evolution_list (dest)) {
- str = e_destination_get_email (dest);
- if (str)
- xmlNewTextChild (dest_node, NULL, "email", str);
- } else {
- GList *iter = dest->priv->list_dests;
-
- while (iter) {
- EDestination *list_dest = E_DESTINATION (iter->data);
- xmlNodePtr list_node = xmlNewNode (NULL, "list_entry");
-
- str = e_destination_get_name (list_dest);
- if (str)
- xmlNewTextChild (list_node, NULL, "name", str);
-
- str = e_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",
- e_destination_list_show_addresses (dest) ? "yes" : "no");
- }
-
- str = e_destination_get_book_uri (dest);
- if (str) {
- xmlNewTextChild (dest_node, NULL, "book_uri", str);
- }
-
- str = e_destination_get_card_uid (dest);
- if (str) {
- char buf[16];
-
- xmlNodePtr uri_node = xmlNewTextChild (dest_node, NULL, "card_uid", str);
- g_snprintf (buf, 16, "%d", e_destination_get_email_num (dest));
- xmlNewProp (uri_node, "email_num", buf);
- }
-
- xmlNewProp (dest_node, "html_mail", e_destination_get_html_mail_pref (dest) ? "yes" : "no");
-
- xmlNewProp (dest_node, "auto_recipient",
- e_destination_is_auto_recipient (dest) ? "yes" : "no");
-
- return dest_node;
-}
-
-gboolean
-e_destination_xml_decode (EDestination *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 && E_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) {
- EDestination *list_dest = e_destination_new ();
-
- if (list_name)
- e_destination_set_name (list_dest, list_name);
- if (list_email)
- e_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;
- }
-
- e_destination_freeze (dest);
-
- e_destination_clear (dest);
-
- if (name) {
- e_destination_set_name (dest, name);
- g_free (name);
- }
- if (email) {
- e_destination_set_email (dest, email);
- g_free (email);
- }
- if (book_uri) {
- e_destination_set_book_uri (dest, book_uri);
- g_free (book_uri);
- }
- if (card_uid) {
- e_destination_set_card_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;
-
- e_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 *
-e_destination_export (const EDestination *dest)
-{
- xmlNodePtr dest_node;
- xmlDocPtr dest_doc;
- xmlChar *buffer = NULL;
- int size = -1;
- char *str;
-
- g_return_val_if_fail (dest && E_IS_DESTINATION (dest), NULL);
-
- dest_node = e_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;
-}
-
-EDestination *
-e_destination_import (const gchar *str)
-{
- EDestination *dest = NULL;
- xmlDocPtr dest_doc;
-
- if (!(str && *str))
- return NULL;
-
- dest_doc = xmlParseMemory ((char *) str, strlen (str));
- if (dest_doc && dest_doc->xmlRootNode) {
- dest = e_destination_new ();
- if (! e_destination_xml_decode (dest, dest_doc->xmlRootNode)) {
- gtk_object_unref (GTK_OBJECT (dest));
- dest = NULL;
- }
- }
- xmlFreeDoc (dest_doc);
-
- return dest;
-}
-
-gchar *
-e_destination_exportv (EDestination **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 (! e_destination_is_empty (destv[i])) {
- xmlNodePtr dest_node = e_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;
-}
-
-EDestination **
-e_destination_importv (const gchar *str)
-{
- GPtrArray *dest_array = NULL;
- xmlDocPtr destv_doc;
- xmlNodePtr node;
- EDestination **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) {
- EDestination *dest;
-
- dest = e_destination_new ();
- if (e_destination_xml_decode (dest, node) && !e_destination_is_empty (dest)) {
- g_ptr_array_add (dest_array, dest);
- } else {
- gtk_object_unref (GTK_OBJECT (dest));
- }
-
- node = node->next;
- }
-
- /* we need destv to be NULL terminated */
- g_ptr_array_add (dest_array, NULL);
-
- destv = (EDestination **) dest_array->pdata;
- g_ptr_array_free (dest_array, FALSE);
-
- finished:
- xmlFreeDoc (destv_doc);
-
- return destv;
-}
-
-EDestination **
-e_destination_list_to_vector_sized (GList *list, int n)
-{
- EDestination **destv;
- int i = 0;
-
- if (n == -1)
- n = g_list_length (list);
-
- if (n == 0)
- return NULL;
-
- destv = g_new (EDestination *, n + 1);
- while (list != NULL && i < n) {
- destv[i] = E_DESTINATION (list->data);
- list->data = NULL;
- i++;
- list = g_list_next (list);
- }
- destv[i] = NULL;
-
- return destv;
-}
-
-EDestination **
-e_destination_list_to_vector (GList *list)
-{
- return e_destination_list_to_vector_sized (list, -1);
-}
-
-void
-e_destination_freev (EDestination **destv)
-{
- int i;
-
- if (destv) {
- for (i = 0; destv[i] != NULL; ++i) {
- gtk_object_unref (GTK_OBJECT (destv[i]));
- }
- g_free (destv);
- }
-
-}
-
-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);
- }
-}
-
-void
-e_destination_touch (EDestination *dest)
-{
- const char *email;
-
- g_return_if_fail (dest && E_IS_DESTINATION (dest));
-
- if (!e_destination_is_auto_recipient (dest)) {
- email = e_destination_get_email (dest);
-
- if (email)
- e_book_query_address_default (email, touch_cb, NULL);
- }
-}
-
-void
-e_destination_touchv (EDestination **destv)
-{
- int i;
-
- g_return_if_fail (destv != NULL);
-
- for (i = 0; destv[i] != NULL; ++i) {
- e_destination_touch (destv[i]);
- }
-}
diff --git a/addressbook/backend/ebook/e-destination.h b/addressbook/backend/ebook/e-destination.h
deleted file mode 100644
index 42dc97800e..0000000000
--- a/addressbook/backend/ebook/e-destination.h
+++ /dev/null
@@ -1,138 +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 <gtk/gtkobject.h>
-#include <ebook/e-card.h>
-#include <ebook/e-book.h>
-#include <gnome-xml/tree.h>
-
-#define E_TYPE_DESTINATION (e_destination_get_type ())
-#define E_DESTINATION(o) (GTK_CHECK_CAST ((o), E_TYPE_DESTINATION, EDestination))
-#define E_DESTINATION_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), E_TYPE_DESTINATION, EDestinationClass))
-#define E_IS_DESTINATION(o) (GTK_CHECK_TYPE ((o), E_TYPE_DESTINATION))
-#define E_IS_DESTINATION_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_TYPE_DESTINATION))
-
-typedef struct _EDestination EDestination;
-typedef struct _EDestinationClass EDestinationClass;
-
-typedef void (*EDestinationCardCallback) (EDestination *dest, ECard *card, gpointer closure);
-
-struct _EDestinationPrivate;
-
-struct _EDestination {
- GtkObject object;
-
- struct _EDestinationPrivate *priv;
-};
-
-struct _EDestinationClass {
- GtkObjectClass parent_class;
-
- void (*changed) (EDestination *dest);
- void (*cardified) (EDestination *dest);
-};
-
-GtkType 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 *); /* "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/evolution-ldif-importer.c b/addressbook/backend/ebook/evolution-ldif-importer.c
deleted file mode 100644
index d792a74172..0000000000
--- a/addressbook/backend/ebook/evolution-ldif-importer.c
+++ /dev/null
@@ -1,629 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * LDIF importer. LDIF is the file format of an exported Netscape
- * addressbook.
- *
- * Framework copied from evolution-gnomecard-importer.c
- *
- * Michael M. Morrison (mmorrison@kqcorp.com)
- *
- * Multi-line value support, mailing list support, base64 support, and
- * various fixups: Chris Toshok (toshok@ximian.com)
- */
-
-#include <config.h>
-#include <bonobo.h>
-#include <gnome.h>
-#include <liboaf/liboaf.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#include <e-book.h>
-#include <e-card-simple.h>
-#include <e-destination.h>
-
-#include <importer/evolution-importer.h>
-#include <importer/GNOME_Evolution_Importer.h>
-
-#define COMPONENT_FACTORY_IID "OAFIID:GNOME_Evolution_Addressbook_LDIF_ImporterFactory"
-
-static BonoboGenericFactory *factory = NULL;
-
-static GHashTable *dn_card_hash;
-
-typedef struct {
- char *filename;
- GList *cardlist;
- GList *iterator;
- EBook *book;
- gboolean ready;
-} LDIFImporter;
-
-static struct {
- char *ldif_attribute;
- ECardSimpleField simple_field;
-#define FLAG_ADDRESS 0x01
- int flags;
-}
-ldif_fields[] = {
- { "cn", E_CARD_SIMPLE_FIELD_FULL_NAME },
- { "mail", E_CARD_SIMPLE_FIELD_EMAIL },
-#if 0
- { "givenname", E_CARD_SIMPLE_FIELD_GIVEN_NAME },
-#endif
- { "sn", E_CARD_SIMPLE_FIELD_FAMILY_NAME },
- { "xmozillanickname", E_CARD_SIMPLE_FIELD_NICKNAME },
- { "o", E_CARD_SIMPLE_FIELD_ORG },
- { "locality", 0, FLAG_ADDRESS},
- { "st", 0, FLAG_ADDRESS },
- { "streetaddress", 0, FLAG_ADDRESS },
- { "title", E_CARD_SIMPLE_FIELD_TITLE },
- { "postalcode", 0, FLAG_ADDRESS },
- { "countryname", 0, FLAG_ADDRESS },
- { "telephonenumber", E_CARD_SIMPLE_FIELD_PHONE_BUSINESS},
- { "homephone", E_CARD_SIMPLE_FIELD_PHONE_HOME },
- { "facsimiletelephonenumber", E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_FAX },
- { "ou", E_CARD_SIMPLE_FIELD_ORG_UNIT },
- { "pagerphone", E_CARD_SIMPLE_FIELD_PHONE_PAGER },
- { "cellphone", E_CARD_SIMPLE_FIELD_PHONE_MOBILE },
- { "homeurl", E_CARD_SIMPLE_FIELD_URL },
- { "description", E_CARD_SIMPLE_FIELD_NOTE },
- { "xmozillausehtmlmail", E_CARD_SIMPLE_FIELD_WANTS_HTML }
-};
-static int num_ldif_fields = sizeof(ldif_fields) / sizeof (ldif_fields[0]);
-
-static unsigned char base64_rank[256] = {
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
- 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
- 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
-};
-
-/**
- * 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 int
-base64_decode_step(unsigned char *in, int 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 = 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 (base64_rank[*inptr] != 0xff) {
- if (*inptr == '=')
- outptr--;
- i--;
- }
- }
-
- /* if i!= 0 then there is a truncation error! */
- return outptr-out;
-}
-
-static int
-base64_decode_simple (char *data, int len)
-{
- int state = 0;
- unsigned int save = 0;
-
- return base64_decode_step ((unsigned char *)data, len,
- (unsigned char *)data, &state, &save);
-}
-
-static GString *
-getValue( char **src )
-{
- GString *dest = g_string_new("");
- char *s = *src;
- gboolean need_base64 = (*s == ':');
-
- copy_line:
- while( *s != 0 && *s != '\n' && *s != '\r' )
- dest = g_string_append_c (dest, *s++);
-
- if (*s == '\r') s++;
- if (*s == '\n') s++;
-
- /* check for continuation here */
- if (*s == ' ') {
- s++;
- goto copy_line;
- }
-
- if (need_base64) {
- int new_len;
- /* it's base64 encoded */
- dest = g_string_erase (dest, 0, 2);
- new_len = base64_decode_simple (dest->str, strlen (dest->str));
- dest = g_string_truncate (dest, new_len);
- }
-
- *src = s;
-
- return dest;
-}
-
-static gboolean
-parseLine( ECardSimple *simple, ECardDeliveryAddress *address, char **buf )
-{
- char *ptr;
- char *colon, *value;
- gboolean field_handled;
- GString *ldif_value;
-
- ptr = *buf;
-
- /* if the string is empty, return */
- if (*ptr == '\0') {
- *buf = NULL;
- return TRUE;
- }
-
- /* skip comment lines */
- if (*ptr == '#') {
- ptr = strchr (ptr, '\n');
- if (!ptr)
- *buf = NULL;
- else
- *buf = ptr + 1;
- return TRUE;
- }
-
- /* first, check for a 'continuation' line */
- if( ptr[0] == ' ' && ptr[1] != '\n' ) {
- g_warning ("unexpected continuation line");
- return FALSE;
- }
-
- colon = (char *)strchr( ptr, ':' );
- if (colon) {
- int i;
-
- *colon = 0;
- value = colon + 1;
- while ( isspace(*value) )
- value++;
-
- ldif_value = getValue(&value );
-
- field_handled = FALSE;
- for (i = 0; i < num_ldif_fields; i ++) {
- if (!g_strcasecmp (ptr, ldif_fields[i].ldif_attribute)) {
- if (ldif_fields[i].flags & FLAG_ADDRESS) {
- if (!g_strcasecmp (ptr, "locality"))
- address->city = g_strdup (ldif_value->str);
- else if (!g_strcasecmp (ptr, "countryname"))
- address->country = g_strdup (ldif_value->str);
- else if (!g_strcasecmp (ptr, "postalcode"))
- address->code = g_strdup (ldif_value->str);
- else if (!g_strcasecmp (ptr, "st"))
- address->region = g_strdup (ldif_value->str);
- else if (!g_strcasecmp (ptr, "streetaddress"))
- address->street = g_strdup (ldif_value->str);
- }
- else {
- e_card_simple_set (simple, ldif_fields[i].simple_field, ldif_value->str);
- printf ("set %s to %s\n", ptr, ldif_value->str);
- }
- field_handled = TRUE;
- break;
- }
- }
-
- /* handle objectclass/dn/member out here */
- if (!field_handled) {
- if (!g_strcasecmp (ptr, "dn"))
- g_hash_table_insert (dn_card_hash, g_strdup(ldif_value->str), simple->card);
- else if (!g_strcasecmp (ptr, "objectclass") && !g_strcasecmp (ldif_value->str, "groupofnames")) {
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_IS_LIST, "true");
- }
- else if (!g_strcasecmp (ptr, "member")) {
- EList *email;
- gtk_object_get (GTK_OBJECT (simple->card),
- "email", &email,
- NULL);
- e_list_append (email, ldif_value->str);
- }
- }
-
- /* put the colon back the way it was, just for kicks */
- *colon = ':';
-
- g_string_free (ldif_value, TRUE);
- }
- else {
- g_warning ("unrecognized entry %s", ptr);
- return FALSE;
- }
-
- *buf = value;
-
- return TRUE;
-}
-
-static ECard *
-getNextLDIFEntry( FILE *f )
-{
- ECard *card;
- ECardAddrLabel *label;
- ECardSimple *simple;
- ECardDeliveryAddress *address;
- GString *str;
- char line[1024];
- char *buf;
-
- str = g_string_new ("");
- /* read from the file until we get to a blank line (or eof) */
- while (!feof (f)) {
- if (!fgets (line, sizeof(line), f))
- break;
- if (line[0] == '\n')
- break;
- str = g_string_append (str, line);
- }
-
- if (strlen (str->str) == 0) {
- g_string_free (str, TRUE);
- return NULL;
- }
-
- /* now parse that entry */
- card = e_card_new ("");
- simple = e_card_simple_new (card);
- address = e_card_delivery_address_new ();
-
- buf = str->str;
- while (buf) {
- if (!parseLine (simple, address, &buf)) {
- /* parsing error */
- gtk_object_unref (GTK_OBJECT (simple));
- e_card_delivery_address_unref (address);
- return NULL;
- }
- }
-
-
- /* fill in the address */
- address->flags = E_CARD_ADDR_HOME;
-
- label = e_card_delivery_address_to_label (address);
- e_card_delivery_address_unref (address);
-
- e_card_simple_set_address (simple, E_CARD_SIMPLE_ADDRESS_ID_HOME, label);
-
- e_card_address_label_unref (label);
-
- e_card_simple_sync_card (simple);
-
- g_string_free (str, TRUE);
-
- return card;
-}
-
-static void
-add_card_cb (EBook *book, EBookStatus status, const gchar *id, gpointer closure)
-{
- ECard *card = E_CARD(closure);
- char *vcard;
-
- e_card_set_id (card, id);
-
- vcard = e_card_get_vcard(card);
-
- g_print ("Saved card: %s\n", vcard);
- g_free(vcard);
-}
-
-static void
-resolve_list_card (LDIFImporter *gci, ECard *card)
-{
- EList *email;
- EIterator *email_iter;
- char *full_name;
-
- if (!e_card_evolution_list (card))
- return;
-
- gtk_object_get (GTK_OBJECT (card),
- "email", &email,
- "full_name", &full_name,
- NULL);
-
- /* set file_as to full_name so we don't later try and figure
- out a first/last name for the list. */
- if (full_name)
- gtk_object_set (GTK_OBJECT (card),
- "file_as", full_name,
- NULL);
-
- email_iter = e_list_get_iterator (email);
- while (e_iterator_is_valid (email_iter)) {
- const char *dn = e_iterator_get (email_iter);
- ECard *dn_card = g_hash_table_lookup (dn_card_hash, dn);
-
- /* break list chains here, since we don't support them just yet */
- if (dn_card && !e_card_evolution_list (dn_card)) {
- EDestination *dest = e_destination_new ();
- gchar *dest_xml;
- e_destination_set_card (dest, dn_card, 0); /* Hard-wired for default e-mail, since netscape only exports 1 email address */
- dest_xml = e_destination_export (dest);
- gtk_object_unref (GTK_OBJECT (dest));
- if (dest_xml) {
- e_iterator_set (email_iter, dest_xml);
- g_free (dest_xml);
- e_iterator_next (email_iter);
- }
- else {
- e_iterator_delete (email_iter);
- }
- }
- else {
- e_iterator_delete (email_iter);
- }
- }
-}
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- LDIFImporter *gci = (LDIFImporter *) closure;
- GList * list = NULL;
- GList * list_list = NULL;
- FILE * file;
- ECard *card;
-
- if(!( file = fopen( gci->filename, "r" ) )) {
- g_warning("!!!Can't open .ldif file");
- return;
- }
-
- dn_card_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- while ((card = getNextLDIFEntry (file))) {
-
- if (e_card_evolution_list (card))
- list_list = g_list_append (list_list, card);
- else
- list = g_list_append (list, card);
- }
-
- fclose( file );
-
- list = g_list_reverse( list );
- list_list = g_list_reverse (list_list);
- list = g_list_concat (list, list_list);
-
- gci->cardlist = list;
- gci->ready = TRUE;
-}
-
-static void
-ebook_create (LDIFImporter *gci)
-{
- gchar *path, *uri;
-
- gci->book = e_book_new ();
-
- if (!gci->book) {
- printf ("%s: %s(): Couldn't create EBook, bailing.\n",
- __FILE__,
- __FUNCTION__);
- return;
- }
-#if 0
- path = g_concat_dir_and_file (g_get_home_dir (),
- "evolution/local/Contacts/addressbook.db");
- uri = g_strdup_printf ("file://%s", path);
- g_free (path);
-
- if (! e_book_load_uri (gci->book, uri, book_open_cb, gci)) {
- printf ("error calling load_uri!\n");
- }
- g_free(uri);
-#endif
-
- if (! e_book_load_default_book (gci->book, book_open_cb, gci)) {
- g_warning ("Error calling load_default_book");
- }
-}
-
-/* EvolutionImporter methods */
-static void
-process_item_fn (EvolutionImporter *importer,
- CORBA_Object listener,
- void *closure,
- CORBA_Environment *ev)
-{
- LDIFImporter *gci = (LDIFImporter *) closure;
- ECard *card;
-
- if (gci->iterator == NULL)
- gci->iterator = gci->cardlist;
-
- if (gci->ready == FALSE) {
- GNOME_Evolution_ImporterListener_notifyResult (listener,
- GNOME_Evolution_ImporterListener_NOT_READY,
- gci->iterator ? TRUE : FALSE,
- ev);
- return;
- }
-
- if (gci->iterator == NULL) {
- GNOME_Evolution_ImporterListener_notifyResult (listener,
- GNOME_Evolution_ImporterListener_UNSUPPORTED_OPERATION,
- FALSE, ev);
- return;
- }
-
- card = gci->iterator->data;
- if (e_card_evolution_list (card))
- resolve_list_card (gci, card);
- e_book_add_card (gci->book, card, add_card_cb, card);
-
- gci->iterator = gci->iterator->next;
-
- GNOME_Evolution_ImporterListener_notifyResult (listener,
- GNOME_Evolution_ImporterListener_OK,
- gci->iterator ? TRUE : FALSE,
- ev);
- if (ev->_major != CORBA_NO_EXCEPTION) {
- g_warning ("Error notifying listeners.");
- }
-
- return;
-}
-
-static char *supported_extensions[2] = {
- ".ldif", NULL
-};
-
-static gboolean
-support_format_fn (EvolutionImporter *importer,
- const char *filename,
- void *closure)
-{
- char *ext;
- int i;
-
- ext = strrchr (filename, '.');
- if (ext == NULL) {
- return FALSE;
- }
-
- for (i = 0; supported_extensions[i] != NULL; i++) {
- if (strcmp (supported_extensions[i], ext) == 0)
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-importer_destroy_cb (GtkObject *object,
- LDIFImporter *gci)
-{
- gtk_main_quit ();
-}
-
-static gboolean
-load_file_fn (EvolutionImporter *importer,
- const char *filename,
- const char *folderpath,
- void *closure)
-{
- LDIFImporter *gci;
-
- gci = (LDIFImporter *) closure;
- gci->filename = g_strdup (filename);
- gci->cardlist = NULL;
- gci->iterator = NULL;
- gci->ready = FALSE;
- ebook_create (gci);
-
- return TRUE;
-}
-
-static BonoboObject *
-factory_fn (BonoboGenericFactory *_factory,
- void *closure)
-{
- EvolutionImporter *importer;
- LDIFImporter *gci;
-
- gci = g_new (LDIFImporter, 1);
- importer = evolution_importer_new (support_format_fn, load_file_fn,
- process_item_fn, NULL, gci);
-
- gtk_signal_connect (GTK_OBJECT (importer), "destroy",
- GTK_SIGNAL_FUNC (importer_destroy_cb), gci);
-
- return BONOBO_OBJECT (importer);
-}
-
-static void
-importer_init (void)
-{
- if (factory != NULL)
- return;
-
- factory = bonobo_generic_factory_new (COMPONENT_FACTORY_IID,
- factory_fn, NULL);
-
- if (factory == NULL) {
- g_error ("Unable to create factory");
- }
-
- bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory));
-}
-
-int
-main (int argc,
- char **argv)
-{
- CORBA_ORB orb;
-
- gnome_init_with_popt_table ("Evolution-LDIF-Importer",
- "0.0", argc, argv, oaf_popt_options, 0,
- NULL);
- orb = oaf_init (argc, argv);
- if (bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE) {
- g_error ("Could not initialize Bonobo.");
- }
-
- importer_init ();
- bonobo_main ();
-
- return 0;
-}
-
-
diff --git a/addressbook/backend/ebook/evolution-vcard-importer.c b/addressbook/backend/ebook/evolution-vcard-importer.c
deleted file mode 100644
index 9e0a475977..0000000000
--- a/addressbook/backend/ebook/evolution-vcard-importer.c
+++ /dev/null
@@ -1,266 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-#include <config.h>
-#include <stdio.h>
-
-#include <liboaf/liboaf.h>
-#include <bonobo/bonobo-context.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-main.h>
-
-#include <e-book.h>
-
-#include <importer/evolution-importer.h>
-#include <importer/GNOME_Evolution_Importer.h>
-
-#include <e-util/e-path.h>
-
-#define COMPONENT_FACTORY_IID "OAFIID:GNOME_Evolution_Addressbook_VCard_ImporterFactory"
-
-static BonoboGenericFactory *factory = NULL;
-
-typedef struct {
- char *filename;
- char *folderpath;
- GList *cardlist;
- GList *iterator;
- EBook *book;
- gboolean ready;
-} VCardImporter;
-
-static void
-add_card_cb (EBook *book, EBookStatus status, const gchar *id, gpointer closure)
-{
- ECard *card = E_CARD(closure);
- gtk_object_unref(GTK_OBJECT(card));
-}
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- VCardImporter *gci = (VCardImporter *) closure;
-
- gci->cardlist = e_card_load_cards_from_file_with_default_charset(gci->filename, "ISO-8859-1");
- gci->ready = TRUE;
-}
-
-static void
-ebook_create (VCardImporter *gci)
-{
- gchar *path, *uri;
- gchar *epath;
-
- gci->book = e_book_new ();
-
- if (!gci->book) {
- printf ("%s: %s(): Couldn't create EBook, bailing.\n",
- __FILE__,
- __FUNCTION__);
- return;
- }
-
-#if 0
- path = g_concat_dir_and_file (g_get_home_dir (), "evolution/local");
- uri = g_strdup_printf ("file://%s", path);
- g_free (path);
-
- epath = e_path_to_physical (uri, gci->folderpath);
- g_free (uri);
- uri = g_strdup_printf ("%s/addressbook.db", epath);
- g_free (epath);
-
- if (! e_book_load_uri (gci->book, uri, book_open_cb, gci)) {
- printf ("error calling load_uri!\n");
- }
- g_free(uri);
-#endif
-
- if (! e_book_load_default_book (gci->book, book_open_cb, gci)) {
- g_warning ("Error calling load_default_book");
- }
-}
-
-/* EvolutionImporter methods */
-static void
-process_item_fn (EvolutionImporter *importer,
- CORBA_Object listener,
- void *closure,
- CORBA_Environment *ev)
-{
- VCardImporter *gci = (VCardImporter *) closure;
- ECard *card;
-
- if (gci->iterator == NULL)
- gci->iterator = gci->cardlist;
-
- if (gci->ready == FALSE) {
- GNOME_Evolution_ImporterListener_notifyResult (listener,
- GNOME_Evolution_ImporterListener_NOT_READY,
- gci->iterator ? TRUE : FALSE,
- ev);
- return;
- }
-
- if (gci->iterator == NULL) {
- GNOME_Evolution_ImporterListener_notifyResult (listener,
- GNOME_Evolution_ImporterListener_UNSUPPORTED_OPERATION,
- FALSE, ev);
- return;
- }
-
- card = gci->iterator->data;
- e_book_add_card (gci->book, card, add_card_cb, card);
-
- gci->iterator = gci->iterator->next;
-
- GNOME_Evolution_ImporterListener_notifyResult (listener,
- GNOME_Evolution_ImporterListener_OK,
- gci->iterator ? TRUE : FALSE,
- ev);
- if (ev->_major != CORBA_NO_EXCEPTION) {
- g_warning ("Error notifying listeners.");
- }
-
- return;
-}
-
-static char *supported_extensions[3] = {
- ".vcf",
- ".gcrd",
- NULL
-};
-
-/* Actually check the contents of this file */
-static gboolean
-check_file_is_vcard (const char *filename)
-{
- FILE *handle;
- char line[4096];
- gboolean result;
-
- handle = fopen (filename, "r");
- if (handle == NULL) {
- g_print ("\n");
- return FALSE;
- }
-
- fgets (line, 4096, handle);
- if (line == NULL) {
- fclose (handle);
- g_print ("\n");
- return FALSE;
- }
-
- if (strncmp (line, "BEGIN:VCARD", 11) == 0) {
- result = TRUE;
- } else {
- result = FALSE;
- }
-
- fclose (handle);
- return result;
-}
-
-static gboolean
-support_format_fn (EvolutionImporter *importer,
- const char *filename,
- void *closure)
-{
- char *ext;
- int i;
-
- ext = strrchr (filename, '.');
- if (ext == NULL) {
- return check_file_is_vcard (filename);
- }
- for (i = 0; supported_extensions[i] != NULL; i++) {
- if (strcmp (supported_extensions[i], ext) == 0)
- return check_file_is_vcard (filename);
- }
-
- return FALSE;
-}
-
-static void
-importer_destroy_cb (GtkObject *object,
- VCardImporter *gci)
-{
- gtk_main_quit ();
-}
-
-static gboolean
-load_file_fn (EvolutionImporter *importer,
- const char *filename,
- const char *folderpath,
- void *closure)
-{
- VCardImporter *gci;
-
- if (check_file_is_vcard (filename) == FALSE) {
- return FALSE;
- }
-
- gci = (VCardImporter *) closure;
- gci->filename = g_strdup (filename);
- gci->folderpath = g_strdup (folderpath);
- gci->cardlist = NULL;
- gci->iterator = NULL;
- gci->ready = FALSE;
- ebook_create (gci);
-
- return TRUE;
-}
-
-static BonoboObject *
-factory_fn (BonoboGenericFactory *_factory,
- void *closure)
-{
- EvolutionImporter *importer;
- VCardImporter *gci;
-
- gci = g_new (VCardImporter, 1);
- importer = evolution_importer_new (support_format_fn, load_file_fn,
- process_item_fn, NULL, gci);
-
- gtk_signal_connect (GTK_OBJECT (importer), "destroy",
- GTK_SIGNAL_FUNC (importer_destroy_cb), gci);
-
- return BONOBO_OBJECT (importer);
-}
-
-static void
-importer_init (void)
-{
- if (factory != NULL)
- return;
-
- factory = bonobo_generic_factory_new (COMPONENT_FACTORY_IID,
- factory_fn, NULL);
-
- if (factory == NULL) {
- g_error ("Unable to create factory");
- }
-
- bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory));
-}
-
-int
-main (int argc,
- char **argv)
-{
- CORBA_ORB orb;
-
- gnome_init_with_popt_table ("Evolution-VCard-Importer",
- PACKAGE, argc, argv, oaf_popt_options, 0,
- NULL);
- orb = oaf_init (argc, argv);
- if (bonobo_init (orb, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE) {
- g_error ("Could not initialize Bonobo.");
- }
-
- importer_init ();
- bonobo_main ();
-
- return 0;
-}
-
-
diff --git a/addressbook/backend/ebook/load-gnomecard-addressbook.c b/addressbook/backend/ebook/load-gnomecard-addressbook.c
deleted file mode 100644
index 6f592a4664..0000000000
--- a/addressbook/backend/ebook/load-gnomecard-addressbook.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-#include <config.h>
-#include <stdio.h>
-#include <glib.h>
-#include <gtk/gtkmain.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnome/gnome-util.h>
-#include <libgnomeui/gnome-init.h>
-#include <bonobo/bonobo-main.h>
-#include <liboaf/liboaf.h>
-
-#include "e-book.h"
-
-static CORBA_Environment ev;
-
-static void
-init_bonobo (int argc, char **argv)
-{
- if (bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE)
- g_error (_("Could not initialize Bonobo"));
-}
-
-static void
-add_card_cb (EBook *book, EBookStatus status, const gchar *id, gpointer closure)
-{
- ECard *card = E_CARD(closure);
- char *vcard = e_card_get_vcard_assume_utf8(card);
- g_print ("Saved card: %s\n", vcard);
- g_free(vcard);
- gtk_object_unref(GTK_OBJECT(card));
-}
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- GList *list = e_card_load_cards_from_file_with_default_charset("gnomecard.vcf", "ISO-8859-1");
- GList *iterator;
- for (iterator = list; iterator; iterator = g_list_next(iterator)) {
- ECard *card = iterator->data;
- e_book_add_card(book, card, add_card_cb, card);
- }
- g_list_free(list);
-}
-
-static guint
-ebook_create (void)
-{
- EBook *book;
- gchar *path, *uri;
-
- book = e_book_new ();
-
- if (!book) {
- printf ("%s: %s(): Couldn't create EBook, bailing.\n",
- __FILE__,
- __FUNCTION__);
- return FALSE;
- }
-
-
- path = g_concat_dir_and_file (g_get_home_dir (),
- "evolution/local/Contacts/addressbook.db");
- uri = g_strdup_printf ("file://%s", path);
- g_free (path);
-
- if (! e_book_load_uri (book, uri, book_open_cb, NULL)) {
- printf ("error calling load_uri!\n");
- }
- g_free(uri);
-
-
- return FALSE;
-}
-
-int
-main (int argc, char **argv)
-{
-
- CORBA_exception_init (&ev);
-
- gnome_init_with_popt_table("blah", "0.0", argc, argv, NULL, 0, NULL);
- oaf_init (argc, argv);
- init_bonobo (argc, argv);
-
- gtk_idle_add ((GtkFunction) ebook_create, NULL);
-
- bonobo_main ();
-
- return 0;
-}
diff --git a/addressbook/backend/ebook/load-pine-addressbook.c b/addressbook/backend/ebook/load-pine-addressbook.c
deleted file mode 100644
index c1d58a88bf..0000000000
--- a/addressbook/backend/ebook/load-pine-addressbook.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-#include <config.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <glib.h>
-#include <gtk/gtkmain.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnome/gnome-util.h>
-#include <libgnomeui/gnome-init.h>
-#include <bonobo/bonobo-main.h>
-#include <liboaf/liboaf.h>
-
-#include "e-book.h"
-
-static CORBA_Environment ev;
-
-static void
-init_bonobo (int argc, char **argv)
-{
- if (bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE)
- g_error (_("Could not initialize Bonobo"));
-}
-
-static void
-add_card_cb (EBook *book, EBookStatus status, const gchar *id, gpointer closure)
-{
- ECard *card = E_CARD(closure);
- char *vcard = e_card_get_vcard_assume_utf8(card);
- g_print ("Saved card: %s\n", vcard);
- g_free(vcard);
- gtk_object_unref(GTK_OBJECT(card));
-}
-
-static void
-parse_line (EBook *book, char *line)
-{
- char **strings;
- ECardName *name;
- ECard *card;
- EList *list;
-
- card = e_card_new("");
- strings = g_strsplit(line, "\t", 3);
- if (strings[0] && strings[1] && strings[2]) {
- name = e_card_name_from_string(strings[1]);
- gtk_object_set(GTK_OBJECT(card),
- "nickname", strings[0],
- "full_name", strings[1],
- "name", name,
- NULL);
- gtk_object_get(GTK_OBJECT(card),
- "email", &list,
- NULL);
- e_list_append(list, strings[2]);
- e_book_add_card(book, card, add_card_cb, card);
- }
- g_strfreev(strings);
-}
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- FILE *fp = fopen (".addressbook", "r");
- char line[2 * 1024];
- int which = 0;
- char *lastline = NULL;
-
- if (!fp) {
- g_warning ("Can't find .addressbook");
- return;
- }
-
- while(fgets(line + which * 1024, 1024, fp)) {
- int length;
- char *thisline = line + which * 1024;
- length = strlen(thisline);
- if (thisline[length - 1] == '\n')
- line[--length] = 0;
- if (lastline && *thisline && isspace(*thisline)) {
- char *temp;
- while(*thisline && isspace(*thisline))
- thisline ++;
- temp = lastline;
- lastline = g_strdup_printf("%s%s", lastline, thisline);
- g_free(temp);
- continue;
- }
- if (lastline) {
- parse_line (book, lastline);
- g_free(lastline);
- }
- lastline = g_strdup(thisline);
- }
-
- if (lastline) {
- parse_line (book, lastline);
- g_free(lastline);
- }
-}
-
-static guint
-ebook_create (void)
-{
- EBook *book;
- gchar *path, *uri;
-
- book = e_book_new ();
-
- if (!book) {
- printf ("%s: %s(): Couldn't create EBook, bailing.\n",
- __FILE__,
- __FUNCTION__);
- return FALSE;
- }
-
-
- path = g_concat_dir_and_file (g_get_home_dir (),
- "evolution/local/Contacts/addressbook.db");
- uri = g_strdup_printf ("file://%s", path);
- g_free (path);
-
- if (! e_book_load_uri (book, uri, book_open_cb, NULL)) {
- printf ("error calling load_uri!\n");
- }
- g_free(uri);
-
-
- return FALSE;
-}
-
-#if 0
-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);
-}
-#endif
-
-int
-main (int argc, char **argv)
-{
-
- CORBA_exception_init (&ev);
-
- gnome_init_with_popt_table("blah", "0.0", argc, argv, NULL, 0, NULL);
- oaf_init (argc, argv);
- init_bonobo (argc, argv);
-
- gtk_idle_add ((GtkFunction) ebook_create, NULL);
-
- bonobo_main ();
-
- return 0;
-}
diff --git a/addressbook/backend/ebook/test-card.c b/addressbook/backend/ebook/test-card.c
deleted file mode 100644
index d625214bfd..0000000000
--- a/addressbook/backend/ebook/test-card.c
+++ /dev/null
@@ -1,191 +0,0 @@
-#include <string.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnomeui/gnome-init.h>
-#include "e-card.h"
-
-#define TEST_VCARD \
-"BEGIN:VCARD\r\n" \
-"FN:Nat\r\n" \
-"N:Friedman;Nat;D;Mr.\r\n" \
-"ORG:Ximian, Inc.\r\n" \
-"TITLE:Head Geek\r\n" \
-"ROLE:Programmer/Executive\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" \
-"ADR;HOME;POSTAL;INTL:P.O. Box 202;;;Any Town 2;MI;12344-4321;USA\r\n" \
-"END:VCARD\r\n" \
-"\r\n"
-
-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)
-{
- char *cardstr;
- ECard *card;
-
- /* Fields */
- char *fname;
- char *org;
- char *org_unit;
- char *title;
- char *role;
- char *nickname;
- char *fburl;
- ECardName *name;
- EList *address;
- EList *phone;
- EList *email;
- EList *arbitrary;
- EIterator *iterator;
- ECardDate *bday;
-
- gnome_init ("TestCard", "0.0", argc, argv);
-
- cardstr = NULL;
- if (argc == 2)
- cardstr = read_file (argv [1]);
-
- if (cardstr == NULL)
- cardstr = TEST_VCARD;
-#if 0
- {
- int i;
- for ( i = 0; i < 100000; i++ ) {
- card = e_card_new (cardstr);
-
- gtk_object_unref (GTK_OBJECT (card));
- }
- }
-#endif
- card = e_card_new_with_default_charset (cardstr, "ISO-8859-1");
- gtk_object_get(GTK_OBJECT(card),
- "full_name", &fname,
- "name", &name,
- "address", &address,
- "phone", &phone,
- "email", &email,
- "org", &org,
- "org_unit", &org_unit,
- "title", &title,
- "role", &role,
- "nickname", &nickname,
- "fburl", &fburl,
- "arbitrary", &arbitrary,
- "birth_date", &bday,
- NULL);
- if ( fname ) {
- printf("Name : %s\n", fname);
- g_free(fname);
- }
- if ( name ) {
- printf("Full Name:\n");
- if ( name->prefix )
- printf(" prefix : %s\n", name->prefix);
- if ( name->given )
- printf(" given : %s\n", name->given);
- if ( name->additional )
- printf(" additional : %s\n", name->additional);
- if ( name->family )
- printf(" family : %s\n", name->family);
- if ( name->suffix )
- printf(" suffix : %s\n", name->suffix);
- }
- if ( org ) {
- printf("Company : %s\n", org);
- }
- if ( org_unit ) {
- printf("Department : %s\n", org_unit);
- }
- if ( title ) {
- printf("Title : %s\n", title);
- }
- if ( role ) {
- printf("Profession : %s\n", role);
- }
- if ( nickname ) {
- printf("Nickname : %s\n", nickname);
- }
- if ( fburl ) {
- printf("Free Busy URL : %s\n", fburl);
- }
- if ( arbitrary ) {
- iterator = e_list_get_iterator(arbitrary);
- for (; e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- ECardArbitrary *arbitrary = (ECardArbitrary *) e_iterator_get(iterator);
- printf("Arbitrary : %s, %s\n", arbitrary->key, arbitrary->value);
- }
- gtk_object_unref(GTK_OBJECT(iterator));
- }
- if ( bday ) {
- printf("BDay : %4d-%02d-%02d\n", bday->year, bday->month, bday->day);
- }
- if ( email ) {
- iterator = e_list_get_iterator(address);
- for (; e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- printf("Email : %s\n", (char *) e_iterator_get(iterator));
- }
- gtk_object_unref(GTK_OBJECT(iterator));
- }
- if ( phone ) {
- iterator = e_list_get_iterator(address);
- for (; e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- ECardPhone *e_card_phone = (ECardPhone *) e_iterator_get(iterator);
- printf("Phone ; %d : %s\n", e_card_phone->flags, e_card_phone->number);
- }
- gtk_object_unref(GTK_OBJECT(iterator));
- }
- if ( address ) {
- iterator = e_list_get_iterator(address);
- for (; e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- ECardDeliveryAddress *del_address = (ECardDeliveryAddress *) e_iterator_get(iterator);
- printf("Address ; %d:\n", del_address->flags);
- if ( del_address->po )
- printf(" Po : %s\n", del_address->po);
- if ( del_address->ext )
- printf(" Ext : %s\n", del_address->ext);
- if ( del_address->street )
- printf(" Street : %s\n", del_address->street);
- if ( del_address->city )
- printf(" City : %s\n", del_address->city);
- if ( del_address->region )
- printf(" Region : %s\n", del_address->region);
- if ( del_address->code )
- printf(" Code : %s\n", del_address->code);
- if ( del_address->country )
- printf(" Country : %s\n", del_address->country);
- }
- gtk_object_unref(GTK_OBJECT(iterator));
- }
- printf("%s", e_card_get_vcard_assume_utf8(card));
- gtk_object_unref (GTK_OBJECT (card));
-
- return 0;
-}
diff --git a/addressbook/backend/ebook/test-client-list.c b/addressbook/backend/ebook/test-client-list.c
deleted file mode 100644
index 8a38ccf4e1..0000000000
--- a/addressbook/backend/ebook/test-client-list.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-#include <config.h>
-
-#include <glib.h>
-#include <gtk/gtkmain.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-init.h>
-#include <liboaf/liboaf.h>
-#include <bonobo/bonobo-main.h>
-
-#include "e-book.h"
-
-CORBA_Environment ev;
-
-static void
-init_bonobo (int argc, char **argv)
-{
- gnome_init ("blah", "0.0", argc, argv);
- oaf_init (argc, argv);
-
- if (bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == 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);
- gtk_object_unref(GTK_OBJECT(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 guint
-ebook_create (void)
-{
- EBook *book;
-
- book = e_book_new ();
-
- if (! e_book_load_uri (book, "file:/tmp/test.db", book_open_cb, NULL)) {
- printf ("error calling load_uri!\n");
- }
-
-
- return FALSE;
-}
-
-int
-main (int argc, char **argv)
-{
-
- CORBA_exception_init (&ev);
- init_bonobo (argc, argv);
-
- gtk_idle_add ((GtkFunction) 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 300f25958b..0000000000
--- a/addressbook/backend/ebook/test-client.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-#include <config.h>
-#include <glib.h>
-#include <gtk/gtkmain.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-init.h>
-#include <bonobo/bonobo-main.h>
-#include <liboaf/liboaf.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 (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == 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__, __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);
- gtk_object_unref(GTK_OBJECT(card));
- }
-}
-
-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);
- gtk_object_unref(GTK_OBJECT(card));
-
- printf ("Getting cards..\n");
- e_book_get_cursor(book, "", 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));
- }
-
- gtk_object_unref(GTK_OBJECT(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 guint
-ebook_create (void)
-{
- EBook *book;
-
- book = e_book_new ();
-
- if (!book) {
- printf ("%s: %s(): Couldn't create EBook, bailing.\n",
- __FILE__,
- __FUNCTION__);
- return FALSE;
- }
-
-
- if (! e_book_load_default_book (book, book_open_cb, NULL)) {
- printf ("error calling load_uri!\n");
- }
-
-
- 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_init_with_popt_table ("blah", "0.0", argc, argv, NULL, 0, NULL);
- oaf_init (argc, argv);
- init_bonobo (argc, argv);
-
- cardstr = NULL;
- if (argc == 2)
- cardstr = read_file (argv [1]);
-
- if (cardstr == NULL)
- cardstr = TEST_VCARD;
-
- gtk_idle_add ((GtkFunction) ebook_create, NULL);
-
- bonobo_main ();
-
- return 0;
-}
diff --git a/addressbook/backend/idl/.cvsignore b/addressbook/backend/idl/.cvsignore
deleted file mode 100644
index 09980ae6ba..0000000000
--- a/addressbook/backend/idl/.cvsignore
+++ /dev/null
@@ -1,6 +0,0 @@
-.deps
-.libs
-Makefile
-Makefile.in
-*.lo
-*.la
diff --git a/addressbook/backend/idl/Makefile.am b/addressbook/backend/idl/Makefile.am
deleted file mode 100644
index db61d2c30c..0000000000
--- a/addressbook/backend/idl/Makefile.am
+++ /dev/null
@@ -1,6 +0,0 @@
-idldir = $(datadir)/idl
-
-idl_DATA = \
- addressbook.idl
-
-EXTRA_DIST = $(idl_DATA)
diff --git a/addressbook/backend/idl/addressbook.idl b/addressbook/backend/idl/addressbook.idl
deleted file mode 100644
index 18a60f074f..0000000000
--- a/addressbook/backend/idl/addressbook.idl
+++ /dev/null
@@ -1,185 +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.
- */
-
-#include <Bonobo.idl>
-
-module GNOME {
-module Evolution {
-module Addressbook {
- typedef string CardId;
- typedef string VCard;
- typedef sequence<VCard> VCardList;
- typedef sequence<string> stringlist;
-
- interface CardCursor : Bonobo::Unknown {
- long count ();
- string getNth (in long n);
- };
-
- /*
- * 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
- * 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.)
- */
- 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 notifyCardRemoved (in CardId id);
- void notifyCardChanged (in VCardList cards);
- void notifySequenceComplete (in CallStatus status);
- void notifyStatusMessage (in string message);
- };
-
- interface BookView : Bonobo::Unknown {
- };
-
- interface Book : Bonobo::Unknown {
- /*
- * Fetching cards in the addresbook.
- */
- void getVCard (in CardId id);
-
- void authenticateUser (in string user, in string passwd,
- in string authMethod);
-
- /*
- * Adding and deleting cards in the book.
- */
- void addCard (in VCard vcard);
- void removeCard (in CardId Id);
-
- /*
- * Modifying cards in the addressbook.
- */
- void modifyCard (in VCard vcard);
-
- /*
- * This function returns a cursor to the book
- * listener. This is for people who want a snapshot
- * of the addressbook.
- */
- void getCursor (in string query);
-
- /*
- * 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);
-
- void getChanges (in BookViewListener listener, 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 ();
-
- void getSupportedFields ();
-
- string getStaticCapabilities ();
-
- string getName ();
- };
-
- interface BookListener : Bonobo::Unknown {
-
- enum CallStatus {
- Success,
- RepositoryOffline,
- PermissionDenied,
- CardNotFound,
- CardIdAlreadyExists,
- ProtocolNotSupported,
- AuthenticationFailed,
- AuthenticationRequired,
- UnsupportedField,
- TLSNotAvailable,
- NoSuchBook,
-
- OtherError
- };
-
- void notifyCardCreated (in CallStatus status, in CardId Id);
-
- void notifyCardRemoved (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);
-
- /**
- * 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);
- };
-
- interface BookFactory : Bonobo::Unknown {
- exception ProtocolNotSupported {};
-
- void openBook (in string uri, in BookListener listener)
- raises (ProtocolNotSupported);
- };
-};
-};
-};
diff --git a/addressbook/backend/pas/.cvsignore b/addressbook/backend/pas/.cvsignore
deleted file mode 100644
index 071cef99ae..0000000000
--- a/addressbook/backend/pas/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-.deps
-.libs
-.pure
-Makefile
-Makefile.in
-addressbook-stubs.c
-addressbook-skels.c
-addressbook-common.c
-addressbook.h
-*.lo
-*.la
diff --git a/addressbook/backend/pas/Makefile.am b/addressbook/backend/pas/Makefile.am
deleted file mode 100644
index 28e29de9d7..0000000000
--- a/addressbook/backend/pas/Makefile.am
+++ /dev/null
@@ -1,81 +0,0 @@
-CORBA_SOURCE_H = addressbook.h
-
-CORBA_SOURCE_C = \
- addressbook-common.c \
- addressbook-stubs.c \
- addressbook-skels.c
-
-CORBA_SOURCE = $(CORBA_SOURCE_H) $(CORBA_SOURCE_C)
-
-idls = \
- $(srcdir)/../idl/addressbook.idl
-
-idl_flags = `$(GNOME_CONFIG) --cflags idl` -I $(datadir)/idl
-
-$(CORBA_SOURCE): $(idls)
- $(ORBIT_IDL) -I $(srcdir) $(srcdir)/../idl/addressbook.idl $(idl_flags)
-
-INCLUDES = \
- $(DB3_CFLAGS) \
- $(LDAP_CFLAGS) \
- -DGNOMELOCALEDIR=\""$(localedir)"\" \
- -DG_LOG_DOMAIN=\"wombat-pas\" \
- -I$(top_srcdir) \
- -I$(top_srcdir)/addressbook/backend \
- -I$(top_builddir)/addressbook/backend \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
-
-LDAP_SCHEMA = \
- evolutionperson.schema
-
-LDAP_BACKEND_FILES = \
- pas-backend-ldap.c \
- pas-backend-ldap.h
-
-if ENABLE_LDAP
-LDAP_BACKEND = libpasldap.a
-endif
-
-privlib_LIBRARIES = libpas.a
-noinst_LIBRARIES = libpasfile.a $(LDAP_BACKEND)
-
-pasincludedir = $(includedir)/evolution/pas
-
-pasinclude_HEADERS = \
- $(CORBA_SOURCE_H) \
- pas-book-factory.h \
- pas-book-view.h \
- pas-book.h \
- pas-backend-card-sexp.h \
- pas-backend.h \
- pas-backend-summary.h \
- pas-card-cursor.h
-
-libpas_a_SOURCES = \
- $(pasinclude_HEADERS) \
- $(CORBA_SOURCE_C) \
- pas-book-factory.c \
- pas-book-view.c \
- pas-book.c \
- pas-backend-card-sexp.c \
- pas-backend-file.c \
- pas-backend.c \
- pas-backend-summary.c \
- pas-card-cursor.c
-
-libpasfile_a_SOURCES = \
- pas-backend-file.c \
- pas-backend-file.h
-
-if ENABLE_LDAP
-libpasldap_a_SOURCES = \
- $(LDAP_BACKEND_FILES)
-endif
-
-BUILT_SOURCES = $(CORBA_SOURCE)
-CLEANFILES = $(BUILT_SOURCES)
-
-dist-hook:
- cd $(distdir); rm -f $(BUILT_SOURCES)
-
-EXTRA_DIST = $(LDAP_BACKEND_FILES) $(LDAP_SCHEMA)
diff --git a/addressbook/backend/pas/TODO b/addressbook/backend/pas/TODO
deleted file mode 100644
index 0c77c1b200..0000000000
--- a/addressbook/backend/pas/TODO
+++ /dev/null
@@ -1,2 +0,0 @@
-* Implement pas_book_factory_activate
-* Authentication \ No newline at end of file
diff --git a/addressbook/backend/pas/evolutionperson.schema b/addressbook/backend/pas/evolutionperson.schema
deleted file mode 100644
index 29270555ea..0000000000
--- a/addressbook/backend/pas/evolutionperson.schema
+++ /dev/null
@@ -1,216 +0,0 @@
-#
-# Depends upon
-# Definition of an X.500 Attribute Type and an Object Class to Hold
-# Uniform Resource Identifiers (URIs) [RFC2079]
-# (core.schema)
-#
-# A Summary of the X.500(96) User Schema for use with LDAPv3 [RFC2256]
-# (core.schema)
-#
-# The COSINE and Internet X.500 Schema [RFC1274] (cosine.schema)
-#
-# The Internet Organizational Person Schema (inetorgperson)
-#
-# OIDs are broken up into the following:
-# 1.3.6.1.4.1.8506.1.?
-# .1 Syntaxes
-# .2 Attributes
-# .3 Objectclasses
-
-# primaryPhone
-attributetype ( 1.3.6.1.4.1.8506.1.2.1
- NAME 'primaryPhone'
- DESC 'preferred phone number used to contact a person'
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
- SINGLE-VALUE )
-
-# carPhone
-attributetype ( 1.3.6.1.4.1.8506.1.2.2
- NAME 'carPhone'
- DESC 'car phone telephone number of the person'
- EQUALITY telephoneNumberMatch
- SUBSTR telephoneNumberSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
- SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.3
- NAME ( 'homeFacsimileTelephoneNumber' 'homeFax' )
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.22 )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.4
- NAME 'otherPhone'
- EQUALITY telephoneNumberMatch
- SUBSTR telephoneNumberSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.5
- NAME 'businessRole'
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.6
- NAME 'managerName'
- SUP name )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.7
- NAME 'assistantName'
- SUP name )
-
-# spouseName
-# single valued (/me smirks)
-attributetype ( 1.3.6.1.4.1.8506.1.2.8
- NAME 'spouseName'
- SUP name
- SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.9
- NAME 'otherPostalAddress'
- EQUALITY caseIgnoreListMatch
- SUBSTR caseIgnoreListSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.41 )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.10
- NAME ( 'mailer' 'mua' )
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32} )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.11
- NAME ( 'birthDate' 'dob' )
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.12
- NAME 'anniversary'
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{128} )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.13
- NAME 'note'
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024} )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.14
- NAME 'evolutionArbitrary'
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} )
- )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.15
- NAME 'fileAs'
- SUP name )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.16
- NAME 'assistantPhone'
- EQUALITY telephoneNumberMatch
- SUBSTR telephoneNumberSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.17
- NAME 'companyPhone'
- EQUALITY telephoneNumberMatch
- SUBSTR telephoneNumberSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.18
- NAME 'callbackPhone'
- EQUALITY telephoneNumberMatch
- SUBSTR telephoneNumberSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.19
- NAME ( 'otherFacsimileTelephoneNumber' 'otherFax' )
- EQUALITY telephoneNumberMatch
- SUBSTR telephoneNumberSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.20
- NAME 'radio'
- EQUALITY telephoneNumberMatch
- SUBSTR telephoneNumberSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.21
- NAME 'telex'
- EQUALITY telephoneNumberMatch
- SUBSTR telephoneNumberSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.22
- NAME 'tty'
- EQUALITY telephoneNumberMatch
- SUBSTR telephoneNumberSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
-
-# deprecated - use the multivalued category
-attributetype ( 1.3.6.1.4.1.8506.1.2.23
- NAME 'categories'
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.24
- NAME 'contact'
- EQUALITY distinguishedNameMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.25
- NAME 'listName'
- SUP name
- SINGLE-VALUE )
-
-# deprecated - use calEntry and its attributes from RFC 2739
-attributetype ( 1.3.6.1.4.1.8506.1.2.26
- NAME 'calendarURI'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE )
-
-# deprecated - use calEntry and its attributes from RFC 2739
-attributetype ( 1.3.6.1.4.1.8506.1.2.27
- NAME 'freeBusyURI'
- EQUALITY caseExactIA5Match
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
- SINGLE-VALUE )
-
-attributetype ( 1.3.6.1.4.1.8506.1.2.28
- NAME 'category'
- EQUALITY caseIgnoreMatch
- SUBSTR caseIgnoreSubstringsMatch
- SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{4096} )
-
-
-# evolutionPerson
-objectclass ( 1.3.6.1.4.1.8506.1.3.1
- NAME 'evolutionPerson'
- DESC 'Objectclass geared to Evolution Usage'
- SUP inetOrgPerson
- STRUCTURAL
- MAY (
- fileAs $ primaryPhone $ carPhone $ homeFacsimileTelephoneNumber $
- otherPhone $ businessRole $ managerName $ assistantName $ assistantPhone $
- otherPostalAddress $ mailer $ birthDate $ anniversary $ spouseName $
- note $ companyPhone $ callbackPhone $ otherFacsimileTelephoneNumber $
- radio $ telex $ tty $ categories $ category $ calendarURI $ freeBusyURI )
- )
-
-# evolutionPersonList
-objectclass ( 1.3.6.1.4.1.8506.1.3.2
- NAME 'evolutionPersonList'
- DESC 'Objectclass geared to Evolution Contact Lists'
- SUP top
- STRUCTURAL
- MUST (
- listName )
- MAY (
- mail $ contact )
- )
diff --git a/addressbook/backend/pas/pas-backend-card-sexp.c b/addressbook/backend/pas/pas-backend-card-sexp.c
deleted file mode 100644
index f747189bba..0000000000
--- a/addressbook/backend/pas/pas-backend-card-sexp.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * pas-backend-card-sexp.c
- * Copyright 1999, 2000, 2001, Ximian, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License, version 2, as published by the Free Software Foundation.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library 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 "pas-backend-card-sexp.h"
-
-#include <string.h>
-#include <e-util/e-sexp.h>
-#include <ebook/e-card-simple.h>
-#include <gal/widgets/e-unicode.h>
-
-static GtkObjectClass *parent_class;
-
-typedef struct _SearchContext SearchContext;
-
-struct _PASBackendCardSExpPrivate {
- ESExp *search_sexp;
- SearchContext *search_context;
-};
-
-struct _SearchContext {
- ECardSimple *card;
-};
-
-static gboolean
-compare_email (ECardSimple *card, 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);
-
- if (email && compare(email, str))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-compare_phone (ECardSimple *card, const char *str,
- char *(*compare)(const char*, const char*))
-{
- int i;
-
- 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);
-
- if (phone && compare(phone->number, str))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-compare_name (ECardSimple *card, 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);
- if (name && compare (name, str))
- return TRUE;
-
- name = e_card_simple_get_const (card, E_CARD_SIMPLE_FIELD_FAMILY_NAME);
- if (name && compare (name, str))
- return TRUE;
-
- return FALSE;
-}
-
-static gboolean
-compare_address (ECardSimple *card, const char *str,
- char *(*compare)(const char*, const char*))
-{
- g_warning("address searching not implemented\n");
- return FALSE;
-}
-
-static gboolean
-compare_category (ECardSimple *card, const char *str,
- char *(*compare)(const char*, const char*))
-{
- EList *categories;
- EIterator *iterator;
- ECard *ecard;
- gboolean ret_val = FALSE;
-
- gtk_object_get (GTK_OBJECT (card),
- "card", &ecard,
- NULL);
- gtk_object_get (GTK_OBJECT (ecard),
- "category_list", &categories,
- NULL);
-
- for (iterator = e_list_get_iterator(categories); e_iterator_is_valid (iterator); e_iterator_next (iterator)) {
- const char *category = e_iterator_get (iterator);
-
- if (compare(category, str)) {
- ret_val = TRUE;
- break;
- }
- }
-
- gtk_object_unref (GTK_OBJECT (iterator));
- e_card_free_empty_lists (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;
-
- gtk_object_get (GTK_OBJECT (card),
- "card", &ecard,
- NULL);
- gtk_object_get (GTK_OBJECT (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);
-
- if (compare(arbitrary->key, str)) {
- ret_val = TRUE;
- break;
- }
- }
-
- gtk_object_unref (GTK_OBJECT (iterator));
- e_card_free_empty_lists (ecard);
- return ret_val;
-}
-
-static struct prop_info {
- ECardSimpleField 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,
- 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 )
-};
-static int num_prop_infos = sizeof(prop_info_table) / sizeof(prop_info_table[0]);
-
-static ESExpResult *
-entry_compare(SearchContext *ctx, struct _ESExp *f,
- int argc, struct _ESExpResult **argv,
- char *(*compare)(const char*, const char*))
-{
- ESExpResult *r;
- int truth = FALSE;
-
- if (argc == 2
- && argv[0]->type == ESEXP_RES_STRING
- && argv[1]->type == ESEXP_RES_STRING) {
- char *propname;
- struct prop_info *info = NULL;
- int i;
- gboolean any_field;
-
- propname = argv[0]->value.string;
-
- any_field = !strcmp(propname, "x-evolution-any-field");
- for (i = 0; i < num_prop_infos; i ++) {
- if (any_field
- || !strcmp (prop_info_table[i].query_prop, propname)) {
- 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 */
-
- prop = e_card_get_id (ctx->card->card);
-
- if (prop && compare(prop, argv[1]->value.string)) {
- truth = TRUE;
- }
- if ((!prop) && compare("", argv[1]->value.string)) {
- truth = TRUE;
- }
- }
-
- /* if we're looking at all fields and find a match,
- or if we're just looking at this one field,
- break. */
- if ((any_field && truth)
- || !any_field)
- break;
- }
- }
-
- }
- r = e_sexp_result_new(f, ESEXP_RES_BOOL);
- r->value.bool = truth;
-
- return r;
-}
-
-static ESExpResult *
-func_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- SearchContext *ctx = data;
-
- return entry_compare (ctx, f, argc, argv, (char *(*)(const char*, const char*)) e_utf8_strstrcase);
-}
-
-static char *
-is_helper (const char *s1, const char *s2)
-{
- if (!strcasecmp(s1, s2))
- return (char*)s1;
- else
- return NULL;
-}
-
-static ESExpResult *
-func_is(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- SearchContext *ctx = data;
-
- return entry_compare (ctx, f, argc, argv, is_helper);
-}
-
-static char *
-endswith_helper (const char *s1, const char *s2)
-{
- char *p;
- if ((p = (char*)e_utf8_strstrcase(s1, s2))
- && (strlen(p) == strlen(s2)))
- return p;
- else
- return NULL;
-}
-
-static ESExpResult *
-func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- SearchContext *ctx = data;
-
- return entry_compare (ctx, f, argc, argv, endswith_helper);
-}
-
-static char *
-beginswith_helper (const char *s1, const char *s2)
-{
- char *p;
- if ((p = (char*)e_utf8_strstrcase(s1, s2))
- && (p == s1))
- return p;
- else
- return NULL;
-}
-
-static ESExpResult *
-func_beginswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- SearchContext *ctx = data;
-
- return entry_compare (ctx, f, argc, argv, beginswith_helper);
-}
-
-/* '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[] = {
- { "contains", func_contains, 0 },
- { "is", func_is, 0 },
- { "beginswith", func_beginswith, 0 },
- { "endswith", func_endswith, 0 },
-};
-
-gboolean
-pas_backend_card_sexp_match_vcard (PASBackendCardSExp *sexp, const char *vcard)
-{
- ECard *card;
- ESExpResult *r;
- gboolean retval;
-
- card = e_card_new ((char*)vcard);
- sexp->priv->search_context->card = e_card_simple_new (card);
- gtk_object_unref(GTK_OBJECT(card));
-
- /* if it's not a valid vcard why is it in our db? :) */
- if (!sexp->priv->search_context->card)
- return FALSE;
-
- r = e_sexp_eval(sexp->priv->search_sexp);
-
- retval = (r && r->type == ESEXP_RES_BOOL && r->value.bool);
-
- gtk_object_unref(GTK_OBJECT(sexp->priv->search_context->card));
-
- e_sexp_result_free(sexp->priv->search_sexp, r);
-
- return retval;
-}
-
-
-
-/**
- * pas_backend_card_sexp_new:
- */
-PASBackendCardSExp *
-pas_backend_card_sexp_new (const char *text)
-{
- PASBackendCardSExp *sexp = gtk_type_new (pas_backend_card_sexp_get_type ());
- int esexp_error;
- int i;
-
- sexp->priv->search_sexp = e_sexp_new();
-
- for(i=0;i<sizeof(symbols)/sizeof(symbols[0]);i++) {
- 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 {
- e_sexp_add_function(sexp->priv->search_sexp, 0, symbols[i].name,
- symbols[i].func, sexp->priv->search_context);
- }
- }
-
- e_sexp_input_text(sexp->priv->search_sexp, text, strlen(text));
- esexp_error = e_sexp_parse(sexp->priv->search_sexp);
-
- if (esexp_error == -1) {
- gtk_object_unref (GTK_OBJECT (sexp));
- sexp = NULL;
- }
-
- return sexp;
-}
-
-static void
-pas_backend_card_sexp_destroy (GtkObject *object)
-{
- PASBackendCardSExp *sexp = PAS_BACKEND_CARD_SEXP (object);
- e_sexp_unref(sexp->priv->search_sexp);
-
- g_free (sexp->priv->search_context);
- g_free (sexp->priv);
-
- GTK_OBJECT_CLASS (parent_class)->destroy (object);
-}
-
-static void
-pas_backend_card_sexp_class_init (PASBackendCardSExpClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
-
- parent_class = gtk_type_class (gtk_object_get_type ());
-
- /* Set the virtual methods. */
-
- object_class->destroy = pas_backend_card_sexp_destroy;
-}
-
-static void
-pas_backend_card_sexp_init (PASBackendCardSExp *sexp)
-{
- PASBackendCardSExpPrivate *priv;
-
- priv = g_new0 (PASBackendCardSExpPrivate, 1);
-
- sexp->priv = priv;
- priv->search_context = g_new (SearchContext, 1);
-}
-
-/**
- * pas_backend_card_sexp_get_type:
- */
-GtkType
-pas_backend_card_sexp_get_type (void)
-{
- static GtkType type = 0;
-
- if (! type) {
- GtkTypeInfo info = {
- "PASBackendCardSExp",
- sizeof (PASBackendCardSExp),
- sizeof (PASBackendCardSExpClass),
- (GtkClassInitFunc) pas_backend_card_sexp_class_init,
- (GtkObjectInitFunc) pas_backend_card_sexp_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (gtk_object_get_type (), &info);
- }
-
- return type;
-}
diff --git a/addressbook/backend/pas/pas-backend-card-sexp.h b/addressbook/backend/pas/pas-backend-card-sexp.h
deleted file mode 100644
index ee51a75dab..0000000000
--- a/addressbook/backend/pas/pas-backend-card-sexp.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * pas-backend-card-sexp.h
- * Copyright 2000, 2001, Ximian, Inc.
- *
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License, version 2, as published by the Free Software Foundation.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library 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 __PAS_BACKEND_CARD_SEXP_H__
-#define __PAS_BACKEND_CARD_SEXP_H__
-
-#include <gtk/gtk.h>
-
-typedef struct _PASBackendCardSExpPrivate PASBackendCardSExpPrivate;
-
-typedef struct {
- GtkObject parent_object;
- PASBackendCardSExpPrivate *priv;
-} PASBackendCardSExp;
-
-typedef struct {
- GtkObjectClass parent_class;
-} PASBackendCardSExpClass;
-
-PASBackendCardSExp *pas_backend_card_sexp_new (const char *text);
-GtkType pas_backend_card_sexp_get_type (void);
-
-gboolean pas_backend_card_sexp_match_vcard (PASBackendCardSExp *sexp, const char *vcard);
-
-#define PAS_BACKEND_CARD_SEXP_TYPE (pas_backend_card_sexp_get_type ())
-#define PAS_BACKEND_CARD_SEXP(o) (GTK_CHECK_CAST ((o), PAS_BACKEND_CARD_SEXP_TYPE, PASBackendCardSExp))
-#define PAS_BACKEND_CARD_SEXP_CLASS(k) (GTK_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendCardSExpClass))
-#define PAS_IS_BACKEND_CARD_SEXP(o) (GTK_CHECK_TYPE ((o), PAS_BACKEND_CARD_SEXP_TYPE))
-#define PAS_IS_BACKEND_CARD_SEXP_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), PAS_BACKEND_CARD_SEXP_TYPE))
-
-#endif /* __PAS_BACKEND_CARD_SEXP_H__ */
diff --git a/addressbook/backend/pas/pas-backend-file.c b/addressbook/backend/pas/pas-backend-file.c
deleted file mode 100644
index 29e6ab59b4..0000000000
--- a/addressbook/backend/pas/pas-backend-file.c
+++ /dev/null
@@ -1,1703 +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.
- */
-
-#include "config.h"
-#include "pas-backend-file.h"
-
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <time.h>
-#include <db.h>
-#include <sys/stat.h>
-
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-
-#include <e-util/e-db3-utils.h>
-
-#if DB_VERSION_MAJOR != 3 || \
- DB_VERSION_MINOR != 1 || \
- DB_VERSION_PATCH != 17
-#error Including wrong DB3. Need libdb 3.1.17.
-#endif
-
-#include <gtk/gtksignal.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-util.h>
-#include <gal/util/e-util.h>
-#include <gal/widgets/e-unicode.h>
-
-#include <ebook/e-card-simple.h>
-#include <e-util/e-dbhash.h>
-#include <e-util/e-db3-utils.h>
-#include "pas-book.h"
-#include "pas-card-cursor.h"
-#include "pas-backend-card-sexp.h"
-#include "pas-backend-summary.h"
-
-#define PAS_BACKEND_FILE_VERSION_NAME "PAS-DB-VERSION"
-#define PAS_BACKEND_FILE_VERSION "0.2"
-
-#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;
-
-struct _PASBackendFilePrivate {
- GList *clients;
- gboolean loaded;
- char *uri;
- char *filename;
- DB *file_db;
- EList *book_views;
- gboolean writable;
- 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)
-{
- memset (dbt, 0, sizeof (*dbt));
- dbt->data = (void*)str;
- dbt->size = strlen (str) + 1;
-}
-
-static void
-build_summary (PASBackendFilePrivate *bfpriv)
-{
- DB *db = bfpriv->file_db;
- DBC *dbc;
- int db_error;
- DBT id_dbt, vcard_dbt;
-
- 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");
- }
-
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
- memset (&id_dbt, 0, sizeof (id_dbt));
- 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)) {
-
- pas_backend_summary_add_card (bfpriv->summary, vcard_dbt.data);
- }
-
- db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
-
- }
-}
-
-static void
-do_summary_query (PASBackendFile *bf,
- PASBackendFileBookView *view,
- gboolean completion_search)
-{
- GPtrArray *ids = pas_backend_summary_search (bf->priv->summary, view->search);
- 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
- can have more than 3 email addresses and the
- summary only stores 3. */
-
- if (completion_search) {
- vcard = pas_backend_summary_get_summary_vcard (bf->priv->summary,
- id);
- }
- else {
-#endif
- string_to_dbt (id, &id_dbt);
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
-
- db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
-
- if (db_error == 0)
- vcard = g_strdup (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)
- gtk_object_ref(GTK_OBJECT(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)
- gtk_object_unref (GTK_OBJECT(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;
-}
-
-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(GtkObject *object, gpointer data)
-{
- 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(GtkObject *object, gpointer data)
-{
- 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 == PAS_BOOK_VIEW(object)) {
- e_iterator_delete(iterator);
- success = TRUE;
- break;
- }
- }
- if (!success)
- g_warning ("Failed to remove from book_views list");
- gtk_object_unref(GTK_OBJECT(iterator));
-
- bonobo_object_unref(BONOBO_OBJECT(book));
-}
-
-static char *
-pas_backend_file_create_unique_id (char *vcard)
-{
- /* 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++);
-}
-
-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 void
-pas_backend_file_search (PASBackendFile *bf,
- PASBook *book,
- const PASBackendFileBookView *cnstview,
- gboolean completion_search)
-{
- PASBackendFileBookView *view = (PASBackendFileBookView *)cnstview;
- gboolean search_needed;
-
- if (!bf->priv->loaded)
- return;
-
- search_needed = TRUE;
-
- if ( ! strcmp (view->search, "(contains \"x-evolution-any-field\" \"\")"))
- search_needed = FALSE;
-
- if (search_needed)
- pas_book_view_notify_status_message (view->book_view, _("Searching..."));
- else
- pas_book_view_notify_status_message (view->book_view, _("Loading..."));
-
- if (view->card_sexp) {
- gtk_object_unref (GTK_OBJECT(view->card_sexp));
- view->card_sexp = NULL;
- }
-
- if (pas_backend_summary_is_summary_query (bf->priv->summary, view->search)) {
- do_summary_query (bf, view, completion_search);
- }
- else {
- gint card_count = 0, card_threshold = 20, card_threshold_max = 3000;
- int db_error = 0;
- GList *cards = NULL;
- DB *db = bf->priv->file_db;
- DBC *dbc;
- DBT id_dbt, vcard_dbt;
- int file_version_name_len;
-
- 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;
- }
-
- file_version_name_len = strlen (PAS_BACKEND_FILE_VERSION_NAME);
-
- db_error = db->cursor (db, NULL, &dbc, 0);
-
- memset (&id_dbt, 0, sizeof (id_dbt));
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
-
- if (db_error != 0) {
- g_warning ("pas_backend_file_search: 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 != file_version_name_len+1
- || strcmp (id_dbt.data, PAS_BACKEND_FILE_VERSION_NAME)) {
- char *vcard_string = vcard_dbt.data;
-
- /* check if the vcard matches the search sexp */
- if ((!search_needed) || vcard_matches_search (view, vcard_string)) {
- cards = g_list_prepend (cards, g_strdup (vcard_string));
- 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);
- }
- }
- }
-
- db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
- }
- dbc->c_close (dbc);
-
- if (db_error != DB_NOTFOUND) {
- g_warning ("pas_backend_file_search: error building list\n");
- }
- }
-
- 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);
-
- /*
- ** It's fine to do this now since the data has been handed off.
- */
- g_list_foreach (cards, (GFunc)g_free, NULL);
- g_list_free (cards);
- }
-}
-
-static void
-pas_backend_file_changes_foreach_key (const char *key, gpointer user_data)
-{
- 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));
-
- if (!bf->priv->loaded)
- return;
-
- /* 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);
- gtk_object_set (GTK_OBJECT (card), "last_use", NULL, "use_score", 0.0, NULL);
- vcard_string = e_card_get_vcard_assume_utf8 (card);
- gtk_object_unref (GTK_OBJECT (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 (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;
- char *vcard;
- char *ret_val;
-
- id = pas_backend_file_create_unique_id (vcard_req);
-
- 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);
-
- string_to_dbt (vcard, &vcard_dbt);
-
- db_error = db->put (db, NULL, &id_dbt, &vcard_dbt, 0);
-
- 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;
- }
-
- gtk_object_unref(GTK_OBJECT(card));
- card = NULL;
-
- if (vcard_ptr && ret_val)
- *vcard_ptr = vcard;
- else
- g_free (vcard);
-
- return ret_val;
-}
-
-static void
-pas_backend_file_process_create_card (PASBackend *backend,
- PASBook *book,
- PASCreateCardRequest *req)
-{
- 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));
- }
- }
- gtk_object_unref(GTK_OBJECT(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);
- }
- else {
- /* XXX need a different call status for this case, i
- think */
- pas_book_respond_create (
- book,
- GNOME_Evolution_Addressbook_BookListener_CardNotFound,
- "");
- }
-}
-
-static void
-pas_backend_file_process_remove_card (PASBackend *backend,
- PASBook *book,
- PASRemoveCardRequest *req)
-{
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- DB *db = bf->priv->file_db;
- DBT id_dbt, vcard_dbt;
- int db_error;
- EIterator *iterator;
- char *vcard_string;
- const char *id;
-
- id = req->id;
- string_to_dbt (id, &id_dbt);
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
-
- db_error = db->get (db, NULL, &id_dbt, &vcard_dbt, 0);
- if (0 != db_error) {
- pas_book_respond_remove (
- book,
- GNOME_Evolution_Addressbook_BookListener_CardNotFound);
- return;
- }
-
- db_error = db->del (db, NULL, &id_dbt, 0);
- if (0 != db_error) {
- pas_book_respond_remove (
- book,
- GNOME_Evolution_Addressbook_BookListener_CardNotFound);
- return;
- }
-
- db_error = db->sync (db, 0);
- if (db_error != 0)
- g_warning ("db->sync failed.\n");
-
-
- vcard_string = vcard_dbt.data;
- for (iterator = e_list_get_iterator (bf->priv->book_views); e_iterator_is_valid(iterator); e_iterator_next(iterator)) {
- const PASBackendFileBookView *view = e_iterator_get(iterator);
- if (vcard_matches_search (view, vcard_string)) {
- bonobo_object_ref (BONOBO_OBJECT (view->book_view));
- pas_book_view_notify_remove (view->book_view, req->id);
- pas_book_view_notify_complete (view->book_view, GNOME_Evolution_Addressbook_BookViewListener_Success);
- bonobo_object_unref (BONOBO_OBJECT (view->book_view));
- }
- }
- gtk_object_unref(GTK_OBJECT(iterator));
-
- pas_book_respond_remove (
- book,
- GNOME_Evolution_Addressbook_BookListener_Success);
- pas_backend_summary_remove_card (bf->priv->summary, id);
-}
-
-static void
-pas_backend_file_process_modify_card (PASBackend *backend,
- PASBook *book,
- PASModifyCardRequest *req)
-{
- 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;
-
- /* create a new ecard from the request data */
- card = e_card_new(req->vcard);
- id = e_card_get_id(card);
-
- /* This is disgusting, but for a time cards were added with
- ID's that are no longer used (they contained both the uri
- and the id.) If we recognize it as a uri (file:///...) trim
- off everything before the last '/', and use that as the
- id.*/
- if (!strncmp (id, "file:///", strlen ("file:///"))) {
- lookup_id = strrchr (id, '/') + 1;
- }
- else
- lookup_id = id;
-
- string_to_dbt (lookup_id, &id_dbt);
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
-
- /* 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);
-
- string_to_dbt (req->vcard, &vcard_dbt);
-
- db_error = db->put (db, NULL, &id_dbt, &vcard_dbt, 0);
-
- if (0 == db_error) {
- db_error = db->sync (db, 0);
- 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 (view->book_view, id);
-
- 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);
-
- CORBA_exception_free (&ev);
- }
-
- gtk_object_unref(GTK_OBJECT(iterator));
-
- pas_book_respond_modify (
- book,
- GNOME_Evolution_Addressbook_BookListener_Success);
-
- 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);
- }
-
- g_free(old_vcard_string);
-
- gtk_object_unref(GTK_OBJECT(card));
-}
-
-static void
-pas_backend_file_build_cards_list(PASBackend *backend,
- PASBackendFileCursorPrivate *cursor_data,
- char *search)
-{
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- DB *db = bf->priv->file_db;
- DBC *dbc;
- int db_error;
- DBT id_dbt, vcard_dbt;
- PASBackendCardSExp *card_sexp = NULL;
- gboolean search_needed;
-
- cursor_data->elements = NULL;
-
- search_needed = TRUE;
-
- if (!strcmp (search, "(contains \"x-evolution-any-field\" \"\")"))
- 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");
-
- 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");
- }
-
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
- memset (&id_dbt, 0, sizeof (id_dbt));
- 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)) {
-
- 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));
- }
- }
-
- db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
-
- }
-
- 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);
- }
-}
-
-static void
-pas_backend_file_process_get_vcard (PASBackend *backend,
- PASBook *book,
- PASGetVCardRequest *req)
-{
- 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);
-
- if (db_error == 0) {
- card = vcard_dbt.data;
- status = GNOME_Evolution_Addressbook_BookListener_Success;
- } else {
- card = NULL;
- status = GNOME_Evolution_Addressbook_BookListener_CardNotFound;
- }
-
- pas_book_respond_get_vcard (book,
- status,
- card);
-}
-
-static void
-pas_backend_file_process_get_cursor (PASBackend *backend,
- PASBook *book,
- PASGetCursorRequest *req)
-{
- /*
- 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);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("pas_backend_file_process_get_cursor: Exception reffing "
- "corba book.\n");
- }
-
- CORBA_exception_free(&ev);
-
- cursor = pas_card_cursor_new(get_length,
- get_nth,
- cursor_data);
-
- gtk_signal_connect(GTK_OBJECT(cursor), "destroy",
- GTK_SIGNAL_FUNC(cursor_destroy), cursor_data);
-
- pas_book_respond_get_cursor (
- book,
- (db_error == 0
- ? GNOME_Evolution_Addressbook_BookListener_Success
- : GNOME_Evolution_Addressbook_BookListener_CardNotFound),
- cursor);
-}
-
-static void
-pas_backend_file_process_get_book_view (PASBackend *backend,
- PASBook *book,
- PASGetBookViewRequest *req)
-{
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- PASBookView *book_view;
- PASBackendFileBookView view;
- EIterator *iterator;
-
- g_return_if_fail (req->listener != NULL);
-
- bonobo_object_ref(BONOBO_OBJECT(book));
-
- book_view = pas_book_view_new (req->listener);
-
- gtk_signal_connect(GTK_OBJECT(book_view), "destroy",
- GTK_SIGNAL_FUNC(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);
-
- iterator = e_list_get_iterator(bf->priv->book_views);
- e_iterator_last(iterator);
- pas_backend_file_search (bf, book, e_iterator_get(iterator), FALSE);
- gtk_object_unref(GTK_OBJECT(iterator));
-}
-
-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;
-
- g_return_if_fail (req->listener != NULL);
-
- bonobo_object_ref(BONOBO_OBJECT(book));
-
- book_view = pas_book_view_new (req->listener);
-
- gtk_signal_connect(GTK_OBJECT(book_view), "destroy",
- GTK_SIGNAL_FUNC(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_completion_view (book,
- (book_view != NULL
- ? GNOME_Evolution_Addressbook_BookListener_Success
- : GNOME_Evolution_Addressbook_BookListener_CardNotFound /* XXX */),
- book_view);
-
- iterator = e_list_get_iterator(bf->priv->book_views);
- e_iterator_last(iterator);
- pas_backend_file_search (bf, book, e_iterator_get(iterator), TRUE);
- gtk_object_unref(GTK_OBJECT(iterator));
-}
-
-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;
-
- g_return_if_fail (req->listener != NULL);
-
- bonobo_object_ref(BONOBO_OBJECT(book));
-
- book_view = pas_book_view_new (req->listener);
-
- gtk_signal_connect(GTK_OBJECT(book_view), "destroy",
- GTK_SIGNAL_FUNC(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);
-
- iterator = e_list_get_iterator(bf->priv->book_views);
- e_iterator_last(iterator);
- pas_backend_file_changes (bf, book, e_iterator_get(iterator));
- gtk_object_unref(GTK_OBJECT(iterator));
-}
-
-static void
-pas_backend_file_process_check_connection (PASBackend *backend,
- PASBook *book,
- PASCheckConnectionRequest *req)
-{
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
-
- pas_book_report_connection (book, bf->priv->file_db != NULL);
-}
-
-static char *
-pas_backend_file_extract_path_from_uri (const char *uri)
-{
- g_assert (strncasecmp (uri, "file:", 5) == 0);
-
- return g_strdup (uri + 5);
-}
-
-static void
-pas_backend_file_process_authenticate_user (PASBackend *backend,
- PASBook *book,
- PASAuthenticateUserRequest *req)
-{
- pas_book_respond_authenticate_user (book,
- GNOME_Evolution_Addressbook_BookListener_Success);
-}
-
-static void
-pas_backend_file_process_get_supported_fields (PASBackend *backend,
- PASBook *book,
- PASGetSupportedFieldsRequest *req)
-{
- EList *fields = e_list_new ((EListCopyFunc)g_strdup, (EListFreeFunc)g_free, NULL);
- ECardSimple *simple;
- ECard *card;
- int i;
-
- /* we support everything, so instantiate an e-card, and loop
- through all fields, adding their ecard_fields. */
-
- 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));
-
- gtk_object_unref (GTK_OBJECT (card));
- gtk_object_unref (GTK_OBJECT (simple));
-
- pas_book_respond_get_supported_fields (book,
- GNOME_Evolution_Addressbook_BookListener_Success,
- fields);
-}
-
-static void
-pas_backend_file_process_client_requests (PASBook *book)
-{
- PASBackend *backend;
- PASRequest *req;
-
- backend = pas_book_get_backend (book);
-
- req = pas_book_pop_request (book);
- if (req == NULL)
- return;
-
- switch (req->op) {
- case CreateCard:
- pas_backend_file_process_create_card (backend, book, (PASCreateCardRequest*)req);
- break;
-
- case RemoveCard:
- pas_backend_file_process_remove_card (backend, book, (PASRemoveCardRequest*)req);
- break;
-
- case ModifyCard:
- pas_backend_file_process_modify_card (backend, book, (PASModifyCardRequest*)req);
- break;
-
- case CheckConnection:
- pas_backend_file_process_check_connection (backend, book, (PASCheckConnectionRequest*)req);
- break;
-
- case GetVCard:
- pas_backend_file_process_get_vcard (backend, book, (PASGetVCardRequest*)req);
- break;
-
- case GetCursor:
- pas_backend_file_process_get_cursor (backend, book, (PASGetCursorRequest*)req);
- break;
-
- case GetBookView:
- pas_backend_file_process_get_book_view (backend, book, (PASGetBookViewRequest*)req);
- break;
-
- case GetCompletionView:
- pas_backend_file_process_get_completion_view (backend, book, (PASGetCompletionViewRequest*)req);
- break;
-
- case GetChanges:
- pas_backend_file_process_get_changes (backend, book, (PASGetChangesRequest*)req);
- break;
-
- case AuthenticateUser:
- pas_backend_file_process_authenticate_user (backend, book, (PASAuthenticateUserRequest*)req);
- break;
-
- case GetSupportedFields:
- pas_backend_file_process_get_supported_fields (backend, book, (PASGetSupportedFieldsRequest*)req);
- break;
- }
-
- pas_book_free_request (req);
-}
-
-static void
-pas_backend_file_book_destroy_cb (PASBook *book, gpointer data)
-{
- PASBackendFile *backend;
-
- backend = PAS_BACKEND_FILE (data);
-
- pas_backend_remove_client (PAS_BACKEND (backend), book);
-}
-
-/*
-** versions:
-**
-** 0.0 just a list of cards
-**
-** 0.1 same as 0.0, but with the version tag
-**
-** 0.2 not a real format upgrade, just a hack to fix broken ids caused
-** by a bug in early betas, but we only need to convert them if
-** the previous version is 0.1, since the bug existed after 0.1
-** came about.
-*/
-static gboolean
-pas_backend_file_upgrade_db (PASBackendFile *bf, char *old_version)
-{
- DB *db = bf->priv->file_db;
- int db_error;
- DBT version_name_dbt, version_dbt;
-
- if (strcmp (old_version, "0.0")
- && strcmp (old_version, "0.1")) {
- g_warning ("unsupported version '%s' found in PAS backend file\n",
- old_version);
- return FALSE;
- }
-
- if (!strcmp (old_version, "0.1")) {
- /* we just loop through all the cards in the db,
- giving them valid ids if they don't have them */
- DBT id_dbt, vcard_dbt;
- DBC *dbc;
- int card_failed = 0;
-
- db_error = db->cursor (db, NULL, &dbc, 0);
- if (db_error != 0) {
- g_warning ("unable to get cursor");
- return FALSE;
- }
-
- memset (&id_dbt, 0, sizeof (id_dbt));
- memset (&vcard_dbt, 0, sizeof (vcard_dbt));
-
- db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_FIRST);
-
- 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;
-
- card = e_card_new (vcard_dbt.data);
-
- /* the cards we're looking for are
- created with a normal id dbt, but
- with the id field in the vcard set
- 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))) {
- char *vcard;
-
- e_card_set_id (card, id_dbt.data);
-
- vcard = e_card_get_vcard (card);
- string_to_dbt (vcard, &vcard_dbt);
-
- db_error = db->put (db, NULL,
- &id_dbt, &vcard_dbt, 0);
-
- g_free (vcard);
-
- if (db_error != 0)
- card_failed++;
- }
-
- gtk_object_unref (GTK_OBJECT(card));
- }
-
- db_error = dbc->c_get(dbc, &id_dbt, &vcard_dbt, DB_NEXT);
- }
-
- if (card_failed) {
- g_warning ("failed to update %d cards\n", card_failed);
- return FALSE;
- }
- }
-
- string_to_dbt (PAS_BACKEND_FILE_VERSION_NAME, &version_name_dbt);
- string_to_dbt (PAS_BACKEND_FILE_VERSION, &version_dbt);
-
- db_error = db->put (db, NULL, &version_name_dbt, &version_dbt, 0);
- if (db_error == 0)
- return TRUE;
- else
- return FALSE;
-}
-
-static gboolean
-pas_backend_file_maybe_upgrade_db (PASBackendFile *bf)
-{
- DB *db = bf->priv->file_db;
- DBT version_name_dbt, version_dbt;
- int db_error;
- char *version;
- gboolean ret_val = TRUE;
-
- string_to_dbt (PAS_BACKEND_FILE_VERSION_NAME, &version_name_dbt);
- memset (&version_dbt, 0, sizeof (version_dbt));
-
- db_error = db->get (db, NULL, &version_name_dbt, &version_dbt, 0);
- if (db_error == 0) {
- /* success */
- version = g_strdup (version_dbt.data);
- }
- else {
- /* key was not in file */
- version = g_strdup ("0.0");
- }
-
- if (strcmp (version, PAS_BACKEND_FILE_VERSION))
- ret_val = pas_backend_file_upgrade_db (bf, version);
-
- g_free (version);
-
- 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) 236-0442\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
-pas_backend_file_load_uri (PASBackend *backend,
- const char *uri)
-{
- PASBackendFile *bf = PAS_BACKEND_FILE (backend);
- char *filename;
- gboolean writable = FALSE;
- int db_error;
- DB *db;
- int major, minor, patch;
- time_t db_mtime;
- struct stat sb;
- char *summary_filename;
-
- g_assert (bf->priv->loaded == FALSE);
-
- db_version (&major, &minor, &patch);
-
- if (major != 3 ||
- minor != 1 ||
- patch != 17) {
- g_warning ("Wrong version of libdb.");
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
- }
-
- filename = pas_backend_file_extract_path_from_uri (uri);
-
- db_error = e_db3_utils_maybe_recover (filename);
- if (db_error != 0)
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
-
- db_error = db_create (&db, NULL, 0);
- if (db_error != 0)
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
-
- db_error = db->open (db, filename, NULL, DB_HASH, 0, 0666);
-
- if (db_error == DB_OLD_VERSION) {
- db_error = e_db3_utils_upgrade_format (filename);
-
- if (db_error != 0)
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
-
- db_error = db->open (db, filename, NULL, DB_HASH, 0, 0666);
- }
-
- bf->priv->file_db = db;
-
- if (db_error == 0) {
- writable = TRUE;
- } else {
- 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;
-
- dir = g_dirname(filename);
- create_initial_file = g_concat_dir_and_file(dir, "create-initial");
-
- if (g_file_exists(create_initial_file)) {
- char *id;
- id = do_create(backend, INITIAL_VCARD, NULL);
- g_free (id);
- }
-
- g_free(create_initial_file);
- g_free(dir);
-
- writable = TRUE;
- }
- }
- }
-
- if (db_error != 0) {
- bf->priv->file_db = NULL;
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
- }
-
- bf->priv->writable = writable;
-
- if (pas_backend_file_maybe_upgrade_db (bf))
- bf->priv->loaded = TRUE;
- else {
- db->close (db, 0);
- bf->priv->file_db = NULL;
- bf->priv->writable = FALSE;
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
- }
-
- g_free(bf->priv->uri);
- bf->priv->uri = g_strdup (uri);
-
- g_free (bf->priv->filename);
- bf->priv->filename = filename;
-
- if (stat (bf->priv->filename, &sb) == -1) {
- db->close (db, 0);
- bf->priv->file_db = NULL;
- bf->priv->writable = FALSE;
- return GNOME_Evolution_Addressbook_BookListener_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);
-
- if (pas_backend_summary_is_up_to_date (bf->priv->summary, db_mtime) == FALSE
- || pas_backend_summary_load (bf->priv->summary) == FALSE ) {
- build_summary (bf->priv);
- }
-
- return GNOME_Evolution_Addressbook_BookListener_Success;
-}
-
-/* Get_uri handler for the addressbook file backend */
-static const char *
-pas_backend_file_get_uri (PASBackend *backend)
-{
- PASBackendFile *bf;
-
- bf = PAS_BACKEND_FILE (backend);
-
- g_return_val_if_fail (bf->priv->loaded, NULL);
- g_assert (bf->priv->uri != NULL);
-
- return bf->priv->uri;
-}
-
-static gboolean
-pas_backend_file_add_client (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener)
-{
- PASBackendFile *bf;
- PASBook *book;
-
- g_assert (backend != NULL);
- g_assert (PAS_IS_BACKEND_FILE (backend));
-
- bf = PAS_BACKEND_FILE (backend);
-
- book = pas_book_new (backend, listener);
-
- if (!book) {
- if (!bf->priv->clients)
- pas_backend_last_client_gone (backend);
-
- return FALSE;
- }
-
- gtk_signal_connect (GTK_OBJECT (book), "destroy",
- pas_backend_file_book_destroy_cb, backend);
-
- gtk_signal_connect (GTK_OBJECT (book), "requests_queued",
- pas_backend_file_process_client_requests, NULL);
-
- bf->priv->clients = g_list_prepend (
- bf->priv->clients, book);
-
- if (bf->priv->loaded) {
- pas_book_respond_open (
- book, GNOME_Evolution_Addressbook_BookListener_Success);
- if (bf->priv->writable)
- pas_book_report_writable (book, bf->priv->writable);
- } else {
- pas_book_respond_open (
- book, GNOME_Evolution_Addressbook_BookListener_OtherError);
- }
-
- bonobo_object_unref (BONOBO_OBJECT (book));
-
- return TRUE;
-}
-
-static void
-pas_backend_file_remove_client (PASBackend *backend,
- PASBook *book)
-{
- PASBackendFile *bf;
- GList *l;
- PASBook *lbook;
-
- g_return_if_fail (backend != NULL);
- g_return_if_fail (PAS_IS_BACKEND_FILE (backend));
- g_return_if_fail (book != NULL);
- g_return_if_fail (PAS_IS_BOOK (book));
-
- bf = PAS_BACKEND_FILE (backend);
-
- /* Find the book in the list of clients */
-
- for (l = bf->priv->clients; l; l = l->next) {
- lbook = PAS_BOOK (l->data);
-
- if (lbook == book)
- break;
- }
-
- g_assert (l != NULL);
-
- /* Disconnect */
-
- bf->priv->clients = g_list_remove_link (bf->priv->clients, l);
- g_list_free_1 (l);
-
- /* When all clients go away, notify the parent factory about it so that
- * it may decide whether to kill the backend or not.
- */
- if (!bf->priv->clients)
- pas_backend_last_client_gone (backend);
-}
-
-static char *
-pas_backend_file_get_static_capabilities (PASBackend *backend)
-{
- return g_strdup("local,do-initial-query,cache-completions");
-}
-
-static gboolean
-pas_backend_file_construct (PASBackendFile *backend)
-{
- g_assert (backend != NULL);
- g_assert (PAS_IS_BACKEND_FILE (backend));
-
- if (! pas_backend_construct (PAS_BACKEND (backend)))
- return FALSE;
-
- return TRUE;
-}
-
-/**
- * pas_backend_file_new:
- */
-PASBackend *
-pas_backend_file_new (void)
-{
- PASBackendFile *backend;
-
- backend = gtk_type_new (pas_backend_file_get_type ());
-
- if (! pas_backend_file_construct (backend)) {
- gtk_object_unref (GTK_OBJECT (backend));
-
- return NULL;
- }
-
- return PAS_BACKEND (backend);
-}
-
-static void
-pas_backend_file_destroy (GtkObject *object)
-{
- PASBackendFile *bf;
-
- bf = PAS_BACKEND_FILE (object);
-
- gtk_object_unref(GTK_OBJECT(bf->priv->book_views));
- gtk_object_unref(GTK_OBJECT(bf->priv->summary));
- g_free (bf->priv->uri);
- g_free (bf->priv->filename);
-
- g_free (bf->priv);
-
- GTK_OBJECT_CLASS (pas_backend_file_parent_class)->destroy (object);
-}
-
-static void
-pas_backend_file_class_init (PASBackendFileClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
- PASBackendClass *parent_class;
-
- pas_backend_file_parent_class = gtk_type_class (pas_backend_get_type ());
-
- parent_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->add_client = pas_backend_file_add_client;
- parent_class->remove_client = pas_backend_file_remove_client;
- parent_class->get_static_capabilities = pas_backend_file_get_static_capabilities;
-
- object_class->destroy = pas_backend_file_destroy;
-}
-
-static void
-pas_backend_file_init (PASBackendFile *backend)
-{
- PASBackendFilePrivate *priv;
-
- priv = g_new0 (PASBackendFilePrivate, 1);
- priv->loaded = FALSE;
- priv->clients = NULL;
- priv->book_views = e_list_new((EListCopyFunc) pas_backend_file_book_view_copy, (EListFreeFunc) pas_backend_file_book_view_free, NULL);
- priv->uri = NULL;
- priv->writable = FALSE;
-
- backend->priv = priv;
-}
-
-/**
- * pas_backend_file_get_type:
- */
-GtkType
-pas_backend_file_get_type (void)
-{
- static GtkType type = 0;
-
- if (! type) {
- GtkTypeInfo info = {
- "PASBackendFile",
- sizeof (PASBackendFile),
- sizeof (PASBackendFileClass),
- (GtkClassInitFunc) pas_backend_file_class_init,
- (GtkObjectInitFunc) pas_backend_file_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (pas_backend_get_type (), &info);
- }
-
- return type;
-}
diff --git a/addressbook/backend/pas/pas-backend-file.h b/addressbook/backend/pas/pas-backend-file.h
deleted file mode 100644
index 6c29c8b7a2..0000000000
--- a/addressbook/backend/pas/pas-backend-file.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2000, Ximian, Inc.
- */
-
-#ifndef __PAS_BACKEND_FILE_H__
-#define __PAS_BACKEND_FILE_H__
-
-#include <libgnome/gnome-defs.h>
-#include "pas-backend.h"
-
-typedef struct _PASBackendFilePrivate PASBackendFilePrivate;
-
-typedef struct {
- PASBackend parent_object;
- PASBackendFilePrivate *priv;
-} PASBackendFile;
-
-typedef struct {
- PASBackendClass parent_class;
-} PASBackendFileClass;
-
-PASBackend *pas_backend_file_new (void);
-GtkType pas_backend_file_get_type (void);
-
-#define PAS_BACKEND_FILE_TYPE (pas_backend_file_get_type ())
-#define PAS_BACKEND_FILE(o) (GTK_CHECK_CAST ((o), PAS_BACKEND_FILE_TYPE, PASBackendFile))
-#define PAS_BACKEND_FILE_CLASS(k) (GTK_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendFileClass))
-#define PAS_IS_BACKEND_FILE(o) (GTK_CHECK_TYPE ((o), PAS_BACKEND_FILE_TYPE))
-#define PAS_IS_BACKEND_FILE_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), PAS_BACKEND_FILE_TYPE))
-
-#endif /* ! __PAS_BACKEND_FILE_H__ */
-
diff --git a/addressbook/backend/pas/pas-backend-ldap.c b/addressbook/backend/pas/pas-backend-ldap.c
deleted file mode 100644
index 00dc5df4a2..0000000000
--- a/addressbook/backend/pas/pas-backend-ldap.c
+++ /dev/null
@@ -1,3521 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Author:
- * Chris Toshok (toshok@ximian.com)
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#define DEBUG
-
-#include "config.h"
-#include <fcntl.h>
-#include <gtk/gtksignal.h>
-
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-
-#ifdef DEBUG
-#define LDAP_DEBUG
-#define LDAP_DEBUG_ADD
-#endif
-#include <ldap.h>
-#ifdef DEBUG
-#undef LDAP_DEBUG
-#endif
-
-#if LDAP_VENDOR_VERSION > 20000
-#define OPENLDAP2
-#else
-#define OPENLDAP1
-#endif
-
-#ifdef OPENLDAP2
-#include <ldap_schema.h>
-#endif
-
-#include <sys/time.h>
-
-#include <e-util/e-sexp.h>
-#include <ebook/e-card-simple.h>
-
-#include "pas-backend-ldap.h"
-#include "pas-backend-card-sexp.h"
-#include "pas-book.h"
-#include "pas-card-cursor.h"
-
-#include <stdlib.h>
-
-typedef enum {
- PAS_BACKEND_LDAP_TLS_NO,
- PAS_BACKEND_LDAP_TLS_ALWAYS,
- PAS_BACKEND_LDAP_TLS_WHEN_POSSIBLE,
-} PASBackendLDAPUseTLS;
-
-/* interval for our poll_ldap timeout */
-#define LDAP_POLL_INTERVAL 20
-
-/* 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 */
-#define TOP "top"
-#define PERSON "person"
-#define ORGANIZATIONALPERSON "organizationalPerson"
-#define INETORGPERSON "inetOrgPerson"
-#define CALENTRY "calEntry"
-#define EVOLUTIONPERSON "evolutionPerson"
-
-static gchar *query_prop_to_ldap(gchar *query_prop);
-
-static PASBackendClass *pas_backend_ldap_parent_class;
-typedef struct _PASBackendLDAPCursorPrivate PASBackendLDAPCursorPrivate;
-typedef struct _PASBackendLDAPBookView PASBackendLDAPBookView;
-typedef struct LDAPOp LDAPOp;
-
-
-struct _PASBackendLDAPPrivate {
- char *uri;
- gboolean connected;
- GList *clients;
-
- gchar *ldap_host; /* the hostname of the server */
- int ldap_port; /* the port of the server */
- char *schema_dn; /* the base dn for schema information */
- gchar *ldap_rootdn; /* the base dn of our searches */
- int ldap_scope; /* the scope used for searches */
- int ldap_limit; /* the search limit */
- int ldap_timeout; /* the search timeout */
-
- gchar *auth_dn;
- gchar *auth_passwd;
-
- gboolean ldap_v3; /* TRUE if the server supports protocol
- revision 3 (necessary for TLS) */
- gboolean starttls; /* TRUE if the *library* supports
- starttls. will be false if openssl
- was not built into openldap. */
- PASBackendLDAPUseTLS use_tls;
-
- EList *book_views;
-
- LDAP *ldap;
-
- EList *supported_fields;
-
- /* whether or not there's support for the objectclass we need
- to store all our additional fields */
- gboolean evolutionPersonSupported;
- gboolean calEntrySupported;
- gboolean evolutionPersonChecked;
-
- gboolean writable;
-
- /* our operations */
- GHashTable *id_to_op;
- int active_ops;
- int poll_timeout;
-};
-
-struct _PASBackendLDAPCursorPrivate {
- PASBackend *backend;
- PASBook *book;
-
- GList *elements;
- long num_elements;
-};
-
-struct _PASBackendLDAPBookView {
- PASBookView *book_view;
- PASBackendLDAPPrivate *blpriv;
- gchar *search;
- PASBackendCardSExp *card_sexp;
- int limit;
-
- LDAPOp *search_op;
-};
-
-typedef void (*LDAPOpHandler)(LDAPOp *op, LDAPMessage *res);
-typedef void (*LDAPOpDtor)(LDAPOp *op);
-
-struct LDAPOp {
- LDAPOpHandler handler;
- LDAPOpDtor dtor;
- PASBackend *backend;
- PASBook *book;
- PASBookView *view;
- int id;
-};
-
-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 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 (ECardSimple *card, char **values);
-struct berval** homephone_ber (ECardSimple *card);
-static gboolean homephone_compare (ECardSimple *ecard1, ECardSimple *ecard2);
-
-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 (ECardSimple *card, char **values);
-struct berval** anniversary_ber (ECardSimple *card);
-static gboolean anniversary_compare (ECardSimple *ecard1, ECardSimple *ecard2);
-
-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 (ECardSimple *card, char **values);
-struct berval** category_ber (ECardSimple *card);
-static gboolean category_compare (ECardSimple *ecard1, ECardSimple *ecard2);
-
-struct prop_info {
- ECardSimpleField field_id;
- char *query_prop;
- char *ldap_attr;
-#define PROP_TYPE_STRING 0x01
-#define PROP_TYPE_COMPLEX 0x02
-#define PROP_DN 0x04
-#define PROP_EVOLVE 0x08
- 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 writing to an ldap server. returns a NULL terminated array of berval*'s */
- struct berval** (*ber_func)(ECardSimple *card);
- /* used to compare list attributes */
- gboolean (*compare_func)(ECardSimple *card1, ECardSimple *card2);
-
-} 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}
-
-
- /* name fields */
- STRING_PROP (E_CARD_SIMPLE_FIELD_FULL_NAME, "full_name", "cn" ),
- STRING_PROP (E_CARD_SIMPLE_FIELD_FAMILY_NAME, "family_name", "sn" ),
-
- /* email addresses */
- COMPLEX_PROP (E_CARD_SIMPLE_FIELD_EMAIL, "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, "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"),
-
- /* 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"),
-
- /* 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"),
-
- /* misc fields */
- STRING_PROP (E_CARD_SIMPLE_FIELD_URL, "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, "category", "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"),
-
-/* E_CARD_SIMPLE_FIELD_NAME_OR_ORG, */
-
-
-#undef E_STRING_PROP
-#undef STRING_PROP
-#undef E_COMPLEX_PROP
-#undef COMPLEX_PROP
-};
-
-static int num_prop_infos = sizeof(prop_info) / sizeof(prop_info[0]);
-
-static void
-remove_view (int msgid, LDAPOp *op, PASBookView *view)
-{
- if (op->view == view)
- op->view = NULL;
-}
-
-static void
-view_destroy(GtkObject *object, gpointer data)
-{
- PASBook *book = (PASBook *)data;
- PASBackendLDAP *bl;
- EIterator *iter;
-
- bl = PAS_BACKEND_LDAP(pas_book_get_backend(book));
-
- iter = e_list_get_iterator (bl->priv->book_views);
-
- while (e_iterator_is_valid (iter)) {
- PASBackendLDAPBookView *view = (PASBackendLDAPBookView*)e_iterator_get (iter);
-
- if (view->book_view == PAS_BOOK_VIEW(object)) {
- GNOME_Evolution_Addressbook_Book corba_book;
- CORBA_Environment ev;
-
- /* if we have an active search, interrupt it */
- if (view->search_op) {
- ldap_op_finished (view->search_op);
- }
- /* and remove us as the view for any other
- operations that might be using us to spew
- status messages to the gui */
- g_hash_table_foreach (bl->priv->id_to_op, (GHFunc)remove_view, view->book_view);
-
- /* free up the view structure */
- g_free (view->search);
- gtk_object_unref (GTK_OBJECT (view->card_sexp));
- g_free (view);
-
- /* and remove it from our list */
- e_iterator_delete (iter);
-
- /* unref the book now */
- corba_book = bonobo_object_corba_objref(BONOBO_OBJECT(book));
-
- CORBA_exception_init(&ev);
-
- GNOME_Evolution_Addressbook_Book_unref(corba_book, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("view_destroy: Exception unreffing "
- "corba book.\n");
- }
-
- CORBA_exception_free(&ev);
- break;
- }
-
- e_iterator_next (iter);
- }
-
- gtk_object_unref (GTK_OBJECT (iter));
-
-}
-
-static void
-book_view_notify_status (PASBookView *view, const char *status)
-{
- if (!view)
- return;
- pas_book_view_notify_status_message (view, status);
-}
-
-static PASBookView*
-find_book_view (PASBackendLDAP *bl)
-{
- EIterator *iter = e_list_get_iterator (bl->priv->book_views);
- PASBookView *rv = NULL;
-
- if (e_iterator_is_valid (iter)) {
- /* just always use the first book view */
- PASBackendLDAPBookView *v = (PASBackendLDAPBookView*)e_iterator_get(iter);
- if (v)
- rv = v->book_view;
- }
-
- gtk_object_unref (GTK_OBJECT (iter));
-
- return rv;
-}
-
-static void
-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]);
-
- if (query_prop) {
- e_list_append (bl->priv->supported_fields, 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");
- }
- else if (!strcmp (query_prop, "business_phone")) {
- e_list_append (bl->priv->supported_fields, "business_phone_2");
- }
- else if (!strcmp (query_prop, "home_phone")) {
- e_list_append (bl->priv->supported_fields, "home_phone_2");
- }
- }
- }
-}
-
-static void
-add_oc_attributes_to_supported_fields (PASBackendLDAP *bl, LDAPObjectClass *oc)
-{
- int i;
- 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);
-
- if (oc->oc_at_oids_must)
- add_to_supported_fields (bl, oc->oc_at_oids_must, attr_hash);
-
- if (oc->oc_at_oids_may)
- add_to_supported_fields (bl, oc->oc_at_oids_may, attr_hash);
-
- g_hash_table_destroy (attr_hash);
-}
-
-static void
-check_schema_support (PASBackendLDAP *bl)
-{
- char *attrs[2];
- LDAPMessage *resp;
- LDAP *ldap = bl->priv->ldap;
- struct timeval timeout;
-
- if (!bl->priv->schema_dn)
- return;
-
- bl->priv->evolutionPersonChecked = TRUE;
-
- attrs[0] = "objectClasses";
- attrs[1] = NULL;
-
- timeout.tv_sec = 30;
- timeout.tv_usec = 0;
-
- if (ldap_search_ext_s (ldap, bl->priv->schema_dn, LDAP_SCOPE_BASE,
- "(objectClass=subschema)", attrs, 0,
- NULL, NULL, &timeout, LDAP_NO_LIMIT, &resp) == LDAP_SUCCESS) {
- char **values;
-
- values = ldap_get_values (ldap, resp, "objectClasses");
-
- if (values) {
- int i;
- for (i = 0; values[i]; i ++) {
- int j;
- int code;
- const char *err;
- LDAPObjectClass *oc = ldap_str2objectclass (values[i], &code, &err, 0);
-
- if (!oc)
- continue;
-
- for (j = 0; oc->oc_names[j]; j++)
- if (!g_strcasecmp (oc->oc_names[j], EVOLUTIONPERSON)) {
- g_print ("support found on ldap server for objectclass evolutionPerson\n");
- bl->priv->evolutionPersonSupported = TRUE;
-
- add_oc_attributes_to_supported_fields (bl, oc);
- }
- else if (!g_strcasecmp (oc->oc_names[j], CALENTRY)) {
- g_print ("support found on ldap server for objectclass calEntry\n");
- bl->priv->calEntrySupported = TRUE;
- add_oc_attributes_to_supported_fields (bl, oc);
- }
- else if (!g_strcasecmp (oc->oc_names[j], INETORGPERSON)
- || !g_strcasecmp (oc->oc_names[j], ORGANIZATIONALPERSON)
- || !g_strcasecmp (oc->oc_names[j], PERSON)) {
- add_oc_attributes_to_supported_fields (bl, oc);
- }
-
- ldap_objectclass_free (oc);
- }
-
- ldap_value_free (values);
- }
-
- ldap_msgfree (resp);
- }
-}
-
-static void
-get_ldap_library_info ()
-{
- LDAPAPIInfo info;
- LDAP *ldap;
-
- if (LDAP_SUCCESS != ldap_create (&ldap)) {
- g_warning ("couldn't create LDAP* for getting at the client lib api info");
- return;
- }
-
- info.ldapai_info_version = LDAP_API_INFO_VERSION;
-
- if (LDAP_OPT_SUCCESS != ldap_get_option (ldap, LDAP_OPT_API_INFO, &info)) {
- g_warning ("couldn't get ldap api info");
- }
- else {
- int i;
- g_message ("libldap vendor/version: %s %2d.%02d.%02d",
- info.ldapai_vendor_name,
- info.ldapai_vendor_version / 10000,
- (info.ldapai_vendor_version % 10000) / 1000,
- info.ldapai_vendor_version % 1000);
-
- g_message ("extensions present:");
- /* yuck. we have to free these? */
- for (i = 0; info.ldapai_extensions[i]; i++) {
- char *extension = info.ldapai_extensions[i];
- g_message (extension);
- ldap_memfree (extension);
- }
- ldap_memfree (info.ldapai_extensions);
- ldap_memfree (info.ldapai_vendor_name);
- }
-
- ldap_unbind_ext_s (ldap, NULL, NULL);
-}
-
-static int
-query_ldap_root_dse (PASBackendLDAP *bl)
-{
-#define MAX_DSE_ATTRS 20
- LDAP *ldap = bl->priv->ldap;
- LDAPMessage *resp;
- int ldap_error;
- char *attrs[MAX_DSE_ATTRS], **values;
- int i = 0;
- struct timeval timeout;
-
- attrs[i++] = "supportedControl";
- attrs[i++] = "supportedExtension";
- attrs[i++] = "supportedFeatures";
- attrs[i++] = "supportedSASLMechanisms";
- attrs[i++] = "supportedLDAPVersion";
- attrs[i++] = "subschemaSubentry"; /* OpenLDAP's dn for schema information */
- attrs[i++] = "schemaNamingContext"; /* Active directory's dn for schema information */
- attrs[i] = NULL;
-
- timeout.tv_sec = 30;
- timeout.tv_usec = 0;
-
- ldap_error = ldap_search_ext_s (ldap,
- LDAP_ROOT_DSE, LDAP_SCOPE_BASE,
- "(objectclass=*)",
- attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, &resp);
- if (ldap_error != LDAP_SUCCESS) {
- g_warning ("could not perform query on Root DSE");
- return ldap_error;
- }
-
- values = ldap_get_values (ldap, resp, "supportedControl");
- if (values) {
- for (i = 0; values[i]; i++)
- g_message ("supported server control: %s", values[i]);
- ldap_value_free (values);
- }
-
- values = ldap_get_values (ldap, resp, "supportedExtension");
- if (values) {
- for (i = 0; values[i]; i++) {
- g_message ("supported server extension: %s", values[i]);
- if (!strcmp (values[i], LDAP_EXOP_START_TLS)) {
- g_message ("server reports LDAP_EXOP_START_TLS");
- }
- }
- ldap_value_free (values);
- }
-
- values = ldap_get_values (ldap, resp, "supportedSASLMechanisms");
- if (values) {
- for (i = 0; values[i]; i++)
- g_message ("supported SASL mechanism: %s", values[i]);
- ldap_value_free (values);
- }
-
-
- values = ldap_get_values (ldap, resp, "subschemaSubentry");
- if (!values || !values[0]) {
- if (values) ldap_value_free (values);
- values = ldap_get_values (ldap, resp, "schemaNamingContext");
- }
- if (values && values[0]) {
- bl->priv->schema_dn = g_strdup (values[0]);
- }
- else {
- g_warning ("could not determine location of schema information on LDAP server");
- }
- if (values)
- ldap_value_free (values);
-
- ldap_msgfree (resp);
-
- return LDAP_SUCCESS;
-}
-
-static GNOME_Evolution_Addressbook_BookListener_CallStatus
-pas_backend_ldap_connect (PASBackendLDAP *bl)
-{
- PASBackendLDAPPrivate *blpriv = bl->priv;
-
- /* close connection first if it's open first */
- if (blpriv->ldap)
- ldap_unbind_ext (blpriv->ldap, NULL, NULL);
-
- blpriv->ldap = ldap_init (blpriv->ldap_host, blpriv->ldap_port);
-#if defined (DEBUG) && defined (LDAP_OPT_DEBUG_LEVEL)
- {
- int debug_level = 4;
- ldap_set_option (blpriv->ldap, LDAP_OPT_DEBUG_LEVEL, &debug_level);
- }
-#endif
-
- if (NULL != blpriv->ldap) {
- int ldap_error;
-
- int protocol_version = LDAP_VERSION3;
- ldap_error = ldap_set_option (blpriv->ldap, LDAP_OPT_PROTOCOL_VERSION, &protocol_version);
- if (LDAP_OPT_SUCCESS != ldap_error) {
- g_warning ("failed to set protocol version to LDAPv3");
- bl->priv->ldap_v3 = FALSE;
- }
- else
- bl->priv->ldap_v3 = TRUE;
-
- if (bl->priv->ldap_port == LDAPS_PORT && bl->priv->use_tls == PAS_BACKEND_LDAP_TLS_ALWAYS) {
- int tls_level = LDAP_OPT_X_TLS_HARD;
- ldap_set_option (blpriv->ldap, LDAP_OPT_X_TLS, &tls_level);
- }
- else if (bl->priv->use_tls) {
- ldap_error = ldap_start_tls_s (blpriv->ldap, NULL, NULL);
- if (LDAP_SUCCESS != ldap_error) {
- if (bl->priv->use_tls == PAS_BACKEND_LDAP_TLS_ALWAYS) {
- 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;
- }
- else {
- g_message ("TLS not available (ldap_error 0x%02x)", ldap_error);
- }
- }
- else
- g_message ("TLS active");
- }
-
- ldap_error = query_ldap_root_dse (bl);
- /* query_ldap_root_dse will cause the actual
- connect(), so any tcpip problems will show up
- here */
-
- if (LDAP_SUCCESS == ldap_error) {
- blpriv->connected = TRUE;
-
- /* check to see if evolutionPerson is supported, if we can (me
- might not be able to if we can't authenticate. if we
- can't, try again in auth_user.) */
- if (!bl->priv->evolutionPersonChecked)
- check_schema_support (bl);
-
- return GNOME_Evolution_Addressbook_BookListener_Success;
- }
- }
-
- g_warning ("pas_backend_ldap_connect failed for "
- "'ldap://%s:%d/%s'\n",
- blpriv->ldap_host,
- blpriv->ldap_port,
- blpriv->ldap_rootdn ? blpriv->ldap_rootdn : "");
- blpriv->connected = FALSE;
- return GNOME_Evolution_Addressbook_BookListener_RepositoryOffline;
-}
-
-static gboolean
-pas_backend_ldap_reconnect (PASBackendLDAP *bl, PASBookView *book_view, int ldap_status)
-{
- /* we need to reconnect if we were previously connected */
- if (bl->priv->connected && ldap_status == LDAP_SERVER_DOWN) {
- GNOME_Evolution_Addressbook_BookListener_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) {
- book_view_notify_status (book_view, "");
- return FALSE;
- }
-
- if (bl->priv->auth_dn)
- ldap_error = ldap_simple_bind_s(bl->priv->ldap,
- bl->priv->auth_dn,
- bl->priv->auth_passwd);
- book_view_notify_status (book_view, "");
- return (ldap_error == LDAP_SUCCESS);
- }
- else {
- return FALSE;
- }
-}
-
-static void
-ldap_op_add (LDAPOp *op, PASBackend *backend,
- PASBook *book, PASBookView *view,
- int id,
- LDAPOpHandler handler, LDAPOpDtor dtor)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
-
- op->backend = backend;
- op->book = book;
- op->view = view;
- op->id = id;
- op->handler = handler;
- op->dtor = dtor;
-
- if (g_hash_table_lookup (bl->priv->id_to_op, &op->id)) {
- g_warning ("conflicting ldap msgid's");
- }
-
- g_hash_table_insert (bl->priv->id_to_op,
- &op->id, op);
-
- bl->priv->active_ops ++;
-
- if (bl->priv->poll_timeout == -1)
- bl->priv->poll_timeout = g_timeout_add (LDAP_POLL_INTERVAL,
- (GSourceFunc) poll_ldap,
- bl);
-}
-
-static void
-ldap_op_finished (LDAPOp *op)
-{
- PASBackend *backend = op->backend;
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
-
- g_hash_table_remove (bl->priv->id_to_op, &op->id);
-
- /* should handle errors here */
- ldap_abandon (bl->priv->ldap, op->id);
-
- op->dtor (op);
-
- bl->priv->active_ops--;
-
- if (bl->priv->active_ops == 0) {
- if (bl->priv->poll_timeout != -1)
- g_source_remove (bl->priv->poll_timeout);
- bl->priv->poll_timeout = -1;
- }
-}
-
-static void
-ldap_op_change_id (LDAPOp *op, int msg_id)
-{
- PASBackend *backend = op->backend;
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
-
- g_hash_table_remove (bl->priv->id_to_op, &op->id);
-
- op->id = msg_id;
-
- g_hash_table_insert (bl->priv->id_to_op,
- &op->id, op);
-}
-
-static int
-ldap_error_to_response (int ldap_error)
-{
- if (ldap_error == LDAP_SUCCESS)
- return GNOME_Evolution_Addressbook_BookListener_Success;
- else if (LDAP_NAME_ERROR (ldap_error))
- return GNOME_Evolution_Addressbook_BookListener_CardNotFound;
- else if (ldap_error == LDAP_INSUFFICIENT_ACCESS)
- return GNOME_Evolution_Addressbook_BookListener_PermissionDenied;
- else if (ldap_error == LDAP_SERVER_DOWN)
- return GNOME_Evolution_Addressbook_BookListener_RepositoryOffline;
- else if (ldap_error == LDAP_ALREADY_EXISTS)
- return GNOME_Evolution_Addressbook_BookListener_CardIdAlreadyExists;
- else
- return GNOME_Evolution_Addressbook_BookListener_OtherError;
-}
-
-
-static char *
-create_dn_from_ecard (ECardSimple *card, const char *root_dn)
-{
- char *cn, *cn_part = NULL;
- char *dn;
-
- cn = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_FULL_NAME);
- if (cn) {
- if (strchr (cn, ',')) {
- /* need to escape commas */
- char *new_cn = g_malloc0 (strlen (cn) * 3 + 1);
- int i, j;
-
- for (i = 0, j = 0; i < strlen (cn); i ++) {
- if (cn[i] == ',') {
- sprintf (new_cn + j, "%%%02X", cn[i]);
- j += 3;
- }
- else {
- new_cn[j++] = cn[i];
- }
- }
- cn_part = g_strdup_printf ("cn=%s", new_cn);
- g_free (new_cn);
- }
- else {
- cn_part = g_strdup_printf ("cn=%s", cn);
- }
- }
- else {
- cn_part = g_strdup ("");
- }
-
- dn = g_strdup_printf ("%s%s%s", cn_part,
- (root_dn && strlen(root_dn)) ? "," : "",
- (root_dn && strlen(root_dn)) ? root_dn: "");
-
- g_free (cn_part);
-
- g_print ("generated dn: %s\n", dn);
-
- return dn;
-}
-
-static void
-free_mods (GPtrArray *mods)
-{
- int i = 0;
- LDAPMod *mod;
-
- while ((mod = g_ptr_array_index (mods, i++))) {
- int j;
- g_free (mod->mod_type);
-
- if (mod->mod_op & LDAP_MOD_BVALUES) {
- for (j = 0; mod->mod_bvalues[j]; j++) {
- g_free (mod->mod_bvalues[j]->bv_val);
- g_free (mod->mod_bvalues[j]);
- }
- }
- else {
- for (j = 0; mod->mod_values[j]; j++)
- g_free (mod->mod_values[j]);
- }
- g_free (mod);
- }
-
- g_ptr_array_free (mods, TRUE);
-}
-
-static GPtrArray*
-build_mods_from_ecards (PASBackendLDAP *bl, ECardSimple *current, ECardSimple *new, gboolean *new_dn_needed)
-{
- gboolean adding = (current == NULL);
- GPtrArray *result = g_ptr_array_new();
- int i;
-
- if (new_dn_needed)
- *new_dn_needed = FALSE;
-
- /* we walk down the list of properties we can deal with (that
- big table at the top of the file) */
-
- for (i = 0; i < num_prop_infos; i ++) {
- gboolean include;
- gboolean new_prop_present = FALSE;
- gboolean current_prop_present = FALSE;
- struct berval** new_prop_bers = NULL;
- char *new_prop = NULL;
- char *current_prop = NULL;
-
- /* XXX if it's an evolutionPerson prop and the ldap
- server doesn't support that objectclass, skip it. */
- 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
- 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_present = (new_prop != NULL);
- }
- else {
- new_prop_bers = prop_info[i].ber_func (new);
- new_prop_present = (new_prop_bers != NULL);
- }
-
- /* 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
- field is there at all */
- if (prop_info[i].prop_type & PROP_TYPE_STRING)
- include = (new_prop_present && *new_prop); /* empty strings cause problems */
- else
- include = new_prop_present;
- }
- else {
- /* if we're modifying an existing card,
- 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_present = (current_prop != NULL);
-
- if (new_prop && current_prop)
- include = *new_prop && strcmp (new_prop, current_prop);
- else
- include = (!!new_prop != !!current_prop);
- }
- else {
- int j;
- struct berval **current_prop_bers = prop_info[i].ber_func (current);
-
- current_prop_present = (current_prop_bers != NULL);
-
- /* free up the current_prop_bers */
- if (current_prop_bers) {
- for (j = 0; current_prop_bers[j]; j++) {
- g_free (current_prop_bers[j]->bv_val);
- g_free (current_prop_bers[j]);
- }
- g_free (current_prop_bers);
- }
-
- include = !prop_info[i].compare_func (new, current);
- }
- }
-
- if (include) {
- LDAPMod *mod = g_new (LDAPMod, 1);
-
- /* the included attribute has changed - we
- need to update the dn if it's one of the
- attributes we compute the dn from. */
- if (new_dn_needed)
- *new_dn_needed |= prop_info[i].prop_type & PROP_DN;
-
- if (adding) {
- mod->mod_op = LDAP_MOD_ADD;
- }
- else {
- if (!new_prop_present)
- mod->mod_op = LDAP_MOD_DELETE;
- else if (!current_prop_present)
- mod->mod_op = LDAP_MOD_ADD;
- else
- mod->mod_op = LDAP_MOD_REPLACE;
- }
-
- mod->mod_type = g_strdup (prop_info[i].ldap_attr);
-
- if (prop_info[i].prop_type & PROP_TYPE_STRING) {
- mod->mod_values = g_new (char*, 2);
- mod->mod_values[0] = new_prop;
- mod->mod_values[1] = NULL;
- }
- else { /* PROP_TYPE_COMPLEX */
- mod->mod_op |= LDAP_MOD_BVALUES;
- mod->mod_bvalues = new_prop_bers;
- }
-
- g_ptr_array_add (result, mod);
- }
-
- }
-
- /* NULL terminate the list of modifications */
- g_ptr_array_add (result, NULL);
-
- return result;
-}
-
-static void
-add_objectclass_mod (PASBackendLDAP *bl, GPtrArray *mod_array, GList *existing_objectclasses)
-{
-#define FIND_INSERT(oc) \
- if (!g_list_find_custom (existing_objectclasses, (oc), (GCompareFunc)g_strcasecmp)) \
- g_ptr_array_add (objectclasses, g_strdup ((oc)))
-#define INSERT(oc) \
- g_ptr_array_add (objectclasses, g_strdup ((oc)))
-
- LDAPMod *objectclass_mod;
- GPtrArray *objectclasses = g_ptr_array_new();
-
- if (existing_objectclasses) {
- objectclass_mod = g_new (LDAPMod, 1);
- objectclass_mod->mod_op = LDAP_MOD_ADD;
- objectclass_mod->mod_type = g_strdup ("objectClass");
-
- /* yes, this is a linear search for each of our
- objectclasses, but really, how many objectclasses
- are there going to be in any sane ldap entry? */
- FIND_INSERT (TOP);
- FIND_INSERT (PERSON);
- FIND_INSERT (ORGANIZATIONALPERSON);
- FIND_INSERT (INETORGPERSON);
- if (bl->priv->calEntrySupported)
- FIND_INSERT (CALENTRY);
- if (bl->priv->evolutionPersonSupported)
- FIND_INSERT (EVOLUTIONPERSON);
-
- if (objectclasses->len) {
- g_ptr_array_add (objectclasses, NULL);
- objectclass_mod->mod_values = (char**)objectclasses->pdata;
- g_ptr_array_add (mod_array, objectclass_mod);
- g_ptr_array_free (objectclasses, FALSE);
- }
- else {
- g_ptr_array_free (objectclasses, TRUE);
- g_free (objectclass_mod->mod_type);
- g_free (objectclass_mod);
- }
-
- }
- else {
- objectclass_mod = g_new (LDAPMod, 1);
- objectclass_mod->mod_op = LDAP_MOD_ADD;
- objectclass_mod->mod_type = g_strdup ("objectClass");
-
- INSERT(TOP);
- INSERT(PERSON);
- INSERT(ORGANIZATIONALPERSON);
- INSERT(INETORGPERSON);
- if (bl->priv->calEntrySupported)
- INSERT(CALENTRY);
- if (bl->priv->evolutionPersonSupported)
- INSERT(EVOLUTIONPERSON);
- g_ptr_array_add (objectclasses, NULL);
- objectclass_mod->mod_values = (char**)objectclasses->pdata;
- g_ptr_array_add (mod_array, objectclass_mod);
- g_ptr_array_free (objectclasses, FALSE);
- }
-}
-
-typedef struct {
- LDAPOp op;
- char *dn;
- ECardSimple *new_card;
-} LDAPCreateOp;
-
-static void
-create_card_handler (LDAPOp *op, LDAPMessage *res)
-{
- LDAPCreateOp *create_op = (LDAPCreateOp*)op;
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
- LDAP *ldap = bl->priv->ldap;
- 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));
- pas_book_respond_create (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError,
- create_op->dn);
- ldap_op_finished (op);
- return;
- }
-
- 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);
- }
- gtk_object_unref (GTK_OBJECT (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);
-
- ldap_op_finished (op);
-}
-
-static void
-create_card_dtor (LDAPOp *op)
-{
- LDAPCreateOp *create_op = (LDAPCreateOp*)op;
-
- g_free (create_op->dn);
- gtk_object_unref (GTK_OBJECT (create_op->new_card));
- g_free (create_op);
-}
-
-static void
-pas_backend_ldap_process_create_card (PASBackend *backend,
- PASBook *book,
- PASRequest *req)
-{
- LDAPCreateOp *create_op = g_new (LDAPCreateOp, 1);
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- PASBookView *book_view;
- int create_card_msgid;
- ECard *new_ecard;
- int response;
- int err;
- GPtrArray *mod_array;
- LDAPMod **ldap_mods;
- LDAP *ldap;
-
- book_view = find_book_view (bl);
-
- printf ("vcard = %s\n", req->create.vcard);
-
- new_ecard = e_card_new (req->create.vcard);
- create_op->new_card = e_card_simple_new (new_ecard);
-
- 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 */
-
- ldap = bl->priv->ldap;
-
- /* build our mods */
- mod_array = build_mods_from_ecards (bl, NULL, create_op->new_card, NULL);
-
-#if 0
- if (!mod_array) {
- /* there's an illegal field in there. report
- UnsupportedAttribute back */
- pas_book_respond_create (book,
- GNOME_Evolution_Addressbook_BookListener_UnsupportedField,
- create_op->dn);
-
- g_free (create_op->dn);
- gtk_object_unref (GTK_OBJECT(create_op->new_card));
- g_free (create_op);
- return;
- }
-#endif
-
- /* remove the NULL at the end */
- g_ptr_array_remove (mod_array, NULL);
-
- /* add our objectclass(es) */
- add_objectclass_mod (bl, mod_array, NULL);
-
- /* then put the NULL back */
- g_ptr_array_add (mod_array, NULL);
-
-#ifdef LDAP_DEBUG_ADD
- {
- int i;
- printf ("Sending the following to the server as ADD\n");
-
- for (i = 0; g_ptr_array_index(mod_array, i); i ++) {
- LDAPMod *mod = g_ptr_array_index(mod_array, i);
- if (mod->mod_op & LDAP_MOD_DELETE)
- printf ("del ");
- else if (mod->mod_op & LDAP_MOD_REPLACE)
- printf ("rep ");
- else
- printf ("add ");
- if (mod->mod_op & LDAP_MOD_BVALUES)
- printf ("ber ");
- else
- printf (" ");
-
- printf (" %s:\n", mod->mod_type);
-
- if (mod->mod_op & LDAP_MOD_BVALUES) {
- int j;
- for (j = 0; mod->mod_bvalues[j] && mod->mod_bvalues[j]->bv_val; j++)
- printf ("\t\t'%s'\n", mod->mod_bvalues[j]->bv_val);
- }
- else {
- int j;
-
- for (j = 0; mod->mod_values[j]; j++)
- printf ("\t\t'%s'\n", mod->mod_values[j]);
- }
- }
- }
-#endif
-
- ldap_mods = (LDAPMod**)mod_array->pdata;
-
- do {
- book_view_notify_status (book_view, _("Adding card to LDAP server..."));
-
- err = ldap_add_ext (ldap, create_op->dn, ldap_mods,
- NULL, NULL, &create_card_msgid);
-
- } while (pas_backend_ldap_reconnect (bl, book_view, err));
-
- /* and clean up */
- free_mods (mod_array);
-
- if (LDAP_SUCCESS != err) {
- response = ldap_error_to_response (err);
- pas_book_respond_create (create_op->op.book,
- response,
- create_op->dn);
- create_card_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);
- }
-}
-
-
-typedef struct {
- LDAPOp op;
- char *id;
-} LDAPRemoveOp;
-
-static void
-remove_card_handler (LDAPOp *op, LDAPMessage *res)
-{
- LDAPRemoveOp *remove_op = (LDAPRemoveOp*)op;
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
- int ldap_error;
-
- 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);
- ldap_op_finished (op);
- return;
- }
-
- 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 (view->book_view, remove_op->id);
-
- bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), &ev);
-
- e_iterator_next (iter);
- }
- gtk_object_unref (GTK_OBJECT (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);
-}
-
-static void
-remove_card_dtor (LDAPOp *op)
-{
- LDAPRemoveOp *remove_op = (LDAPRemoveOp*)op;
-
- g_free (remove_op->id);
- g_free (remove_op);
-}
-
-static void
-pas_backend_ldap_process_remove_card (PASBackend *backend,
- PASBook *book,
- PASRequest *req)
-{
- LDAPRemoveOp *remove_op = g_new (LDAPRemoveOp, 1);
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- PASBookView *book_view;
- int remove_msgid;
- int ldap_error;
-
- book_view = find_book_view (bl);
-
- remove_op->id = g_strdup (req->remove.id);
-
- do {
- book_view_notify_status (book_view, _("Removing card from LDAP server..."));
-
- ldap_error = ldap_delete_ext (bl->priv->ldap,
- remove_op->id,
- NULL, NULL, &remove_msgid);
- } 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);
- 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);
- }
-}
-
-
-/*
-** MODIFY
-**
-** 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.
-**
-*/
-
-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;
- GList *existing_objectclasses;
-} LDAPModifyOp;
-
-static void
-modify_card_modify_handler (LDAPOp *op, LDAPMessage *res)
-{
- LDAPModifyOp *modify_op = (LDAPModifyOp*)op;
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
- LDAP *ldap = bl->priv->ldap;
- int ldap_error;
-
- if (LDAP_RES_MODIFY != ldap_msgtype (res)) {
- g_warning ("incorrect msg type %d passed to modify_card_handler", ldap_msgtype (res));
- pas_book_respond_modify (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError);
- ldap_op_finished (op);
- return;
- }
-
- 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 (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);
- }
- gtk_object_unref (GTK_OBJECT (iter));
- }
- else {
- ldap_perror (ldap, "ldap_modify_s");
- }
-
- /* and lastly respond */
- pas_book_respond_modify (op->book,
- ldap_error_to_response (ldap_error));
- ldap_op_finished (op);
-}
-
-static void
-modify_card_search_handler (LDAPOp *op, LDAPMessage *res)
-{
- LDAPModifyOp *modify_op = (LDAPModifyOp*)op;
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
- LDAP *ldap = bl->priv->ldap;
- int msg_type;
-
- /* if it's successful, we should get called with a
- RES_SEARCH_ENTRY and a RES_SEARCH_RESULT. if it's
- unsuccessful, we should only see a RES_SEARCH_RESULT */
-
- msg_type = ldap_msgtype (res);
- if (msg_type == LDAP_RES_SEARCH_ENTRY) {
- LDAPMessage *e = ldap_first_entry(ldap, res);
-
- if (!e) {
- g_warning ("uh, this shouldn't happen");
- pas_book_respond_modify (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError);
- 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);
- }
- else if (msg_type == LDAP_RES_SEARCH_RESULT) {
- int ldap_error;
- LDAPMod **ldap_mods;
- GPtrArray *mod_array;
- gboolean differences;
- gboolean need_new_dn;
- int modify_card_msgid;
-
- /* grab the result code, and set up the actual modify
- if it was successful */
- ldap_parse_result (bl->priv->ldap, res, &ldap_error,
- NULL, NULL, NULL, NULL, 0);
-
- if (ldap_error != LDAP_SUCCESS) {
- /* more here i'm sure */
- pas_book_respond_modify (op->book,
- ldap_error_to_response (ldap_error));
- 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);
- differences = mod_array->len > 0;
-
- if (differences) {
- /* remove the NULL at the end */
- g_ptr_array_remove (mod_array, NULL);
-
- /* add our objectclass(es), making sure
- evolutionPerson is there if it's supported */
- add_objectclass_mod (bl, mod_array, modify_op->existing_objectclasses);
-
- /* then put the NULL back */
- g_ptr_array_add (mod_array, NULL);
-
- ldap_mods = (LDAPMod**)mod_array->pdata;
-
- /* actually perform the ldap modify */
- ldap_error = ldap_modify_ext (ldap, modify_op->id, ldap_mods,
- NULL, NULL, &modify_card_msgid);
-
- if (ldap_error == LDAP_SUCCESS) {
- op->handler = modify_card_modify_handler;
- ldap_op_change_id ((LDAPOp*)modify_op,
- modify_card_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_op_finished (op);
- return;
- }
- }
-
- /* and clean up */
- free_mods (mod_array);
- }
- else {
- g_warning ("unhandled result type %d returned", msg_type);
- pas_book_respond_modify (op->book,
- GNOME_Evolution_Addressbook_BookListener_OtherError);
- ldap_op_finished (op);
- }
-}
-
-static void
-modify_card_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)
- gtk_object_unref (GTK_OBJECT (modify_op->current_card));
- g_free (modify_op->vcard);
- if (modify_op->card)
- gtk_object_unref (GTK_OBJECT (modify_op->card));
- g_free (modify_op);
-}
-
-static void
-pas_backend_ldap_process_modify_card (PASBackend *backend,
- PASBook *book,
- PASRequest *req)
-{
- 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;
- PASBookView *book_view;
-
- book_view = find_book_view (bl);
-
- modify_op->vcard = g_strdup (req->modify.vcard);
- new_ecard = e_card_new (modify_op->vcard);
- modify_op->card = e_card_simple_new (new_ecard);
- gtk_object_unref (GTK_OBJECT (new_ecard));
- modify_op->id = e_card_simple_get_id(modify_op->card);
-
- ldap = bl->priv->ldap;
-
- book_view_notify_status (book_view, _("Modifying card from LDAP server..."));
-
- do {
- book_view_notify_status (book_view, _("Modifying card 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);
-
- } 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);
- }
- 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);
- }
-}
-
-
-typedef struct {
- LDAPOp op;
-} LDAPGetVCardOp;
-
-static void
-get_vcard_handler (LDAPOp *op, LDAPMessage *res)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (op->backend);
- int msg_type;
-
- /* the msg_type will be either SEARCH_ENTRY (if we're
- successful) or SEARCH_RESULT (if we're not), so we finish
- the op after either */
- msg_type = ldap_msgtype (res);
- if (msg_type == LDAP_RES_SEARCH_ENTRY) {
- LDAPMessage *e = ldap_first_entry(bl->priv->ldap, res);
- ECardSimple *simple;
- char *vcard;
-
- if (!e) {
- g_warning ("uh, this shouldn't happen");
- pas_book_respond_get_vcard (op->book,
- GNOME_Evolution_Addressbook_BookListener_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);
- g_free (vcard);
- gtk_object_unref (GTK_OBJECT (simple));
- 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), "");
- 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,
- "");
- ldap_op_finished (op);
- }
-
-}
-
-static void
-get_vcard_dtor (LDAPOp *op)
-{
- LDAPGetVCardOp *get_vcard_op = (LDAPGetVCardOp*)op;
-
- g_free (get_vcard_op);
-}
-
-static void
-pas_backend_ldap_process_get_vcard (PASBackend *backend,
- PASBook *book,
- PASRequest *req)
-{
- LDAPGetVCardOp *get_vcard_op = g_new0 (LDAPGetVCardOp, 1);
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- LDAP *ldap = bl->priv->ldap;
- int get_vcard_msgid;
- PASBookView *book_view;
- int ldap_error;
-
- book_view = find_book_view (bl);
-
- do {
- ldap_error = ldap_search_ext (ldap, req->get_vcard.id,
- LDAP_SCOPE_BASE,
- "(objectclass=*)",
- NULL, 0, NULL, NULL,
- NULL, /* XXX timeout */
- 1, &get_vcard_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);
- }
- else {
- pas_book_respond_get_vcard (book,
- ldap_error_to_response (ldap_error),
- "");
- get_vcard_dtor ((LDAPOp*)get_vcard_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(GtkObject *object, gpointer data)
-{
- 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);
- gtk_object_unref (GTK_OBJECT (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);
-
- gtk_signal_connect(GTK_OBJECT(cursor), "destroy",
- GTK_SIGNAL_FUNC(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 (NULL, cursor_op->cursor_data);
- }
-
- g_free (op);
-}
-
-static void
-pas_backend_ldap_process_get_cursor (PASBackend *backend,
- PASBook *book,
- PASRequest *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);
- }
-}
-
-
-/* List property functions */
-static void
-email_populate(ECardSimple *card, char **values)
-{
- int i;
-
- for (i = 0; values[i] && i < 3; i ++) {
- e_card_simple_set_email (card, i, values[i]);
- }
-}
-
-struct berval**
-email_ber(ECardSimple *card)
-{
- struct berval** result;
- const char *emails[3];
- int i, j, num;
-
- num = 0;
- for (i = 0; i < 3; i ++) {
- emails[i] = e_card_simple_get_email (card, E_CARD_SIMPLE_EMAIL_ID_EMAIL + i);
- if (emails[i])
- num++;
- }
-
- if (num == 0)
- return NULL;
-
- result = g_new (struct berval*, num + 1);
-
- for (i = 0; i < num; i ++)
- result[i] = g_new (struct berval, 1);
-
- j = 0;
- for (i = 0; i < 3; i ++) {
- if (emails[i]) {
- result[j]->bv_val = g_strdup (emails[i]);
- result[j++]->bv_len = strlen (emails[i]);
- }
- }
-
- result[num] = NULL;
-
- return result;
-}
-
-static gboolean
-email_compare (ECardSimple *ecard1, ECardSimple *ecard2)
-{
- 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);
-
- if (email1 && email2)
- equal = !strcmp (email1, email2);
- else
- equal = (!!email1 == !!email2);
-
- if (!equal)
- return equal;
- }
-
- return TRUE;
-}
-
-static void
-homephone_populate(ECardSimple *card, char **values)
-{
- if (values[0]) {
- e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_HOME, values[0]);
- if (values[1])
- e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_HOME_2, values[1]);
- }
-}
-
-struct berval**
-homephone_ber(ECardSimple *card)
-{
- 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)))
- num++;
- if ((homephones[1] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_HOME_2)))
- num++;
-
- if (num == 0)
- return NULL;
-
- result = g_new (struct berval*, num + 1);
-
- for (i = 0; i < num; i ++)
- result[i] = g_new (struct berval, 1);
-
- j = 0;
- for (i = 0; i < 2; i ++) {
- if (homephones[i]) {
- result[j]->bv_val = g_strdup (homephones[i]);
- result[j++]->bv_len = strlen (homephones[i]);
- }
- }
-
- result[num] = NULL;
-
- return result;
-}
-
-static gboolean
-homephone_compare (ECardSimple *ecard1, ECardSimple *ecard2)
-{
- int phone_ids[2] = { E_CARD_SIMPLE_FIELD_PHONE_HOME, E_CARD_SIMPLE_FIELD_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]);
-
- if (phone1 && phone2)
- equal = !strcmp (phone1, phone2);
- else
- equal = (!!phone1 == !!phone2);
-
- if (!equal)
- return equal;
- }
-
- return TRUE;
-}
-
-static void
-business_populate(ECardSimple *card, char **values)
-{
- if (values[0]) {
- e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, values[0]);
- if (values[1])
- e_card_simple_set (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2, values[1]);
- }
-}
-
-struct berval**
-business_ber(ECardSimple *card)
-{
- 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)))
- num++;
- if ((business_phones[1] = e_card_simple_get (card, E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2)))
- num++;
-
- if (num == 0)
- return NULL;
-
- result = g_new (struct berval*, num + 1);
-
- for (i = 0; i < num; i ++)
- result[i] = g_new (struct berval, 1);
-
- j = 0;
- for (i = 0; i < 2; i ++) {
- if (business_phones[i]) {
- result[j]->bv_val = g_strdup (business_phones[i]);
- result[j++]->bv_len = strlen (business_phones[i]);
- }
- }
-
- result[num] = NULL;
-
- return result;
-}
-
-static gboolean
-business_compare (ECardSimple *ecard1, ECardSimple *ecard2)
-{
- int phone_ids[2] = { E_CARD_SIMPLE_FIELD_PHONE_BUSINESS, E_CARD_SIMPLE_FIELD_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]);
-
- if (phone1 && phone2)
- equal = !strcmp (phone1, phone2);
- else
- equal = (!!phone1 == !!phone2);
-
- if (!equal)
- return equal;
- }
-
- return TRUE;
-}
-
-static void
-anniversary_populate (ECardSimple *card, char **values)
-{
- if (values[0]) {
- ECardDate dt = e_card_date_from_string (values[0]);
- gtk_object_set (GTK_OBJECT (card->card),
- "anniversary", &dt,
- NULL);
- }
-}
-
-struct berval**
-anniversary_ber (ECardSimple *card)
-{
- ECardDate *dt;
- struct berval** result = NULL;
-
- gtk_object_get (GTK_OBJECT (card->card),
- "anniversary", &dt,
- NULL);
-
- if (dt) {
- char *anniversary;
-
- anniversary = e_card_date_to_string (dt);
-
- result = g_new (struct berval*, 2);
- result[0] = g_new (struct berval, 1);
- result[0]->bv_val = anniversary;
- result[0]->bv_len = strlen (anniversary);
-
- result[1] = NULL;
- }
-
- return result;
-}
-
-static gboolean
-anniversary_compare (ECardSimple *ecard1, ECardSimple *ecard2)
-{
- ECardDate *dt;
- char *date1 = NULL, *date2 = NULL;
- gboolean equal;
-
- gtk_object_get (GTK_OBJECT (ecard1->card),
- "anniversary", &dt,
- NULL);
- if (dt)
- date1 = e_card_date_to_string (dt);
-
- gtk_object_get (GTK_OBJECT (ecard2->card),
- "anniversary", &dt,
- NULL);
- if (dt)
- date2 = e_card_date_to_string (dt);
-
- if (date1 && date2)
- equal = !strcmp (date1, date2);
- else
- equal = (!!date1 == !!date2);
-
- g_free (date1);
- g_free (date2);
-
- return equal;
-}
-
-static void
-birthday_populate (ECardSimple *card, char **values)
-{
- if (values[0]) {
- ECardDate dt = e_card_date_from_string (values[0]);
- gtk_object_set (GTK_OBJECT (card->card),
- "birth_date", &dt,
- NULL);
- }
-}
-
-struct berval**
-birthday_ber (ECardSimple *card)
-{
- ECardDate *dt;
- struct berval** result = NULL;
-
- gtk_object_get (GTK_OBJECT (card->card),
- "birth_date", &dt,
- NULL);
-
- if (dt) {
- char *birthday;
-
- birthday = e_card_date_to_string (dt);
-
- result = g_new (struct berval*, 2);
- result[0] = g_new (struct berval, 1);
- result[0]->bv_val = birthday;
- result[0]->bv_len = strlen (birthday);
-
- result[1] = NULL;
- }
-
- return result;
-}
-
-static gboolean
-birthday_compare (ECardSimple *ecard1, ECardSimple *ecard2)
-{
- ECardDate *dt;
- char *date1 = NULL, *date2 = NULL;
- gboolean equal;
-
- gtk_object_get (GTK_OBJECT (ecard1->card),
- "birth_date", &dt,
- NULL);
- if (dt)
- date1 = e_card_date_to_string (dt);
-
- gtk_object_get (GTK_OBJECT (ecard2->card),
- "birth_date", &dt,
- NULL);
- if (dt)
- date2 = e_card_date_to_string (dt);
-
- if (date1 && date2)
- equal = !strcmp (date1, date2);
- else
- equal = (!!date1 == !!date2);
-
- g_free (date1);
- g_free (date2);
-
- return equal;
-}
-
-static void
-category_populate (ECardSimple *card, char **values)
-{
- int i;
- ECard *ecard;
- EList *categories;
-
- gtk_object_get (GTK_OBJECT (card),
- "card", &ecard,
- NULL);
-
- categories = e_list_new((EListCopyFunc) g_strdup,
- (EListFreeFunc) g_free,
- NULL);
-
- for (i = 0; values[i]; i++)
- e_list_append (categories, values[i]);
-
- gtk_object_set (GTK_OBJECT (ecard),
- "category_list", categories,
- NULL);
-
- gtk_object_unref (GTK_OBJECT (categories));
-
- e_card_simple_sync_card (card);
-}
-
-struct berval**
-category_ber (ECardSimple *card)
-{
- struct berval** result = NULL;
- EList *categories;
- EIterator *iterator;
- ECard *ecard;
- int i;
-
- gtk_object_get (GTK_OBJECT (card),
- "card", &ecard,
- NULL);
-
- gtk_object_get (GTK_OBJECT (ecard),
- "category_list", &categories,
- NULL);
-
- if (e_list_length (categories) != 0) {
- result = g_new0 (struct berval*, e_list_length (categories) + 1);
-
- for (iterator = e_list_get_iterator(categories), i = 0; e_iterator_is_valid (iterator);
- e_iterator_next (iterator), i++) {
- const char *category = e_iterator_get (iterator);
-
- result[i] = g_new (struct berval, 1);
- result[i]->bv_val = g_strdup (category);
- result[i]->bv_len = strlen (category);
- }
-
- gtk_object_unref (GTK_OBJECT (iterator));
- }
-
- return result;
-}
-
-static gboolean
-category_compare (ECardSimple *ecard1, ECardSimple *ecard2)
-{
- 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);
-
- equal = !strcmp (categories1, categories2);
-
- g_free (categories1);
- g_free (categories2);
-
- return equal;
-}
-
-typedef struct {
- GList *list;
- PASBackendLDAP *bl;
-} PASBackendLDAPSExpData;
-
-#define IS_RFC2254_CHAR(c) ((c) == '*' || (c) =='\\' || (c) == '(' || (c) == ')' || (c) == '\0')
-static char *
-rfc2254_escape(char *str)
-{
- int i;
- int len = strlen(str);
- int newlen = 0;
-
- for (i = 0; i < len; i ++) {
- if (IS_RFC2254_CHAR(str[i]))
- newlen += 3;
- else
- newlen ++;
- }
-
- if (len == newlen) {
- return g_strdup (str);
- }
- else {
- char *newstr = g_malloc0 (newlen + 1);
- int j = 0;
- for (i = 0; i < len; i ++) {
- if (IS_RFC2254_CHAR(str[i])) {
- sprintf (newstr + j, "\\%02x", str[i]);
- j+= 3;
- }
- else {
- newstr[j++] = str[i];
- }
- }
- return newstr;
- }
-}
-
-static ESExpResult *
-func_and(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- PASBackendLDAPSExpData *ldap_data = data;
- ESExpResult *r;
- char ** strings;
-
- if (argc > 0) {
- int i;
-
- strings = g_new0(char*, argc+3);
- strings[0] = g_strdup ("(&");
- strings[argc+3 - 2] = g_strdup (")");
-
- for (i = 0; i < argc; i ++) {
- GList *list_head = ldap_data->list;
- if (!list_head)
- break;
- strings[argc - i] = list_head->data;
- ldap_data->list = g_list_remove_link(list_head, list_head);
- g_list_free_1(list_head);
- }
-
- ldap_data->list = g_list_prepend(ldap_data->list, g_strjoinv(" ", strings));
-
- for (i = 0 ; i < argc + 2; i ++)
- g_free (strings[i]);
-
- g_free (strings);
- }
-
- 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)
-{
- PASBackendLDAPSExpData *ldap_data = data;
- ESExpResult *r;
- char ** strings;
-
- if (argc > 0) {
- int i;
-
- strings = g_new0(char*, argc+3);
- strings[0] = g_strdup ("(|");
- strings[argc+3 - 2] = g_strdup (")");
-
- for (i = 0; i < argc; i ++) {
- GList *list_head = ldap_data->list;
- if (!list_head)
- break;
- strings[argc - i] = list_head->data;
- ldap_data->list = g_list_remove_link(list_head, list_head);
- g_list_free_1(list_head);
- }
-
- ldap_data->list = g_list_prepend(ldap_data->list, g_strjoinv(" ", strings));
-
- for (i = 0 ; i < argc + 2; i ++)
- g_free (strings[i]);
-
- g_free (strings);
- }
-
- 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)
-{
- PASBackendLDAPSExpData *ldap_data = data;
- ESExpResult *r;
-
- /* just replace the head of the list with the NOT of it. */
- if (argc > 0) {
- char *term = ldap_data->list->data;
- ldap_data->list->data = g_strdup_printf("(!%s)", term);
- g_free (term);
- }
-
- 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)
-{
- PASBackendLDAPSExpData *ldap_data = 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 = rfc2254_escape(argv[1]->value.string);
- gboolean one_star = FALSE;
-
- if (strlen(str) == 0)
- one_star = TRUE;
-
- if (!strcmp (propname, "x-evolution-any-field")) {
- int i;
- int query_length;
- char *big_query;
- char *match_str;
-
- match_str = g_strdup_printf("=*%s%s)",
- str, one_star ? "" : "*");
-
- 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=*%s%s)",
- ldap_attr,
- str,
- one_star ? "" : "*"));
- }
-
- g_free (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)
-{
- PASBackendLDAPSExpData *ldap_data = 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 = rfc2254_escape(argv[1]->value.string);
- char *ldap_attr = query_prop_to_ldap(propname);
-
- if (ldap_attr)
- ldap_data->list = g_list_prepend(ldap_data->list,
- g_strdup_printf("(%s=%s)",
- ldap_attr, str));
- else {
- g_warning ("unknown query property\n");
- /* we want something that'll always be false */
- ldap_data->list = g_list_prepend(ldap_data->list,
- g_strdup("objectClass=MyBarnIsBiggerThanYourBarn"));
- }
-
- g_free (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)
-{
- PASBackendLDAPSExpData *ldap_data = 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 = rfc2254_escape(argv[1]->value.string);
- char *ldap_attr = query_prop_to_ldap(propname);
-
- /* insert hack for fileAs queries, since we need to do
- the right thing if the server supports them or not,
- and for entries that have no fileAs attribute. */
- if (ldap_attr) {
- if (!strcmp (propname, "full_name")) {
- ldap_data->list = g_list_prepend(ldap_data->list,
- g_strdup_printf(
- "(|(cn=%s*)(sn=%s*))",
- str, str));
- }
- else if (!strcmp (ldap_attr, "fileAs")) {
- ldap_data->list = g_list_prepend(ldap_data->list,
- g_strdup_printf(
- "(|(fileAs=%s*)(&(!(fileAs=*))(sn=%s*)))",
- str, str));
- }
- else {
- ldap_data->list = g_list_prepend(ldap_data->list,
- g_strdup_printf("(%s=%s*)",
- ldap_attr,
- str));
- }
- }
-
- g_free (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)
-{
- PASBackendLDAPSExpData *ldap_data = 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 = rfc2254_escape(argv[1]->value.string);
- char *ldap_attr = query_prop_to_ldap(propname);
-
- if (ldap_attr)
- ldap_data->list = g_list_prepend(ldap_data->list,
- g_strdup_printf("(%s=*%s)",
- ldap_attr,
- str));
- g_free (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 },
-};
-
-static gchar *
-pas_backend_ldap_build_query (PASBackendLDAP *bl, gchar *query)
-{
- ESExp *sexp;
- ESExpResult *r;
- gchar *retval;
- PASBackendLDAPSExpData data;
- int i;
-
- data.list = NULL;
- data.bl = bl;
-
- 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, &data);
- } else {
- e_sexp_add_function(sexp, 0, symbols[i].name,
- symbols[i].func, &data);
- }
- }
-
- e_sexp_input_text(sexp, query, strlen(query));
- e_sexp_parse(sexp);
-
- r = e_sexp_eval(sexp);
-
- e_sexp_result_free(sexp, r);
- e_sexp_unref (sexp);
-
- if (data.list) {
- if (data.list->next) {
- g_warning ("conversion to ldap query string failed");
- retval = NULL;
- g_list_foreach (data.list, (GFunc)g_free, NULL);
- }
- else {
- retval = data.list->data;
- }
- }
- else {
- g_warning ("conversion to ldap query string failed");
- retval = NULL;
- }
-
- g_list_free (data.list);
- return retval;
-}
-
-static gchar *
-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))
- return prop_info[i].ldap_attr;
-
- return NULL;
-}
-
-
-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;
-
- /* 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)
-{
- ECard *ecard = e_card_new ("");
- ECardSimple *card = e_card_simple_new (ecard);
- char *dn;
- char *attr;
- BerElement *ber = NULL;
-
- dn = ldap_get_dn(ldap, e);
- e_card_simple_set_id (card, dn);
- ldap_memfree (dn);
-
- for (attr = ldap_first_attribute (ldap, e, &ber); attr;
- attr = ldap_next_attribute (ldap, e, ber)) {
- int i;
- struct prop_info *info = NULL;
- char **values;
-
- if (existing_objectclasses && !strcasecmp (attr, "objectclass")) {
- values = ldap_get_values (ldap, e, attr);
- for (i = 0; values[i]; i ++)
- *existing_objectclasses = g_list_append (*existing_objectclasses, g_strdup (values[i]));
-
- ldap_value_free (values);
- }
- else {
- for (i = 0; i < num_prop_infos; i ++)
- if (!g_strcasecmp (attr, prop_info[i].ldap_attr)) {
- info = &prop_info[i];
- break;
- }
-
- if (info) {
- values = ldap_get_values (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]);
-
- }
- else if (info->prop_type & PROP_TYPE_COMPLEX) {
- /* if it's a list call the ecard-populate function,
- which calls gtk_object_set to set the property */
- info->populate_ecard_func(card,
- values);
- }
-
- ldap_value_free (values);
- }
- }
- }
-
- ldap_memfree (attr);
- }
-
- if (ber)
- ber_free (ber, 0);
-
- e_card_simple_sync_card (card);
-
- gtk_object_unref (GTK_OBJECT (ecard));
-
- return card;
-}
-
-static gboolean
-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");
- return FALSE;
- }
-
- timeout.tv_sec = 0;
- timeout.tv_usec = LDAP_RESULT_TIMEOUT_MILLIS * 1000;
-
- rc = ldap_result (ldap, LDAP_RES_ANY, 0, &timeout, &res);
- if (rc != 0) {/* rc == 0 means timeout exceeded */
- if (rc == -1) {
- PASBookView *book_view = find_book_view (bl);
- g_warning ("ldap_result returned -1, restarting ops");
-
- pas_backend_ldap_reconnect (bl, book_view, LDAP_SERVER_DOWN);
-#if 0
- if (bl->priv->connected)
- restart_ops (bl);
-#endif
- }
- else {
- int msgid = ldap_msgid (res);
- LDAPOp *op;
-
- op = g_hash_table_lookup (bl->priv->id_to_op, &msgid);
-
- if (op)
- op->handler (op, res);
- else
- g_warning ("unknown operation, msgid = %d", msgid);
-
- ldap_msgfree(res);
- }
- }
-
- 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);
- }
- gtk_object_unref (GTK_OBJECT (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);
- 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;
- 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);
-
- if (!search_op->notified_receiving_results) {
- search_op->notified_receiving_results = TRUE;
- book_view_notify_status (op->view, _("Receiving LDAP search results..."));
- }
-
- msg_type = ldap_msgtype (res);
- if (msg_type == LDAP_RES_SEARCH_ENTRY) {
- e = ldap_first_entry(ldap, res);
-
- while (NULL != e) {
- ECardSimple *card = build_card_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 ++;
-
- gtk_object_unref (GTK_OBJECT(card));
-
- e = ldap_next_entry(ldap, e);
- }
- }
- else if (msg_type == LDAP_RES_SEARCH_RESULT) {
- int ldap_error;
-
- ldap_parse_result (ldap, res, &ldap_error,
- NULL, NULL, NULL, NULL, 0);
-
- 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);
- else if (ldap_error == LDAP_SIZELIMIT_EXCEEDED)
- pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_SearchSizeLimitExceeded);
- else if (ldap_error == LDAP_SUCCESS)
- pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_Success);
- else
- pas_book_view_notify_complete (search_op->op.view, GNOME_Evolution_Addressbook_BookViewListener_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);
- ldap_op_finished (op);
- }
-
-
- bonobo_object_release_unref(bonobo_object_corba_objref(BONOBO_OBJECT(view->book_view)), NULL);
-}
-
-static void
-ldap_search_dtor (LDAPOp *op)
-{
- LDAPSearchOp *search_op = (LDAPSearchOp*) op;
-
- /* 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;
-
- g_free (search_op);
-}
-
-static void
-pas_backend_ldap_search (PASBackendLDAP *bl,
- PASBook *book,
- PASBackendLDAPBookView *view)
-{
- char *ldap_query;
-
- ldap_query = pas_backend_ldap_build_query(bl, view->search);
-
- 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..."));
-
- ldap_err = ldap_search_ext (ldap, bl->priv->ldap_rootdn,
- bl->priv->ldap_scope,
- ldap_query,
- NULL, 0,
- NULL, /* XXX */
- NULL, /* XXX */
- NULL, /* XXX timeout */
- view->limit, &search_msgid);
- } while (pas_backend_ldap_reconnect (bl, view->book_view, ldap_err));
-
- g_free (ldap_query);
-
- if (ldap_err != LDAP_SUCCESS) {
- book_view_notify_status (view->book_view, ldap_err2string(ldap_err));
- return;
- }
- else if (search_msgid == -1) {
- book_view_notify_status (view->book_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;
-
- view->search_op = (LDAPOp*)op;
-
- ldap_op_add ((LDAPOp*)op, PAS_BACKEND(bl), book, view->book_view,
- search_msgid,
- ldap_search_handler, ldap_search_dtor);
-
- }
- return;
- }
- else {
- pas_book_view_notify_complete (view->book_view,
- GNOME_Evolution_Addressbook_BookViewListener_InvalidQuery);
- return;
- }
-
-}
-
-static void
-pas_backend_ldap_process_get_book_view (PASBackend *backend,
- PASBook *book,
- PASRequest *req)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- PASBookView *book_view;
- PASBackendLDAPBookView *view;
-
- g_return_if_fail (req->get_book_view.listener != NULL);
-
- book_view = pas_book_view_new (req->get_book_view.listener);
-
- bonobo_object_ref(BONOBO_OBJECT(book));
- gtk_signal_connect(GTK_OBJECT(book_view), "destroy",
- GTK_SIGNAL_FUNC(view_destroy), book);
-
- view = g_new0(PASBackendLDAPBookView, 1);
- view->book_view = book_view;
- view->search = g_strdup(req->get_book_view.search);
- view->card_sexp = pas_backend_card_sexp_new (view->search);
- view->blpriv = bl->priv;
-
- if (req->op == GetCompletionView) {
- view->limit = MIN (bl->priv->ldap_limit, 100);
- }
- else {
- view->limit = bl->priv->ldap_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_check_connection (PASBackend *backend,
- PASBook *book,
- PASRequest *req)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
-
- pas_book_report_connection (book, bl->priv->connected);
-}
-
-static void
-pas_backend_ldap_process_authenticate_user (PASBackend *backend,
- PASBook *book,
- PASRequest *req)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- int ldap_error;
- char *dn = NULL;
-
- if (!strcmp (req->auth_user.auth_method, "ldap/simple-email")) {
- LDAPMessage *res, *e;
- char *query = g_strdup_printf ("(mail=%s)", req->auth_user.user);
-
- ldap_error = ldap_search_s (bl->priv->ldap,
- bl->priv->ldap_rootdn,
- bl->priv->ldap_scope,
- query,
- NULL, 0, &res);
- g_free (query);
-
- if (ldap_error == LDAP_SUCCESS) {
- char *entry_dn;
-
- e = ldap_first_entry (bl->priv->ldap, res);
-
- entry_dn = ldap_get_dn (bl->priv->ldap, e);
- dn = g_strdup(entry_dn);
-
- ldap_memfree (entry_dn);
- ldap_msgfree (res);
- }
- else {
- pas_book_respond_authenticate_user (book,
- GNOME_Evolution_Addressbook_BookListener_PermissionDenied);
- return;
- }
- }
- else if (!strcmp (req->auth_user.auth_method, "ldap/simple-binddn")) {
- dn = g_strdup (req->auth_user.user);
- }
-
- /* now authenticate against the DN we were either supplied or queried for */
- printf ("authenticating as %s\n", dn);
- ldap_error = ldap_simple_bind_s(bl->priv->ldap,
- dn,
- req->auth_user.passwd);
-
- bl->priv->auth_dn = dn;
- bl->priv->auth_passwd = g_strdup (req->auth_user.passwd);
-
- pas_book_respond_authenticate_user (book,
- ldap_error_to_response (ldap_error));
-
- bl->priv->writable = (ldap_error == LDAP_SUCCESS);
-
- if (!bl->priv->evolutionPersonChecked)
- check_schema_support (bl);
-
- pas_book_report_writable (book, bl->priv->writable);
-}
-
-static void
-pas_backend_ldap_process_get_supported_fields (PASBackend *backend,
- PASBook *book,
- PASRequest *req)
-
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
-
- pas_book_respond_get_supported_fields (book,
- GNOME_Evolution_Addressbook_BookListener_Success,
- bl->priv->supported_fields);
-}
-
-static void
-pas_backend_ldap_process_client_requests (PASBook *book)
-{
- PASBackend *backend;
- PASRequest *req;
-
- backend = pas_book_get_backend (book);
-
- req = pas_book_pop_request (book);
- if (req == NULL)
- return;
-
- switch (req->op) {
- case CreateCard:
- pas_backend_ldap_process_create_card (backend, book, req);
- break;
-
- case RemoveCard:
- pas_backend_ldap_process_remove_card (backend, book, req);
- break;
-
- case ModifyCard:
- pas_backend_ldap_process_modify_card (backend, book, req);
- break;
-
- case CheckConnection:
- pas_backend_ldap_process_check_connection (backend, book, req);
- break;
-
- case GetVCard:
- pas_backend_ldap_process_get_vcard (backend, book, req);
- break;
-
- case GetCursor:
- pas_backend_ldap_process_get_cursor (backend, book, req);
- break;
-
- case GetBookView:
- pas_backend_ldap_process_get_book_view (backend, book, req);
- break;
-
- case GetCompletionView:
- /* we don't support summaries so completion view requests are the same as book view requests */
- pas_backend_ldap_process_get_book_view (backend, book, req);
- break;
-
- case GetChanges:
- /* FIXME: Code this. */
- break;
-
- case AuthenticateUser:
- pas_backend_ldap_process_authenticate_user (backend, book, req);
- break;
-
- case GetSupportedFields:
- pas_backend_ldap_process_get_supported_fields (backend, book, req);
- break;
- }
-
- pas_book_free_request (req);
-}
-
-static void
-pas_backend_ldap_book_destroy_cb (PASBook *book, gpointer data)
-{
- PASBackendLDAP *backend;
-
- backend = PAS_BACKEND_LDAP (data);
-
- pas_backend_remove_client (PAS_BACKEND (backend), book);
-}
-
-static GNOME_Evolution_Addressbook_BookListener_CallStatus
-pas_backend_ldap_load_uri (PASBackend *backend,
- const char *uri)
-{
- PASBackendLDAP *bl = PAS_BACKEND_LDAP (backend);
- LDAPURLDesc *lud;
- int ldap_error;
- char **attributes;
- int i;
- int limit = 100;
- int timeout = 60; /* 1 minute */
-
- g_assert (bl->priv->connected == FALSE);
-
- attributes = g_strsplit (uri, ";", 0);
-
- if (attributes[0] == NULL)
- return FALSE;
-
- for (i = 1; attributes[i]; i++) {
- char *equals;
- char *value;
- int key_length;
- equals = strchr (attributes[i], '=');
- if (equals) {
- key_length = equals - attributes[i];
- value = equals + 1;
- } else {
- key_length = strlen (attributes[i]);
- value = NULL;
- }
-
- if (key_length == strlen("limit") && !strncmp (attributes[i], "limit", key_length)) {
- if (value)
- limit = atoi(value);
- }
- else if (key_length == strlen("ssl") && !strncmp (attributes[i], "ssl", key_length)) {
- if (value) {
- if (!strncmp (value, "always", 6)) {
- bl->priv->use_tls = PAS_BACKEND_LDAP_TLS_ALWAYS;
- }
- else if (!strncmp (value, "whenever_possible", 3)) {
- bl->priv->use_tls = PAS_BACKEND_LDAP_TLS_WHEN_POSSIBLE;
- }
- else {
- g_warning ("unhandled value for use_tls, not using it");
- }
- }
- else {
- bl->priv->use_tls = PAS_BACKEND_LDAP_TLS_WHEN_POSSIBLE;
- }
- }
- else if (key_length == strlen("timeout") && !strncmp (attributes[i], "timeout", key_length)) {
- if (value)
- timeout = atoi (value);
- }
- }
-
- ldap_error = ldap_url_parse ((char*)attributes[0], &lud);
- g_strfreev (attributes);
-
- if (ldap_error == LDAP_SUCCESS) {
- g_free(bl->priv->uri);
- bl->priv->uri = g_strdup (uri);
- bl->priv->ldap_host = g_strdup(lud->lud_host);
- bl->priv->ldap_port = lud->lud_port;
- /* if a port wasn't specified, default to LDAP_PORT */
- if (bl->priv->ldap_port == 0)
- bl->priv->ldap_port = LDAP_PORT;
- bl->priv->ldap_rootdn = g_strdup(lud->lud_dn);
- bl->priv->ldap_limit = limit;
- bl->priv->ldap_timeout = timeout;
- bl->priv->ldap_scope = lud->lud_scope;
-
- ldap_free_urldesc(lud);
-
- 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;
-}
-
-static gboolean
-pas_backend_ldap_add_client (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener)
-{
- PASBackendLDAP *bl;
- PASBook *book;
-
- g_assert (backend != NULL);
- g_assert (PAS_IS_BACKEND_LDAP (backend));
-
- bl = PAS_BACKEND_LDAP (backend);
-
- book = pas_book_new (backend, listener);
-
- if (!book) {
- if (!bl->priv->clients)
- pas_backend_last_client_gone (backend);
-
- return FALSE;
- }
-
- gtk_signal_connect (GTK_OBJECT (book), "destroy",
- pas_backend_ldap_book_destroy_cb, backend);
-
- gtk_signal_connect (GTK_OBJECT (book), "requests_queued",
- pas_backend_ldap_process_client_requests, NULL);
-
- bl->priv->clients = g_list_prepend (
- bl->priv->clients, book);
-
- if (bl->priv->connected) {
- pas_book_respond_open (
- book, GNOME_Evolution_Addressbook_BookListener_Success);
- } else {
- pas_book_respond_open (
- book, GNOME_Evolution_Addressbook_BookListener_OtherError);
- }
-
- pas_book_report_writable (book, bl->priv->writable);
-
- bonobo_object_unref (BONOBO_OBJECT (book));
-
- return TRUE;
-}
-
-static void
-pas_backend_ldap_remove_client (PASBackend *backend,
- PASBook *book)
-{
- PASBackendLDAP *bl;
-
- g_return_if_fail (backend != NULL);
- g_return_if_fail (PAS_IS_BACKEND_LDAP (backend));
- g_return_if_fail (book != NULL);
- g_return_if_fail (PAS_IS_BOOK (book));
-
- bl = PAS_BACKEND_LDAP (backend);
-
- /* Disconnect */
- bl->priv->clients = g_list_remove (bl->priv->clients, book);
-
- /* When all clients go away, notify the parent factory about it so that
- * it may decide whether to kill the backend or not.
- */
- if (!bl->priv->clients)
- pas_backend_last_client_gone (backend);
-}
-
-static char *
-pas_backend_ldap_get_static_capabilities (PASBackend *backend)
-{
- return g_strdup("net");
-}
-
-static gboolean
-pas_backend_ldap_construct (PASBackendLDAP *backend)
-{
- g_assert (backend != NULL);
- g_assert (PAS_IS_BACKEND_LDAP (backend));
-
- if (! pas_backend_construct (PAS_BACKEND (backend)))
- return FALSE;
-
- return TRUE;
-}
-
-/**
- * pas_backend_ldap_new:
- */
-PASBackend *
-pas_backend_ldap_new (void)
-{
- PASBackendLDAP *backend;
-
- backend = gtk_type_new (pas_backend_ldap_get_type ());
-
- if (! pas_backend_ldap_construct (backend)) {
- gtk_object_unref (GTK_OBJECT (backend));
-
- return NULL;
- }
-
- return PAS_BACKEND (backend);
-}
-
-static gboolean
-call_dtor (int msgid, LDAPOp *op, gpointer data)
-{
- ldap_abandon (PAS_BACKEND_LDAP(op->backend)->priv->ldap, op->id);
-
- op->dtor (op);
-
- return TRUE;
-}
-
-static void
-pas_backend_ldap_destroy (GtkObject *object)
-{
- PASBackendLDAP *bl;
-
- bl = PAS_BACKEND_LDAP (object);
-
- g_hash_table_foreach_remove (bl->priv->id_to_op, (GHRFunc)call_dtor, NULL);
- g_hash_table_destroy (bl->priv->id_to_op);
-
- if (bl->priv->poll_timeout != -1) {
- printf ("removing timeout\n");
- g_source_remove (bl->priv->poll_timeout);
- }
-
- gtk_object_unref (GTK_OBJECT (bl->priv->book_views));
-
- if (bl->priv->supported_fields)
- gtk_object_unref (GTK_OBJECT (bl->priv->supported_fields));
-
- g_free (bl->priv->uri);
-
- GTK_OBJECT_CLASS (pas_backend_ldap_parent_class)->destroy (object);
-}
-
-static void
-pas_backend_ldap_class_init (PASBackendLDAPClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
- PASBackendClass *parent_class;
-
- /* get client side information (extensions present in the library) */
- get_ldap_library_info ();
-
- pas_backend_ldap_parent_class = gtk_type_class (pas_backend_get_type ());
-
- parent_class = PAS_BACKEND_CLASS (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->add_client = pas_backend_ldap_add_client;
- parent_class->remove_client = pas_backend_ldap_remove_client;
- parent_class->get_static_capabilities = pas_backend_ldap_get_static_capabilities;
-
- object_class->destroy = pas_backend_ldap_destroy;
-}
-
-static void
-pas_backend_ldap_init (PASBackendLDAP *backend)
-{
- PASBackendLDAPPrivate *priv;
-
- 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);
-
- backend->priv = priv;
-}
-
-/**
- * pas_backend_ldap_get_type:
- */
-GtkType
-pas_backend_ldap_get_type (void)
-{
- static GtkType type = 0;
-
- if (! type) {
- GtkTypeInfo info = {
- "PASBackendLDAP",
- sizeof (PASBackendLDAP),
- sizeof (PASBackendLDAPClass),
- (GtkClassInitFunc) pas_backend_ldap_class_init,
- (GtkObjectInitFunc) pas_backend_ldap_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (pas_backend_get_type (), &info);
- }
-
- return type;
-}
diff --git a/addressbook/backend/pas/pas-backend-ldap.h b/addressbook/backend/pas/pas-backend-ldap.h
deleted file mode 100644
index 9f32c58bbf..0000000000
--- a/addressbook/backend/pas/pas-backend-ldap.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2000, Ximian, Inc.
- */
-
-#ifndef __PAS_BACKEND_LDAP_H__
-#define __PAS_BACKEND_LDAP_H__
-
-#include <libgnome/gnome-defs.h>
-#include "pas-backend.h"
-
-typedef struct _PASBackendLDAPPrivate PASBackendLDAPPrivate;
-
-typedef struct {
- PASBackend parent_object;
- PASBackendLDAPPrivate *priv;
-} PASBackendLDAP;
-
-typedef struct {
- PASBackendClass parent_class;
-} PASBackendLDAPClass;
-
-PASBackend *pas_backend_ldap_new (void);
-GtkType pas_backend_ldap_get_type (void);
-
-#define PAS_BACKEND_LDAP_TYPE (pas_backend_ldap_get_type ())
-#define PAS_BACKEND_LDAP(o) (GTK_CHECK_CAST ((o), PAS_BACKEND_LDAP_TYPE, PASBackendLDAP))
-#define PAS_BACKEND_LDAP_CLASS(k) (GTK_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendLDAPClass))
-#define PAS_IS_BACKEND_LDAP(o) (GTK_CHECK_TYPE ((o), PAS_BACKEND_LDAP_TYPE))
-#define PAS_IS_BACKEND_LDAP_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), PAS_BACKEND_LDAP_TYPE))
-
-#endif /* ! __PAS_BACKEND_LDAP_H__ */
-
diff --git a/addressbook/backend/pas/pas-backend-summary.c b/addressbook/backend/pas/pas-backend-summary.c
deleted file mode 100644
index fb91718b9b..0000000000
--- a/addressbook/backend/pas/pas-backend-summary.c
+++ /dev/null
@@ -1,1087 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * pas-backend-summary.c
- * Copyright 2000, 2001, Ximian, Inc.
- *
- * Authors:
- * Chris Toshok <toshok@ximian.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License, version 2, as published by the Free Software Foundation.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library 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 <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include <netinet/in.h>
-
-#include <gal/widgets/e-unicode.h>
-
-#include "ebook/e-card-simple.h"
-#include "pas-backend-summary.h"
-#include "e-util/e-sexp.h"
-
-static GtkObjectClass *parent_class;
-
-struct _PASBackendSummaryPrivate {
- char *summary_path;
- FILE *fp;
- guint32 file_version;
- time_t mtime;
- gboolean upgraded;
- gboolean dirty;
- int flush_timeout_millis;
- int flush_timeout;
- GPtrArray *items;
- GHashTable *id_to_item;
- guint32 num_items; /* used only for loading */
-#ifdef SUMMARY_STATS
- int size;
-#endif
-};
-
-typedef struct {
- char *id;
- char *nickname;
- char *full_name;
- char *given_name;
- char *surname;
- char *file_as;
- char *email_1;
- char *email_2;
- char *email_3;
- gboolean wants_html;
- gboolean wants_html_set;
- gboolean list;
- gboolean list_show_addresses;
-} PASBackendSummaryItem;
-
-typedef struct {
- /* these lengths do *not* including the terminating \0, as
- it's not stored on disk. */
- guint16 id_len;
- guint16 nickname_len;
- guint16 full_name_len; /* version 3.0 field */
- guint16 given_name_len;
- guint16 surname_len;
- guint16 file_as_len;
- guint16 email_1_len;
- guint16 email_2_len;
- guint16 email_3_len;
- guint8 wants_html;
- guint8 wants_html_set;
- guint8 list;
- guint8 list_show_addresses;
-} PASBackendSummaryDiskItem;
-
-typedef struct {
- guint32 file_version;
- guint32 num_items;
- guint32 summary_mtime; /* version 2.0 field */
-} PASBackendSummaryHeader;
-
-#define PAS_SUMMARY_MAGIC "PAS-SUMMARY"
-#define PAS_SUMMARY_MAGIC_LEN 11
-
-#define PAS_SUMMARY_FILE_VERSION_1_0 1000
-#define PAS_SUMMARY_FILE_VERSION_2_0 2000
-#define PAS_SUMMARY_FILE_VERSION_3_0 3000
-#define PAS_SUMMARY_FILE_VERSION_4_0 4000
-
-#define PAS_SUMMARY_FILE_VERSION PAS_SUMMARY_FILE_VERSION_4_0
-
-static void
-free_summary_item (PASBackendSummaryItem *item)
-{
- g_free (item->id);
- g_free (item->nickname);
- g_free (item->full_name);
- g_free (item->given_name);
- g_free (item->surname);
- g_free (item->file_as);
- g_free (item->email_1);
- g_free (item->email_2);
- g_free (item->email_3);
- g_free (item);
-}
-
-static void
-clear_items (PASBackendSummary *summary)
-{
- int i;
- int num = summary->priv->items->len;
- for (i = 0; i < num; i++) {
- PASBackendSummaryItem *item = g_ptr_array_remove_index_fast (summary->priv->items, 0);
- g_hash_table_remove (summary->priv->id_to_item, item->id);
- free_summary_item (item);
- }
-}
-
-PASBackendSummary*
-pas_backend_summary_new (const char *summary_path, int flush_timeout_millis)
-{
- PASBackendSummary *summary = gtk_type_new (PAS_BACKEND_SUMMARY_TYPE);
-
- summary->priv->summary_path = g_strdup (summary_path);
- summary->priv->flush_timeout_millis = flush_timeout_millis;
- summary->priv->file_version = PAS_SUMMARY_FILE_VERSION_4_0;
-
- return summary;
-}
-
-static void
-pas_backend_summary_destroy (GtkObject *object)
-{
- PASBackendSummary *summary = PAS_BACKEND_SUMMARY (object);
-
- if (summary->priv->dirty)
- g_warning ("Destroying dirty summary");
-
- if (summary->priv->flush_timeout) {
- gtk_timeout_remove (summary->priv->flush_timeout);
- summary->priv->flush_timeout = 0;
- }
-
- if (summary->priv->fp)
- fclose (summary->priv->fp);
-
- g_free (summary->priv->summary_path);
- clear_items (summary);
- g_ptr_array_free (summary->priv->items, TRUE);
-
- g_hash_table_destroy (summary->priv->id_to_item);
-
- g_free (summary->priv);
-
- GTK_OBJECT_CLASS (parent_class)->destroy (object);
-}
-
-static void
-pas_backend_summary_class_init (PASBackendSummaryClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
-
- parent_class = gtk_type_class (gtk_object_get_type ());
-
- /* Set the virtual methods. */
-
- object_class->destroy = pas_backend_summary_destroy;
-}
-
-static void
-pas_backend_summary_init (PASBackendSummary *summary)
-{
- PASBackendSummaryPrivate *priv;
-
- priv = g_new(PASBackendSummaryPrivate, 1);
-
- summary->priv = priv;
-
- priv->summary_path = NULL;
- priv->fp = NULL;
- priv->dirty = FALSE;
- priv->upgraded = FALSE;
- priv->items = g_ptr_array_new();
- priv->id_to_item = g_hash_table_new (g_str_hash, g_str_equal);
- priv->flush_timeout_millis = 0;
- priv->flush_timeout = 0;
-#ifdef SUMMARY_STATS
- priv->size = 0;
-#endif
-}
-
-/**
- * pas_backend_summary_get_type:
- */
-GtkType
-pas_backend_summary_get_type (void)
-{
- static GtkType type = 0;
-
- if (! type) {
- GtkTypeInfo info = {
- "PASBackendSummary",
- sizeof (PASBackendSummary),
- sizeof (PASBackendSummaryClass),
- (GtkClassInitFunc) pas_backend_summary_class_init,
- (GtkObjectInitFunc) pas_backend_summary_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (gtk_object_get_type (), &info);
- }
-
- return type;
-}
-
-
-static gboolean
-pas_backend_summary_check_magic (PASBackendSummary *summary, FILE *fp)
-{
- char buf [PAS_SUMMARY_MAGIC_LEN + 1];
- int rv;
-
- memset (buf, 0, sizeof (buf));
-
- rv = fread (buf, PAS_SUMMARY_MAGIC_LEN, 1, fp);
- if (rv != 1)
- return FALSE;
- if (strcmp (buf, PAS_SUMMARY_MAGIC))
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-pas_backend_summary_load_header (PASBackendSummary *summary, FILE *fp,
- PASBackendSummaryHeader *header)
-{
- int rv;
-
- rv = fread (&header->file_version, sizeof (header->file_version), 1, fp);
- if (rv != 1)
- return FALSE;
-
- header->file_version = ntohl (header->file_version);
-
- if (header->file_version < PAS_SUMMARY_FILE_VERSION) {
- return FALSE; /* this will cause the entire summary to be rebuilt */
- }
-
- rv = fread (&header->num_items, sizeof (header->num_items), 1, fp);
- if (rv != 1)
- return FALSE;
-
- header->num_items = ntohl (header->num_items);
-
- rv = fread (&header->summary_mtime, sizeof (header->summary_mtime), 1, fp);
- if (rv != 1)
- return FALSE;
- header->summary_mtime = ntohl (header->summary_mtime);
-
- return TRUE;
-}
-
-static char *
-read_string (FILE *fp, int len)
-{
- char *buf;
- int rv;
-
- buf = g_new0 (char, len + 1);
-
- rv = fread (buf, len, 1, fp);
- if (rv != 1) {
- g_free (buf);
- return NULL;
- }
-
- return buf;
-}
-
-static gboolean
-pas_backend_summary_load_item (PASBackendSummary *summary,
- PASBackendSummaryItem **new_item)
-{
- PASBackendSummaryItem *item;
- char *buf;
- FILE *fp = summary->priv->fp;
-
- if (summary->priv->file_version >= PAS_SUMMARY_FILE_VERSION_4_0) {
- PASBackendSummaryDiskItem disk_item;
- int rv = fread (&disk_item, sizeof (disk_item), 1, fp);
- if (rv != 1)
- return FALSE;
-
- disk_item.id_len = ntohs (disk_item.id_len);
- disk_item.nickname_len = ntohs (disk_item.nickname_len);
- disk_item.full_name_len = ntohs (disk_item.full_name_len);
- disk_item.given_name_len = ntohs (disk_item.given_name_len);
- disk_item.surname_len = ntohs (disk_item.surname_len);
- disk_item.file_as_len = ntohs (disk_item.file_as_len);
- disk_item.email_1_len = ntohs (disk_item.email_1_len);
- disk_item.email_2_len = ntohs (disk_item.email_2_len);
- disk_item.email_3_len = ntohs (disk_item.email_3_len);
-
- item = g_new0 (PASBackendSummaryItem, 1);
-
- item->wants_html = disk_item.wants_html;
- item->wants_html_set = disk_item.wants_html_set;
- item->list = disk_item.list;
- item->list_show_addresses = disk_item.list_show_addresses;
-
- if (disk_item.id_len) {
- buf = read_string (fp, disk_item.id_len);
- if (!buf) {
- free_summary_item (item);
- return FALSE;
- }
- item->id = buf;
- }
-
- if (disk_item.nickname_len) {
- buf = read_string (fp, disk_item.nickname_len);
- if (!buf) {
- free_summary_item (item);
- return FALSE;
- }
- item->nickname = buf;
- }
-
- if (disk_item.full_name_len) {
- buf = read_string (fp, disk_item.full_name_len);
- if (!buf) {
- free_summary_item (item);
- return FALSE;
- }
- item->full_name = buf;
- }
-
- if (disk_item.given_name_len) {
- buf = read_string (fp, disk_item.given_name_len);
- if (!buf) {
- free_summary_item (item);
- return FALSE;
- }
- item->given_name = buf;
- }
-
- if (disk_item.surname_len) {
- buf = read_string (fp, disk_item.surname_len);
- if (!buf) {
- free_summary_item (item);
- return FALSE;
- }
- item->surname = buf;
- }
-
- if (disk_item.file_as_len) {
- buf = read_string (fp, disk_item.file_as_len);
- if (!buf) {
- free_summary_item (item);
- return FALSE;
- }
- item->file_as = buf;
- }
-
- if (disk_item.email_1_len) {
- buf = read_string (fp, disk_item.email_1_len);
- if (!buf) {
- free_summary_item (item);
- return FALSE;
- }
- item->email_1 = buf;
- }
-
- if (disk_item.email_2_len) {
- buf = read_string (fp, disk_item.email_2_len);
- if (!buf) {
- free_summary_item (item);
- return FALSE;
- }
- item->email_2 = buf;
- }
-
- if (disk_item.email_3_len) {
- buf = read_string (fp, disk_item.email_3_len);
- if (!buf) {
- free_summary_item (item);
- return FALSE;
- }
- item->email_3 = buf;
- }
-
- /* the only field that has to be there is the id */
- if (!item->id) {
- free_summary_item (item);
- return FALSE;
- }
- }
- else {
- /* unhandled file version */
- return FALSE;
- }
-
- *new_item = item;
- return TRUE;
-}
-
-/* opens the file and loads the header */
-static gboolean
-pas_backend_summary_open (PASBackendSummary *summary)
-{
- FILE *fp;
- PASBackendSummaryHeader header;
- struct stat sb;
-
- if (summary->priv->fp)
- return TRUE;
-
- if (stat (summary->priv->summary_path, &sb) == -1) {
- /* if there's no summary present, look for the .new
- file and rename it if it's there, and attempt to
- load that */
- char *new_filename = g_strconcat (summary->priv->summary_path, ".new", NULL);
- if (stat (new_filename, &sb) == -1) {
- g_warning ("no summary present");
- g_free (new_filename);
- return FALSE;
- }
- else {
- rename (new_filename, summary->priv->summary_path);
- g_free (new_filename);
- }
- }
-
- fp = fopen (summary->priv->summary_path, "r");
- if (!fp) {
- g_warning ("failed to open summary file");
- return FALSE;
- }
-
- if (!pas_backend_summary_check_magic (summary, fp)) {
- g_warning ("file is not a valid summary file");
- fclose (fp);
- return FALSE;
- }
-
- if (!pas_backend_summary_load_header (summary, fp, &header)) {
- g_warning ("failed to read summary header");
- fclose (fp);
- return FALSE;
- }
-
- summary->priv->num_items = header.num_items;
- summary->priv->file_version = header.file_version;
- summary->priv->mtime = header.summary_mtime;
- summary->priv->fp = fp;
-
- return TRUE;
-}
-
-gboolean
-pas_backend_summary_load (PASBackendSummary *summary)
-{
- PASBackendSummaryItem *new_item;
- int i;
-
- if (!pas_backend_summary_open (summary))
- return FALSE;
-
- for (i = 0; i < summary->priv->num_items; i ++) {
- if (!pas_backend_summary_load_item (summary, &new_item)) {
- g_warning ("error while reading summary item");
- clear_items (summary);
- fclose (summary->priv->fp);
- summary->priv->fp = NULL;
- summary->priv->dirty = FALSE;
- return FALSE;
- }
-
- g_ptr_array_add (summary->priv->items, new_item);
- g_hash_table_insert (summary->priv->id_to_item, new_item->id, new_item);
- }
-
- if (summary->priv->upgraded) {
- pas_backend_summary_save (summary);
- }
- summary->priv->dirty = FALSE;
-
- return TRUE;
-}
-
-static gboolean
-pas_backend_summary_save_magic (FILE *fp)
-{
- int rv;
- rv = fwrite (PAS_SUMMARY_MAGIC, PAS_SUMMARY_MAGIC_LEN, 1, fp);
- if (rv != 1)
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-pas_backend_summary_save_header (PASBackendSummary *summary, FILE *fp)
-{
- PASBackendSummaryHeader header;
- int rv;
-
- header.file_version = htonl (PAS_SUMMARY_FILE_VERSION);
- header.num_items = htonl (summary->priv->items->len);
- header.summary_mtime = htonl (time (NULL));
-
- rv = fwrite (&header, sizeof (header), 1, fp);
- if (rv != 1)
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-save_string (const char *str, FILE *fp)
-{
- int rv;
-
- if (!str || !*str)
- return TRUE;
-
- rv = fwrite (str, strlen (str), 1, fp);
- return (rv == 1);
-}
-
-static gboolean
-pas_backend_summary_save_item (PASBackendSummary *summary, FILE *fp, PASBackendSummaryItem *item)
-{
- PASBackendSummaryDiskItem disk_item;
- int len;
- int rv;
-
- len = item->id ? strlen (item->id) : 0;
- disk_item.id_len = htons (len);
-
- len = item->nickname ? strlen (item->nickname) : 0;
- disk_item.nickname_len = htons (len);
-
- len = item->given_name ? strlen (item->given_name) : 0;
- disk_item.given_name_len = htons (len);
-
- len = item->full_name ? strlen (item->full_name) : 0;
- disk_item.full_name_len = htons (len);
-
- len = item->surname ? strlen (item->surname) : 0;
- disk_item.surname_len = htons (len);
-
- len = item->file_as ? strlen (item->file_as) : 0;
- disk_item.file_as_len = htons (len);
-
- len = item->email_1 ? strlen (item->email_1) : 0;
- disk_item.email_1_len = htons (len);
-
- len = item->email_2 ? strlen (item->email_2) : 0;
- disk_item.email_2_len = htons (len);
-
- len = item->email_3 ? strlen (item->email_3) : 0;
- disk_item.email_3_len = htons (len);
-
- disk_item.wants_html = item->wants_html;
- disk_item.wants_html_set = item->wants_html_set;
- disk_item.list = item->list;
- disk_item.list_show_addresses = item->list_show_addresses;
-
- rv = fwrite (&disk_item, sizeof(disk_item), 1, fp);
- if (rv != 1)
- return FALSE;
-
- if (!save_string (item->id, fp))
- return FALSE;
- if (!save_string (item->nickname, fp))
- return FALSE;
- if (!save_string (item->full_name, fp))
- return FALSE;
- if (!save_string (item->given_name, fp))
- return FALSE;
- if (!save_string (item->surname, fp))
- return FALSE;
- if (!save_string (item->file_as, fp))
- return FALSE;
- if (!save_string (item->email_1, fp))
- return FALSE;
- if (!save_string (item->email_2, fp))
- return FALSE;
- if (!save_string (item->email_3, fp))
- return FALSE;
-
- return TRUE;
-}
-
-gboolean
-pas_backend_summary_save (PASBackendSummary *summary)
-{
- struct stat sb;
- FILE *fp = NULL;
- char *new_filename = NULL;
- int i;
-
- if (!summary->priv->dirty)
- return TRUE;
-
- new_filename = g_strconcat (summary->priv->summary_path, ".new", NULL);
-
- fp = fopen (new_filename, "w");
- if (!fp) {
- g_warning ("could not create new summary file");
- goto lose;
- }
-
- if (!pas_backend_summary_save_magic (fp)) {
- g_warning ("could not write magic to new summary file");
- goto lose;
- }
-
- if (!pas_backend_summary_save_header (summary, fp)) {
- g_warning ("could not write header to new summary file");
- goto lose;
- }
-
- for (i = 0; i < summary->priv->items->len; i ++) {
- PASBackendSummaryItem *item = g_ptr_array_index (summary->priv->items, i);
- if (!pas_backend_summary_save_item (summary, fp, item)) {
- g_warning ("failed to write an item to new summary file, errno = %d", errno);
- goto lose;
- }
- }
-
- fclose (fp);
-
- /* if we have a queued flush, clear it (since we just flushed) */
- if (summary->priv->flush_timeout) {
- gtk_timeout_remove (summary->priv->flush_timeout);
- summary->priv->flush_timeout = 0;
- }
-
- /* unlink the old summary and rename the new one */
- unlink (summary->priv->summary_path);
- rename (new_filename, summary->priv->summary_path);
-
- g_free (new_filename);
-
- /* lastly, update the in memory mtime to that of the file */
- if (stat (summary->priv->summary_path, &sb) == -1) {
- g_warning ("error stat'ing saved summary");
- }
- else {
- summary->priv->mtime = sb.st_mtime;
- }
-
- return TRUE;
-
- lose:
- if (fp)
- fclose (fp);
- if (new_filename)
- unlink (new_filename);
- g_free (new_filename);
- return FALSE;
-}
-
-void
-pas_backend_summary_add_card (PASBackendSummary *summary, const char *vcard)
-{
- 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;
-
- g_ptr_array_add (summary->priv->items, new_item);
- g_hash_table_insert (summary->priv->id_to_item, new_item->id, new_item);
-
- gtk_object_unref (GTK_OBJECT (simple));
- gtk_object_unref (GTK_OBJECT (card));
-
-#ifdef SUMMARY_STATS
- summary->priv->size += sizeof (PASBackendSummaryItem);
- summary->priv->size += new_item->id ? strlen (new_item->id) : 0;
- summary->priv->size += new_item->nickname ? strlen (new_item->nickname) : 0;
- summary->priv->size += new_item->full_name ? strlen (new_item->full_name) : 0;
- summary->priv->size += new_item->given_name ? strlen (new_item->given_name) : 0;
- summary->priv->size += new_item->surname ? strlen (new_item->surname) : 0;
- summary->priv->size += new_item->file_as ? strlen (new_item->file_as) : 0;
- summary->priv->size += new_item->email_1 ? strlen (new_item->email_1) : 0;
- summary->priv->size += new_item->email_2 ? strlen (new_item->email_2) : 0;
- summary->priv->size += new_item->email_3 ? strlen (new_item->email_3) : 0;
-#endif
- pas_backend_summary_touch (summary);
-}
-
-void
-pas_backend_summary_remove_card (PASBackendSummary *summary, const char *id)
-{
- PASBackendSummaryItem *item = g_hash_table_lookup (summary->priv->id_to_item, id);
-
- if (item) {
- g_ptr_array_remove (summary->priv->items, item);
- g_hash_table_remove (summary->priv->id_to_item, id);
- free_summary_item (item);
- pas_backend_summary_touch (summary);
- return;
- }
-
- g_warning ("pas_backend_summary_remove_card: unable to locate id `%s'", id);
-}
-
-static int
-summary_flush_func (gpointer data)
-{
- PASBackendSummary *summary = PAS_BACKEND_SUMMARY (data);
-
- if (!summary->priv->dirty) {
- summary->priv->flush_timeout = 0;
- return FALSE;
- }
-
- if (!pas_backend_summary_save (summary)) {
- /* this isn't fatal, as we can just either 1) flush
- out with the next change, or 2) regen the summary
- when we next load the uri */
- g_warning ("failed to flush summary file to disk");
- return TRUE; /* try again after the next timeout */
- }
-
- g_warning ("flushed summary to disk");
-
- /* we only want this to execute once, so return FALSE and set
- summary->flush_timeout to 0 */
- summary->priv->flush_timeout = 0;
- return FALSE;
-}
-
-void
-pas_backend_summary_touch (PASBackendSummary *summary)
-{
- summary->priv->dirty = TRUE;
- if (!summary->priv->flush_timeout
- && summary->priv->flush_timeout_millis)
- summary->priv->flush_timeout = gtk_timeout_add (summary->priv->flush_timeout_millis,
- summary_flush_func, summary);
-}
-
-gboolean
-pas_backend_summary_is_up_to_date (PASBackendSummary *summary, time_t t)
-{
- if (!pas_backend_summary_open (summary))
- return FALSE;
- else
- return summary->priv->mtime >= t;
-}
-
-
-/* we only want to do summary queries if the query is over the set fields in the summary */
-
-static ESExpResult *
-func_check(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- ESExpResult *r;
- int truth = FALSE;
-
- if (argc == 2
- && argv[0]->type == ESEXP_RES_STRING
- && argv[1]->type == ESEXP_RES_STRING) {
- char *query_name = argv[0]->value.string;
-
- if (!strcmp (query_name, "nickname") ||
- !strcmp (query_name, "full_name") ||
- !strcmp (query_name, "file_as") ||
- !strcmp (query_name, "email")) {
- truth = TRUE;
- }
- }
-
- r = e_sexp_result_new(f, ESEXP_RES_BOOL);
- r->value.bool = truth;
-
- 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 */
-} check_symbols[] = {
- { "contains", func_check, 0 },
- { "is", func_check, 0 },
- { "beginswith", func_check, 0 },
- { "endswith", func_check, 0 },
-};
-
-gboolean
-pas_backend_summary_is_summary_query (PASBackendSummary *summary, const char *query)
-{
- ESExp *sexp;
- ESExpResult *r;
- gboolean retval;
- int i;
- int esexp_error;
-
- sexp = e_sexp_new();
-
- for(i=0;i<sizeof(check_symbols)/sizeof(check_symbols[0]);i++) {
- if (check_symbols[i].type == 1) {
- e_sexp_add_ifunction(sexp, 0, check_symbols[i].name,
- (ESExpIFunc *)check_symbols[i].func, summary);
- } else {
- e_sexp_add_function(sexp, 0, check_symbols[i].name,
- check_symbols[i].func, summary);
- }
- }
-
- e_sexp_input_text(sexp, query, strlen(query));
- esexp_error = e_sexp_parse(sexp);
-
- if (esexp_error == -1) {
- return FALSE;
- }
-
- r = e_sexp_eval(sexp);
-
- retval = (r && r->type == ESEXP_RES_BOOL && r->value.bool);
-
- e_sexp_result_free(sexp, r);
-
- e_sexp_unref (sexp);
-
- return retval;
-}
-
-
-
-/* the actual query mechanics */
-static ESExpResult *
-do_compare (PASBackendSummary *summary, struct _ESExp *f, int argc,
- struct _ESExpResult **argv,
- char *(*compare)(const char*, const char*))
-{
- GPtrArray *result = g_ptr_array_new ();
- ESExpResult *r;
- int i;
-
- if (argc == 2
- && argv[0]->type == ESEXP_RES_STRING
- && argv[1]->type == ESEXP_RES_STRING) {
-
- for (i = 0; i < summary->priv->items->len; i ++) {
- PASBackendSummaryItem *item = g_ptr_array_index (summary->priv->items, i);
- if (!strcmp (argv[0]->value.string, "full_name")) {
- char *given = item->given_name;
- char *surname = item->surname;
- if ((given && compare (given, argv[1]->value.string))
- || (surname && compare (surname, argv[1]->value.string)))
- g_ptr_array_add (result, item->id);
- }
- else if (!strcmp (argv[0]->value.string, "email")) {
- char *email_1 = item->email_1;
- char *email_2 = item->email_2;
- char *email_3 = item->email_3;
- if ((email_1 && compare (email_1, argv[1]->value.string))
- || (email_2 && compare (email_2, argv[1]->value.string))
- || (email_3 && compare (email_3, argv[1]->value.string)))
- g_ptr_array_add (result, item->id);
- }
- else if (!strcmp (argv[0]->value.string, "file_as")) {
- char *file_as = item->file_as;
- if (file_as && compare (file_as, argv[1]->value.string))
- g_ptr_array_add (result, item->id);
- }
- else if (!strcmp (argv[0]->value.string, "nickname")) {
- char *nickname = item->nickname;
- if (nickname && compare (nickname, argv[1]->value.string))
- g_ptr_array_add (result, item->id);
- }
- }
- }
-
- r = e_sexp_result_new(f, ESEXP_RES_ARRAY_PTR);
- r->value.ptrarray = result;
-
- return r;
-}
-
-static ESExpResult *
-func_contains(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- PASBackendSummary *summary = data;
-
- return do_compare (summary, f, argc, argv, (char *(*)(const char*, const char*)) e_utf8_strstrcase);
-}
-
-static char *
-is_helper (const char *s1, const char *s2)
-{
- if (!strcasecmp(s1, s2))
- return (char*)s1;
- else
- return NULL;
-}
-
-static ESExpResult *
-func_is(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- PASBackendSummary *summary = data;
-
- return do_compare (summary, f, argc, argv, is_helper);
-}
-
-static char *
-endswith_helper (const char *s1, const char *s2)
-{
- char *p;
- if ((p = (char*)e_utf8_strstrcase(s1, s2))
- && (strlen(p) == strlen(s2)))
- return p;
- else
- return NULL;
-}
-
-static ESExpResult *
-func_endswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- PASBackendSummary *summary = data;
-
- return do_compare (summary, f, argc, argv, endswith_helper);
-}
-
-static char *
-beginswith_helper (const char *s1, const char *s2)
-{
- char *p;
- if ((p = (char*)e_utf8_strstrcase(s1, s2))
- && (p == s1))
- return p;
- else
- return NULL;
-}
-
-static ESExpResult *
-func_beginswith(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data)
-{
- PASBackendSummary *summary = data;
-
- return do_compare (summary, f, argc, argv, beginswith_helper);
-}
-
-/* '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[] = {
- { "contains", func_contains, 0 },
- { "is", func_is, 0 },
- { "beginswith", func_beginswith, 0 },
- { "endswith", func_endswith, 0 },
-};
-
-GPtrArray*
-pas_backend_summary_search (PASBackendSummary *summary, const char *query)
-{
- ESExp *sexp;
- ESExpResult *r;
- GPtrArray *retval = g_ptr_array_new();
- int i;
- int esexp_error;
-
- 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, summary);
- } else {
- e_sexp_add_function(sexp, 0, symbols[i].name,
- symbols[i].func, summary);
- }
- }
-
- e_sexp_input_text(sexp, query, strlen(query));
- esexp_error = e_sexp_parse(sexp);
-
- if (esexp_error == -1) {
- return NULL;
- }
-
- r = e_sexp_eval(sexp);
-
- if (r && r->type == ESEXP_RES_ARRAY_PTR && r->value.ptrarray) {
- GPtrArray *ptrarray = r->value.ptrarray;
- int i;
-
- for (i = 0; i < ptrarray->len; i ++)
- g_ptr_array_add (retval, g_ptr_array_index (ptrarray, i));
- }
-
- e_sexp_result_free(sexp, r);
-
- e_sexp_unref (sexp);
-
- return retval;
-}
-
-char*
-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);
- 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_card_simple_sync_card (simple);
-
- 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_card_simple_get_vcard (simple);
-
- gtk_object_unref (GTK_OBJECT (simple));
- gtk_object_unref (GTK_OBJECT (card));
-
- return vcard;
- }
- else {
- g_warning ("in unable to locate card `%s' in summary", id);
- return NULL;
- }
-}
-
diff --git a/addressbook/backend/pas/pas-backend-summary.h b/addressbook/backend/pas/pas-backend-summary.h
deleted file mode 100644
index 96f069652e..0000000000
--- a/addressbook/backend/pas/pas-backend-summary.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * pas-backend-summary.h
- * Copyright 2000, 2001, Ximian, Inc.
- *
- * Authors:
- * Chris Toshok <toshok@ximian.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License, version 2, as published by the Free Software Foundation.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library 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 __PAS_BACKEND_SUMMARY_H__
-#define __PAS_BACKEND_SUMMARY_H__
-
-#include <gtk/gtk.h>
-
-typedef struct _PASBackendSummaryPrivate PASBackendSummaryPrivate;
-
-typedef struct {
- GtkObject parent_object;
- PASBackendSummaryPrivate *priv;
-} PASBackendSummary;
-
-typedef struct {
- GtkObjectClass parent_class;
-} PASBackendSummaryClass;
-
-PASBackendSummary* pas_backend_summary_new (const char *summary_path,
- int flush_timeout_millis);
-GtkType pas_backend_summary_get_type (void);
-
-/* returns FALSE if the load fails for any reason (including that the
- summary is out of date), TRUE if it succeeds */
-gboolean pas_backend_summary_load (PASBackendSummary *summary);
-/* 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_touch (PASBackendSummary *summary);
-
-/* returns TRUE if the summary's mtime is >= @t. */
-gboolean pas_backend_summary_is_up_to_date (PASBackendSummary *summary, time_t t);
-
-gboolean pas_backend_summary_is_summary_query (PASBackendSummary *summary, const char *query);
-GPtrArray* pas_backend_summary_search (PASBackendSummary *summary, const char *query);
-char* pas_backend_summary_get_summary_vcard (PASBackendSummary *summary, const char *id);
-
-#define PAS_BACKEND_SUMMARY_TYPE (pas_backend_summary_get_type ())
-#define PAS_BACKEND_SUMMARY(o) (GTK_CHECK_CAST ((o), PAS_BACKEND_SUMMARY_TYPE, PASBackendSummary))
-#define PAS_BACKEND_SUMMARY_CLASS(k) (GTK_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendSummaryClass))
-#define PAS_IS_BACKEND_SUMMARY(o) (GTK_CHECK_TYPE ((o), PAS_BACKEND_SUMMARY_TYPE))
-#define PAS_IS_BACKEND_SUMMARY_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), PAS_BACKEND_SUMMARY_TYPE))
-
-#endif /* __PAS_BACKEND_SUMMARY_H__ */
diff --git a/addressbook/backend/pas/pas-backend.c b/addressbook/backend/pas/pas-backend.c
deleted file mode 100644
index a17e014002..0000000000
--- a/addressbook/backend/pas/pas-backend.c
+++ /dev/null
@@ -1,178 +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.
- */
-
-#include <config.h>
-#include <gtk/gtkobject.h>
-#include <gtk/gtksignal.h>
-#include "pas-backend.h"
-
-#define CLASS(o) PAS_BACKEND_CLASS (GTK_OBJECT (o)->klass)
-
-/* Signal IDs */
-enum {
- LAST_CLIENT_GONE,
- LAST_SIGNAL
-};
-
-static guint pas_backend_signals[LAST_SIGNAL];
-
-
-gboolean
-pas_backend_construct (PASBackend *backend)
-{
- return TRUE;
-}
-
-GNOME_Evolution_Addressbook_BookListener_CallStatus
-pas_backend_load_uri (PASBackend *backend,
- const char *uri)
-{
- 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);
-
- g_assert (CLASS (backend)->load_uri != NULL);
-
- return (* CLASS (backend)->load_uri) (backend, uri);
-}
-
-/**
- * pas_backend_get_uri:
- * @backend: An addressbook backend.
- *
- * Queries the URI that an addressbook backend is serving.
- *
- * Return value: URI for the 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_assert (CLASS (backend)->get_uri != NULL);
-
- return (* CLASS (backend)->get_uri) (backend);
-}
-
-/**
- * pas_backend_add_client:
- * @backend: An addressbook backend.
- * @listener: Listener for notification to the client.
- *
- * 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)
-{
- g_return_val_if_fail (backend != NULL, FALSE);
- g_return_val_if_fail (PAS_IS_BACKEND (backend), FALSE);
- g_return_val_if_fail (listener != CORBA_OBJECT_NIL, FALSE);
-
- g_assert (CLASS (backend)->add_client != NULL);
-
- return CLASS (backend)->add_client (backend, listener);
-}
-
-void
-pas_backend_remove_client (PASBackend *backend,
- PASBook *book)
-{
- g_return_if_fail (backend != NULL);
- g_return_if_fail (PAS_IS_BACKEND (backend));
- g_return_if_fail (book != NULL);
- g_return_if_fail (PAS_IS_BOOK (book));
-
- g_assert (CLASS (backend)->remove_client != NULL);
-
- 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_assert (CLASS (backend)->get_static_capabilities != NULL);
-
- return CLASS (backend)->get_static_capabilities (backend);
-}
-
-/**
- * pas_backend_last_client_gone:
- * @backend: An addressbook backend.
- *
- * Emits the "last_client_gone" signal for the specified backend. Should
- * only be called from backend implementations if the backend really does
- * not have any more clients.
- **/
-void
-pas_backend_last_client_gone (PASBackend *backend)
-{
- g_return_if_fail (backend != NULL);
- g_return_if_fail (PAS_IS_BACKEND (backend));
-
- gtk_signal_emit (GTK_OBJECT (backend), pas_backend_signals[LAST_CLIENT_GONE]);
-}
-
-static void
-pas_backend_init (PASBackend *backend)
-{
-}
-
-static void
-pas_backend_class_init (PASBackendClass *klass)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) klass;
-
- pas_backend_signals[LAST_CLIENT_GONE] =
- gtk_signal_new ("last_client_gone",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (PASBackendClass, last_client_gone),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, pas_backend_signals, LAST_SIGNAL);
-
- klass->add_client = NULL;
- klass->remove_client = NULL;
- klass->get_static_capabilities = NULL;
-}
-
-/**
- * pas_backend_get_type:
- */
-GtkType
-pas_backend_get_type (void)
-{
- static GtkType type = 0;
-
- if (! type) {
- GtkTypeInfo info = {
- "PASBackend",
- sizeof (PASBackend),
- sizeof (PASBackendClass),
- (GtkClassInitFunc) pas_backend_class_init,
- (GtkObjectInitFunc) pas_backend_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (gtk_object_get_type (), &info);
- }
-
- return type;
-}
diff --git a/addressbook/backend/pas/pas-backend.h b/addressbook/backend/pas/pas-backend.h
deleted file mode 100644
index cdf8f37c30..0000000000
--- a/addressbook/backend/pas/pas-backend.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * An abstract class which defines the API to a given backend.
- * There will be one PASBackend object for every URI which is loaded.
- *
- * Two people will call into the PASBackend API:
- *
- * 1. The PASBookFactory, when it has been asked to load a book.
- * It will create a new PASBackend if one is not already running
- * for the requested URI. It will call pas_backend_add_client to
- * add a new client to an existing PASBackend server.
- *
- * 2. A PASBook, when a client has requested an operation on the
- * GNOME_Evolution_Addressbook_Book interface.
- *
- * Author:
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#ifndef __PAS_BACKEND_H__
-#define __PAS_BACKEND_H__
-
-#include <libgnome/gnome-defs.h>
-#include <gtk/gtkobject.h>
-#include <pas/addressbook.h>
-
-typedef struct _PASBackend PASBackend;
-typedef struct _PASBackendPrivate PASBackendPrivate;
-
-#include <pas/pas-book.h>
-
-struct _PASBackend {
- GtkObject parent_object;
- PASBackendPrivate *priv;
-};
-
-typedef struct {
- GtkObjectClass 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);
- char *(*get_static_capabilities) (PASBackend *backend);
-
- /* Notification signals */
- void (* last_client_gone) (PASBackend *backend);
-} PASBackendClass;
-
-typedef PASBackend * (*PASBackendFactoryFn) (void);
-
-gboolean pas_backend_construct (PASBackend *backend);
-
-GNOME_Evolution_Addressbook_BookListener_CallStatus
- pas_backend_load_uri (PASBackend *backend,
- const char *uri);
-const char *pas_backend_get_uri (PASBackend *backend);
-
-gboolean pas_backend_add_client (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener);
-void pas_backend_remove_client (PASBackend *backend,
- PASBook *book);
-char *pas_backend_get_static_capabilities (PASBackend *backend);
-
-void pas_backend_last_client_gone (PASBackend *backend);
-
-GtkType pas_backend_get_type (void);
-
-#define PAS_BACKEND_TYPE (pas_backend_get_type ())
-#define PAS_BACKEND(o) (GTK_CHECK_CAST ((o), PAS_BACKEND_TYPE, PASBackend))
-#define PAS_BACKEND_CLASS(k) (GTK_CHECK_CLASS_CAST((k), PAS_BACKEND_TYPE, PASBackendClass))
-#define PAS_IS_BACKEND(o) (GTK_CHECK_TYPE ((o), PAS_BACKEND_TYPE))
-#define PAS_IS_BACKEND_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), PAS_BACKEND_TYPE))
-
-#endif /* ! __PAS_BACKEND_H__ */
-
diff --git a/addressbook/backend/pas/pas-book-factory.c b/addressbook/backend/pas/pas-book-factory.c
deleted file mode 100644
index 9c713f5ce8..0000000000
--- a/addressbook/backend/pas/pas-book-factory.c
+++ /dev/null
@@ -1,666 +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.
- */
-
-#include <config.h>
-#include <ctype.h>
-
-#include <gtk/gtksignal.h>
-#include <liboaf/liboaf.h>
-#include "addressbook.h"
-#include "pas-book-factory.h"
-
-#define DEFAULT_PAS_BOOK_FACTORY_OAF_ID "OAFIID:GNOME_Evolution_Wombat_ServerFactory"
-
-static BonoboObjectClass *pas_book_factory_parent_class;
-POA_GNOME_Evolution_Addressbook_BookFactory__vepv pas_book_factory_vepv;
-
-typedef struct {
- char *uri;
- GNOME_Evolution_Addressbook_BookListener listener;
-} PASBookFactoryQueuedRequest;
-
-struct _PASBookFactoryPrivate {
- gint idle_id;
- GHashTable *backends;
- GHashTable *active_server_map;
- GList *queued_requests;
-
- /* OAFIID of the factory */
- char *iid;
-
- /* Whether the factory has been registered with OAF yet */
- guint registered : 1;
-};
-
-/* Signal IDs */
-enum {
- LAST_BOOK_GONE,
- LAST_SIGNAL
-};
-
-static guint factory_signals[LAST_SIGNAL];
-
-static char *
-pas_book_factory_canonicalize_uri (const char *uri)
-{
- /* FIXME: What do I do here? */
-
- return g_strdup (uri);
-}
-
-static char *
-pas_book_factory_extract_proto_from_uri (const char *uri)
-{
- char *proto;
- char *p;
-
- p = strchr (uri, ':');
-
- if (p == NULL)
- return NULL;
-
- proto = g_malloc0 (p - uri + 1);
-
- strncpy (proto, uri, p - uri);
-
- return proto;
-}
-
-/**
- * pas_book_factory_register_backend:
- * @factory:
- * @proto:
- * @backend:
- */
-void
-pas_book_factory_register_backend (PASBookFactory *factory,
- const char *proto,
- PASBackendFactoryFn backend)
-{
- g_return_if_fail (factory != NULL);
- g_return_if_fail (PAS_IS_BOOK_FACTORY (factory));
- g_return_if_fail (proto != NULL);
- g_return_if_fail (backend != NULL);
-
- if (g_hash_table_lookup (factory->priv->backends, proto) != NULL) {
- g_warning ("pas_book_factory_register_backend: "
- "Proto \"%s\" already registered!\n", proto);
- }
-
- g_hash_table_insert (factory->priv->backends,
- g_strdup (proto), backend);
-}
-
-/**
- * pas_book_factory_get_n_backends:
- * @factory: An addressbook factory.
- *
- * Queries the number of running addressbook backends in an addressbook factory.
- *
- * Return value: Number of running backends.
- **/
-int
-pas_book_factory_get_n_backends (PASBookFactory *factory)
-{
- 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);
-}
-
-static void
-dump_active_server_map_entry (gpointer key, gpointer value, gpointer data)
-{
- char *uri;
- PASBackend *backend;
-
- uri = key;
- backend = PAS_BACKEND (value);
-
- g_message (" %s: %p", uri, backend);
-}
-
-void
-pas_book_factory_dump_active_backends (PASBookFactory *factory)
-{
- g_message ("Active PAS backends");
-
- g_hash_table_foreach (factory->priv->active_server_map,
- dump_active_server_map_entry,
- NULL);
-
-}
-
-/* Callback used when a backend loses its last connected client */
-static void
-backend_last_client_gone_cb (PASBackend *backend, gpointer data)
-{
- PASBookFactory *factory;
- const char *uri;
- gpointer orig_key;
- gboolean result;
- char *orig_uri;
-
- factory = PAS_BOOK_FACTORY (data);
-
- /* Remove the backend from the active server map */
-
- uri = pas_backend_get_uri (backend);
- g_assert (uri != NULL);
-
- result = g_hash_table_lookup_extended (factory->priv->active_server_map, uri,
- &orig_key, NULL);
- g_assert (result != FALSE);
-
- orig_uri = orig_key;
-
- g_hash_table_remove (factory->priv->active_server_map, orig_uri);
- g_free (orig_uri);
-
- gtk_object_unref (GTK_OBJECT (backend));
-
- /* Notify upstream if there are no more backends */
-
- if (g_hash_table_size (factory->priv->active_server_map) == 0)
- gtk_signal_emit (GTK_OBJECT (factory), factory_signals[LAST_BOOK_GONE]);
-}
-
-static PASBackendFactoryFn
-pas_book_factory_lookup_backend_factory (PASBookFactory *factory,
- const char *uri)
-{
- PASBackendFactoryFn backend_fn;
- char *proto;
- char *canonical_uri;
-
- g_assert (factory != NULL);
- g_assert (PAS_IS_BOOK_FACTORY (factory));
- g_assert (uri != NULL);
-
- canonical_uri = pas_book_factory_canonicalize_uri (uri);
- if (canonical_uri == NULL)
- return NULL;
-
- proto = pas_book_factory_extract_proto_from_uri (canonical_uri);
- if (proto == NULL) {
- g_free (canonical_uri);
- return NULL;
- }
-
- backend_fn = g_hash_table_lookup (factory->priv->backends, proto);
-
- g_free (proto);
- g_free (canonical_uri);
-
- return backend_fn;
-}
-
-static PASBackend *
-pas_book_factory_launch_backend (PASBookFactory *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);
- return NULL;
- }
-
- g_hash_table_insert (factory->priv->active_server_map,
- g_strdup (uri),
- backend);
-
- gtk_signal_connect (GTK_OBJECT (backend), "last_client_gone",
- backend_last_client_gone_cb,
- factory);
-
- return backend;
-}
-
-static void
-pas_book_factory_process_request (PASBookFactory *factory,
- PASBookFactoryQueuedRequest *request)
-{
- PASBackend *backend;
- char *uri;
- GNOME_Evolution_Addressbook_BookListener listener;
- CORBA_Environment ev;
-
- uri = request->uri;
- listener = request->listener;
- g_free (request);
-
- /* Look up the backend and create one if needed */
-
- 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;
-
- 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");
- }
-
- CORBA_exception_free (&ev);
-
- goto out;
- }
-
- pas_backend_add_client (backend, listener);
-
- goto out;
- }
-
- pas_backend_add_client (backend, listener);
-
- out:
- g_free (uri);
-
- CORBA_exception_init (&ev);
- CORBA_Object_release (listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_factory_process_request(): could not release the listener");
-
- CORBA_exception_free (&ev);
-}
-
-static gboolean
-pas_book_factory_process_queue (PASBookFactory *factory)
-{
- /* Process pending Book-creation requests. */
- if (factory->priv->queued_requests != NULL) {
- PASBookFactoryQueuedRequest *request;
- GList *l;
-
- 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);
- }
-}
-
-
-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_from_servant (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;
- }
-
- pas_book_factory_queue_request (factory, uri, listener);
-}
-
-static gboolean
-pas_book_factory_construct (PASBookFactory *factory)
-{
- POA_GNOME_Evolution_Addressbook_BookFactory *servant;
- CORBA_Environment ev;
- CORBA_Object obj;
-
- g_assert (factory != NULL);
- g_assert (PAS_IS_BOOK_FACTORY (factory));
-
- servant = (POA_GNOME_Evolution_Addressbook_BookFactory *) g_new0 (BonoboObjectServant, 1);
- servant->vepv = &pas_book_factory_vepv;
-
- CORBA_exception_init (&ev);
-
- POA_GNOME_Evolution_Addressbook_BookFactory__init ((PortableServer_Servant) servant, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_free (servant);
- CORBA_exception_free (&ev);
-
- return FALSE;
- }
-
- CORBA_exception_free (&ev);
-
- obj = bonobo_object_activate_servant (BONOBO_OBJECT (factory), servant);
- if (obj == CORBA_OBJECT_NIL) {
- g_free (servant);
-
- return FALSE;
- }
-
- bonobo_object_construct (BONOBO_OBJECT (factory), obj);
-
- return TRUE;
-}
-
-/**
- * pas_book_factory_new:
- */
-PASBookFactory *
-pas_book_factory_new (void)
-{
- PASBookFactory *factory;
-
- factory = gtk_type_new (pas_book_factory_get_type ());
-
- if (! pas_book_factory_construct (factory)) {
- g_warning ("pas_book_factory_new: Could not construct PASBookFactory!\n");
- gtk_object_unref (GTK_OBJECT (factory));
-
- return NULL;
- }
-
- return factory;
-}
-
-/**
- * pas_book_factory_activate:
- */
-gboolean
-pas_book_factory_activate (PASBookFactory *factory, const char *iid)
-{
- PASBookFactoryPrivate *priv;
- CORBA_Object obj;
- OAF_RegistrationResult result;
- char *tmp_iid;
-
- g_return_val_if_fail (factory != NULL, FALSE);
- g_return_val_if_fail (PAS_IS_BOOK_FACTORY (factory), FALSE);
-
- priv = factory->priv;
-
- g_return_val_if_fail (!priv->registered, FALSE);
-
- /* if iid is NULL, use the default factory OAFIID */
- if (iid)
- tmp_iid = g_strdup (iid);
- else
- tmp_iid = g_strdup (DEFAULT_PAS_BOOK_FACTORY_OAF_ID);
-
- obj = bonobo_object_corba_objref (BONOBO_OBJECT (factory));
-
- result = oaf_active_server_register (tmp_iid, obj);
-
- switch (result) {
- case OAF_REG_SUCCESS:
- priv->registered = TRUE;
- priv->iid = tmp_iid;
- return TRUE;
- case OAF_REG_NOT_LISTED:
- g_message ("Error registering the PAS factory: not listed");
- break;
- case OAF_REG_ALREADY_ACTIVE:
- g_message ("Error registering the PAS factory: already active");
- break;
- case OAF_REG_ERROR:
- default:
- g_message ("Error registering the PAS factory: generic error");
- break;
- }
-
- g_free (tmp_iid);
- return FALSE;
-}
-
-static void
-pas_book_factory_init (PASBookFactory *factory)
-{
- factory->priv = g_new0 (PASBookFactoryPrivate, 1);
-
- 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;
-}
-
-static void
-free_active_server_map_entry (gpointer key, gpointer value, gpointer data)
-{
- char *uri;
- PASBackend *backend;
-
- uri = key;
- g_free (uri);
-
- backend = PAS_BACKEND (value);
- gtk_object_unref (GTK_OBJECT (backend));
-}
-
-static void
-remove_backends_entry (gpointer key, gpointer value, gpointer data)
-{
- char *uri;
-
- uri = key;
- g_free (uri);
-}
-
-static void
-pas_book_factory_destroy (GtkObject *object)
-{
- PASBookFactory *factory = PAS_BOOK_FACTORY (object);
- GList *l;
-
- for (l = factory->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 (factory->priv->queued_requests);
- factory->priv->queued_requests = NULL;
-
- g_hash_table_foreach (factory->priv->active_server_map,
- free_active_server_map_entry,
- NULL);
- g_hash_table_destroy (factory->priv->active_server_map);
- factory->priv->active_server_map = NULL;
-
- g_hash_table_foreach (factory->priv->backends,
- remove_backends_entry,
- NULL);
- g_hash_table_destroy (factory->priv->backends);
- factory->priv->backends = NULL;
-
- if (factory->priv->registered) {
- CORBA_Object obj;
-
- obj = bonobo_object_corba_objref (BONOBO_OBJECT (factory));
- oaf_active_server_unregister (factory->priv->iid, obj);
- factory->priv->registered = FALSE;
- }
-
- g_free (factory->priv->iid);
-
- g_free (factory->priv);
-
- GTK_OBJECT_CLASS (pas_book_factory_parent_class)->destroy (object);
-}
-
-static POA_GNOME_Evolution_Addressbook_BookFactory__epv *
-pas_book_factory_get_epv (void)
-{
- POA_GNOME_Evolution_Addressbook_BookFactory__epv *epv;
-
- epv = g_new0 (POA_GNOME_Evolution_Addressbook_BookFactory__epv, 1);
-
- epv->openBook = impl_GNOME_Evolution_Addressbook_BookFactory_openBook;
-
- return epv;
-
-}
-
-static void
-pas_book_factory_corba_class_init (void)
-{
- pas_book_factory_vepv.Bonobo_Unknown_epv = bonobo_object_get_epv ();
- pas_book_factory_vepv.GNOME_Evolution_Addressbook_BookFactory_epv = pas_book_factory_get_epv ();
-}
-
-static void
-pas_book_factory_class_init (PASBookFactoryClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
-
- pas_book_factory_parent_class = gtk_type_class (bonobo_object_get_type ());
-
- factory_signals[LAST_BOOK_GONE] =
- gtk_signal_new ("last_book_gone",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (PASBookFactoryClass, last_book_gone),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, factory_signals, LAST_SIGNAL);
-
- object_class->destroy = pas_book_factory_destroy;
-
- pas_book_factory_corba_class_init ();
-}
-
-/**
- * pas_book_factory_get_type:
- */
-GtkType
-pas_book_factory_get_type (void)
-{
- static GtkType type = 0;
-
- if (! type) {
- GtkTypeInfo info = {
- "PASBookFactory",
- sizeof (PASBookFactory),
- sizeof (PASBookFactoryClass),
- (GtkClassInitFunc) pas_book_factory_class_init,
- (GtkObjectInitFunc) pas_book_factory_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (bonobo_object_get_type (), &info);
- }
-
- return type;
-}
diff --git a/addressbook/backend/pas/pas-book-factory.h b/addressbook/backend/pas/pas-book-factory.h
deleted file mode 100644
index 1936701296..0000000000
--- a/addressbook/backend/pas/pas-book-factory.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2000, Ximian, Inc.
- */
-
-#include <bonobo/bonobo-object.h>
-#include <libgnome/gnome-defs.h>
-
-#include <pas/pas-backend.h>
-
-#ifndef __PAS_BOOK_FACTORY_H__
-#define __PAS_BOOK_FACTORY_H__
-
-BEGIN_GNOME_DECLS
-
-typedef struct _PASBookFactoryPrivate PASBookFactoryPrivate;
-
-typedef struct {
- BonoboObject parent_object;
- PASBookFactoryPrivate *priv;
-} PASBookFactory;
-
-typedef struct {
- BonoboObjectClass parent_class;
-
- /* Notification signals */
-
- void (* last_book_gone) (PASBookFactory *factory);
-} PASBookFactoryClass;
-
-PASBookFactory *pas_book_factory_new (void);
-
-void pas_book_factory_register_backend (PASBookFactory *factory,
- const char *proto,
- PASBackendFactoryFn backend_factory);
-
-int pas_book_factory_get_n_backends (PASBookFactory *factory);
-
-void pas_book_factory_dump_active_backends (PASBookFactory *factory);
-
-gboolean pas_book_factory_activate (PASBookFactory *factory, const char *iid);
-
-GtkType pas_book_factory_get_type (void);
-
-#define PAS_BOOK_FACTORY_TYPE (pas_book_factory_get_type ())
-#define PAS_BOOK_FACTORY(o) (GTK_CHECK_CAST ((o), PAS_BOOK_FACTORY_TYPE, PASBookFactory))
-#define PAS_BOOK_FACTORY_CLASS(k) (GTK_CHECK_CLASS_CAST((k), PAS_BOOK_FACTORY_TYPE, PASBookFactoryClass))
-#define PAS_IS_BOOK_FACTORY(o) (GTK_CHECK_TYPE ((o), PAS_BOOK_FACTORY_TYPE))
-#define PAS_IS_BOOK_FACTORY_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), PAS_BOOK_FACTORY_TYPE))
-
-END_GNOME_DECLS
-
-#endif /* ! __PAS_BOOK_FACTORY_H__ */
diff --git a/addressbook/backend/pas/pas-book-view.c b/addressbook/backend/pas/pas-book-view.c
deleted file mode 100644
index 27d0f3ae06..0000000000
--- a/addressbook/backend/pas/pas-book-view.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * pas-book-view.c
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#include <config.h>
-#include <glib.h>
-#include "pas-book-view.h"
-
-static BonoboObjectClass *pas_book_view_parent_class;
-POA_GNOME_Evolution_Addressbook_BookView__vepv pas_book_view_vepv;
-
-struct _PASBookViewPrivate {
- GNOME_Evolution_Addressbook_BookViewListener listener;
-};
-
-/**
- * pas_book_view_notify_change:
- */
-void
-pas_book_view_notify_change (PASBookView *book_view,
- const GList *cards)
-{
- CORBA_Environment ev;
- gint i, length;
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard card_sequence;
-
- length = g_list_length((GList *) cards);
-
- card_sequence._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf(length);
- card_sequence._maximum = length;
- card_sequence._length = length;
-
- for ( i = 0; cards; cards = g_list_next(cards), i++ ) {
- card_sequence._buffer[i] = CORBA_string_dup((char *) cards->data);
- }
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookViewListener_notifyCardChanged (
- book_view->priv->listener, &card_sequence, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_change: Exception signaling BookViewListener!\n");
- }
-
- CORBA_exception_free (&ev);
-
- CORBA_free(card_sequence._buffer);
-}
-
-void
-pas_book_view_notify_change_1 (PASBookView *book_view,
- const char *card)
-{
- GList *list = g_list_append(NULL, (char *) card);
- pas_book_view_notify_change(book_view, list);
- g_list_free(list);
-}
-
-/**
- * pas_book_view_notify_remove:
- */
-void
-pas_book_view_notify_remove (PASBookView *book_view,
- const char *id)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookViewListener_notifyCardRemoved (
- book_view->priv->listener, (GNOME_Evolution_Addressbook_CardId) id, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_remove: Exception signaling BookViewListener!\n");
- }
-
- CORBA_exception_free (&ev);
-}
-
-/**
- * pas_book_view_notify_add:
- */
-void
-pas_book_view_notify_add (PASBookView *book_view,
- const GList *cards)
-{
- CORBA_Environment ev;
- gint i, length;
- CORBA_sequence_GNOME_Evolution_Addressbook_VCard card_sequence;
-
- length = g_list_length((GList *)cards);
-
- card_sequence._buffer = CORBA_sequence_GNOME_Evolution_Addressbook_VCard_allocbuf(length);
- card_sequence._maximum = length;
- card_sequence._length = length;
-
- for ( i = 0; cards; cards = g_list_next(cards), i++ ) {
- card_sequence._buffer[i] = CORBA_string_dup((char *) cards->data);
- }
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookViewListener_notifyCardAdded (
- book_view->priv->listener, &card_sequence, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_add: Exception signaling BookViewListener!\n");
- }
-
- CORBA_exception_free (&ev);
-
- CORBA_free(card_sequence._buffer);
-}
-
-void
-pas_book_view_notify_add_1 (PASBookView *book_view,
- const char *card)
-{
- GList *list = g_list_append(NULL, (char *) card);
- pas_book_view_notify_add(book_view, list);
- g_list_free(list);
-}
-
-void
-pas_book_view_notify_complete (PASBookView *book_view,
- GNOME_Evolution_Addressbook_BookViewListener_CallStatus status)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookViewListener_notifySequenceComplete (
- book_view->priv->listener, status, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_complete: Exception signaling BookViewListener!\n");
- }
-
- CORBA_exception_free (&ev);
-}
-
-void
-pas_book_view_notify_status_message (PASBookView *book_view,
- const char *message)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookViewListener_notifyStatusMessage (
- book_view->priv->listener, message, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_view_notify_status_message: Exception signaling BookViewListener!\n");
- }
-
- CORBA_exception_free (&ev);
-}
-
-static gboolean
-pas_book_view_construct (PASBookView *book_view,
- GNOME_Evolution_Addressbook_BookViewListener listener)
-{
- POA_GNOME_Evolution_Addressbook_BookView *servant;
- CORBA_Environment ev;
- CORBA_Object obj;
-
- g_assert (book_view != NULL);
- g_assert (PAS_IS_BOOK_VIEW (book_view));
- g_assert (listener != CORBA_OBJECT_NIL);
-
- servant = (POA_GNOME_Evolution_Addressbook_BookView *) g_new0 (BonoboObjectServant, 1);
- servant->vepv = &pas_book_view_vepv;
-
- CORBA_exception_init (&ev);
-
- POA_GNOME_Evolution_Addressbook_BookView__init ((PortableServer_Servant) servant, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_free (servant);
- CORBA_exception_free (&ev);
-
- return FALSE;
- }
-
- bonobo_object_dup_ref (listener, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning("Unable to duplicate & ref listener object in pas-book-view.c\n");
- CORBA_exception_free (&ev);
-
- return FALSE;
- }
-
- CORBA_exception_free (&ev);
-
- obj = bonobo_object_activate_servant (BONOBO_OBJECT (book_view), servant);
- if (obj == CORBA_OBJECT_NIL) {
- g_free (servant);
-
- return FALSE;
- }
-
- bonobo_object_construct (BONOBO_OBJECT (book_view), obj);
-
- book_view->priv->listener = listener;
-
- return TRUE;
-}
-
-/**
- * pas_book_view_new:
- */
-PASBookView *
-pas_book_view_new (GNOME_Evolution_Addressbook_BookViewListener listener)
-{
- PASBookView *book_view;
-
- g_return_val_if_fail (listener != CORBA_OBJECT_NIL, NULL);
-
- book_view = gtk_type_new (pas_book_view_get_type ());
-
- if (! pas_book_view_construct (book_view, listener)) {
- gtk_object_unref (GTK_OBJECT (book_view));
-
- return NULL;
- }
-
- return book_view;
-}
-
-static void
-pas_book_view_destroy (GtkObject *object)
-{
- PASBookView *book_view = PAS_BOOK_VIEW (object);
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (book_view->priv->listener, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- CORBA_exception_free (&ev);
-
- return;
- }
- CORBA_exception_free (&ev);
-
- g_free (book_view->priv);
-
- GTK_OBJECT_CLASS (pas_book_view_parent_class)->destroy (object);
-}
-
-static POA_GNOME_Evolution_Addressbook_BookView__epv *
-pas_book_view_get_epv (void)
-{
- POA_GNOME_Evolution_Addressbook_BookView__epv *epv;
-
- epv = g_new0 (POA_GNOME_Evolution_Addressbook_BookView__epv, 1);
-
- return epv;
-
-}
-
-static void
-pas_book_view_corba_class_init (void)
-{
- pas_book_view_vepv.Bonobo_Unknown_epv = bonobo_object_get_epv ();
- pas_book_view_vepv.GNOME_Evolution_Addressbook_BookView_epv = pas_book_view_get_epv ();
-}
-
-static void
-pas_book_view_class_init (PASBookViewClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
-
- pas_book_view_parent_class = gtk_type_class (bonobo_object_get_type ());
-
- object_class->destroy = pas_book_view_destroy;
-
- pas_book_view_corba_class_init ();
-}
-
-static void
-pas_book_view_init (PASBookView *book_view)
-{
- book_view->priv = g_new0 (PASBookViewPrivate, 1);
- book_view->priv->listener = CORBA_OBJECT_NIL;
-}
-
-/**
- * pas_book_view_get_type:
- */
-GtkType
-pas_book_view_get_type (void)
-{
- static GtkType type = 0;
-
- if (! type) {
- GtkTypeInfo info = {
- "PASBookView",
- sizeof (PASBookView),
- sizeof (PASBookViewClass),
- (GtkClassInitFunc) pas_book_view_class_init,
- (GtkObjectInitFunc) pas_book_view_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (bonobo_object_get_type (), &info);
- }
-
- return type;
-}
-
diff --git a/addressbook/backend/pas/pas-book-view.h b/addressbook/backend/pas/pas-book-view.h
deleted file mode 100644
index 712f3c3b96..0000000000
--- a/addressbook/backend/pas/pas-book-view.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * A wrapper object which exports the GNOME_Evolution_Addressbook_Book CORBA interface
- * and which maintains a request queue.
- *
- * Author:
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#ifndef __PAS_BOOK_VIEW_H__
-#define __PAS_BOOK_VIEW_H__
-
-#include <bonobo/bonobo-object.h>
-#include <libgnome/gnome-defs.h>
-#include <pas/addressbook.h>
-
-typedef struct _PASBookView PASBookView;
-typedef struct _PASBookViewClass PASBookViewClass;
-typedef struct _PASBookViewPrivate PASBookViewPrivate;
-
-struct _PASBookView {
- BonoboObject parent_object;
- PASBookViewPrivate *priv;
-};
-
-struct _PASBookViewClass {
- BonoboObjectClass parent_class;
-};
-PASBookView *pas_book_view_new (GNOME_Evolution_Addressbook_BookViewListener listener);
-
-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);
-void pas_book_view_notify_remove (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);
-void pas_book_view_notify_status_message (PASBookView *book_view,
- const char *message);
-
-GtkType pas_book_view_get_type (void);
-
-#define PAS_BOOK_VIEW_TYPE (pas_book_view_get_type ())
-#define PAS_BOOK_VIEW(o) (GTK_CHECK_CAST ((o), PAS_BOOK_VIEW_TYPE, PASBookView))
-#define PAS_BOOK_VIEW_CLASS(k) (GTK_CHECK_CLASS_CAST((k), PAS_BOOK_VIEW_FACTORY_TYPE, PASBookViewClass))
-#define PAS_IS_BOOK_VIEW(o) (GTK_CHECK_TYPE ((o), PAS_BOOK_VIEW_TYPE))
-#define PAS_IS_BOOK_VIEW_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), PAS_BOOK_VIEW_TYPE))
-
-#endif /* ! __PAS_BOOK_VIEW_H__ */
diff --git a/addressbook/backend/pas/pas-book.c b/addressbook/backend/pas/pas-book.c
deleted file mode 100644
index 7a3ab55f92..0000000000
--- a/addressbook/backend/pas/pas-book.c
+++ /dev/null
@@ -1,1021 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * pas-book.c
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#include <config.h>
-#include <gtk/gtksignal.h>
-#include "e-util/e-list.h"
-#include "pas-book.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;
- GNOME_Evolution_Addressbook_BookListener listener;
-
- GList *request_queue;
- gint timeout_id;
-
- guint timeout_lock : 1;
-};
-
-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) {
- gtk_signal_emit (GTK_OBJECT (book),
- pas_book_signals [REQUESTS_QUEUED]);
- }
-
- 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_card (PASBook *book, const char *id)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = RemoveCard;
- req->remove.id = g_strdup (id);
-
- 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_book_view (PASBook *book, const GNOME_Evolution_Addressbook_BookViewListener listener, const char *search)
-{
- 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");
- }
-
- CORBA_exception_free (&ev);
-
- pas_book_queue_request (book, req);
-}
-
-static void
-pas_book_queue_get_completion_view (PASBook *book, const GNOME_Evolution_Addressbook_BookViewListener listener, const char *search)
-{
- 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");
- }
-
- CORBA_exception_free (&ev);
-
- pas_book_queue_request (book, req);
-}
-
-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)
-{
- PASRequest *req;
-
- req = g_new0 (PASRequest, 1);
- req->op = CheckConnection;
-
- pas_book_queue_request (book, req);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_getVCard (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_CardId id,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object_from_servant (servant));
-
- pas_book_queue_get_vcard (book, id);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_authenticateUser (PortableServer_Servant servant,
- const char* user,
- const char* passwd,
- const char* auth_method,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object_from_servant (servant));
-
- pas_book_queue_authenticate_user (book, user, passwd, auth_method);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_addCard (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_VCard vcard,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object_from_servant (servant));
-
- pas_book_queue_create_card (book, (const char *) vcard);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_removeCard (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_CardId id,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object_from_servant (servant));
-
- pas_book_queue_remove_card (book, (const char *) id);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_modifyCard (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_VCard vcard,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object_from_servant (servant));
-
- pas_book_queue_modify_card (book, (const char *) vcard);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_getCursor (PortableServer_Servant servant,
- const CORBA_char *search,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object_from_servant (servant));
-
- pas_book_queue_get_cursor (book, search);
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_getBookView (PortableServer_Servant servant,
- const GNOME_Evolution_Addressbook_BookViewListener listener,
- const CORBA_char *search,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object_from_servant (servant));
-
- pas_book_queue_get_book_view (book, listener, 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_from_servant (servant));
-
- pas_book_queue_get_completion_view (book, listener, search);
-}
-
-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_from_servant (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_from_servant (servant));
-
- pas_book_queue_check_connection (book);
-}
-
-static char *
-impl_GNOME_Evolution_Addressbook_Book_getStaticCapabilities (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object_from_servant (servant));
- char *temp;
- char *ret_val;
-
- temp = pas_backend_get_static_capabilities (book->priv->backend);
- ret_val = CORBA_string_dup(temp);
- g_free(temp);
- return ret_val;
-}
-
-static void
-impl_GNOME_Evolution_Addressbook_Book_getSupportedFields (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- PASBook *book = PAS_BOOK (bonobo_object_from_servant (servant));
-
- pas_book_queue_get_supported_fields (book);
-}
-
-/**
- * pas_book_get_backend:
- */
-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);
-
- 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);
-
- return book->priv->listener;
-}
-
-/**
- * pas_book_check_pending
- */
-gint
-pas_book_check_pending (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);
-}
-
-/**
- * pas_book_pop_request:
- */
-PASRequest *
-pas_book_pop_request (PASBook *book)
-{
- 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;
-
- popped = book->priv->request_queue;
- book->priv->request_queue =
- g_list_remove_link (book->priv->request_queue, popped);
-
- g_list_free_1 (popped);
-
- return req;
-}
-
-/**
- * pas_book_respond_open:
- */
-void
-pas_book_respond_open (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_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);
- }
-
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_open: Exception "
- "responding to BookListener!\n");
- }
-
- CORBA_exception_free (&ev);
-}
-
-/**
- * pas_book_respond_create:
- */
-void
-pas_book_respond_create (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- const char *id)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookListener_notifyCardCreated (
- book->priv->listener, status, (char *)id, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_create: Exception "
- "responding to BookListener!\n");
- }
-
- CORBA_exception_free (&ev);
-}
-
-/**
- * pas_book_respond_remove:
- */
-void
-pas_book_respond_remove (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookListener_notifyCardRemoved (
- book->priv->listener, status, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_remove: Exception "
- "responding to BookListener!\n");
- }
-
- CORBA_exception_free (&ev);
-}
-
-/**
- * pas_book_respond_modify:
- */
-void
-pas_book_respond_modify (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookListener_notifyCardModified (
- book->priv->listener, status, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_modify: Exception "
- "responding to BookListener!\n");
- }
-
- CORBA_exception_free (&ev);
-}
-
-/**
- * pas_book_respond_authenticate_user:
- */
-void
-pas_book_respond_authenticate_user (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookListener_notifyAuthenticationResult (
- book->priv->listener, status, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_authenticate_user: Exception "
- "responding to BookListener!\n");
- }
-
- CORBA_exception_free (&ev);
-}
-
-void
-pas_book_respond_get_supported_fields (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- EList *fields)
-{
- CORBA_Environment ev;
- GNOME_Evolution_Addressbook_stringlist stringlist;
- int num_fields;
- EIterator *iter;
- int i;
-
- CORBA_exception_init (&ev);
-
- num_fields = e_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));
- }
-
- gtk_object_unref (GTK_OBJECT (fields));
-
- GNOME_Evolution_Addressbook_BookListener_notifySupportedFields (
- book->priv->listener, status,
- &stringlist,
- &ev);
-
- CORBA_exception_free (&ev);
-
- 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");
- }
-
- CORBA_exception_free (&ev);
-}
-
-/**
- * pas_book_respond_get_book_view:
- */
-void
-pas_book_respond_get_book_view (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASBookView *book_view)
-{
- CORBA_Environment ev;
- CORBA_Object object;
-
- CORBA_exception_init (&ev);
-
- object = bonobo_object_corba_objref(BONOBO_OBJECT(book_view));
-
- GNOME_Evolution_Addressbook_BookListener_notifyViewRequested (
- book->priv->listener, status, object, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_get_book_view: Exception "
- "responding to BookListener!\n");
- }
-
- CORBA_exception_free (&ev);
-}
-
-/**
- * pas_book_respond_get_book_view:
- */
-void
-pas_book_respond_get_completion_view (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASBookView *completion_view)
-{
- 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);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_get_completion_view: Exception "
- "responding to BookListener!\n");
- }
-
- CORBA_exception_free (&ev);
-}
-
-/**
- * pas_book_respond_get_changes:
- */
-void
-pas_book_respond_get_vcard (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- char *vcard)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookListener_notifyCardRequested (
- book->priv->listener, status, vcard, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_get_card: Exception "
- "responding to BookListener!\n");
- }
-
- CORBA_exception_free (&ev);
-}
-
-/**
- * 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;
-
- CORBA_exception_init (&ev);
-
- object = bonobo_object_corba_objref(BONOBO_OBJECT(book_view));
-
- GNOME_Evolution_Addressbook_BookListener_notifyChangesRequested (
- book->priv->listener, status, object, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_respond_get_changes: Exception "
- "responding to BookListener!\n");
- }
-
- CORBA_exception_free (&ev);
-}
-
-/**
- * pas_book_report_connection:
- */
-void
-pas_book_report_connection (PASBook *book,
- gboolean connected)
-{
- CORBA_Environment ev;
-
- 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");
- }
-
- CORBA_exception_free (&ev);
-}
-
-/**
- * pas_book_report_writable:
- */
-void
-pas_book_report_writable (PASBook *book,
- gboolean writable)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_Addressbook_BookListener_notifyWritable (
- book->priv->listener, (CORBA_boolean) writable, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_warning ("pas_book_report_writable: Exception "
- "responding to BookListener!\n");
- }
-
- CORBA_exception_free (&ev);
-}
-
-static gboolean
-pas_book_construct (PASBook *book,
- PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener)
-{
- POA_GNOME_Evolution_Addressbook_Book *servant;
- CORBA_Environment ev;
- CORBA_Object obj;
-
- g_assert (book != NULL);
- g_assert (PAS_IS_BOOK (book));
- g_assert (listener != CORBA_OBJECT_NIL);
-
- servant = (POA_GNOME_Evolution_Addressbook_Book *) g_new0 (BonoboObjectServant, 1);
- servant->vepv = &pas_book_vepv;
-
- CORBA_exception_init (&ev);
-
- POA_GNOME_Evolution_Addressbook_Book__init ((PortableServer_Servant) servant, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_free (servant);
- CORBA_exception_free (&ev);
-
- return FALSE;
- }
-
- CORBA_exception_free (&ev);
-
- obj = bonobo_object_activate_servant (BONOBO_OBJECT (book), servant);
- if (obj == CORBA_OBJECT_NIL) {
- g_free (servant);
-
- return FALSE;
- }
-
- bonobo_object_construct (BONOBO_OBJECT (book), obj);
-
- CORBA_exception_init (&ev);
- book->priv->listener = CORBA_Object_duplicate (listener, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_construct(): could not duplicate the listener");
-
- CORBA_exception_free (&ev);
-
- book->priv->listener = listener;
- book->priv->backend = backend;
-
- return TRUE;
-}
-
-/**
- * pas_book_new:
- */
-PASBook *
-pas_book_new (PASBackend *backend,
- GNOME_Evolution_Addressbook_BookListener listener)
-{
- PASBook *book;
-
- g_return_val_if_fail (listener != CORBA_OBJECT_NIL, NULL);
-
- book = gtk_type_new (pas_book_get_type ());
-
- if (! pas_book_construct (book, backend, listener)) {
- gtk_object_unref (GTK_OBJECT (book));
-
- return NULL;
- }
-
- return book;
-}
-
-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 RemoveCard:
- g_free (req->remove.id);
- 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);
-
- 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;
- }
-
- g_free (req);
-}
-
-static void
-pas_book_destroy (GtkObject *object)
-{
- PASBook *book = PAS_BOOK (object);
- 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);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("pas_book_construct(): could not release the listener");
-
- CORBA_exception_free (&ev);
-
- g_free (book->priv);
- book->priv = NULL;
-
- GTK_OBJECT_CLASS (pas_book_parent_class)->destroy (object);
-}
-
-static POA_GNOME_Evolution_Addressbook_Book__epv *
-pas_book_get_epv (void)
-{
- POA_GNOME_Evolution_Addressbook_Book__epv *epv;
-
- epv = g_new0 (POA_GNOME_Evolution_Addressbook_Book__epv, 1);
-
- epv->getVCard = impl_GNOME_Evolution_Addressbook_Book_getVCard;
- epv->authenticateUser = impl_GNOME_Evolution_Addressbook_Book_authenticateUser;
- epv->addCard = impl_GNOME_Evolution_Addressbook_Book_addCard;
- epv->removeCard = impl_GNOME_Evolution_Addressbook_Book_removeCard;
- epv->modifyCard = impl_GNOME_Evolution_Addressbook_Book_modifyCard;
- epv->checkConnection = impl_GNOME_Evolution_Addressbook_Book_checkConnection;
- epv->getStaticCapabilities = impl_GNOME_Evolution_Addressbook_Book_getStaticCapabilities;
- epv->getSupportedFields = impl_GNOME_Evolution_Addressbook_Book_getSupportedFields;
- 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;
-
- return epv;
-
-}
-
-static void
-pas_book_corba_class_init (void)
-{
- pas_book_vepv.Bonobo_Unknown_epv = bonobo_object_get_epv ();
- pas_book_vepv.GNOME_Evolution_Addressbook_Book_epv = pas_book_get_epv ();
-}
-
-static void
-pas_book_class_init (PASBookClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
-
- pas_book_parent_class = gtk_type_class (bonobo_object_get_type ());
-
- pas_book_signals [REQUESTS_QUEUED] =
- gtk_signal_new ("requests_queued",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (PASBookClass, requests_queued),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, pas_book_signals, LAST_SIGNAL);
-
- object_class->destroy = pas_book_destroy;
-
- pas_book_corba_class_init ();
-}
-
-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;
-}
-
-/**
- * pas_book_get_type:
- */
-GtkType
-pas_book_get_type (void)
-{
- static GtkType type = 0;
-
- if (! type) {
- GtkTypeInfo info = {
- "PASBook",
- sizeof (PASBook),
- sizeof (PASBookClass),
- (GtkClassInitFunc) pas_book_class_init,
- (GtkObjectInitFunc) pas_book_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (bonobo_object_get_type (), &info);
- }
-
- return type;
-}
-
diff --git a/addressbook/backend/pas/pas-book.h b/addressbook/backend/pas/pas-book.h
deleted file mode 100644
index 4dcd1e205d..0000000000
--- a/addressbook/backend/pas/pas-book.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * A wrapper object which exports the GNOME_Evolution_Addressbook_Book CORBA interface
- * and which maintains a request queue.
- *
- * Author:
- * Nat Friedman (nat@ximian.com)
- *
- * Copyright 2000, Ximian, Inc.
- */
-
-#ifndef __PAS_BOOK_H__
-#define __PAS_BOOK_H__
-
-#include <bonobo/bonobo-object.h>
-#include <libgnome/gnome-defs.h>
-#include <pas/addressbook.h>
-#include <pas/pas-book-view.h>
-#include "e-util/e-list.h"
-
-typedef struct _PASBook PASBook;
-typedef struct _PASBookPrivate PASBookPrivate;
-
-#include <pas/pas-backend.h>
-#include <pas/pas-card-cursor.h>
-
-typedef enum {
- CreateCard,
- RemoveCard,
- ModifyCard,
- GetVCard,
- GetCursor,
- GetBookView,
- GetCompletionView,
- GetChanges,
- CheckConnection,
- AuthenticateUser,
- GetSupportedFields
-} PASOperation;
-
-typedef struct {
- PASOperation op;
- char *id;
- char *vcard;
-} PASCreateCardRequest;
-
-typedef struct {
- PASOperation op;
- char *id;
-} PASRemoveCardRequest;
-
-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 union {
- PASOperation op;
-
- PASCreateCardRequest create;
- PASRemoveCardRequest 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;
-} PASRequest;
-
-struct _PASBook {
- BonoboObject parent_object;
- PASBookPrivate *priv;
-};
-
-typedef struct {
- BonoboObjectClass parent_class;
-
- /* 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_cursor (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_CallStatus status,
- PASCardCursor *cursor);
-void pas_book_respond_get_book_view (PASBook *book,
- GNOME_Evolution_Addressbook_BookListener_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,
- 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_report_writable (PASBook *book,
- gboolean writable);
-
-GtkType pas_book_get_type (void);
-
-#define PAS_BOOK_TYPE (pas_book_get_type ())
-#define PAS_BOOK(o) (GTK_CHECK_CAST ((o), PAS_BOOK_TYPE, PASBook))
-#define PAS_BOOK_CLASS(k) (GTK_CHECK_CLASS_CAST((k), PAS_BOOK_FACTORY_TYPE, PASBookClass))
-#define PAS_IS_BOOK(o) (GTK_CHECK_TYPE ((o), PAS_BOOK_TYPE))
-#define PAS_IS_BOOK_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), PAS_BOOK_TYPE))
-
-#endif /* ! __PAS_BOOK_H__ */
diff --git a/addressbook/backend/pas/pas-card-cursor.c b/addressbook/backend/pas/pas-card-cursor.c
deleted file mode 100644
index 572f63f46e..0000000000
--- a/addressbook/backend/pas/pas-card-cursor.c
+++ /dev/null
@@ -1,226 +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 "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;
-
-/*
- * The VEPV for the CardCursor object
- */
-static POA_GNOME_Evolution_Addressbook_CardCursor__vepv cursor_vepv;
-
-/*
- * Implemented GtkObject::destroy
- */
-static void
-pas_card_cursor_destroy (GtkObject *object)
-{
- PASCardCursor *cursor = PAS_CARD_CURSOR (object);
-
- if ( cursor->priv )
- g_free ( cursor->priv );
-
- GTK_OBJECT_CLASS (parent_class)->destroy (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_from_servant (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_from_servant (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 ("");
-}
-
-/*
- * If you want users to derive classes from your implementation
- * you need to support this method.
- */
-POA_GNOME_Evolution_Addressbook_CardCursor__epv *
-pas_card_cursor_get_epv (void)
-{
- POA_GNOME_Evolution_Addressbook_CardCursor__epv *epv;
-
- epv = g_new0 (POA_GNOME_Evolution_Addressbook_CardCursor__epv, 1);
-
- /*
- * This is the method invoked by CORBA
- */
- epv->count = impl_pas_card_cursor_get_length;
- epv->getNth = impl_pas_card_cursor_get_nth;
-
- return epv;
-}
-
-static void
-init_pas_card_cursor_corba_class (void)
-{
- cursor_vepv.Bonobo_Unknown_epv = bonobo_object_get_epv ();
- cursor_vepv.GNOME_Evolution_Addressbook_CardCursor_epv = pas_card_cursor_get_epv ();
-}
-
-static void
-pas_card_cursor_class_init (PASCardCursorClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
-
- parent_class = gtk_type_class (bonobo_object_get_type ());
-
- object_class->destroy = pas_card_cursor_destroy;
-
- init_pas_card_cursor_corba_class ();
-}
-
-static void
-pas_card_cursor_init (PASCardCursor *cursor)
-{
- cursor->priv = g_new(PASCardCursorPrivate, 1);
- cursor->priv->get_length = NULL;
- cursor->priv->get_nth = NULL;
- cursor->priv->data = NULL;
-}
-
-GtkType
-pas_card_cursor_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type){
- GtkTypeInfo info = {
- "PASCardCursor",
- sizeof (PASCardCursor),
- sizeof (PASCardCursorClass),
- (GtkClassInitFunc) pas_card_cursor_class_init,
- (GtkObjectInitFunc) pas_card_cursor_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (bonobo_object_get_type (), &info);
- }
-
- return type;
-}
-
-PASCardCursor *
-pas_card_cursor_construct (PASCardCursor *cursor,
- GNOME_Evolution_Addressbook_CardCursor corba_cursor,
- PASCardCursorLengthFunc get_length,
- PASCardCursorNthFunc get_nth,
- gpointer data)
-{
- g_return_val_if_fail (cursor != NULL, NULL);
- g_return_val_if_fail (PAS_IS_CARD_CURSOR (cursor), NULL);
- g_return_val_if_fail (corba_cursor != CORBA_OBJECT_NIL, NULL);
-
- /*
- * Call parent constructor
- */
- if (!bonobo_object_construct (BONOBO_OBJECT (cursor), (CORBA_Object) corba_cursor))
- return NULL;
-
- /*
- * Initialize cursor
- */
- cursor->priv->get_length = get_length;
- cursor->priv->get_nth = get_nth;
- cursor->priv->data = data;
-
- /*
- * Success: return the GtkType we were given
- */
- return cursor;
-}
-
-/*
- * This routine creates the ORBit CORBA server and initializes the
- * CORBA side of things
- */
-static GNOME_Evolution_Addressbook_CardCursor
-create_cursor (BonoboObject *cursor)
-{
- POA_GNOME_Evolution_Addressbook_CardCursor *servant;
- CORBA_Environment ev;
-
- servant = (POA_GNOME_Evolution_Addressbook_CardCursor *) g_new0 (BonoboObjectServant, 1);
- servant->vepv = &cursor_vepv;
-
- CORBA_exception_init (&ev);
- POA_GNOME_Evolution_Addressbook_CardCursor__init ((PortableServer_Servant) servant, &ev);
- if (ev._major != CORBA_NO_EXCEPTION){
- g_free (servant);
- CORBA_exception_free (&ev);
- return CORBA_OBJECT_NIL;
- }
-
- CORBA_exception_free (&ev);
-
- /*
- * Activates the CORBA object.
- */
- return (GNOME_Evolution_Addressbook_CardCursor) bonobo_object_activate_servant (cursor, servant);
-}
-
-PASCardCursor *
-pas_card_cursor_new (PASCardCursorLengthFunc get_length,
- PASCardCursorNthFunc get_nth,
- gpointer data)
-{
- PASCardCursor *cursor;
- GNOME_Evolution_Addressbook_CardCursor corba_cursor;
-
- cursor = gtk_type_new (pas_card_cursor_get_type ());
- corba_cursor = create_cursor (BONOBO_OBJECT (cursor));
-
- if (corba_cursor == CORBA_OBJECT_NIL){
- gtk_object_unref (GTK_OBJECT (cursor));
- return NULL;
- }
-
- return pas_card_cursor_construct (cursor,
- corba_cursor,
- get_length,
- get_nth,
- data);
-}
diff --git a/addressbook/backend/pas/pas-card-cursor.h b/addressbook/backend/pas/pas-card-cursor.h
deleted file mode 100644
index 70ecb5e718..0000000000
--- a/addressbook/backend/pas/pas-card-cursor.h
+++ /dev/null
@@ -1,58 +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 <libgnome/gnome-defs.h>
-#include <bonobo/bonobo-object.h>
-#include <pas/addressbook.h>
-
-BEGIN_GNOME_DECLS
-
-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;
-};
-
-/* Creating a new addressbook. */
-PASCardCursor *pas_card_cursor_new (PASCardCursorLengthFunc get_length,
- PASCardCursorNthFunc get_nth,
- gpointer data);
-PASCardCursor *pas_card_cursor_construct (PASCardCursor *cursor,
- GNOME_Evolution_Addressbook_CardCursor corba_cursor,
- PASCardCursorLengthFunc get_length,
- PASCardCursorNthFunc get_nth,
- gpointer data);
-
-GtkType pas_card_cursor_get_type (void);
-POA_GNOME_Evolution_Addressbook_CardCursor__epv *
- pas_card_cursor_get_epv (void);
-
-/* Fetching cards. */
-#define PAS_CARD_CURSOR_TYPE (pas_card_cursor_get_type ())
-#define PAS_CARD_CURSOR(o) (GTK_CHECK_CAST ((o), PAS_CARD_CURSOR_TYPE, PASCardCursor))
-#define PAS_CARD_CURSOR_CLASS(k) (GTK_CHECK_CLASS_CAST((k), PAS_CARD_CURSOR_TYPE, PASCardCursorClass))
-#define PAS_IS_CARD_CURSOR(o) (GTK_CHECK_TYPE ((o), PAS_CARD_CURSOR_TYPE))
-#define PAS_IS_CARD_CURSOR_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), PAS_CARD_CURSOR_TYPE))
-
-END_GNOME_DECLS
-
-#endif /* ! __PAS_CARD_CURSOR_H__ */
diff --git a/addressbook/conduit/.cvsignore b/addressbook/conduit/.cvsignore
deleted file mode 100644
index 87b35d3be5..0000000000
--- a/addressbook/conduit/.cvsignore
+++ /dev/null
@@ -1,9 +0,0 @@
-.deps
-.libs
-*.lo
-Makefile.in
-Makefile
-libeaddress_conduit.la
-e-address-conduit-control-applet
-e-address-conduit-control-applet.desktop
-e-address.conduit
diff --git a/addressbook/conduit/Makefile.am b/addressbook/conduit/Makefile.am
deleted file mode 100644
index 28d31e4868..0000000000
--- a/addressbook/conduit/Makefile.am
+++ /dev/null
@@ -1,43 +0,0 @@
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/addressbook \
- -I$(top_srcdir)/addressbook/backend \
- -I$(top_builddir)/addressbook/backend \
- -I$(top_srcdir)/e-util \
- -I$(top_builddir)/e-util \
- $(PISOCK_CFLAGS) \
- $(EVOLUTION_ADDRESSBOOK_CONDUIT_CFLAGS) \
- -DCAMEL_PROVIDERDIR=\""$(providerdir)"\"
-
-# Address Conduit
-e_address_conduitsdir=$(libdir)/gnome-pilot/conduits
-e_address_conduits_LTLIBRARIES = libeaddress_conduit.la
-
-libeaddress_conduit_la_SOURCES = \
- address-conduit.c
-
-libeaddress_conduit_la_LDFLAGS = -module -avoid-version
-libeaddress_conduit_la_LIBADD = \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/addressbook/backend/ebook/libebook-static.la \
- $(top_builddir)/e-util/ename/libename-static.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/e-util/libeconduit-static.la \
- $(top_builddir)/camel/libcamel.la \
- $(EVOLUTION_ADDRESSBOOK_CONDUIT_LIBS)
-
-e-address.conduit: e-address.conduit.in Makefile
- sed -e 's^\@prefix\@^$(prefix)^g' \
- -e 's^\@datadir\@^$(datadir)^g' \
- < $(srcdir)/e-address.conduit.in > e-address.conduit.tmp \
- && mv e-address.conduit.tmp e-address.conduit
-
-
-Conduitdir = $(datadir)/gnome-pilot/conduits/
-Conduit_DATA = e-address.conduit
-
-EXTRA_DIST = \
- e-address.conduit.in
-
-install-data-local:
- $(mkinstalldirs) $(Conduitdir)
diff --git a/addressbook/conduit/address-conduit.c b/addressbook/conduit/address-conduit.c
deleted file mode 100644
index b87226864c..0000000000
--- a/addressbook/conduit/address-conduit.c
+++ /dev/null
@@ -1,1911 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Evolution addressbook - Address Conduit
- *
- * Copyright (C) 1998 Free Software Foundation
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Eskil Heyn Olsen <deity@eskil.dk>
- * JP Rosevear <jpr@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 <liboaf/liboaf.h>
-#include <bonobo.h>
-#include <gnome-xml/parser.h>
-#include <pi-source.h>
-#include <pi-socket.h>
-#include <pi-dlp.h>
-#include <pi-address.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 <gpilotd/gnome-pilot-conduit.h>
-#include <gpilotd/gnome-pilot-conduit-sync-abs.h>
-#include <libgpilotdCM/gnome-pilot-conduit-management.h>
-#include <libgpilotdCM/gnome-pilot-conduit-config.h>
-#include <e-dialog-widgets.h>
-#include <e-pilot-map.h>
-#include <e-pilot-settings.h>
-#include <e-pilot-util.h>
-
-GnomePilotConduit * conduit_get_gpilot_conduit (guint32);
-void conduit_destroy_gpilot_conduit (GnomePilotConduit*);
-
-#define CONDUIT_VERSION "0.1.2"
-#ifdef G_LOG_DOMAIN
-#undef G_LOG_DOMAIN
-#endif
-#define G_LOG_DOMAIN "eaddrconduit"
-
-#define DEBUG_CONDUIT 1
-/* #undef DEBUG_CONDUIT */
-
-#ifdef DEBUG_CONDUIT
-#define LOG(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, e)
-#else
-#define LOG(e...)
-#endif
-
-#define WARN(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, e)
-#define INFO(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, e)
-
-typedef struct {
- EBookStatus status;
- char *id;
-} CardObjectChangeStatus;
-
-typedef enum {
- CARD_ADDED,
- CARD_MODIFIED,
- CARD_DELETED
-} CardObjectChangeType;
-
-typedef struct
-{
- ECard *card;
- CardObjectChangeType type;
-} CardObjectChange;
-
-enum {
- LABEL_WORK,
- LABEL_HOME,
- LABEL_FAX,
- LABEL_OTHER,
- LABEL_EMAIL,
- LABEL_MAIN,
- LABEL_PAGER,
- LABEL_MOBILE
-};
-
-static ECardSimpleField priority [] = {
- E_CARD_SIMPLE_FIELD_PHONE_BUSINESS,
- E_CARD_SIMPLE_FIELD_PHONE_HOME,
- E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_FAX,
- E_CARD_SIMPLE_FIELD_EMAIL,
- E_CARD_SIMPLE_FIELD_PHONE_PAGER,
- E_CARD_SIMPLE_FIELD_PHONE_MOBILE,
- E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2,
- E_CARD_SIMPLE_FIELD_PHONE_HOME_2,
- E_CARD_SIMPLE_FIELD_PHONE_HOME_FAX,
- E_CARD_SIMPLE_FIELD_EMAIL_2,
- E_CARD_SIMPLE_FIELD_PHONE_OTHER,
- E_CARD_SIMPLE_FIELD_PHONE_PRIMARY,
- E_CARD_SIMPLE_FIELD_PHONE_OTHER_FAX,
- E_CARD_SIMPLE_FIELD_EMAIL_3,
- E_CARD_SIMPLE_FIELD_LAST
-};
-
-static int priority_label [] = {
- LABEL_WORK,
- LABEL_HOME,
- LABEL_FAX,
- LABEL_EMAIL,
- LABEL_PAGER,
- LABEL_MOBILE,
- LABEL_WORK,
- LABEL_HOME,
- LABEL_FAX,
- LABEL_EMAIL,
- LABEL_OTHER,
- LABEL_MAIN,
- LABEL_FAX,
- LABEL_EMAIL,
- -1
-};
-
-typedef struct _EAddrLocalRecord EAddrLocalRecord;
-typedef struct _EAddrConduitCfg EAddrConduitCfg;
-typedef struct _EAddrConduitGui EAddrConduitGui;
-typedef struct _EAddrConduitContext EAddrConduitContext;
-
-/* Local Record */
-struct _EAddrLocalRecord {
- /* The stuff from gnome-pilot-conduit-standard-abs.h
- Must be first in the structure, or instances of this
- structure cannot be used by gnome-pilot-conduit-standard-abs.
- */
- GnomePilotDesktopRecord local;
-
- /* The corresponding ECard object */
- ECard *ecard;
-
- /* pilot-link address structure, used for implementing Transmit. */
- struct Address *addr;
-};
-
-
-static void
-addrconduit_destroy_record (EAddrLocalRecord *local)
-{
- gtk_object_unref (GTK_OBJECT (local->ecard));
- free_Address (local->addr);
- g_free (local->addr);
- g_free (local);
-}
-
-/* Configuration */
-struct _EAddrConduitCfg {
- guint32 pilot_id;
- GnomePilotConduitSyncType sync_type;
-
- gboolean secret;
- ECardSimpleAddressId default_address;
-
- gchar *last_uri;
-};
-
-static EAddrConduitCfg *
-addrconduit_load_configuration (guint32 pilot_id)
-{
- EAddrConduitCfg *c;
- GnomePilotConduitManagement *management;
- GnomePilotConduitConfig *config;
- gchar *address, prefix[256];
- g_snprintf (prefix, 255, "/gnome-pilot.d/e-address-conduit/Pilot_%u/",
- pilot_id);
-
- c = g_new0 (EAddrConduitCfg,1);
- g_assert (c != NULL);
-
- c->pilot_id = pilot_id;
- management = gnome_pilot_conduit_management_new ("e_address_conduit", GNOME_PILOT_CONDUIT_MGMT_ID);
- config = gnome_pilot_conduit_config_new (management, pilot_id);
- if (!gnome_pilot_conduit_config_is_enabled (config, &c->sync_type))
- c->sync_type = GnomePilotConduitSyncTypeNotSet;
- gtk_object_unref (GTK_OBJECT (config));
- gtk_object_unref (GTK_OBJECT (management));
-
- /* Custom settings */
- gnome_config_push_prefix (prefix);
-
- c->secret = gnome_config_get_bool ("secret=FALSE");
- address = gnome_config_get_string ("default_address=business");
- if (!strcmp (address, "business"))
- c->default_address = E_CARD_SIMPLE_ADDRESS_ID_BUSINESS;
- else if (!strcmp (address, "home"))
- c->default_address = E_CARD_SIMPLE_ADDRESS_ID_HOME;
- else if (!strcmp (address, "other"))
- c->default_address = E_CARD_SIMPLE_ADDRESS_ID_OTHER;
- g_free (address);
- c->last_uri = gnome_config_get_string ("last_uri");
-
- gnome_config_pop_prefix ();
-
- return c;
-}
-
-static void
-addrconduit_save_configuration (EAddrConduitCfg *c)
-{
- gchar prefix[256];
-
- g_snprintf (prefix, 255, "/gnome-pilot.d/e-address-conduit/Pilot_%u/",
- c->pilot_id);
-
- gnome_config_push_prefix (prefix);
- gnome_config_set_bool ("secret", c->secret);
- switch (c->default_address) {
- case E_CARD_SIMPLE_ADDRESS_ID_BUSINESS:
- gnome_config_set_string ("default_address", "business");
- break;
- case E_CARD_SIMPLE_ADDRESS_ID_HOME:
- gnome_config_set_string ("default_address", "home");
- break;
- case E_CARD_SIMPLE_ADDRESS_ID_OTHER:
- gnome_config_set_string ("default_address", "other");
- break;
- default:
- g_warning ("Unknown default_address value");
- }
- gnome_config_set_string ("last_uri", c->last_uri);
- gnome_config_pop_prefix ();
-
- gnome_config_sync ();
- gnome_config_drop_all ();
-}
-
-static EAddrConduitCfg*
-addrconduit_dupe_configuration (EAddrConduitCfg *c)
-{
- EAddrConduitCfg *retval;
-
- g_return_val_if_fail (c != NULL, NULL);
-
- retval = g_new0 (EAddrConduitCfg, 1);
- retval->sync_type = c->sync_type;
- retval->pilot_id = c->pilot_id;
-
- retval->secret = c->secret;
- retval->default_address = c->default_address;
- retval->last_uri = g_strdup (c->last_uri);
-
- return retval;
-}
-
-static void
-addrconduit_destroy_configuration (EAddrConduitCfg *c)
-{
- g_return_if_fail (c != NULL);
-
- g_free (c->last_uri);
- g_free (c);
-}
-
-/* Gui */
-struct _EAddrConduitGui {
- GtkWidget *default_address;
-};
-
-static EAddrConduitGui *
-e_addr_gui_new (EPilotSettings *ps)
-{
- EAddrConduitGui *gui;
- GtkWidget *lbl, *menu;
- gint rows, i;
- static const char *items[] = {"Business", "Home", "Other", NULL};
-
- g_return_val_if_fail (ps != NULL, NULL);
- g_return_val_if_fail (E_IS_PILOT_SETTINGS (ps), NULL);
-
- gtk_table_resize (GTK_TABLE (ps), E_PILOT_SETTINGS_TABLE_ROWS + 1,
- E_PILOT_SETTINGS_TABLE_COLS);
-
- gui = g_new0 (EAddrConduitGui, 1);
-
- rows = E_PILOT_SETTINGS_TABLE_ROWS;
- lbl = gtk_label_new (_("Default Sync Address:"));
- gtk_misc_set_alignment (GTK_MISC (lbl), 0.0, 0.5);
- gui->default_address = gtk_option_menu_new ();
- menu = gtk_menu_new ();
- for (i = 0; items[i] != NULL; i++) {
- GtkWidget *item;
-
- item = gtk_menu_item_new_with_label (items[i]);
- gtk_widget_show (item);
-
- gtk_menu_append (GTK_MENU (menu), item);
- }
- gtk_widget_show (menu);
- gtk_option_menu_set_menu (GTK_OPTION_MENU (gui->default_address), menu);
- gtk_table_attach_defaults (GTK_TABLE (ps), lbl, 0, 1, rows, rows + 1);
- gtk_table_attach_defaults (GTK_TABLE (ps), gui->default_address, 1, 2, rows, rows + 1);
- gtk_widget_show (lbl);
- gtk_widget_show (gui->default_address);
-
- return gui;
-}
-
-static const int default_address_map[] = {
- E_CARD_SIMPLE_ADDRESS_ID_BUSINESS,
- E_CARD_SIMPLE_ADDRESS_ID_HOME,
- E_CARD_SIMPLE_ADDRESS_ID_OTHER,
- -1
-};
-
-static void
-e_addr_gui_fill_widgets (EAddrConduitGui *gui, EAddrConduitCfg *cfg)
-{
- g_return_if_fail (gui != NULL);
- g_return_if_fail (cfg != NULL);
-
- e_dialog_option_menu_set (gui->default_address,
- cfg->default_address,
- default_address_map);
-}
-
-static void
-e_addr_gui_fill_config (EAddrConduitGui *gui, EAddrConduitCfg *cfg)
-{
- g_return_if_fail (gui != NULL);
- g_return_if_fail (cfg != NULL);
-
- cfg->default_address = e_dialog_option_menu_get (gui->default_address,
- default_address_map);
-}
-
-static void
-e_addr_gui_destroy (EAddrConduitGui *gui)
-{
- g_free (gui);
-}
-
-/* Context */
-struct _EAddrConduitContext {
- GnomePilotDBInfo *dbi;
-
- EAddrConduitCfg *cfg;
- EAddrConduitCfg *new_cfg;
- EAddrConduitGui *gui;
- GtkWidget *ps;
-
- struct AddressAppInfo ai;
-
- EBook *ebook;
- GList *cards;
- GList *changed;
- GHashTable *changed_hash;
- GList *locals;
-
- gboolean address_load_tried;
- gboolean address_load_success;
-
- EPilotMap *map;
-};
-
-static EAddrConduitContext *
-e_addr_context_new (guint32 pilot_id)
-{
- EAddrConduitContext *ctxt = g_new0 (EAddrConduitContext, 1);
-
- ctxt->cfg = addrconduit_load_configuration (pilot_id);
- ctxt->new_cfg = addrconduit_dupe_configuration (ctxt->cfg);
- ctxt->gui = NULL;
- ctxt->ps = NULL;
- ctxt->ebook = NULL;
- ctxt->cards = NULL;
- ctxt->changed_hash = NULL;
- ctxt->changed = NULL;
- ctxt->locals = NULL;
- ctxt->map = NULL;
-
- return ctxt;
-}
-
-static void
-e_addr_context_destroy (EAddrConduitContext *ctxt)
-{
- GList *l;
-
- g_return_if_fail (ctxt != NULL);
-
- if (ctxt->cfg != NULL)
- addrconduit_destroy_configuration (ctxt->cfg);
- if (ctxt->new_cfg != NULL)
- addrconduit_destroy_configuration (ctxt->new_cfg);
- if (ctxt->gui != NULL)
- e_addr_gui_destroy (ctxt->gui);
-
- if (ctxt->ebook != NULL)
- gtk_object_unref (GTK_OBJECT (ctxt->ebook));
-
- if (ctxt->cards != NULL) {
- for (l = ctxt->cards; l != NULL; l = l->next)
- gtk_object_unref (GTK_OBJECT (l->data));
- g_list_free (ctxt->cards);
- }
-
- if (ctxt->changed_hash != NULL)
- g_hash_table_destroy (ctxt->changed_hash);
-
- if (ctxt->changed != NULL) {
- CardObjectChange *coc;
-
- for (l = ctxt->changed; l != NULL; l = l->next) {
- coc = l->data;
-
- gtk_object_unref (GTK_OBJECT (coc->card));
- g_free (coc);
- }
- g_list_free (ctxt->changed);
- }
-
- if (ctxt->locals != NULL) {
- for (l = ctxt->locals; l != NULL; l = l->next)
- addrconduit_destroy_record (l->data);
- g_list_free (ctxt->locals);
- }
-
- if (ctxt->map != NULL)
- e_pilot_map_destroy (ctxt->map);
-
- g_free (ctxt);
-}
-
-/* Debug routines */
-static char *
-print_local (EAddrLocalRecord *local)
-{
- static char buff[ 4096 ];
-
- if (local == NULL) {
- sprintf (buff, "[NULL]");
- return buff;
- }
-
- if (local->addr) {
- g_snprintf (buff, 4096, "['%s' '%s' '%s']",
- local->addr->entry[entryLastname] ?
- local->addr->entry[entryLastname] : "",
- local->addr->entry[entryFirstname] ?
- local->addr->entry[entryFirstname] : "",
- local->addr->entry[entryCompany] ?
- local->addr->entry[entryCompany] : "");
- return buff;
- }
-
- return "";
-}
-
-static char *print_remote (GnomePilotRecord *remote)
-{
- static char buff[ 4096 ];
- struct Address addr;
-
- if (remote == NULL) {
- sprintf (buff, "[NULL]");
- return buff;
- }
-
- memset (&addr, 0, sizeof (struct Address));
- unpack_Address (&addr, remote->record, remote->length);
-
- g_snprintf (buff, 4096, "['%s' '%s' '%s']",
- addr.entry[entryLastname] ?
- addr.entry[entryLastname] : "",
- addr.entry[entryFirstname] ?
- addr.entry[entryFirstname] : "",
- addr.entry[entryCompany] ?
- addr.entry[entryCompany] : "");
-
- free_Address (&addr);
-
- return buff;
-}
-
-/* Addressbok Server routines */
-static void
-add_card_cb (EBook *ebook, EBookStatus status, const char *id, gpointer closure)
-{
- CardObjectChangeStatus *cons = closure;
-
- cons->status = status;
- cons->id = g_strdup (id);
-
- gtk_main_quit();
-}
-
-static void
-status_cb (EBook *ebook, EBookStatus status, gpointer closure)
-{
- (*(EBookStatus*)closure) = status;
- gtk_main_quit();
-}
-
-static void
-cursor_cb (EBook *book, EBookStatus status, ECardCursor *cursor, gpointer closure)
-{
- EAddrConduitContext *ctxt = (EAddrConduitContext*)closure;
-
- if (status == E_BOOK_STATUS_SUCCESS) {
- long length;
- int i;
-
- ctxt->address_load_success = TRUE;
-
- length = e_card_cursor_get_length (cursor);
- ctxt->cards = NULL;
- for (i = 0; i < length; i ++) {
- ECard *card = e_card_cursor_get_nth (cursor, i);
-
- if (e_card_evolution_list (card))
- continue;
-
- ctxt->cards = g_list_append (ctxt->cards, card);
- }
-
- gtk_main_quit(); /* end the sub event loop */
- }
- else {
- WARN (_("Cursor could not be loaded\n"));
- gtk_main_quit(); /* end the sub event loop */
- }
-}
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- EAddrConduitContext *ctxt = (EAddrConduitContext*)closure;
-
- if (status == E_BOOK_STATUS_SUCCESS) {
- e_book_get_cursor (book, "(contains \"full_name\" \"\")", cursor_cb, ctxt);
- } else {
- WARN (_("EBook not loaded\n"));
- gtk_main_quit(); /* end the sub event loop */
- }
-}
-
-static int
-start_addressbook_server (EAddrConduitContext *ctxt)
-{
- gboolean result;
-
- g_return_val_if_fail(ctxt!=NULL,-2);
-
- ctxt->ebook = e_book_new ();
-
- result = e_book_load_default_book (ctxt->ebook, book_open_cb, ctxt);
-
- /* run a sub event loop to turn ebook's async loading into a
- synchronous call */
- gtk_main ();
-
- if (ctxt->address_load_success)
- return 0;
-
- return -1;
-}
-
-/* Utility routines */
-static char *
-map_name (EAddrConduitContext *ctxt)
-{
- char *filename = NULL;
-
- filename = g_strdup_printf ("%s/evolution/local/Contacts/pilot-map-%d.xml", g_get_home_dir (), ctxt->cfg->pilot_id);
-
- return filename;
-}
-
-static GList *
-next_changed_item (EAddrConduitContext *ctxt, GList *changes)
-{
- CardObjectChange *coc;
- GList *l;
-
- for (l = changes; l != NULL; l = l->next) {
- coc = l->data;
-
- if (g_hash_table_lookup (ctxt->changed_hash, e_card_get_id (coc->card)))
- return l;
- }
-
- return NULL;
-}
-
-static ECardSimpleField
-get_next_mail (ECardSimpleField *field)
-{
- if (field == NULL)
- return E_CARD_SIMPLE_FIELD_EMAIL;
-
- switch (*field) {
- case E_CARD_SIMPLE_FIELD_EMAIL:
- return E_CARD_SIMPLE_FIELD_EMAIL_2;
- case E_CARD_SIMPLE_FIELD_EMAIL_2:
- return E_CARD_SIMPLE_FIELD_EMAIL_3;
- default:
- }
-
- return E_CARD_SIMPLE_FIELD_LAST;
-}
-
-static ECardSimpleField
-get_next_home (ECardSimpleField *field)
-{
- if (field == NULL)
- return E_CARD_SIMPLE_FIELD_PHONE_HOME;
-
- switch (*field) {
- case E_CARD_SIMPLE_FIELD_PHONE_HOME:
- return E_CARD_SIMPLE_FIELD_PHONE_HOME_2;
- default:
- }
-
- return E_CARD_SIMPLE_FIELD_LAST;
-}
-
-static ECardSimpleField
-get_next_work (ECardSimpleField *field)
-{
- if (field == NULL)
- return E_CARD_SIMPLE_FIELD_PHONE_BUSINESS;
-
- switch (*field) {
- case E_CARD_SIMPLE_FIELD_PHONE_BUSINESS:
- return E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_2;
- default:
- }
-
- return E_CARD_SIMPLE_FIELD_LAST;
-}
-
-static ECardSimpleField
-get_next_fax (ECardSimpleField *field)
-{
- if (field == NULL)
- return E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_FAX;
-
- switch (*field) {
- case E_CARD_SIMPLE_FIELD_PHONE_BUSINESS_FAX:
- return E_CARD_SIMPLE_FIELD_PHONE_HOME_FAX;
- case E_CARD_SIMPLE_FIELD_PHONE_HOME_FAX:
- return E_CARD_SIMPLE_FIELD_PHONE_OTHER_FAX;
- default:
- }
-
- return E_CARD_SIMPLE_FIELD_LAST;
-}
-
-static ECardSimpleField
-get_next_other (ECardSimpleField *field)
-{
- if (field == NULL)
- return E_CARD_SIMPLE_FIELD_PHONE_OTHER;
-
- return E_CARD_SIMPLE_FIELD_LAST;
-}
-
-static ECardSimpleField
-get_next_main (ECardSimpleField *field)
-{
- if (field == NULL)
- return E_CARD_SIMPLE_FIELD_PHONE_PRIMARY;
-
- return E_CARD_SIMPLE_FIELD_LAST;
-}
-
-static ECardSimpleField
-get_next_pager (ECardSimpleField *field)
-{
- if (field == NULL)
- return E_CARD_SIMPLE_FIELD_PHONE_PAGER;
-
- return E_CARD_SIMPLE_FIELD_LAST;
-}
-
-static ECardSimpleField
-get_next_mobile (ECardSimpleField *field)
-{
- if (field == NULL)
- return E_CARD_SIMPLE_FIELD_PHONE_MOBILE;
-
- return E_CARD_SIMPLE_FIELD_LAST;
-}
-
-static void
-get_next_init (ECardSimpleField *next_mail,
- ECardSimpleField *next_home,
- ECardSimpleField *next_work,
- ECardSimpleField *next_fax,
- ECardSimpleField *next_other,
- ECardSimpleField *next_main,
- ECardSimpleField *next_pager,
- ECardSimpleField *next_mobile)
-{
- *next_mail = get_next_mail (NULL);
- *next_home = get_next_home (NULL);
- *next_work = get_next_work (NULL);
- *next_fax = get_next_fax (NULL);
- *next_other = get_next_other (NULL);
- *next_main = get_next_main (NULL);
- *next_pager = get_next_pager (NULL);
- *next_mobile = get_next_mobile (NULL);
-}
-
-static gboolean
-is_next_done (ECardSimpleField field)
-{
- if (field == E_CARD_SIMPLE_FIELD_LAST)
- return TRUE;
-
- return FALSE;
-}
-
-static gboolean
-is_syncable (EAddrConduitContext *ctxt, EAddrLocalRecord *local)
-{
- ECardSimpleField next_mail, next_home, next_work, next_fax;
- ECardSimpleField next_other, next_main, next_pager, next_mobile;
- gboolean syncable = TRUE;
- int i, l = 0;
-
- /* See if there are fields we can't sync or not in priority order */
- get_next_init (&next_mail, &next_home, &next_work, &next_fax,
- &next_other, &next_main, &next_pager, &next_mobile);
-
- for (i = entryPhone1; i <= entryPhone5 && syncable; i++) {
- int phonelabel = local->addr->phoneLabel[i - entryPhone1];
- const char *phone_str = local->addr->entry[i];
- gboolean empty = !(phone_str && *phone_str);
-
- if (empty)
- continue;
-
- for ( ; priority_label[l] != -1; l++)
- if (phonelabel == priority_label[l])
- break;
-
- if (priority_label[l] == -1) {
- syncable = FALSE;
- continue;
- }
-
- if (phonelabel == LABEL_EMAIL) {
- if (is_next_done (next_mail) || next_mail != priority[l]) {
- syncable = FALSE;
- break;
- }
- next_mail = get_next_mail (&next_mail);
- } else if (phonelabel == LABEL_HOME) {
- if (is_next_done (next_home) || next_home != priority[l]) {
- syncable = FALSE;
- break;
- }
- next_home = get_next_home (&next_home);
- } else if (phonelabel == LABEL_WORK) {
- if (is_next_done (next_work) || next_work != priority[l]) {
- syncable = FALSE;
- break;
- }
- next_work = get_next_work (&next_work);
- } else if (phonelabel == LABEL_FAX) {
- if (is_next_done (next_fax) || next_fax != priority[l]) {
- syncable = FALSE;
- break;
- }
- next_fax = get_next_fax (&next_fax);
- } else if (phonelabel == LABEL_OTHER) {
- if (is_next_done (next_other) || next_other != priority[l]) {
- syncable = FALSE;
- break;
- }
- next_other = get_next_other (&next_other);
- } else if (phonelabel == LABEL_MAIN) {
- if (is_next_done (next_main) || next_main != priority[l]) {
- syncable = FALSE;
- break;
- }
- next_main = get_next_main (&next_main);
- } else if (phonelabel == LABEL_PAGER) {
- if (is_next_done (next_pager) || next_pager != priority[l]) {
- syncable = FALSE;
- break;
- }
- next_pager = get_next_pager (&next_pager);
- } else if (phonelabel == LABEL_MOBILE) {
- if (is_next_done (next_mobile) || next_mobile != priority[l]) {
- syncable = FALSE;
- break;
- }
- next_mobile = get_next_mobile (&next_mobile);
- }
- }
-
- return syncable;
-}
-
-static char *
-get_entry_text (struct Address address, int field)
-{
- if (address.entry[field])
- return e_pilot_utf8_from_pchar (address.entry[field]);
-
- return g_strdup ("");
-}
-
-static void
-clear_entry_text (struct Address address, int field)
-{
- if (address.entry[field]) {
- free (address.entry[field]);
- address.entry[field] = NULL;
- }
-}
-
-static void
-compute_status (EAddrConduitContext *ctxt, EAddrLocalRecord *local, const char *uid)
-{
- CardObjectChange *coc;
-
- local->local.archived = FALSE;
- local->local.secret = FALSE;
-
- coc = g_hash_table_lookup (ctxt->changed_hash, uid);
-
- if (coc == NULL) {
- local->local.attr = GnomePilotRecordNothing;
- return;
- }
-
- switch (coc->type) {
- case CARD_ADDED:
- local->local.attr = GnomePilotRecordNew;
- break;
- case CARD_MODIFIED:
- local->local.attr = GnomePilotRecordModified;
- break;
- case CARD_DELETED:
- local->local.attr = GnomePilotRecordDeleted;
- break;
- }
-}
-
-static GnomePilotRecord
-local_record_to_pilot_record (EAddrLocalRecord *local,
- EAddrConduitContext *ctxt)
-{
- GnomePilotRecord p;
- static char record[0xffff];
-
- g_assert (local->addr != NULL );
-
- LOG ("local_record_to_pilot_record\n");
-
- p.ID = local->local.ID;
- p.category = local->local.category;
- p.attr = local->local.attr;
- p.archived = local->local.archived;
- p.secret = local->local.secret;
-
- /* Generate pilot record structure */
- p.record = record;
- p.length = pack_Address (local->addr, p.record, 0xffff);
-
- return p;
-}
-
-static void
-local_record_from_ecard (EAddrLocalRecord *local, ECard *ecard, EAddrConduitContext *ctxt)
-{
- ECardSimple *simple;
- const ECardDeliveryAddress *delivery;
- ECardSimpleAddressId mailing_address;
- int phone = entryPhone1;
-
- gboolean syncable;
- int i;
-
- g_return_if_fail (local != NULL);
- g_return_if_fail (ecard != NULL);
-
- local->ecard = ecard;
- gtk_object_ref (GTK_OBJECT (ecard));
- simple = e_card_simple_new (ecard);
-
- local->local.ID = e_pilot_map_lookup_pid (ctxt->map, ecard->id, TRUE);
-
- compute_status (ctxt, local, ecard->id);
-
- local->addr = g_new0 (struct Address, 1);
-
- /* Handle the fields and category we don't sync by making sure
- * we don't overwrite them
- */
- if (local->local.ID != 0) {
- struct Address addr;
- char record[0xffff];
- int cat = 0;
-
- if (dlp_ReadRecordById (ctxt->dbi->pilot_socket,
- ctxt->dbi->db_handle,
- local->local.ID, &record,
- NULL, NULL, NULL, &cat) > 0) {
- local->local.category = cat;
- memset (&addr, 0, sizeof (struct Address));
- unpack_Address (&addr, record, 0xffff);
- for (i = 0; i < 5; i++) {
- if (addr.entry[entryPhone1 + i])
- local->addr->entry[entryPhone1 + i] =
- strdup (addr.entry[entryPhone1 + i]);
- local->addr->phoneLabel[i] = addr.phoneLabel[i];
- }
- local->addr->showPhone = addr.showPhone;
- for (i = 0; i < 4; i++) {
- if (addr.entry[entryCustom1 + i])
- local->addr->entry[entryCustom1 + i] =
- strdup (addr.entry[entryCustom1 + i]);
- }
- free_Address (&addr);
- }
- }
-
- if (ecard->name) {
- local->addr->entry[entryFirstname] = e_pilot_utf8_to_pchar (ecard->name->given);
- local->addr->entry[entryLastname] = e_pilot_utf8_to_pchar (ecard->name->family);
- }
-
- local->addr->entry[entryCompany] = e_pilot_utf8_to_pchar (ecard->org);
- local->addr->entry[entryTitle] = e_pilot_utf8_to_pchar (ecard->title);
-
- mailing_address = -1;
- for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) {
- const ECardAddrLabel *address;
-
- address = e_card_simple_get_address(simple, i);
- if (address && (address->flags & E_CARD_ADDR_DEFAULT))
- mailing_address = i;
- }
- if (mailing_address == -1)
- mailing_address = ctxt->cfg->default_address;
-
- delivery = e_card_simple_get_delivery_address (simple, mailing_address);
- if (delivery) {
- local->addr->entry[entryAddress] = e_pilot_utf8_to_pchar (delivery->street);
- local->addr->entry[entryCity] = e_pilot_utf8_to_pchar (delivery->city);
- local->addr->entry[entryState] = e_pilot_utf8_to_pchar (delivery->region);
- local->addr->entry[entryZip] = e_pilot_utf8_to_pchar (delivery->code);
- local->addr->entry[entryCountry] = e_pilot_utf8_to_pchar (delivery->country);
- }
-
- /* Phone numbers */
-
- /* See if everything is syncable */
- syncable = is_syncable (ctxt, local);
-
- if (syncable) {
- INFO ("Syncable");
-
- /* Sync by priority */
- for (i = 0, phone = entryPhone1;
- priority[i] != E_CARD_SIMPLE_FIELD_LAST && phone <= entryPhone5; i++) {
- const char *phone_str;
-
- phone_str = e_card_simple_get_const (simple, priority[i]);
- if (phone_str && *phone_str) {
- clear_entry_text (*local->addr, phone);
- local->addr->entry[phone] = e_pilot_utf8_to_pchar (phone_str);
- local->addr->phoneLabel[phone - entryPhone1] = priority_label[i];
- phone++;
- }
- }
- for ( ; phone <= entryPhone5; phone++)
- local->addr->phoneLabel[phone - entryPhone1] = phone - entryPhone1;
- local->addr->showPhone = 0;
- } else {
- ECardSimpleField next_mail, next_home, next_work, next_fax;
- ECardSimpleField next_other, next_main, next_pager, next_mobile;
-
- INFO ("Not Syncable");
- get_next_init (&next_mail, &next_home, &next_work, &next_fax,
- &next_other, &next_main, &next_pager, &next_mobile);
-
- /* Not completely syncable, so do the best we can */
- for (i = entryPhone1; i <= entryPhone5; i++) {
- int phonelabel = local->addr->phoneLabel[i - entryPhone1];
- const char *phone_str = NULL;
-
- if (phonelabel == LABEL_EMAIL && !is_next_done (next_mail)) {
- phone_str = e_card_simple_get_const (simple, next_mail);
- next_mail = get_next_mail (&next_mail);
- } else if (phonelabel == LABEL_HOME && !is_next_done (next_home)) {
- phone_str = e_card_simple_get_const (simple, next_home);
- next_home = get_next_home (&next_home);
- } else if (phonelabel == LABEL_WORK && !is_next_done (next_work)) {
- phone_str = e_card_simple_get_const (simple, next_work);
- next_work = get_next_work (&next_work);
- } else if (phonelabel == LABEL_FAX && !is_next_done (next_fax)) {
- phone_str = e_card_simple_get_const (simple, next_fax);
- next_fax = get_next_fax (&next_fax);
- } else if (phonelabel == LABEL_OTHER && !is_next_done (next_other)) {
- phone_str = e_card_simple_get_const (simple, next_other);
- next_other = get_next_other (&next_other);
- } else if (phonelabel == LABEL_MAIN && !is_next_done (next_main)) {
- phone_str = e_card_simple_get_const (simple, next_main);
- next_main = get_next_main (&next_main);
- } else if (phonelabel == LABEL_PAGER && !is_next_done (next_pager)) {
- phone_str = e_card_simple_get_const (simple, next_pager);
- next_pager = get_next_pager (&next_pager);
- } else if (phonelabel == LABEL_MOBILE && !is_next_done (next_mobile)) {
- phone_str = e_card_simple_get_const (simple, next_mobile);
- next_mobile = get_next_mobile (&next_mobile);
- }
-
- if (phone_str && *phone_str) {
- clear_entry_text (*local->addr, i);
- local->addr->entry[i] = e_pilot_utf8_to_pchar (phone_str);
- }
- }
- }
-
- /* Note */
- local->addr->entry[entryNote] = e_pilot_utf8_to_pchar (ecard->note);
-
- gtk_object_unref (GTK_OBJECT (simple));
-}
-
-static void
-local_record_from_uid (EAddrLocalRecord *local,
- const char *uid,
- EAddrConduitContext *ctxt)
-{
- ECard *ecard = NULL;
- GList *l;
-
- g_assert (local != NULL);
-
- for (l = ctxt->cards; l != NULL; l = l->next) {
- ecard = l->data;
-
- if (ecard->id && !strcmp (ecard->id, uid))
- break;
-
- ecard = NULL;
- }
-
- if (ecard != NULL) {
- local_record_from_ecard (local, ecard, ctxt);
- } else {
- ecard = e_card_new ("");
- e_card_set_id (ecard, uid);
- local_record_from_ecard (local, ecard, ctxt);
- gtk_object_unref (GTK_OBJECT (ecard));
- }
-}
-
-static ECard *
-ecard_from_remote_record(EAddrConduitContext *ctxt,
- GnomePilotRecord *remote,
- ECard *in_card)
-{
- struct Address address;
- ECard *ecard;
- ECardSimple *simple;
- ECardName *name;
- ECardDeliveryAddress *delivery;
- ECardAddrLabel *label;
- ECardSimpleAddressId mailing_address;
- char *txt;
- ECardSimpleField next_mail, next_home, next_work, next_fax;
- ECardSimpleField next_other, next_main, next_pager, next_mobile;
- int i;
-
- g_return_val_if_fail(remote!=NULL,NULL);
- memset (&address, 0, sizeof (struct Address));
- unpack_Address (&address, remote->record, remote->length);
-
- if (in_card == NULL)
- ecard = e_card_new("");
- else
- ecard = e_card_duplicate (in_card);
-
- /* Name */
- name = e_card_name_copy (ecard->name);
- name->given = get_entry_text (address, entryFirstname);
- name->family = get_entry_text (address, entryLastname);
-
- simple = e_card_simple_new (ecard);
- txt = e_card_name_to_string (name);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_FULL_NAME, txt);
- e_card_simple_set_name (simple, name);
-
- /* File as */
- if (!(txt && *txt))
- e_card_simple_set(simple, E_CARD_SIMPLE_FIELD_FILE_AS,
- address.entry[entryCompany]);
-
- g_free (txt);
- e_card_name_unref (name);
-
- /* Title and Company */
- txt = get_entry_text (address, entryTitle);
- e_card_simple_set(simple, E_CARD_SIMPLE_FIELD_TITLE, txt);
- g_free (txt);
-
- txt = get_entry_text (address, entryCompany);
- e_card_simple_set(simple, E_CARD_SIMPLE_FIELD_ORG, txt);
- g_free (txt);
-
- /* Address */
- mailing_address = -1;
- for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) {
- const ECardAddrLabel *addr;
-
- addr = e_card_simple_get_address(simple, i);
- if (addr && (addr->flags & E_CARD_ADDR_DEFAULT))
- mailing_address = i;
- }
- if (mailing_address == -1)
- mailing_address = ctxt->cfg->default_address;
-
- delivery = e_card_delivery_address_new ();
- delivery->flags |= E_CARD_ADDR_DEFAULT;
- delivery->street = get_entry_text (address, entryAddress);
- delivery->city = get_entry_text (address, entryCity);
- delivery->region = get_entry_text (address, entryState);
- delivery->country = get_entry_text (address, entryCountry);
- delivery->code = get_entry_text (address, entryZip);
-
- label = e_card_address_label_new ();
- label->flags |= E_CARD_ADDR_DEFAULT;
- label->data = e_card_delivery_address_to_string (delivery);
-
- e_card_simple_set_address (simple, mailing_address, label);
- e_card_simple_set_delivery_address (simple, mailing_address, delivery);
-
- e_card_delivery_address_unref (delivery);
- e_card_address_label_unref (label);
-
- /* Phone numbers */
- get_next_init (&next_mail, &next_home, &next_work, &next_fax,
- &next_other, &next_main, &next_pager, &next_mobile);
-
- for (i = entryPhone1; i <= entryPhone5; i++) {
- int phonelabel = address.phoneLabel[i - entryPhone1];
- char *phonenum = get_entry_text (address, i);
-
- if (phonelabel == LABEL_EMAIL && !is_next_done (next_mail)) {
- e_card_simple_set (simple, next_mail, phonenum);
- next_mail = get_next_mail (&next_mail);
- } else if (phonelabel == LABEL_HOME && !is_next_done (next_home)) {
- e_card_simple_set (simple, next_home, phonenum);
- next_home = get_next_home (&next_home);
- } else if (phonelabel == LABEL_WORK && !is_next_done (next_work)) {
- e_card_simple_set (simple, next_work, phonenum);
- next_work = get_next_work (&next_work);
- } else if (phonelabel == LABEL_FAX && !is_next_done (next_fax)) {
- e_card_simple_set (simple, next_fax, phonenum);
- next_fax = get_next_fax (&next_fax);
- } else if (phonelabel == LABEL_OTHER && !is_next_done (next_other)) {
- e_card_simple_set (simple, next_other, phonenum);
- next_other = get_next_other (&next_other);
- } else if (phonelabel == LABEL_MAIN && !is_next_done (next_main)) {
- e_card_simple_set (simple, next_main, phonenum);
- next_main = get_next_main (&next_main);
- } else if (phonelabel == LABEL_PAGER && !is_next_done (next_pager)) {
- e_card_simple_set (simple, next_pager, phonenum);
- next_pager = get_next_pager (&next_pager);
- } else if (phonelabel == LABEL_MOBILE && !is_next_done (next_mobile)) {
- e_card_simple_set (simple, next_mobile, phonenum);
- next_mobile = get_next_mobile (&next_mobile);
- }
-
- g_free (phonenum);
- }
-
- /* Note */
- txt = get_entry_text (address, entryNote);
- e_card_simple_set(simple, E_CARD_SIMPLE_FIELD_NOTE, txt);
- g_free (txt);
-
- e_card_simple_sync_card (simple);
- gtk_object_unref(GTK_OBJECT(simple));
-
- free_Address(&address);
-
- return ecard;
-}
-
-static void
-check_for_slow_setting (GnomePilotConduit *c, EAddrConduitContext *ctxt)
-{
- GnomePilotConduitStandard *conduit = GNOME_PILOT_CONDUIT_STANDARD (c);
- int map_count;
- const char *uri;
-
- map_count = g_hash_table_size (ctxt->map->pid_map);
- if (map_count == 0)
- gnome_pilot_conduit_standard_set_slow (conduit, TRUE);
-
- /* Or if the URI's don't match */
- uri = e_book_get_uri (ctxt->ebook);
- LOG(" Current URI %s (%s)\n", uri, ctxt->cfg->last_uri ? ctxt->cfg->last_uri : "<NONE>");
- if (ctxt->cfg->last_uri != NULL && strcmp (ctxt->cfg->last_uri, uri)) {
- gnome_pilot_conduit_standard_set_slow (conduit, TRUE);
- e_pilot_map_clear (ctxt->map);
- }
-
- if (gnome_pilot_conduit_standard_get_slow (conduit)) {
- ctxt->map->write_touched_only = TRUE;
- LOG (" doing slow sync\n");
- } else {
- LOG (" doing fast sync\n");
- }
-}
-
-static void
-card_added (EBookView *book_view, const GList *cards, EAddrConduitContext *ctxt)
-{
- const GList *l;
-
- for (l = cards; l != NULL; l = l->next) {
- ECard *card = E_CARD (l->data);
- CardObjectChange *coc;
-
- if (e_card_evolution_list (card))
- continue;
-
- coc = g_new0 (CardObjectChange, 1);
- coc->card = card;
- coc->type = CARD_ADDED;
-
- gtk_object_ref (GTK_OBJECT (coc->card));
- ctxt->changed = g_list_prepend (ctxt->changed, coc);
- if (!e_pilot_map_uid_is_archived (ctxt->map, e_card_get_id (coc->card)))
- g_hash_table_insert (ctxt->changed_hash, (gpointer)e_card_get_id (coc->card), coc);
- }
-}
-
-static void
-card_changed (EBookView *book_view, const GList *cards, EAddrConduitContext *ctxt)
-{
- const GList *l;
-
- for (l = cards; l != NULL; l = l->next) {
- ECard *card = E_CARD (l->data);
- CardObjectChange *coc;
-
- if (e_card_evolution_list (card))
- continue;
-
- coc = g_new0 (CardObjectChange, 1);
- coc->card = E_CARD (l->data);
- coc->type = CARD_MODIFIED;
-
- gtk_object_ref (GTK_OBJECT (coc->card));
- ctxt->changed = g_list_prepend (ctxt->changed, coc);
- if (!e_pilot_map_uid_is_archived (ctxt->map, e_card_get_id (coc->card)))
- g_hash_table_insert (ctxt->changed_hash, (gpointer)e_card_get_id (coc->card), coc);
- }
-}
-
-
-static void
-card_removed (EBookView *book_view, const char *id, EAddrConduitContext *ctxt)
-{
- CardObjectChange *coc;
- gboolean archived;
-
- archived = e_pilot_map_uid_is_archived (ctxt->map, id);
-
- /* If its deleted, not in the archive and not in the map its a list */
- if (!archived && e_pilot_map_lookup_pid (ctxt->map, id, FALSE) == 0)
- return;
-
- coc = g_new0 (CardObjectChange, 1);
- coc->card = e_card_new ("");
- e_card_set_id (coc->card, id);
- coc->type = CARD_DELETED;
-
- ctxt->changed = g_list_prepend (ctxt->changed, coc);
-
- if (!archived)
- g_hash_table_insert (ctxt->changed_hash, (gpointer)e_card_get_id (coc->card), coc);
- else
- e_pilot_map_remove_by_uid (ctxt->map, id);
-}
-
-static void
-sequence_complete (EBookView *book_view, EBookViewStatus status, EAddrConduitContext *ctxt)
-{
- gtk_signal_disconnect_by_data (GTK_OBJECT (book_view), ctxt);
- gtk_object_unref (GTK_OBJECT (book_view));
- gtk_main_quit ();
-}
-
-static void
-view_cb (EBook *book, EBookStatus status, EBookView *book_view, gpointer data)
-{
- EAddrConduitContext *ctxt = data;
-
- gtk_object_ref (GTK_OBJECT (book_view));
-
- gtk_signal_connect (GTK_OBJECT (book_view), "card_added",
- (GtkSignalFunc) card_added, ctxt);
- gtk_signal_connect (GTK_OBJECT (book_view), "card_changed",
- (GtkSignalFunc) card_changed, ctxt);
- gtk_signal_connect (GTK_OBJECT (book_view), "card_removed",
- (GtkSignalFunc) card_removed, ctxt);
- gtk_signal_connect (GTK_OBJECT (book_view), "sequence_complete",
- (GtkSignalFunc) sequence_complete, ctxt);
-
-}
-
-/* Pilot syncing callbacks */
-static gint
-pre_sync (GnomePilotConduit *conduit,
- GnomePilotDBInfo *dbi,
- EAddrConduitContext *ctxt)
-{
- GnomePilotConduitSyncAbs *abs_conduit;
-/* GList *l; */
- int len;
- unsigned char *buf;
- char *filename;
- char *change_id;
-/* gint num_records; */
-
- abs_conduit = GNOME_PILOT_CONDUIT_SYNC_ABS (conduit);
-
- LOG ("---------------------------------------------------------\n");
- LOG ("pre_sync: Addressbook Conduit v.%s", CONDUIT_VERSION);
- /* g_message ("Addressbook Conduit v.%s", CONDUIT_VERSION); */
-
- ctxt->dbi = dbi;
- ctxt->ebook = NULL;
-
- if (start_addressbook_server (ctxt) != 0) {
- WARN(_("Could not start wombat server"));
- gnome_pilot_conduit_error (conduit, _("Could not start wombat"));
- return -1;
- }
-
- /* Load the uid <--> pilot id mappings */
- filename = map_name (ctxt);
- e_pilot_map_read (filename, &ctxt->map);
- g_free (filename);
-
- /* Count and hash the changes */
- change_id = g_strdup_printf ("pilot-sync-evolution-addressbook-%d", ctxt->cfg->pilot_id);
- ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal);
- e_book_get_changes (ctxt->ebook, change_id, view_cb, ctxt);
-
- /* Force the view loading to be synchronous */
- gtk_main ();
- g_free (change_id);
-
- /* Set the count information */
-/* num_records = cal_client_get_n_objects (ctxt->client, CALOBJ_TYPE_TODO); */
-/* 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); */
-/* gnome_pilot_conduit_sync_abs_set_num_deleted_local_records(abs_conduit, del_records); */
-
- buf = (unsigned char*)g_malloc (0xffff);
- len = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0,
- (unsigned char *)buf, 0xffff);
-
- if (len < 0) {
- WARN (_("Could not read pilot's Address application block"));
- WARN ("dlp_ReadAppBlock(...) = %d", len);
- gnome_pilot_conduit_error (conduit,
- _("Could not read pilot's Address application block"));
- return -1;
- }
- unpack_AddressAppInfo (&(ctxt->ai), buf, len);
- g_free (buf);
-
- check_for_slow_setting (conduit, ctxt);
- if (ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyToPilot
- || ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyFromPilot)
- ctxt->map->write_touched_only = TRUE;
-
- return 0;
-}
-
-static gint
-post_sync (GnomePilotConduit *conduit,
- GnomePilotDBInfo *dbi,
- EAddrConduitContext *ctxt)
-{
- gchar *filename, *change_id;
-
- LOG ("post_sync: Address Conduit v.%s", CONDUIT_VERSION);
-
- g_free (ctxt->cfg->last_uri);
- ctxt->cfg->last_uri = g_strdup (e_book_get_uri (ctxt->ebook));
- addrconduit_save_configuration (ctxt->cfg);
-
- filename = map_name (ctxt);
- e_pilot_map_write (filename, ctxt->map);
- g_free (filename);
-
- /* FIX ME ugly hack - our changes musn't count, this does introduce
- * a race condition if anyone changes a record elsewhere during sycnc
- */
- change_id = g_strdup_printf ("pilot-sync-evolution-addressbook-%d", ctxt->cfg->pilot_id);
- e_book_get_changes (ctxt->ebook, change_id, view_cb, ctxt);
- g_free (change_id);
- gtk_main ();
-
- LOG ("---------------------------------------------------------\n");
-
- return 0;
-}
-
-static gint
-set_pilot_id (GnomePilotConduitSyncAbs *conduit,
- EAddrLocalRecord *local,
- guint32 ID,
- EAddrConduitContext *ctxt)
-{
- LOG ("set_pilot_id: setting to %d\n", ID);
-
- e_pilot_map_insert (ctxt->map, ID, local->ecard->id, FALSE);
-
- return 0;
-}
-
-static gint
-set_status_cleared (GnomePilotConduitSyncAbs *conduit,
- EAddrLocalRecord *local,
- EAddrConduitContext *ctxt)
-{
- LOG ("set_status_cleared: clearing status\n");
-
- g_hash_table_remove (ctxt->changed_hash, e_card_get_id (local->ecard));
-
- return 0;
-}
-
-static gint
-for_each (GnomePilotConduitSyncAbs *conduit,
- EAddrLocalRecord **local,
- EAddrConduitContext *ctxt)
-{
- static GList *cards, *iterator;
- static int count;
-
- g_return_val_if_fail (local != NULL, -1);
-
- if (*local == NULL) {
- LOG ("beginning for_each");
-
- cards = ctxt->cards;
- count = 0;
-
- if (cards != NULL) {
- LOG ("iterating over %d records", g_list_length (cards));
-
- *local = g_new0 (EAddrLocalRecord, 1);
- local_record_from_ecard (*local, cards->data, ctxt);
- g_list_prepend (ctxt->locals, *local);
-
- iterator = cards;
- } else {
- LOG ("no events");
- (*local) = NULL;
- return 0;
- }
- } else {
- count++;
- if (g_list_next (iterator)) {
- iterator = g_list_next (iterator);
-
- *local = g_new0 (EAddrLocalRecord, 1);
- local_record_from_ecard (*local, iterator->data, ctxt);
- g_list_prepend (ctxt->locals, *local);
- } else {
- LOG ("for_each ending");
-
- /* Tell the pilot the iteration is over */
- *local = NULL;
-
- return 0;
- }
- }
-
- return 0;
-}
-
-static gint
-for_each_modified (GnomePilotConduitSyncAbs *conduit,
- EAddrLocalRecord **local,
- EAddrConduitContext *ctxt)
-{
- static GList *iterator;
- static int count;
-
- g_return_val_if_fail (local != NULL, 0);
-
- if (*local == NULL) {
- LOG ("for_each_modified beginning\n");
-
- iterator = ctxt->changed;
-
- count = 0;
-
- iterator = next_changed_item (ctxt, iterator);
- if (iterator != NULL) {
- CardObjectChange *coc = iterator->data;
-
- LOG ("iterating over %d records", g_hash_table_size (ctxt->changed_hash));
-
- *local = g_new0 (EAddrLocalRecord, 1);
- local_record_from_ecard (*local, coc->card, ctxt);
- g_list_prepend (ctxt->locals, *local);
- } else {
- LOG ("no events");
-
- *local = NULL;
- }
- } else {
- count++;
- iterator = g_list_next (iterator);
- if (iterator && (iterator = next_changed_item (ctxt, iterator))) {
- CardObjectChange *coc = iterator->data;
-
- *local = g_new0 (EAddrLocalRecord, 1);
- local_record_from_ecard (*local, coc->card, ctxt);
- g_list_prepend (ctxt->locals, *local);
- } else {
- LOG ("for_each_modified ending");
-
- /* Signal the iteration is over */
- *local = NULL;
-
- return 0;
- }
- }
-
- return 0;
-}
-
-static gint
-compare (GnomePilotConduitSyncAbs *conduit,
- EAddrLocalRecord *local,
- GnomePilotRecord *remote,
- EAddrConduitContext *ctxt)
-{
- GnomePilotRecord local_pilot;
- int retval = 0;
-
- LOG ("compare: local=%s remote=%s...\n",
- print_local (local), print_remote (remote));
-
- g_return_val_if_fail (local != NULL, -1);
- g_return_val_if_fail (remote != NULL, -1);
-
- local_pilot = local_record_to_pilot_record (local, ctxt);
-
- if (remote->length != local_pilot.length
- || memcmp (local_pilot.record, remote->record, remote->length))
- retval = 1;
-
- if (retval == 0)
- LOG (" equal");
- else
- LOG (" not equal");
-
- return retval;
-}
-
-static gint
-add_record (GnomePilotConduitSyncAbs *conduit,
- GnomePilotRecord *remote,
- EAddrConduitContext *ctxt)
-{
- ECard *ecard;
- CardObjectChangeStatus cons;
- int retval = 0;
-
- g_return_val_if_fail (remote != NULL, -1);
-
- LOG ("add_record: adding %s to desktop\n", print_remote (remote));
-
- ecard = ecard_from_remote_record (ctxt, remote, NULL);
-
- /* add the ecard to the server */
- e_book_add_card (ctxt->ebook, ecard, add_card_cb, &cons);
-
- gtk_main(); /* enter sub mainloop */
-
- if (cons.status != E_BOOK_STATUS_SUCCESS) {
- WARN ("add_record: failed to add card to ebook\n");
- return -1;
- }
-
- e_card_set_id (ecard, cons.id);
- e_pilot_map_insert (ctxt->map, remote->ID, ecard->id, FALSE);
-
- gtk_object_unref (GTK_OBJECT (ecard));
-
- return retval;
-}
-
-static gint
-replace_record (GnomePilotConduitSyncAbs *conduit,
- EAddrLocalRecord *local,
- GnomePilotRecord *remote,
- EAddrConduitContext *ctxt)
-{
- ECard *new_ecard;
- EBookStatus commit_status;
- CardObjectChange *coc;
- CardObjectChangeStatus cons;
- char *old_id;
- int retval = 0;
-
- g_return_val_if_fail (remote != NULL, -1);
-
- LOG ("replace_record: replace %s with %s\n",
- print_local (local), print_remote (remote));
-
- old_id = g_strdup (e_card_get_id (local->ecard));
- coc = g_hash_table_lookup (ctxt->changed_hash, old_id);
-
- new_ecard = ecard_from_remote_record (ctxt, remote, local->ecard);
- gtk_object_unref (GTK_OBJECT (local->ecard));
- local->ecard = new_ecard;
-
- if (coc && coc->type == CARD_DELETED)
- e_book_add_card (ctxt->ebook, local->ecard, add_card_cb, &cons);
- else
- e_book_commit_card (ctxt->ebook, local->ecard, status_cb, &commit_status);
-
- gtk_main (); /* enter sub mainloop */
-
- /* Adding a record causes wombat to assign a new uid so we must tidy */
- if (coc && coc->type == CARD_DELETED) {
- gboolean arch = e_pilot_map_uid_is_archived (ctxt->map, e_card_get_id (local->ecard));
-
- e_card_set_id (local->ecard, cons.id);
- e_pilot_map_insert (ctxt->map, remote->ID, cons.id, arch);
-
- coc = g_hash_table_lookup (ctxt->changed_hash, old_id);
- if (coc) {
- g_hash_table_remove (ctxt->changed_hash, e_card_get_id (coc->card));
- gtk_object_unref (GTK_OBJECT (coc->card));
- gtk_object_ref (GTK_OBJECT (local->ecard));
- coc->card = local->ecard;
- g_hash_table_insert (ctxt->changed_hash, (gpointer)e_card_get_id (coc->card), coc);
- }
-
- commit_status = cons.status;
- }
-
- if (commit_status != E_BOOK_STATUS_SUCCESS)
- WARN ("replace_record: failed to update card in ebook\n");
-
- return retval;
-}
-
-static gint
-delete_record (GnomePilotConduitSyncAbs *conduit,
- EAddrLocalRecord *local,
- EAddrConduitContext *ctxt)
-{
- EBookStatus commit_status;
- int retval = 0;
-
- g_return_val_if_fail (local != NULL, -1);
- g_return_val_if_fail (local->ecard != NULL, -1);
-
- LOG ("delete_record: delete %s\n", print_local (local));
-
- e_pilot_map_remove_by_uid (ctxt->map, local->ecard->id);
- e_book_remove_card_by_id (ctxt->ebook, local->ecard->id, status_cb, &commit_status);
-
- gtk_main (); /* enter sub mainloop */
-
- if (commit_status != E_BOOK_STATUS_SUCCESS && commit_status != E_BOOK_STATUS_CARD_NOT_FOUND)
- WARN ("delete_record: failed to delete card in ebook\n");
-
- return retval;
-}
-
-static gint
-archive_record (GnomePilotConduitSyncAbs *conduit,
- EAddrLocalRecord *local,
- gboolean archive,
- EAddrConduitContext *ctxt)
-{
- int retval = 0;
-
- g_return_val_if_fail (local != NULL, -1);
-
- LOG ("archive_record: %s\n", archive ? "yes" : "no");
-
- e_pilot_map_insert (ctxt->map, local->local.ID, local->ecard->id, archive);
-
- return retval;
-}
-
-static gint
-match (GnomePilotConduitSyncAbs *conduit,
- GnomePilotRecord *remote,
- EAddrLocalRecord **local,
- EAddrConduitContext *ctxt)
-{
- const char *uid;
-
- LOG ("match: looking for local copy of %s\n",
- print_remote (remote));
-
- g_return_val_if_fail (local != NULL, -1);
- g_return_val_if_fail (remote != NULL, -1);
-
- *local = NULL;
- uid = e_pilot_map_lookup_uid (ctxt->map, remote->ID, TRUE);
-
- if (!uid)
- return 0;
-
- LOG (" matched\n");
-
- *local = g_new0 (EAddrLocalRecord, 1);
- local_record_from_uid (*local, uid, ctxt);
-
- return 0;
-}
-
-static gint
-free_match (GnomePilotConduitSyncAbs *conduit,
- EAddrLocalRecord *local,
- EAddrConduitContext *ctxt)
-{
- LOG ("free_match: freeing\n");
-
- g_return_val_if_fail (local != NULL, -1);
-
- addrconduit_destroy_record (local);
-
- return 0;
-}
-
-static gint
-prepare (GnomePilotConduitSyncAbs *conduit,
- EAddrLocalRecord *local,
- GnomePilotRecord *remote,
- EAddrConduitContext *ctxt)
-{
- LOG ("prepare: encoding local %s\n", print_local (local));
-
- *remote = local_record_to_pilot_record (local, ctxt);
-
- return 0;
-}
-
-/* Pilot Settings Callbacks */
-static void
-fill_widgets (EAddrConduitContext *ctxt)
-{
- e_pilot_settings_set_secret (E_PILOT_SETTINGS (ctxt->ps),
- ctxt->cfg->secret);
-
- e_addr_gui_fill_widgets (ctxt->gui, ctxt->cfg);
-}
-
-static gint
-create_settings_window (GnomePilotConduit *conduit,
- GtkWidget *parent,
- EAddrConduitContext *ctxt)
-{
- LOG ("create_settings_window");
-
- ctxt->ps = e_pilot_settings_new ();
- ctxt->gui = e_addr_gui_new (E_PILOT_SETTINGS (ctxt->ps));
-
- gtk_container_add (GTK_CONTAINER (parent), ctxt->ps);
- gtk_widget_show (ctxt->ps);
-
- fill_widgets (ctxt);
-
- return 0;
-}
-static void
-display_settings (GnomePilotConduit *conduit, EAddrConduitContext *ctxt)
-{
- LOG ("display_settings");
-
- fill_widgets (ctxt);
-}
-
-static void
-save_settings (GnomePilotConduit *conduit, EAddrConduitContext *ctxt)
-{
- LOG ("save_settings");
-
- ctxt->new_cfg->secret =
- e_pilot_settings_get_secret (E_PILOT_SETTINGS (ctxt->ps));
- e_addr_gui_fill_config (ctxt->gui, ctxt->new_cfg);
-
- addrconduit_save_configuration (ctxt->new_cfg);
-}
-
-static void
-revert_settings (GnomePilotConduit *conduit, EAddrConduitContext *ctxt)
-{
- LOG ("revert_settings");
-
- addrconduit_save_configuration (ctxt->cfg);
- addrconduit_destroy_configuration (ctxt->new_cfg);
- ctxt->new_cfg = addrconduit_dupe_configuration (ctxt->cfg);
-}
-
-static ORBit_MessageValidationResult
-accept_all_cookies (CORBA_unsigned_long request_id,
- CORBA_Principal *principal,
- CORBA_char *operation)
-{
- /* allow ALL cookies */
- return ORBIT_MESSAGE_ALLOW_ALL;
-}
-
-
-GnomePilotConduit *
-conduit_get_gpilot_conduit (guint32 pilot_id)
-{
- GtkObject *retval;
- EAddrConduitContext *ctxt;
-
- LOG ("in address's conduit_get_gpilot_conduit\n");
-
- /* we need to find wombat with oaf, so make sure oaf
- is initialized here. once the desktop is converted
- to oaf and gpilotd is built with oaf, this can go away */
- if (!oaf_is_initialized ()) {
- char *argv[ 1 ] = {"hi"};
- oaf_init (1, argv);
-
- if (bonobo_init (CORBA_OBJECT_NIL,
- CORBA_OBJECT_NIL,
- CORBA_OBJECT_NIL) == FALSE)
- g_error (_("Could not initialize Bonobo"));
-
- ORBit_set_request_validation_handler (accept_all_cookies);
- }
-
- retval = gnome_pilot_conduit_sync_abs_new ("AddressDB", 0x61646472);
- g_assert (retval != NULL);
-
- ctxt = e_addr_context_new (pilot_id);
- gtk_object_set_data (GTK_OBJECT (retval), "addrconduit_context", ctxt);
-
- gtk_signal_connect (retval, "pre_sync", (GtkSignalFunc) pre_sync, ctxt);
- gtk_signal_connect (retval, "post_sync", (GtkSignalFunc) post_sync, ctxt);
-
- gtk_signal_connect (retval, "set_pilot_id", (GtkSignalFunc) set_pilot_id, ctxt);
- gtk_signal_connect (retval, "set_status_cleared", (GtkSignalFunc) set_status_cleared, ctxt);
-
- gtk_signal_connect (retval, "for_each", (GtkSignalFunc) for_each, ctxt);
- gtk_signal_connect (retval, "for_each_modified", (GtkSignalFunc) for_each_modified, ctxt);
- gtk_signal_connect (retval, "compare", (GtkSignalFunc) compare, ctxt);
-
- gtk_signal_connect (retval, "add_record", (GtkSignalFunc) add_record, ctxt);
- gtk_signal_connect (retval, "replace_record", (GtkSignalFunc) replace_record, ctxt);
- gtk_signal_connect (retval, "delete_record", (GtkSignalFunc) delete_record, ctxt);
- gtk_signal_connect (retval, "archive_record", (GtkSignalFunc) archive_record, ctxt);
-
- gtk_signal_connect (retval, "match", (GtkSignalFunc) match, ctxt);
- gtk_signal_connect (retval, "free_match", (GtkSignalFunc) free_match, ctxt);
-
- gtk_signal_connect (retval, "prepare", (GtkSignalFunc) prepare, ctxt);
-
- /* Gui Settings */
- gtk_signal_connect (retval, "create_settings_window", (GtkSignalFunc) create_settings_window, ctxt);
- gtk_signal_connect (retval, "display_settings", (GtkSignalFunc) display_settings, ctxt);
- gtk_signal_connect (retval, "save_settings", (GtkSignalFunc) save_settings, ctxt);
- gtk_signal_connect (retval, "revert_settings", (GtkSignalFunc) revert_settings, ctxt);
-
- return GNOME_PILOT_CONDUIT (retval);
-}
-
-void
-conduit_destroy_gpilot_conduit (GnomePilotConduit *conduit)
-{
- EAddrConduitContext *ctxt;
-
- ctxt = gtk_object_get_data (GTK_OBJECT (conduit),
- "addrconduit_context");
-
- e_addr_context_destroy (ctxt);
-
- gtk_object_destroy (GTK_OBJECT (conduit));
-}
diff --git a/addressbook/conduit/e-address.conduit.in b/addressbook/conduit/e-address.conduit.in
deleted file mode 100644
index e5a5ab765e..0000000000
--- a/addressbook/conduit/e-address.conduit.in
+++ /dev/null
@@ -1,9 +0,0 @@
-<gnome-pilot-conduit version="1.0">
- <conduit id="e_address_conduit" type="shlib" location="@prefix@/lib/gnome-pilot/conduits/libeaddress_conduit.so"/>
- <name value="EAddress"/>
- <conduit-attribute name="description" value="Synchronizes Addressbook with Evolution"/>
- <conduit-attribute name="default-synctype" value="synchronize"/>
- <conduit-attribute name="valid-synctypes" value="synchronize copy_from_pilot copy_to_pilot"/>
- <conduit-attribute name="settings" value="TRUE"/>
- <conduit-attribute name="icon" value="@datadir@/images/evolution/conduits/48_evo-address-conduit.png"/>
-</gnome-pilot-conduit>
diff --git a/addressbook/gui/.cvsignore b/addressbook/gui/.cvsignore
deleted file mode 100644
index 09980ae6ba..0000000000
--- a/addressbook/gui/.cvsignore
+++ /dev/null
@@ -1,6 +0,0 @@
-.deps
-.libs
-Makefile
-Makefile.in
-*.lo
-*.la
diff --git a/addressbook/gui/Makefile.am b/addressbook/gui/Makefile.am
index 6b0850da5d..7f08bf425d 100644
--- a/addressbook/gui/Makefile.am
+++ b/addressbook/gui/Makefile.am
@@ -1 +1,3 @@
-SUBDIRS = contact-editor contact-list-editor merging widgets search component
+SUBDIRS = merging widgets contact-editor contact-list-editor
+
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/gui/component/.cvsignore b/addressbook/gui/component/.cvsignore
deleted file mode 100644
index 8bcb766191..0000000000
--- a/addressbook/gui/component/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-.deps
-.libs
-.pure
-Makefile
-Makefile.in
-*.lo
-*.la
-evolution-addressbook
-evolution-addressbook.pure
-test-addressbook
-GNOME_Evolution_Addressbook.oaf \ No newline at end of file
diff --git a/addressbook/gui/component/GNOME_Evolution_Addressbook.oaf.in b/addressbook/gui/component/GNOME_Evolution_Addressbook.oaf.in
deleted file mode 100644
index 294db83fe9..0000000000
--- a/addressbook/gui/component/GNOME_Evolution_Addressbook.oaf.in
+++ /dev/null
@@ -1,177 +0,0 @@
-<oaf_info>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_MiniCard_ControlFactory"
- type="exe"
- location="evolution-addressbook">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory for the Addressbook Minicard control"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_MiniCard_Control"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_MiniCard_ControlFactory">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:Bonobo/Control:1.0"/>
- <item value="IDL:Bonobo/PersistStream:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="bonobo:supported_mime_types" type="stringv">
- <item value="text/vcard"/>
- <item value="text/x-vcard"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string"
- _value="Evolution Addressbook minicard viewer"/>
- <oaf_attribute name="description" type="string"
- _value="Control that displays an Evolution addressbook minicard."/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_ControlFactory"
- type="exe"
- location="evolution-addressbook">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory for the sample Addressbook control"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_Control"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_ControlFactory">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:BonoboControl/addressbook-control:1.0"/>
- <item value="IDL:GNOME/Control:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="A sample Bonobo control which displays an addressbook."/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_ShellComponent"
- type="exe"
- location="evolution-addressbook">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/ShellComponent:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Evolution component for handling contacts."/>
-
- <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_AddressWidgetFactory"
- type="exe"
- location="evolution-addressbook">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory for the Addressbook's address displayer"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_AddressWidget"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_AddressWidgetFactory">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:BonoboControl/address-widget:1.0"/>
- <item value="IDL:GNOME/Control:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="A Bonobo control for displaying an address."/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_AddressPopupFactory"
- type="exe"
- location="evolution-addressbook">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory for the Addressbook's address popup"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_AddressPopup"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_AddressPopupFactory">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:BonoboControl/address-widget:1.0"/>
- <item value="IDL:GNOME/Control:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="A Bonobo control for an address popup."/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_ConfigControlFactory"
- type="exe"
- location="evolution-addressbook">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/GenericFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory for the configuration controls for the Evolution Addressbook."/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_LDAPStorage_ConfigControl"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_ConfigControlFactory">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/ConfigControl:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="evolution:config_item:title" type="string"
- _value="Directory Servers"/>
-
- <oaf_attribute name="evolution:config_item:description" type="string"
- _value="Configure access to LDAP directory servers here"/>
-
- <oaf_attribute name="evolution:config_item:icon_name" type="string"
- value="ldap-settings.png"/>
-
- <oaf_attribute name="evolution:config_item:type" type="stringv">
- <item value="contacts/ldap"/>
- </oaf_attribute>
-
- <oaf_attribute name="evolution:config_item:priority" type="string" value="-6"/>
-
- <oaf_attribute name="description" type="string"
- _value="Configuration control for the Evolution Addressbook Storages."/>
-
-</oaf_server>
-
-</oaf_info>
diff --git a/addressbook/gui/component/Makefile.am b/addressbook/gui/component/Makefile.am
deleted file mode 100644
index 842d0489b5..0000000000
--- a/addressbook/gui/component/Makefile.am
+++ /dev/null
@@ -1,96 +0,0 @@
-SUBDIRS = select-names
-
-INCLUDES = \
- -DG_LOG_DOMAIN=\"evolution-addressbook\" \
- -I$(top_srcdir) \
- -I$(top_builddir) \
- -I$(top_srcdir)/shell \
- -I$(top_builddir)/shell \
- -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 \
- -DEVOLUTION_DATADIR=\""$(datadir)"\" \
- -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
- -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
- -DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \
- -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
- -DCAMEL_PROVIDERDIR=\""$(providerdir)"\" \
- -DEVOLUTION_IMAGESDIR=\""$(datadir)"/images/evolution\" \
- $(LDAP_CFLAGS) \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
-
-bin_PROGRAMS = \
- evolution-addressbook
-
-evolution_addressbook_SOURCES = \
- addressbook-component.c \
- addressbook-component.h \
- addressbook-config.c \
- addressbook-config.h \
- addressbook-factory.c \
- addressbook-storage.c \
- addressbook-storage.h \
- addressbook.c \
- addressbook.h \
- e-cardlist-model.c \
- e-cardlist-model.h \
- e-address-widget.h \
- e-address-widget.c \
- e-address-popup.h \
- e-address-popup.c
-
-evolution_addressbook_LDADD = \
- select-names/libeselectnames.la \
- $(top_builddir)/shell/libeshell.la \
- $(top_builddir)/addressbook/gui/widgets/libeminicard.a \
- $(top_builddir)/addressbook/backend/ebook/libebook.la \
- $(top_builddir)/camel/libcamel.la \
- $(top_builddir)/e-util/ename/libename.la \
- $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.a \
- $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.a \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/widgets/misc/libemiscwidgets.a \
- $(top_builddir)/addressbook/printing/libecontactprint.a \
- $(top_builddir)/addressbook/gui/search/libeaddressbooksearch.a \
- $(top_builddir)/addressbook/gui/merging/libecardmerging.a \
- $(top_builddir)/filter/libfilter.la \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/widgets/menus/libmenus.la \
- $(EVOLUTION_ADDRESSBOOK_LIBS) $(LDAP_LIBS)
-
-evolution_addressbook_LDFLAGS = `gnome-config --libs gdk_pixbuf` -export-dynamic
-
-@XML_I18N_MERGE_OAF_RULE@
-
-oafdir = $(datadir)/oaf
-oaf_in_files = GNOME_Evolution_Addressbook.oaf.in
-oaf_DATA = $(oaf_in_files:.oaf.in=.oaf)
-
-gladedir = $(datadir)/evolution/glade
-glade_DATA = ldap-config.glade
-
-iconsdir = $(datadir)/images/evolution
-
-etspecdir = $(datadir)/evolution/etspec
-etspec_DATA = addressbook-config.etspec
-
-EXTRA_DIST = \
- $(glade_DATA) \
- $(oaf_DATA) \
- $(oaf_in_files) \
- $(etspec_DATA)
-
-if ENABLE_PURIFY
-PLINK = $(LIBTOOL) --mode=link $(PURIFY) $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
-
-all-local: evolution-addressbook.pure
-
-evolution-addressbook.pure: evolution-addressbook
- @rm -f evolution-addressbook.pure
- $(PLINK) $(evolution_addressbook_LDFLAGS) $(evolution_addressbook_OBJECTS) $(evolution_addressbook_LDADD) $(LIBS)
-
-endif
diff --git a/addressbook/gui/component/addressbook-component.c b/addressbook/gui/component/addressbook-component.c
deleted file mode 100644
index 791e49ac48..0000000000
--- a/addressbook/gui/component/addressbook-component.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* addressbook-component.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.
- *
- * Author: Ettore Perazzoli
- */
-
-#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 <bonobo/bonobo-generic-factory.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;
-
-EvolutionShellClient *
-addressbook_component_get_shell_client (void)
-{
- return global_shell_client;
-}
-
-static char *accepted_dnd_types[] = {
- "text/x-vcard",
- NULL
-};
-
-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 }
-};
-
-#define IS_CONTACT_TYPE(x) (g_strcasecmp((x), "contacts") == 0 || g_strcasecmp ((x), "contacts/ldap") == 0 || g_strcasecmp((x), "contacts/public"))
-
-/* 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;
-
- if (!IS_CONTACT_TYPE (type))
- return EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE;
-
- control = addressbook_factory_new_control ();
- bonobo_control_set_property (control, "folder_uri", physical_uri, NULL);
-
- *control_return = control;
-
- return EVOLUTION_SHELL_COMPONENT_OK;
-}
-
-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;
-
- 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);
-}
-
-static void
-remove_folder (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- const GNOME_Evolution_ShellComponentListener listener,
- void *closure)
-{
- CORBA_Environment ev;
- char *addressbook_db_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_concat_dir_and_file (physical_uri + 7, "subfolders");
- 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;
- }
-
- addressbook_db_path = g_concat_dir_and_file (physical_uri + 7, "addressbook.db");
- rv = unlink (addressbook_db_path);
- g_free (addressbook_db_path);
- if (rv == 0) {
- GNOME_Evolution_ShellComponentListener_notifyResult (listener,
- GNOME_Evolution_ShellComponentListener_OK,
- &ev);
- }
- else {
- if (errno == EACCES || errno == EPERM)
- GNOME_Evolution_ShellComponentListener_notifyResult (listener,
- GNOME_Evolution_ShellComponentListener_PERMISSION_DENIED,
- &ev);
- else
- GNOME_Evolution_ShellComponentListener_notifyResult (listener,
- GNOME_Evolution_ShellComponentListener_INVALID_URI, /*XXX*/
- &ev);
- }
- CORBA_exception_free(&ev);
-}
-
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-
-/* This code is cut & pasted from calendar/gui/component-factory.c */
-
-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;
- }
-
- /* 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;
- }
-
- 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 (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);
- }
-
- 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;
-}
-
-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)
-{
- CORBA_Environment ev;
-
- GnomeVFSURI *src_uri;
- GnomeVFSURI *dest_uri;
- GnomeVFSResult 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;
- }
-
- /* 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;
- }
-
- result = xfer_file (src_uri, dest_uri, "addressbook.db", remove_source);
-
- GNOME_Evolution_ShellComponentListener_notifyResult (listener, 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;
-}
-
-static int owner_count = 0;
-
-static void
-owner_set_cb (EvolutionShellComponent *shell_component,
- EvolutionShellClient *shell_client,
- const char *evolution_homedir,
- gpointer user_data)
-{
- owner_count ++;
-
- if (global_shell_client == NULL)
- global_shell_client = shell_client;
-
- addressbook_config_register_factory (bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)));
-
- addressbook_storage_setup (shell_component, evolution_homedir);
-}
-
-static gboolean
-gtk_main_quit_cb (gpointer closure)
-{
- gtk_main_quit ();
- return TRUE;
-}
-
-static void
-owner_unset_cb (EvolutionShellComponent *shell_component,
- GNOME_Evolution_Shell shell_interface,
- gpointer user_data)
-{
- owner_count --;
- if (owner_count == 0) {
- g_idle_add (gtk_main_quit_cb, NULL);
- }
-}
-
-/* FIXME We should perhaps take the time to figure out if the book is editable. */
-static void
-new_item_cb (EBook *book, gpointer closure)
-{
- gboolean is_list = GPOINTER_TO_INT (closure);
- if (book == NULL)
- return;
- if (is_list)
- e_addressbook_show_contact_list_editor (book, e_card_new(""), TRUE, TRUE);
- else
- e_addressbook_show_contact_editor (book, e_card_new(""), TRUE, TRUE);
-}
-
-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));
- }
-}
-
-
-/* Destination side DnD */
-
-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;
-}
-
-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)
-{
- 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);
-
- book = e_book_new ();
- addressbook_load_uri (book, expanded_uri,
- (EBookCallback)dnd_drop_book_open_cb, card_list);
-
- g_free (expanded_uri);
-
- return TRUE;
-}
-
-
-/* Quitting. */
-
-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;
-}
-
-
-/* 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_concat_dir_and_file (EVOLUTION_ICONSDIR, icon_name);
- icon = gdk_pixbuf_new_from_file (icon_path);
- }
-
- 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);
-}
-
-static BonoboObject *
-create_component (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");
-
- gtk_signal_connect (GTK_OBJECT (shell_component), "owner_set",
- GTK_SIGNAL_FUNC (owner_set_cb), NULL);
- gtk_signal_connect (GTK_OBJECT (shell_component), "owner_unset",
- GTK_SIGNAL_FUNC (owner_unset_cb), NULL);
- gtk_signal_connect (GTK_OBJECT (shell_component), "user_create_new_item",
- GTK_SIGNAL_FUNC (user_create_new_item_cb), NULL);
-
- return BONOBO_OBJECT (shell_component);
-}
-
-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. */
- Bonobo_ConfigDatabase db;
- CORBA_Environment ev;
- char *val;
-
- CORBA_exception_init (&ev);
-
- db = addressbook_config_database (&ev);
-
- val = bonobo_config_get_string (db, "/Addressbook/Completion/uris", &ev);
-
- 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 = gnome_util_prepend_user_home("evolution/local/Contacts");
- 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);
- bonobo_config_set_string (db, "/Addressbook/Completion/uris", val, &ev);
-
- g_free (val);
- }
-
- CORBA_exception_free (&ev);
-}
-
-
-/* FIXME this should probably be renamed as we don't use factories anymore. */
-void
-addressbook_component_factory_init (void)
-{
- BonoboObject *object;
- int result;
-
- object = create_component ();
-
- /* FIXME: Handle errors better? */
-
- result = oaf_active_server_register (GNOME_EVOLUTION_ADDRESSBOOK_COMPONENT_ID,
- bonobo_object_corba_objref (object));
- if (result == OAF_REG_ERROR)
- g_error ("Cannot register -- %s", GNOME_EVOLUTION_ADDRESSBOOK_COMPONENT_ID);
-
- /* XXX this could probably go someplace else, but I'll leave
- it here for now since it's a component init time
- operation. */
- ensure_completion_uris_exist ();
-}
diff --git a/addressbook/gui/component/addressbook-component.h b/addressbook/gui/component/addressbook-component.h
deleted file mode 100644
index 9b36873902..0000000000
--- a/addressbook/gui/component/addressbook-component.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* addressbook-component.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.
- *
- * Author: Ettore Perazzoli
- */
-
-#ifndef _ADDRESSBOOK_COMPONENT_H
-#define _ADDRESSBOOK_COMPONENT_H
-
-#include "evolution-shell-component.h"
-#include "evolution-storage.h"
-
-void addressbook_component_factory_init (void);
-EvolutionShellClient *addressbook_component_get_shell_client (void);
-
-#endif /* _ADDRESSBOOK_COMPONENT_H */
diff --git a/addressbook/gui/component/addressbook-config.c b/addressbook/gui/component/addressbook-config.c
deleted file mode 100644
index fdaee205dc..0000000000
--- a/addressbook/gui/component/addressbook-config.c
+++ /dev/null
@@ -1,1752 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors:
- * Chris Toshok <toshok@ximian.com>
- * Chris Lahey <clahey@ximian.com>
- **/
-
-/*#define STANDALONE*/
-/*#define NEW_ADVANCED_UI*/
-
-#include <config.h>
-
-#include "addressbook-config.h"
-
-#include "addressbook.h"
-#include "addressbook-storage.h"
-
-#include "evolution-config-control.h"
-#include <shell/e-folder-list.h>
-
-#include <gal/widgets/e-unicode.h>
-#include <gal/e-table/e-table-memory-store.h>
-#include <gal/e-table/e-table-scrolled.h>
-#include <e-util/e-html-utils.h>
-
-#include <gtkhtml/gtkhtml.h>
-
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <libgnomeui/gnome-stock.h>
-
-#include <bonobo/bonobo-generic-factory.h>
-
-#include <glade/glade.h>
-
-#include <stdlib.h>
-#include <sys/time.h>
-
-#ifdef HAVE_LDAP
-#include "ldap.h"
-#include "ldap_schema.h"
-#endif
-
-#define LDAP_PORT_STRING "389"
-#define LDAPS_PORT_STRING "636"
-
-#define GLADE_FILE_NAME "ldap-config.glade"
-#define CONFIG_CONTROL_FACTORY_ID "OAFIID:GNOME_Evolution_Addressbook_ConfigControlFactory"
-#define LDAP_CONFIG_CONTROL_ID "OAFIID:GNOME_Evolution_LDAPStorage_ConfigControl"
-
-#ifdef HAVE_LDAP
-GtkWidget* addressbook_dialog_create_sources_table (char *name, char *string1, char *string2,
- int num1, int num2);
-GtkWidget* supported_bases_create_table (char *name, char *string1, char *string2,
- int num1, int num2);
-
-#ifdef NEW_ADVANCED_UI
-GtkWidget* objectclasses_create_server_table (char *name, char *string1, char *string2,
- int num1, int num2);
-GtkWidget* objectclasses_create_evolution_table (char *name, char *string1, char *string2,
- int num1, int num2);
-#endif
-
-/* default objectclasses */
-#define TOP "top"
-#define PERSON "person"
-#define ORGANIZATIONALPERSON "organizationalPerson"
-#define INETORGPERSON "inetOrgPerson"
-#define EVOLUTIONPERSON "evolutionPerson"
-#define CALENTRY "calEntry"
-
-
-typedef struct {
- GtkWidget *notebook;
- int page_num;
-} FocusHelpClosure;
-
-static void
-focus_help (GtkWidget *w, GdkEventFocus *event, FocusHelpClosure *closure)
-{
- gtk_notebook_set_page (GTK_NOTEBOOK(closure->notebook), closure->page_num);
-}
-
-static void
-add_focus_handler (GtkWidget *widget, GtkWidget *notebook, int page_num)
-{
- FocusHelpClosure *focus_closure = g_new0 (FocusHelpClosure, 1);
- focus_closure->notebook = notebook;
- focus_closure->page_num = page_num;
-
- gtk_signal_connect_full (GTK_OBJECT (widget),
- "focus_in_event" /* XXX */,
- (GtkSignalFunc) focus_help, NULL,
- focus_closure,
- (GtkDestroyNotify) g_free,
- FALSE, FALSE);
-}
-
-
-typedef struct {
- EvolutionConfigControl *config_control;
- GtkWidget *page;
-
- GladeXML *gui;
- GNOME_Evolution_Shell shell;
-
- GtkWidget *sourcesTable;
- ETableModel *sourcesModel;
- GtkWidget *addSource;
- GtkWidget *editSource;
- GtkWidget *deleteSource;
-
-} AddressbookDialog;
-
-typedef struct {
- AddressbookDialog *addressbook_dialog;
- GladeXML *gui;
-
- GtkWidget *window;
- GtkWidget *druid; /* only used (obviously) in the druid */
-
- /* info page fields */
- GtkSignalFunc general_modify_func;
- GtkWidget *host;
- GtkWidget *auth_optionmenu;
- AddressbookLDAPAuthType auth;
- GtkWidget *auth_label_notebook;
- GtkWidget *auth_entry_notebook;
- GtkWidget *email;
- GtkWidget *binddn;
-
- /* connecting page fields */
- GtkSignalFunc connecting_modify_func;
- GtkWidget *port_combo;
- GtkWidget *ssl_optionmenu;
- AddressbookLDAPSSLType ssl;
-
- /* searching page fields */
- GtkSignalFunc searching_modify_func;
- GtkWidget *rootdn;
- AddressbookLDAPScopeType scope;
- GtkWidget *scope_optionmenu;
- GtkWidget *timeout_scale;
- GtkWidget *limit_spinbutton;
-
- /* display name page fields */
- GtkWidget *display_name;
- gboolean display_name_changed; /* only used in the druid */
-
- gboolean schema_query_successful;
-
-#ifdef NEW_ADVANCED_UI
- /* objectclasses tab fields */
- GPtrArray *server_objectclasses; /* the objectclasses available on the server */
- GPtrArray *evolution_objectclasses; /* the objectclasses evolution will use */
- GPtrArray *default_objectclasses; /* the objectclasses we default to (actually the
- intersection between defaults and server_objectclasses) */
- GtkSignalFunc objectclasses_modify_func;
- GtkWidget *objectclasses_server_table;
- ETableModel *objectclasses_server_model;
- GtkWidget *objectclasses_evolution_table;
- ETableModel *objectclasses_evolution_model;
- GtkWidget *objectclasses_add_button;
- GtkWidget *objectclasses_remove_button;
-
- /* refs we keep around so we can add/hide the tabs */
- GtkWidget *objectclasses_tab;
- GtkWidget *objectclasses_label;
- GtkWidget *mappings_tab;
- GtkWidget *mappings_label;
- GtkWidget *dn_customization_tab;
- GtkWidget *dn_customization_label;
-#endif
-
- /* stuff for the account editor window */
- int source_model_row;
- GtkWidget *ok_button;
- GtkWidget *apply_button;
- GtkWidget *close_button;
- GtkWidget *advanced_button_notebook;
- GtkWidget *notebook; /* the toplevel notebook */
-
- gboolean advanced;
-
-} AddressbookSourceDialog;
-
-
-/* ldap api foo */
-static LDAP *
-addressbook_ldap_init (GtkWidget *window, AddressbookSource *source)
-{
- LDAP *ldap = ldap_init (source->host, atoi(source->port));
-
- if (!ldap) {
- GtkWidget *dialog;
- dialog = gnome_error_dialog_parented (_("Failed to connect to LDAP server"), GTK_WINDOW(window));
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- return NULL;
- }
-
- /* XXX do TLS if it's configured in */
-
- return ldap;
-}
-
-static int
-addressbook_ldap_auth (GtkWidget *window, AddressbookSource *source, LDAP *ldap)
-{
- int ldap_error;
-
- /* XXX use auth info from source */
- ldap_error = ldap_simple_bind_s (ldap, NULL, NULL);
- if (LDAP_SUCCESS != ldap_error) {
- GtkWidget *dialog;
- dialog = gnome_error_dialog_parented (_("Failed to authenticate with LDAP server"), GTK_WINDOW (window));
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- }
- return ldap_error;
-
-}
-
-static int
-addressbook_root_dse_query (GtkWindow *window, AddressbookSource *source, LDAP *ldap, char **attrs, LDAPMessage **resp)
-{
- int ldap_error;
- struct timeval timeout;
-
- /* 3 second timeout */
- timeout.tv_sec = 3;
- timeout.tv_usec = 0;
-
- ldap_error = ldap_search_ext_s (ldap,
- LDAP_ROOT_DSE, LDAP_SCOPE_BASE,
- "(objectclass=*)",
- attrs, 0, NULL, NULL, &timeout, LDAP_NO_LIMIT, resp);
- if (LDAP_SUCCESS != ldap_error) {
- GtkWidget *dialog;
- dialog = gnome_error_dialog_parented (_("Could not perform query on Root DSE"), window);
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- }
-
- return ldap_error;
-}
-
-
-static AddressbookSource *
-addressbook_dialog_get_source (AddressbookSourceDialog *dialog)
-{
- AddressbookSource *source = g_new0 (AddressbookSource, 1);
-
- source->name = e_utf8_gtk_entry_get_text (GTK_ENTRY (dialog->display_name));
- source->host = e_utf8_gtk_entry_get_text (GTK_ENTRY (dialog->host));
- source->email_addr = e_utf8_gtk_entry_get_text (GTK_ENTRY (dialog->email));
- source->binddn = e_utf8_gtk_entry_get_text (GTK_ENTRY (dialog->binddn));
- source->port = e_utf8_gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(dialog->port_combo)->entry));
- source->rootdn = e_utf8_gtk_entry_get_text (GTK_ENTRY (dialog->rootdn));
- source->limit = atoi(e_utf8_gtk_entry_get_text (GTK_ENTRY (dialog->limit_spinbutton)));
- source->scope = dialog->scope;
- source->auth = dialog->auth;
- source->ssl = dialog->ssl;
-
- addressbook_storage_init_source_uri (source);
-
- return source;
-}
-
-static void
-addressbook_source_dialog_set_source (AddressbookSourceDialog *dialog, AddressbookSource *source)
-{
- char *string;
- e_utf8_gtk_entry_set_text (GTK_ENTRY (dialog->display_name), source ? source->name : "");
- e_utf8_gtk_entry_set_text (GTK_ENTRY (dialog->host), source ? source->host : "");
- e_utf8_gtk_entry_set_text (GTK_ENTRY (dialog->email), source ? source->email_addr : "");
- e_utf8_gtk_entry_set_text (GTK_ENTRY (dialog->binddn), source ? source->binddn : "");
- e_utf8_gtk_entry_set_text (GTK_ENTRY (GTK_COMBO(dialog->port_combo)->entry), source ? source->port : LDAP_PORT_STRING);
- e_utf8_gtk_entry_set_text (GTK_ENTRY (dialog->rootdn), source ? source->rootdn : "");
-
- string = g_strdup_printf ("%d", source ? source->limit : 100);
- e_utf8_gtk_entry_set_text (GTK_ENTRY (dialog->limit_spinbutton), string);
- g_free (string);
-
- dialog->auth = source ? source->auth : ADDRESSBOOK_LDAP_AUTH_NONE;
- gtk_option_menu_set_history (GTK_OPTION_MENU(dialog->auth_optionmenu), dialog->auth);
- if (dialog->auth != ADDRESSBOOK_LDAP_AUTH_NONE) {
- gtk_notebook_set_page (GTK_NOTEBOOK(dialog->auth_label_notebook), dialog->auth - 1);
- gtk_notebook_set_page (GTK_NOTEBOOK(dialog->auth_entry_notebook), dialog->auth - 1);
- }
- gtk_widget_set_sensitive (dialog->auth_label_notebook, dialog->auth != ADDRESSBOOK_LDAP_AUTH_NONE);
- gtk_widget_set_sensitive (dialog->auth_entry_notebook, dialog->auth != ADDRESSBOOK_LDAP_AUTH_NONE);
-
- dialog->scope = source ? source->scope : ADDRESSBOOK_LDAP_SCOPE_ONELEVEL;
- gtk_option_menu_set_history (GTK_OPTION_MENU(dialog->scope_optionmenu), dialog->scope);
-
- dialog->ssl = source ? source->ssl : ADDRESSBOOK_LDAP_SSL_WHENEVER_POSSIBLE;
- gtk_option_menu_set_history (GTK_OPTION_MENU(dialog->ssl_optionmenu), dialog->ssl);
-}
-
-static void
-addressbook_source_dialog_destroy (GtkWidget *widget, AddressbookSourceDialog *dialog)
-{
-#ifdef NEW_ADVANCED_UI
-#define IF_UNREF(x) if (x) gtk_object_unref (GTK_OBJECT ((x)))
-
- int i;
-
- if (dialog->server_objectclasses) {
- for (i = 0; i < dialog->server_objectclasses->len; i ++)
- ldap_objectclass_free (g_ptr_array_index (dialog->server_objectclasses, i));
- g_ptr_array_free (dialog->server_objectclasses, TRUE);
- }
-
- if (dialog->evolution_objectclasses) {
- for (i = 0; i < dialog->evolution_objectclasses->len; i ++)
- ldap_objectclass_free (g_ptr_array_index (dialog->evolution_objectclasses, i));
- g_ptr_array_free (dialog->evolution_objectclasses, TRUE);
- }
-
- if (dialog->default_objectclasses) {
- for (i = 0; i < dialog->default_objectclasses->len; i ++)
- ldap_objectclass_free (g_ptr_array_index (dialog->default_objectclasses, i));
- g_ptr_array_free (dialog->default_objectclasses, TRUE);
- }
-
- IF_UNREF (dialog->objectclasses_server_model);
- IF_UNREF (dialog->objectclasses_evolution_model);
-
- IF_UNREF (dialog->objectclasses_tab);
- IF_UNREF (dialog->objectclasses_label);
- IF_UNREF (dialog->mappings_tab);
- IF_UNREF (dialog->mappings_label);
- IF_UNREF (dialog->dn_customization_tab);
- IF_UNREF (dialog->dn_customization_label);
-
-#undef IF_UNREF
-#endif
-
- gtk_object_destroy (GTK_OBJECT (dialog->gui));
-
- g_free (dialog);
-}
-
-static void
-addressbook_add_server_druid_cancel (GtkWidget *widget, AddressbookSourceDialog *dialog)
-{
- gtk_widget_destroy (dialog->window);
-}
-
-static void
-addressbook_add_server_druid_finish (GnomeDruidPage *druid_page, GtkWidget *gnome_druid, AddressbookSourceDialog *sdialog)
-{
- AddressbookSource *source = addressbook_dialog_get_source (sdialog);
- AddressbookDialog *dialog = sdialog->addressbook_dialog;
-
- printf ("in finish (%s,%s)\n", source->name, source->host);
-
- e_table_memory_store_insert (E_TABLE_MEMORY_STORE (dialog->sourcesModel),
- -1, source, source->name, source->host);
-
- evolution_config_control_changed (dialog->config_control);
-
- /* tear down the widgets */
- gtk_widget_destroy (sdialog->window);
-}
-
-static void
-reparent_to_vbox (AddressbookSourceDialog *dialog, char *vbox_name, char *widget_name)
-{
- GtkWidget *vbox, *widget;
-
- vbox = glade_xml_get_widget (dialog->gui, vbox_name);
- widget = glade_xml_get_widget (dialog->gui, widget_name);
-
- gtk_widget_reparent (widget, vbox);
- gtk_box_set_child_packing (GTK_BOX (vbox), widget, TRUE, TRUE, 0, GTK_PACK_START);
-}
-
-static void
-auth_optionmenu_activated (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- dialog->auth = g_list_index (gtk_container_children (GTK_CONTAINER (item->parent)),
- item);
-
- dialog->general_modify_func (item, dialog);
-
- if (dialog->auth == 0) {
- gtk_widget_set_sensitive (dialog->auth_label_notebook, FALSE);
- gtk_widget_set_sensitive (dialog->auth_entry_notebook, FALSE);
- }
- else {
- gtk_widget_set_sensitive (dialog->auth_label_notebook, TRUE);
- gtk_widget_set_sensitive (dialog->auth_entry_notebook, TRUE);
- gtk_notebook_set_page (GTK_NOTEBOOK(dialog->auth_label_notebook), dialog->auth - 1);
- gtk_notebook_set_page (GTK_NOTEBOOK(dialog->auth_entry_notebook), dialog->auth - 1);
- }
-}
-
-static void
-add_auth_activate_cb (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- gtk_signal_connect (GTK_OBJECT (item), "activate",
- GTK_SIGNAL_FUNC (auth_optionmenu_activated), dialog);
-}
-
-static void
-setup_general_tab (AddressbookSourceDialog *dialog, GtkSignalFunc modify_func)
-{
- GtkWidget *general_tab_help;
- GtkWidget *menu;
-
- general_tab_help = glade_xml_get_widget (dialog->gui, "general-tab-help");
-
- dialog->general_modify_func = modify_func;
- dialog->host = glade_xml_get_widget (dialog->gui, "server-name-entry");
- gtk_signal_connect (GTK_OBJECT (dialog->host), "changed",
- modify_func, dialog);
- add_focus_handler (dialog->host, general_tab_help, 0);
-
- dialog->auth_label_notebook = glade_xml_get_widget (dialog->gui, "auth-label-notebook");
- dialog->auth_entry_notebook = glade_xml_get_widget (dialog->gui, "auth-entry-notebook");
- dialog->email = glade_xml_get_widget (dialog->gui, "email-entry");
- gtk_signal_connect (GTK_OBJECT (dialog->email), "changed",
- modify_func, dialog);
- add_focus_handler (dialog->email, general_tab_help, 1);
- dialog->binddn = glade_xml_get_widget (dialog->gui, "dn-entry");
- gtk_signal_connect (GTK_OBJECT (dialog->binddn), "changed",
- modify_func, dialog);
- add_focus_handler (dialog->binddn, general_tab_help, 2);
-
- dialog->auth_optionmenu = glade_xml_get_widget (dialog->gui, "auth-optionmenu");
- menu = gtk_option_menu_get_menu (GTK_OPTION_MENU(dialog->auth_optionmenu));
- gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback)add_auth_activate_cb, dialog);
- add_focus_handler (dialog->auth_optionmenu, general_tab_help, 3);
-}
-
-static gboolean
-general_tab_check (AddressbookSourceDialog *dialog)
-{
- gboolean valid = TRUE;
- char *string;
-
- string = e_utf8_gtk_entry_get_text (GTK_ENTRY (dialog->host));
- if (!string || !string[0])
- valid = FALSE;
- g_free (string);
-
- if (valid) {
- if (dialog->auth != ADDRESSBOOK_LDAP_AUTH_NONE) {
- if (dialog->auth == ADDRESSBOOK_LDAP_AUTH_SIMPLE_BINDDN)
- string = e_utf8_gtk_entry_get_text (GTK_ENTRY (dialog->binddn));
- else
- string = e_utf8_gtk_entry_get_text (GTK_ENTRY (dialog->email));
-
- if (!string || !string[0])
- valid = FALSE;
- g_free (string);
- }
- }
-
- return valid;
-}
-
-static void
-druid_info_page_modify_cb (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- gnome_druid_set_buttons_sensitive (GNOME_DRUID(dialog->druid),
- TRUE, /* back */
- general_tab_check (dialog), /* next */
- TRUE /* cancel */);
-}
-
-static void
-druid_info_page_prepare (GnomeDruidPage *dpage, GtkWidget *gdruid, AddressbookSourceDialog *dialog)
-{
- druid_info_page_modify_cb (NULL, dialog);
- /* stick the focus in the hostname field */
- gtk_widget_grab_focus (dialog->host);
-}
-
-
-/* connecting page */
-static void
-ssl_optionmenu_activated (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- dialog->ssl = g_list_index (gtk_container_children (GTK_CONTAINER (item->parent)),
- item);
-
- dialog->connecting_modify_func (item, dialog);
-}
-
-static void
-ssl_optionmenu_selected (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- GtkWidget *connecting_tab_help;
- int ssl_type = g_list_index (gtk_container_children (GTK_CONTAINER (item->parent)),
- item);
-
- connecting_tab_help = glade_xml_get_widget (dialog->gui, "connecting-tab-help");
-
- gtk_notebook_set_page (GTK_NOTEBOOK(connecting_tab_help), ssl_type + 1);
-}
-
-static void
-add_ssl_activate_cb (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- gtk_signal_connect (GTK_OBJECT (item), "activate",
- GTK_SIGNAL_FUNC (ssl_optionmenu_activated), dialog);
- gtk_signal_connect (GTK_OBJECT (item), "select",
- GTK_SIGNAL_FUNC (ssl_optionmenu_selected), dialog);
-}
-
-static void
-port_changed_func (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- /* if the port value is ldaps, set the SSL/TLS option menu to
- Always and desensitize it */
- char *string = e_utf8_gtk_entry_get_text (GTK_ENTRY (item));
-
- dialog->connecting_modify_func (item, dialog);
-
- if (!strcmp (string, LDAPS_PORT_STRING)) {
- dialog->ssl = ADDRESSBOOK_LDAP_SSL_ALWAYS;
- gtk_option_menu_set_history (GTK_OPTION_MENU(dialog->ssl_optionmenu),
- dialog->ssl);
-
- gtk_widget_set_sensitive (dialog->ssl_optionmenu, FALSE);
- }
- else {
- gtk_widget_set_sensitive (dialog->ssl_optionmenu, TRUE);
- }
-
-
- g_free (string);
-}
-
-static void
-setup_connecting_tab (AddressbookSourceDialog *dialog, GtkSignalFunc modify_func)
-{
- GtkWidget *menu;
- GtkWidget *connecting_tab_help;
-
- dialog->connecting_modify_func = modify_func;
-
- connecting_tab_help = glade_xml_get_widget (dialog->gui, "connecting-tab-help");
-
- dialog->port_combo = glade_xml_get_widget (dialog->gui, "port-combo");
- add_focus_handler (dialog->port_combo, connecting_tab_help, 0);
- add_focus_handler (GTK_COMBO(dialog->port_combo)->entry, connecting_tab_help, 0);
- gtk_signal_connect (GTK_OBJECT (GTK_COMBO(dialog->port_combo)->entry), "changed",
- modify_func, dialog);
- gtk_signal_connect (GTK_OBJECT (GTK_COMBO(dialog->port_combo)->entry), "changed",
- port_changed_func, dialog);
- dialog->ssl_optionmenu = glade_xml_get_widget (dialog->gui, "ssl-optionmenu");
- menu = gtk_option_menu_get_menu (GTK_OPTION_MENU(dialog->ssl_optionmenu));
- gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback)add_ssl_activate_cb, dialog);
-}
-
-static gboolean
-connecting_tab_check (AddressbookSourceDialog *dialog)
-{
- gboolean valid = TRUE;
- char *string;
-
- string = e_utf8_gtk_entry_get_text (GTK_ENTRY (GTK_COMBO(dialog->port_combo)->entry));
- if (!string || !string[0])
- valid = FALSE;
- g_free (string);
-
- return valid;
-}
-
-static void
-druid_connecting_page_modify_cb (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- gnome_druid_set_buttons_sensitive (GNOME_DRUID(dialog->druid),
- TRUE, /* back */
- connecting_tab_check (dialog), /* next */
- TRUE /* cancel */);
-}
-
-static void
-druid_connecting_page_prepare (GnomeDruidPage *dpage, GtkWidget *gdruid, AddressbookSourceDialog *dialog)
-{
- druid_connecting_page_modify_cb (NULL, dialog);
- /* stick the focus in the port combo */
- gtk_widget_grab_focus (GTK_COMBO(dialog->port_combo)->entry);
-}
-
-
-/* searching page */
-static ETableMemoryStoreColumnInfo bases_table_columns[] = {
- E_TABLE_MEMORY_STORE_STRING,
- E_TABLE_MEMORY_STORE_TERMINATOR
-};
-
-#define BASES_TABLE_SPEC \
-"<ETableSpecification cursor-mode=\"line\" no-headers=\"true\"> \
- <ETableColumn model_col= \"0\" _title=\"Base\" expansion=\"1.0\" minimum_width=\"20\" resizable=\"true\" cell=\"string\" compare=\"string\"/> \
- <ETableState> \
- <column source=\"0\"/> \
- <grouping></grouping> \
- </ETableState> \
-</ETableSpecification>"
-
-GtkWidget*
-supported_bases_create_table (char *name, char *string1, char *string2, int num1, int num2)
-{
- GtkWidget *table;
- ETableModel *model;
-
- model = e_table_memory_store_new (bases_table_columns);
-
- table = e_table_scrolled_new (model, NULL, BASES_TABLE_SPEC, NULL);
-
- gtk_object_set_data (GTK_OBJECT (table), "model", model);
-
- return table;
-}
-
-static gboolean
-do_ldap_root_dse_query (GtkWidget *dialog, ETableModel *model, AddressbookSource *source, char ***rvalues)
-{
- LDAP* ldap;
- char *attrs[2];
- int ldap_error;
- char **values;
- LDAPMessage *resp;
- int i;
-
- ldap = addressbook_ldap_init (dialog, source);
- if (!ldap)
- return FALSE;
-
- if (LDAP_SUCCESS != addressbook_ldap_auth (dialog, source, ldap))
- goto fail;
-
- attrs[0] = "namingContexts";
- attrs[1] = NULL;
-
- ldap_error = addressbook_root_dse_query (GTK_WINDOW (dialog), source, ldap, attrs, &resp);
-
- if (ldap_error != LDAP_SUCCESS)
- goto fail;
-
- values = ldap_get_values (ldap, resp, "namingContexts");
- if (!values || values[0] == NULL) {
- GtkWidget *error_dialog;
- error_dialog = gnome_ok_dialog_parented (_("The server responded with no supported search bases"), GTK_WINDOW (dialog));
- gtk_window_set_modal (GTK_WINDOW (error_dialog), TRUE);
- goto fail;
- }
-
- for (i = 0; values[i]; i++)
- e_table_memory_store_insert (E_TABLE_MEMORY_STORE (model),
- -1, GINT_TO_POINTER(i), values[i]);
-
- *rvalues = values;
-
- ldap_unbind_s (ldap);
- return TRUE;
-
- fail:
- ldap_unbind_s (ldap);
- return FALSE;
-}
-
-static void
-search_base_selection_model_changed (ESelectionModel *selection_model, GtkWidget *dialog)
-{
- gnome_dialog_set_sensitive (GNOME_DIALOG (dialog),
- 0 /* OK */, e_selection_model_selected_count (selection_model) == 1);
-}
-
-static void
-query_for_supported_bases (GtkWidget *button, AddressbookSourceDialog *sdialog)
-{
- ESelectionModel *selection_model;
- AddressbookSource *source = addressbook_dialog_get_source (sdialog);
- GtkWidget *dialog;
- GtkWidget *supported_bases_table;
- ETableModel *model;
- int id;
- char **values;
-
- dialog = glade_xml_get_widget (sdialog->gui, "supported-bases-dialog");
-
- supported_bases_table = glade_xml_get_widget (sdialog->gui, "supported-bases-table");
- selection_model = e_table_get_selection_model (e_table_scrolled_get_table (E_TABLE_SCROLLED(supported_bases_table)));
- model = gtk_object_get_data (GTK_OBJECT (supported_bases_table), "model");
-
- gtk_signal_connect (GTK_OBJECT (selection_model), "selection_changed",
- search_base_selection_model_changed, dialog);
-
- search_base_selection_model_changed (selection_model, dialog);
-
- if (do_ldap_root_dse_query (dialog, model, source, &values)) {
- gnome_dialog_close_hides (GNOME_DIALOG(dialog), TRUE);
-
- id = gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
-
- if (id == 0) {
- int i;
- /* OK was clicked */
-
- /* ugh. */
- for (i = 0; values[i]; i ++) {
- if (e_selection_model_is_row_selected (selection_model, i)) {
- e_utf8_gtk_entry_set_text (GTK_ENTRY (sdialog->rootdn), values[i]);
- break; /* single selection, so we can quit when we've found it. */
- }
- }
- }
-
- ldap_value_free (values);
-
- e_table_memory_store_clear (E_TABLE_MEMORY_STORE (model));
- }
-
- addressbook_source_free (source);
-}
-
-static void
-scope_optionmenu_activated (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- dialog->scope = g_list_index (gtk_container_children (GTK_CONTAINER (item->parent)),
- item);
-
- if (dialog->searching_modify_func)
- dialog->searching_modify_func (item, dialog);
-}
-
-static void
-add_scope_activate_cb (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- gtk_signal_connect (GTK_OBJECT (item), "activate",
- GTK_SIGNAL_FUNC (scope_optionmenu_activated), dialog);
-}
-
-static void
-setup_searching_tab (AddressbookSourceDialog *dialog, GtkSignalFunc modify_func)
-{
- GtkWidget *menu;
- GtkWidget *rootdn_button;
- GtkWidget *searching_tab_help;
-
- dialog->searching_modify_func = modify_func;
-
- searching_tab_help = glade_xml_get_widget (dialog->gui, "searching-tab-help");
-
- dialog->rootdn = glade_xml_get_widget (dialog->gui, "rootdn-entry");
- add_focus_handler (dialog->rootdn, searching_tab_help, 0);
- if (modify_func)
- gtk_signal_connect (GTK_OBJECT (dialog->rootdn), "changed",
- modify_func, dialog);
-
- dialog->scope_optionmenu = glade_xml_get_widget (dialog->gui, "scope-optionmenu");
- add_focus_handler (dialog->scope_optionmenu, searching_tab_help, 1);
- menu = gtk_option_menu_get_menu (GTK_OPTION_MENU(dialog->scope_optionmenu));
- gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback)add_scope_activate_cb, dialog);
-
- dialog->timeout_scale = glade_xml_get_widget (dialog->gui, "timeout-scale");
- add_focus_handler (dialog->timeout_scale, searching_tab_help, 2);
- if (modify_func)
- gtk_signal_connect (GTK_OBJECT (GTK_RANGE(dialog->timeout_scale)->adjustment),
- "value_changed",
- modify_func, dialog);
-
- dialog->limit_spinbutton = glade_xml_get_widget (dialog->gui, "download-limit-spinbutton");
- if (modify_func)
- gtk_signal_connect (GTK_OBJECT (dialog->limit_spinbutton), "changed",
- modify_func, dialog);
-
- /* special handling for the "Show Supported Bases button" */
- rootdn_button = glade_xml_get_widget (dialog->gui, "rootdn-button");
- gtk_signal_connect (GTK_OBJECT (rootdn_button), "clicked",
- GTK_SIGNAL_FUNC(query_for_supported_bases), dialog);
-}
-
-static void
-druid_searching_page_prepare (GnomeDruidPage *dpage, GtkWidget *gdruid, AddressbookSourceDialog *dialog)
-{
- gnome_druid_set_buttons_sensitive (GNOME_DRUID(dialog->druid),
- TRUE, /* back */
- TRUE, /* next */
- TRUE /* cancel */);
-}
-
-
-/* display name page */
-static gboolean
-display_name_check (AddressbookSourceDialog *dialog)
-{
- gboolean valid = TRUE;
- char *string;
-
- string = e_utf8_gtk_entry_get_text (GTK_ENTRY (dialog->display_name));
- if (!string || !string[0])
- valid = FALSE;
- g_free (string);
-
- return valid;
-}
-
-static void
-display_name_page_prepare (GtkWidget *page, GtkWidget *gnome_druid, AddressbookSourceDialog *dialog)
-{
- if (!dialog->display_name_changed) {
- char *server_name = e_utf8_gtk_entry_get_text (GTK_ENTRY (dialog->host));
- e_utf8_gtk_entry_set_text (GTK_ENTRY (dialog->display_name), server_name);
- g_free (server_name);
- }
-
- gnome_druid_set_buttons_sensitive (GNOME_DRUID(dialog->druid),
- TRUE, /* back */
- display_name_check (dialog), /* next */
- TRUE /* cancel */);
-}
-
-static void
-druid_display_name_page_modify_cb (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- dialog->display_name_changed = TRUE;
- display_name_page_prepare (NULL, NULL, dialog);
-}
-
-
-#ifdef NEW_ADVANCED_UI
-/* objectclasses page */
-static ETableMemoryStoreColumnInfo objectclasses_table_columns[] = {
- E_TABLE_MEMORY_STORE_STRING,
- E_TABLE_MEMORY_STORE_TERMINATOR
-};
-
-#define OBJECTCLASSES_TABLE_SPEC \
-"<ETableSpecification cursor-mode=\"line\" no-headers=\"true\"> \
- <ETableColumn model_col= \"0\" _title=\"Objectclass\" expansion=\"1.0\" minimum_width=\"20\" resizable=\"true\" cell=\"string\" compare=\"string\"/> \
- <ETableState> \
- <column source=\"0\"/> \
- <grouping> <leaf column=\"0\" ascending=\"true\"/> </grouping> \
- </ETableState> \
-</ETableSpecification>"
-
-GtkWidget*
-objectclasses_create_server_table (char *name, char *string1, char *string2,
- int num1, int num2)
-{
- GtkWidget *table;
- ETableModel *model;
-
- model = e_table_memory_store_new (objectclasses_table_columns);
-
- table = e_table_scrolled_new (model, NULL, OBJECTCLASSES_TABLE_SPEC, NULL);
-
- gtk_object_set_data (GTK_OBJECT (table), "model", model);
-
- return table;
-}
-
-GtkWidget*
-objectclasses_create_evolution_table (char *name, char *string1, char *string2,
- int num1, int num2)
-{
- GtkWidget *table;
- ETableModel *model;
-
- model = e_table_memory_store_new (objectclasses_table_columns);
-
- table = e_table_scrolled_new (model, NULL, OBJECTCLASSES_TABLE_SPEC, NULL);
-
- gtk_object_set_data (GTK_OBJECT (table), "model", model);
-
- return table;
-}
-
-static void
-objectclasses_add_foreach (int model_row, AddressbookSourceDialog *dialog)
-{
- LDAPObjectClass *oc = e_table_memory_get_data (E_TABLE_MEMORY (dialog->objectclasses_server_model), model_row);
- e_table_memory_store_remove (E_TABLE_MEMORY_STORE (dialog->objectclasses_server_model), model_row);
- /* XXX remove from the server array */
- e_table_memory_store_insert (E_TABLE_MEMORY_STORE (dialog->objectclasses_evolution_model),
- -1, oc, oc->oc_names[0]);
- /* XXX add to the evolution array */
-}
-
-static void
-objectclasses_add (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- ESelectionModel *esm = e_table_get_selection_model (e_table_scrolled_get_table (E_TABLE_SCROLLED(dialog->objectclasses_server_table)));
-
- e_selection_model_foreach (esm, (EForeachFunc)objectclasses_add_foreach, dialog);
- dialog->objectclasses_modify_func (item, dialog);
-}
-
-static void
-objectclasses_server_double_click (ETable *et, int row, int col, GdkEvent *event, AddressbookSourceDialog *dialog)
-{
- objectclasses_add_foreach (row, dialog);
- dialog->objectclasses_modify_func (GTK_WIDGET (et), dialog);
-}
-
-static void
-objectclasses_remove_foreach (int model_row, AddressbookSourceDialog *dialog)
-{
- LDAPObjectClass *oc = e_table_memory_get_data (E_TABLE_MEMORY (dialog->objectclasses_evolution_model), model_row);
- e_table_memory_store_remove (E_TABLE_MEMORY_STORE (dialog->objectclasses_evolution_model), model_row);
- /* XXX remove from the evolution array */
- e_table_memory_store_insert (E_TABLE_MEMORY_STORE (dialog->objectclasses_server_model),
- -1, oc, oc->oc_names[0]);
- /* XXX add to the server array */
-}
-
-static void
-objectclasses_remove (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- ESelectionModel *esm = e_table_get_selection_model (e_table_scrolled_get_table (E_TABLE_SCROLLED(dialog->objectclasses_evolution_table)));
-
- e_selection_model_foreach (esm, (EForeachFunc)objectclasses_add_foreach, dialog);
-
- dialog->objectclasses_modify_func (item, dialog);
-}
-
-static void
-objectclasses_evolution_double_click (ETable *et, int row, int col, GdkEvent *event, AddressbookSourceDialog *dialog)
-{
- objectclasses_remove_foreach (row, dialog);
- dialog->objectclasses_modify_func (GTK_WIDGET (et), dialog);
-}
-
-static void
-objectclasses_restore_default (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- int i;
-
- dialog->objectclasses_modify_func (item, dialog);
-
- /* clear out our evolution list */
- for (i = 0; i < dialog->evolution_objectclasses->len; i ++) {
- g_ptr_array_add (dialog->server_objectclasses, g_ptr_array_index (dialog->evolution_objectclasses, i));
- }
- g_ptr_array_set_size (dialog->evolution_objectclasses, 0);
-
- e_table_memory_store_clear (E_TABLE_MEMORY_STORE (dialog->objectclasses_evolution_model));
-
- for (i = 0; i < dialog->default_objectclasses->len; i++) {
- LDAPObjectClass *oc = g_ptr_array_index (dialog->default_objectclasses, i);
- g_ptr_array_add (dialog->evolution_objectclasses, oc);
- e_table_memory_store_insert (E_TABLE_MEMORY_STORE (dialog->objectclasses_evolution_model),
- i, oc, oc->oc_names[0]);
- }
-}
-
-static void
-server_selection_model_changed (ESelectionModel *selection_model, AddressbookSourceDialog *dialog)
-{
- gtk_widget_set_sensitive (dialog->objectclasses_add_button,
- e_selection_model_selected_count (selection_model) > 0);
-}
-
-static void
-evolution_selection_model_changed (ESelectionModel *selection_model, AddressbookSourceDialog *dialog)
-{
- gtk_widget_set_sensitive (dialog->objectclasses_remove_button,
- e_selection_model_selected_count (selection_model) > 0);
-}
-
-static void
-setup_objectclasses_tab (AddressbookSourceDialog *dialog, GtkSignalFunc modify_func)
-{
- ETable *table;
- GtkWidget *restore_default;
- ESelectionModel *esm;
-
- dialog->server_objectclasses = g_ptr_array_new ();
- dialog->evolution_objectclasses = g_ptr_array_new ();
- dialog->default_objectclasses = g_ptr_array_new ();
-
- dialog->objectclasses_modify_func = modify_func;
-
- dialog->objectclasses_server_table = glade_xml_get_widget (dialog->gui, "objectclasses-server-table");
- dialog->objectclasses_server_model = gtk_object_get_data (GTK_OBJECT (dialog->objectclasses_server_table), "model");
-
- dialog->objectclasses_evolution_table = glade_xml_get_widget (dialog->gui, "objectclasses-evolution-table");
- dialog->objectclasses_evolution_model = gtk_object_get_data (GTK_OBJECT (dialog->objectclasses_evolution_table), "model");
-
- table = e_table_scrolled_get_table (E_TABLE_SCROLLED(dialog->objectclasses_server_table));
- gtk_signal_connect (GTK_OBJECT (table), "double_click",
- GTK_SIGNAL_FUNC (objectclasses_server_double_click), dialog);
- esm = e_table_get_selection_model (table);
- gtk_signal_connect (GTK_OBJECT (esm), "selection_changed",
- server_selection_model_changed, dialog);
-
- table = e_table_scrolled_get_table (E_TABLE_SCROLLED(dialog->objectclasses_evolution_table));
- gtk_signal_connect (GTK_OBJECT (table), "double_click",
- GTK_SIGNAL_FUNC (objectclasses_evolution_double_click), dialog);
- esm = e_table_get_selection_model (table);
- gtk_signal_connect (GTK_OBJECT (esm), "selection_changed",
- evolution_selection_model_changed, dialog);
-
- dialog->objectclasses_add_button = glade_xml_get_widget (dialog->gui, "objectclasses-add-button");
- gtk_signal_connect (GTK_OBJECT (dialog->objectclasses_add_button), "clicked",
- GTK_SIGNAL_FUNC(objectclasses_add), dialog);
-
- dialog->objectclasses_remove_button = glade_xml_get_widget (dialog->gui, "objectclasses-remove-button");
- gtk_signal_connect (GTK_OBJECT (dialog->objectclasses_remove_button), "clicked",
- GTK_SIGNAL_FUNC(objectclasses_remove), dialog);
-
- restore_default = glade_xml_get_widget (dialog->gui, "objectclasses-default-button");
- gtk_signal_connect (GTK_OBJECT (restore_default), "clicked",
- GTK_SIGNAL_FUNC(objectclasses_restore_default), dialog);
-}
-#endif
-
-
-static AddressbookSourceDialog *
-addressbook_add_server_druid (AddressbookDialog *dialog)
-{
- AddressbookSourceDialog *sdialog = g_new0 (AddressbookSourceDialog, 1);
- GtkWidget *page;
-
- sdialog->addressbook_dialog = dialog;
-
- sdialog->gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, NULL);
-
- sdialog->window = glade_xml_get_widget (sdialog->gui, "account-druid-window");
- sdialog->druid = glade_xml_get_widget (sdialog->gui, "account-druid");
-
- /* info page */
- page = glade_xml_get_widget (sdialog->gui, "add-server-druid-info-page");
- reparent_to_vbox (sdialog, "account-druid-general-vbox", "general-tab");
- setup_general_tab (sdialog, GTK_SIGNAL_FUNC (druid_info_page_modify_cb));
- gtk_signal_connect (GTK_OBJECT(page), "prepare",
- GTK_SIGNAL_FUNC(druid_info_page_prepare), sdialog);
-
- /* connecting page */
- page = glade_xml_get_widget (sdialog->gui, "add-server-druid-connecting-page");
- reparent_to_vbox (sdialog, "account-druid-connecting-vbox", "connecting-tab");
- setup_connecting_tab (sdialog, druid_connecting_page_modify_cb);
- gtk_signal_connect (GTK_OBJECT(page), "prepare",
- GTK_SIGNAL_FUNC(druid_connecting_page_prepare), sdialog);
-
- /* searching page */
- page = glade_xml_get_widget (sdialog->gui, "add-server-druid-searching-page");
- reparent_to_vbox (sdialog, "account-druid-searching-vbox", "searching-tab");
- setup_searching_tab (sdialog, NULL);
- gtk_signal_connect (GTK_OBJECT(page), "prepare",
- GTK_SIGNAL_FUNC(druid_searching_page_prepare), sdialog);
-
- /* display name page */
- page = glade_xml_get_widget (sdialog->gui, "add-server-druid-display-name-page");
- sdialog->display_name = glade_xml_get_widget (sdialog->gui, "druid-display-name-entry");
- gtk_signal_connect (GTK_OBJECT (sdialog->display_name), "changed",
- druid_display_name_page_modify_cb, sdialog);
- gtk_signal_connect (GTK_OBJECT(page), "prepare",
- GTK_SIGNAL_FUNC(display_name_page_prepare), sdialog);
-
- page = glade_xml_get_widget (sdialog->gui, "add-server-druid-finish-page");
- gtk_signal_connect (GTK_OBJECT(page), "finish",
- GTK_SIGNAL_FUNC(addressbook_add_server_druid_finish), sdialog);
- gtk_signal_connect (GTK_OBJECT(sdialog->druid), "cancel",
- GTK_SIGNAL_FUNC(addressbook_add_server_druid_cancel), sdialog);
- gtk_signal_connect (GTK_OBJECT(sdialog->window), "destroy",
- GTK_SIGNAL_FUNC(addressbook_source_dialog_destroy), sdialog);
-
- /* make sure we fill in the default values */
- addressbook_source_dialog_set_source (sdialog, NULL);
-
- gtk_window_set_modal (GTK_WINDOW (sdialog->window), TRUE);
-
- gtk_widget_show (sdialog->window);
-
- return sdialog;
-}
-
-static void
-editor_modify_cb (GtkWidget *item, AddressbookSourceDialog *dialog)
-{
- gboolean valid = TRUE;
-
- valid = display_name_check (dialog);
- if (valid)
- valid = general_tab_check (dialog);
-#if 0
- if (valid)
- valid = connecting_tab_check (dialog);
- if (valid)
- valid = searching_tab_check (dialog);
-#endif
-
- gtk_widget_set_sensitive (dialog->ok_button, valid);
- gtk_widget_set_sensitive (dialog->apply_button, valid);
-}
-
-static void
-set_advanced_button_state (AddressbookSourceDialog *dialog)
-{
- if (dialog->advanced) {
- gtk_notebook_set_page (GTK_NOTEBOOK(dialog->advanced_button_notebook), 0);
-#ifdef NEW_ADVANCED_UI
- gtk_notebook_append_page (GTK_NOTEBOOK(dialog->notebook), dialog->objectclasses_tab, dialog->objectclasses_label);
- gtk_notebook_append_page (GTK_NOTEBOOK(dialog->notebook), dialog->mappings_tab, dialog->mappings_label);
- gtk_notebook_append_page (GTK_NOTEBOOK(dialog->notebook), dialog->dn_customization_tab, dialog->dn_customization_label);
-#endif
- }
- else {
- gtk_notebook_set_page (GTK_NOTEBOOK(dialog->advanced_button_notebook), 1);
-
- /* hide the advanced tabs of the main notebook */
- gtk_notebook_remove_page (GTK_NOTEBOOK(dialog->notebook), 5);
- gtk_notebook_remove_page (GTK_NOTEBOOK(dialog->notebook), 4);
- gtk_notebook_remove_page (GTK_NOTEBOOK(dialog->notebook), 3);
- }
-}
-
-#ifdef NEW_ADVANCED_UI
-static void
-advanced_button_clicked (GtkWidget *button, AddressbookSourceDialog *dialog)
-{
- dialog->advanced = !dialog->advanced;
- set_advanced_button_state (dialog);
-}
-
-static gboolean
-do_schema_query (AddressbookSourceDialog *sdialog)
-{
- LDAP *ldap;
- int ldap_error;
- char *schema_dn;
- char *attrs[3];
- char **values;
- int i;
- AddressbookSource *source = addressbook_dialog_get_source (sdialog);
- LDAPMessage *resp;
- struct timeval timeout;
-
- ldap = addressbook_ldap_init (sdialog->window, source);
- if (!ldap)
- goto fail;
-
- if (LDAP_SUCCESS != addressbook_ldap_auth (sdialog->window, source, ldap))
- goto fail;
-
- attrs[0] = "subschemaSubentry";
- attrs[1] = NULL;
-
- ldap_error = addressbook_root_dse_query (sdialog->window, source, ldap, attrs, &resp);
-
- if (ldap_error != LDAP_SUCCESS)
- goto fail;
-
- values = ldap_get_values (ldap, resp, "subschemaSubentry");
- if (!values || values[0] == NULL) {
- GtkWidget *dialog;
- dialog = gnome_ok_dialog_parented (_("This server does not support LDAPv3 schema information"), GTK_WINDOW (sdialog->window));
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- goto fail;
- }
-
- schema_dn = g_strdup (values[0]);
-
- ldap_value_free (values);
- ldap_msgfree (resp);
-
- attrs[0] = "objectClasses";
- attrs[1] = NULL;
-
- /* 3 second timeout */
- timeout.tv_sec = 3;
- timeout.tv_usec = 0;
-
- ldap_error = ldap_search_ext_s (ldap, schema_dn, LDAP_SCOPE_BASE,
- "(objectClass=subschema)", attrs, 0,
- NULL, NULL, &timeout, LDAP_NO_LIMIT, &resp);
- if (LDAP_SUCCESS != ldap_error) {
- GtkWidget *dialog;
- dialog = gnome_error_dialog_parented (_("Error retrieving schema information"), GTK_WINDOW (sdialog->window));
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- goto fail;
- }
-
- values = ldap_get_values (ldap, resp, "objectClasses");
- if (!values) {
- GtkWidget *dialog;
- dialog = gnome_error_dialog_parented (_("Server did not respond with valid schema information"), GTK_WINDOW (sdialog->window));
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- goto fail;
- }
-
- for (i = 0; values[i]; i ++) {
- int j;
- int code;
- const char *err;
- LDAPObjectClass *oc = ldap_str2objectclass (values[i], &code, &err, 0);
-
- if (!oc)
- continue;
-
- /* we fill in the default list of classes here */
- for (j = 0; oc->oc_names[j]; j ++) {
- if (!g_strcasecmp (oc->oc_names[j], EVOLUTIONPERSON) ||
- !g_strcasecmp (oc->oc_names[j], INETORGPERSON) ||
- !g_strcasecmp (oc->oc_names[j], ORGANIZATIONALPERSON) ||
- !g_strcasecmp (oc->oc_names[j], PERSON) ||
- !g_strcasecmp (oc->oc_names[j], CALENTRY) ||
- !g_strcasecmp (oc->oc_names[j], TOP))
- g_ptr_array_add (sdialog->default_objectclasses, oc);
- }
-
- g_ptr_array_add (sdialog->server_objectclasses, oc);
- }
-
- addressbook_source_free (source);
- ldap_unbind_s (ldap);
- return TRUE;
-
- fail:
- addressbook_source_free (source);
- if (ldap)
- ldap_unbind_s (ldap);
- return FALSE;
-}
-
-static void
-edit_dialog_switch_page (GtkNotebook *notebook,
- GtkNotebookPage *page, guint page_num,
- AddressbookSourceDialog *sdialog)
-{
- if (page_num >= 3 && !sdialog->schema_query_successful) {
- int i;
-
- gtk_widget_set_sensitive (GTK_WIDGET (notebook), FALSE);
-
- sdialog->schema_query_successful = do_schema_query (sdialog);
-
- if (sdialog->schema_query_successful) {
- /* fill in the objectclasses model */
- for (i = 0; i < sdialog->server_objectclasses->len; i ++) {
- LDAPObjectClass *oc = g_ptr_array_index (sdialog->server_objectclasses, i);
- e_table_memory_store_insert (E_TABLE_MEMORY_STORE (sdialog->objectclasses_server_model),
- -1, oc, oc->oc_names[0]);
- }
- gtk_widget_set_sensitive (page->child, TRUE);
- }
- else {
- gtk_widget_set_sensitive (page->child, FALSE);
- }
-
- gtk_widget_set_sensitive (GTK_WIDGET (notebook), TRUE);
- }
-}
-#endif
-
-static gboolean
-edit_dialog_store_change (AddressbookSourceDialog *sdialog)
-{
- AddressbookSource *source = addressbook_dialog_get_source (sdialog);
- AddressbookDialog *dialog = sdialog->addressbook_dialog;
- AddressbookSource *old_source;
-
- /* check the display name for uniqueness */
- if (FALSE /* XXX */) {
- return FALSE;
- }
-
- /* store the new source in the addressbook dialog */
- old_source = e_table_memory_get_data (E_TABLE_MEMORY (dialog->sourcesModel), sdialog->source_model_row);
- addressbook_source_free (old_source);
- e_table_memory_store_remove (E_TABLE_MEMORY_STORE (dialog->sourcesModel),
- sdialog->source_model_row);
-
- e_table_memory_store_insert (E_TABLE_MEMORY_STORE (dialog->sourcesModel),
- sdialog->source_model_row, source, source->name, source->host);
-
- /* and let the config control know about the change */
- evolution_config_control_changed (dialog->config_control);
-
- return TRUE;
-}
-
-static void
-edit_dialog_apply_clicked (GtkWidget *item, AddressbookSourceDialog *sdialog)
-{
- if (!edit_dialog_store_change (sdialog))
- return;
-
- /* resensitize the buttons */
- gtk_widget_set_sensitive (sdialog->ok_button, FALSE);
- gtk_widget_set_sensitive (sdialog->apply_button, FALSE);
-}
-
-static void
-edit_dialog_close_clicked (GtkWidget *item, AddressbookSourceDialog *sdialog)
-{
- gtk_widget_destroy (sdialog->window);
-}
-
-static void
-edit_dialog_ok_clicked (GtkWidget *item, AddressbookSourceDialog *sdialog)
-{
- if (edit_dialog_store_change (sdialog))
- edit_dialog_close_clicked (item, sdialog);
-}
-
-static AddressbookSourceDialog*
-addressbook_edit_server_dialog (AddressbookDialog *dialog, int model_row)
-{
- AddressbookSource *source = e_table_memory_get_data (E_TABLE_MEMORY(dialog->sourcesModel), model_row);
- AddressbookSourceDialog *sdialog = g_new0 (AddressbookSourceDialog, 1);
- GtkWidget *general_tab_help;
- GtkWidget *fewer_options_button, *more_options_button;
-
- sdialog->addressbook_dialog = dialog;
- sdialog->source_model_row = model_row;
-
- sdialog->gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, NULL);
-
- sdialog->window = glade_xml_get_widget (sdialog->gui, "account-editor-window");
-
- /* general tab */
- general_tab_help = glade_xml_get_widget (dialog->gui, "general-tab-help");
- reparent_to_vbox (sdialog, "account-editor-general-vbox", "general-tab");
- setup_general_tab (sdialog, GTK_SIGNAL_FUNC (editor_modify_cb));
- sdialog->display_name = glade_xml_get_widget (sdialog->gui, "account-editor-display-name-entry");
- gtk_signal_connect (GTK_OBJECT (sdialog->display_name), "changed",
- editor_modify_cb, sdialog);
- add_focus_handler (sdialog->display_name, general_tab_help, 4);
-
- /* connecting tab */
- reparent_to_vbox (sdialog, "account-editor-connecting-vbox", "connecting-tab");
- setup_connecting_tab (sdialog, GTK_SIGNAL_FUNC (editor_modify_cb));
-
- /* searching tab */
- reparent_to_vbox (sdialog, "account-editor-searching-vbox", "searching-tab");
- setup_searching_tab (sdialog, GTK_SIGNAL_FUNC (editor_modify_cb));
-
-#ifdef NEW_ADVANCED_UI
- /* objectclasses tab */
- reparent_to_vbox (sdialog, "account-editor-objectclasses-vbox", "objectclasses-tab");
- setup_objectclasses_tab (sdialog, GTK_SIGNAL_FUNC (editor_modify_cb));
-
- /* mappings tab */
- reparent_to_vbox (sdialog, "account-editor-mappings-vbox", "mappings-tab");
- /* XXX setup_mappings_tab */
-
- /* dn customization tab */
- reparent_to_vbox (sdialog, "account-editor-dn-customization-vbox", "dn-customization-tab");
- /* XXX setup_dn_customization_tab */
-#endif
-
- sdialog->ok_button = glade_xml_get_widget (sdialog->gui, "account-editor-ok-button");
- sdialog->apply_button = glade_xml_get_widget (sdialog->gui, "account-editor-apply-button");
- sdialog->close_button = glade_xml_get_widget (sdialog->gui, "account-editor-close-button");
-
- sdialog->advanced_button_notebook = glade_xml_get_widget (sdialog->gui, "account-editor-advanced-button-notebook");
- fewer_options_button = glade_xml_get_widget (sdialog->gui, "account-editor-fewer-options-button");
- more_options_button = glade_xml_get_widget (sdialog->gui, "account-editor-more-options-button");
-
- sdialog->notebook = glade_xml_get_widget (sdialog->gui, "account-editor-notebook");
-#ifdef NEW_ADVANCED_UI
- sdialog->objectclasses_label = glade_xml_get_widget (sdialog->gui, "account-editor-objectclasses-label");
- gtk_object_ref (GTK_OBJECT (sdialog->objectclasses_label));
- sdialog->objectclasses_tab = glade_xml_get_widget (sdialog->gui, "account-editor-objectclasses-vbox");
- gtk_object_ref (GTK_OBJECT (sdialog->objectclasses_tab));
- sdialog->mappings_label = glade_xml_get_widget (sdialog->gui, "account-editor-mappings-label");
- gtk_object_ref (GTK_OBJECT (sdialog->mappings_label));
- sdialog->mappings_tab = glade_xml_get_widget (sdialog->gui, "account-editor-mappings-vbox");
- gtk_object_ref (GTK_OBJECT (sdialog->mappings_tab));
- sdialog->dn_customization_label = glade_xml_get_widget (sdialog->gui, "account-editor-dn-customization-label");
- gtk_object_ref (GTK_OBJECT (sdialog->dn_customization_label));
- sdialog->dn_customization_tab = glade_xml_get_widget (sdialog->gui, "account-editor-dn-customization-vbox");
- gtk_object_ref (GTK_OBJECT (sdialog->dn_customization_tab));
-#endif
-
- addressbook_source_dialog_set_source (sdialog, source);
-
- set_advanced_button_state (sdialog);
-
-#ifdef NEW_ADVANCED_UI
- gtk_signal_connect (GTK_OBJECT (fewer_options_button),
- "clicked", advanced_button_clicked, sdialog);
- gtk_signal_connect (GTK_OBJECT (more_options_button),
- "clicked", advanced_button_clicked, sdialog);
-
-#else
- gtk_widget_hide (sdialog->advanced_button_notebook);
-#endif
-
-#ifdef NEW_ADVANCED_UI
- /* set up a signal handler to query for schema info if the user switches to the advanced tabs */
- gtk_signal_connect (GTK_OBJECT (sdialog->notebook), "switch_page",
- GTK_SIGNAL_FUNC (edit_dialog_switch_page), sdialog);
-#endif
-
- gtk_signal_connect (GTK_OBJECT (sdialog->ok_button),
- "clicked", GTK_SIGNAL_FUNC(edit_dialog_ok_clicked), sdialog);
- gtk_signal_connect (GTK_OBJECT (sdialog->apply_button),
- "clicked", GTK_SIGNAL_FUNC(edit_dialog_apply_clicked), sdialog);
- gtk_signal_connect (GTK_OBJECT (sdialog->close_button),
- "clicked", GTK_SIGNAL_FUNC(edit_dialog_close_clicked), sdialog);
- gtk_signal_connect (GTK_OBJECT(sdialog->window), "destroy",
- GTK_SIGNAL_FUNC(addressbook_source_dialog_destroy), sdialog);
-
- gtk_widget_set_sensitive (sdialog->ok_button, FALSE);
- gtk_widget_set_sensitive (sdialog->apply_button, FALSE);
-
- gtk_window_set_modal (GTK_WINDOW (sdialog->window), TRUE);
-
- gtk_widget_show (sdialog->window);
-
- return sdialog;
-}
-
-static void
-add_source_clicked (GtkWidget *widget, AddressbookDialog *dialog)
-{
- addressbook_add_server_druid (dialog);
-}
-
-static void
-edit_source_clicked (GtkWidget *widget, AddressbookDialog *dialog)
-{
- int i;
- ESelectionModel *selection_model;
- int row_count;
-
- selection_model = e_table_get_selection_model (e_table_scrolled_get_table (E_TABLE_SCROLLED(dialog->sourcesTable)));
- row_count = e_selection_model_row_count (selection_model);
-
- for (i = 0; i < row_count; i ++) {
- if (e_selection_model_is_row_selected (selection_model, i)) {
- addressbook_edit_server_dialog (dialog, i);
- break; /* single select so we're done now */
- }
- }
-
-#if 0
- AddressbookSource *source;
- AddressbookSourceDialog *sdialog;
-
- source = gtk_clist_get_row_data (GTK_CLIST (dialog->clistSources), dialog->source_row);
-
- sdialog = addressbook_config_source_with_gui (dialog->gui, source, dialog->page);
- if (sdialog->id == 0) {
- /* Ok was clicked */
- source = addressbook_source_copy(sdialog->source);
-
- e_utf8_gtk_clist_set_text (GTK_CLIST (dialog->clistSources), dialog->source_row, 0, source->name);
- e_utf8_gtk_clist_set_text (GTK_CLIST (dialog->clistSources), dialog->source_row, 1, source->host);
- gtk_clist_set_row_data (GTK_CLIST (dialog->clistSources), dialog->source_row, source);
-
- evolution_config_control_changed (dialog->config_control);
-
- update_sensitivity (dialog);
- }
-#endif
-}
-
-static void
-delete_source_clicked (GtkWidget *widget, AddressbookDialog *dialog)
-{
- int i;
- ESelectionModel *selection_model;
- int row_count;
-
- selection_model = e_table_get_selection_model (e_table_scrolled_get_table (E_TABLE_SCROLLED(dialog->sourcesTable)));
- row_count = e_selection_model_row_count (selection_model);
-
- for (i = 0; i < row_count; i ++) {
- if (e_selection_model_is_row_selected (selection_model, i)) {
- AddressbookSource *source = e_table_memory_get_data (E_TABLE_MEMORY(dialog->sourcesModel), i);
- e_table_memory_store_remove (E_TABLE_MEMORY_STORE (dialog->sourcesModel), i);
- addressbook_source_free (source);
-
- break; /* single select so we're done now */
- }
- }
-
- evolution_config_control_changed (dialog->config_control);
-}
-
-static void
-ldap_config_control_destroy_callback (EvolutionConfigControl *config_control,
- void *data)
-{
- AddressbookDialog *dialog;
-
- dialog = (AddressbookDialog *) data;
-
- gtk_object_unref (GTK_OBJECT (dialog->gui));
-
- /* XXX free more stuff here */
-
- g_free (dialog);
-}
-
-static void
-ldap_config_control_apply_callback (EvolutionConfigControl *config_control,
- void *data)
-{
- AddressbookDialog *dialog;
- int i;
- int count;
-
- dialog = (AddressbookDialog *) data;
-
- addressbook_storage_clear_sources();
-
- count = e_table_model_row_count (E_TABLE_MODEL (dialog->sourcesModel));
-
- for (i = 0; i < count; i ++) {
- AddressbookSource *source = e_table_memory_get_data (E_TABLE_MEMORY (dialog->sourcesModel), i);
- addressbook_storage_add_source (addressbook_source_copy (source));
- }
-
- addressbook_storage_write_sources();
-}
-
-static void
-sources_selection_changed (ESelectionModel *esm, AddressbookDialog *dialog)
-{
- gboolean sensitive = e_selection_model_selected_count (esm) == 1;
-
- gtk_widget_set_sensitive (dialog->editSource, sensitive);
- gtk_widget_set_sensitive (dialog->deleteSource, sensitive);
-}
-
-static void
-sources_table_double_click (ETable *et, int row, int col, GdkEvent *event, AddressbookDialog *dialog)
-{
- addressbook_edit_server_dialog (dialog, row);
-}
-
-
-static AddressbookDialog *
-ldap_dialog_new (GNOME_Evolution_Shell shell)
-{
- AddressbookDialog *dialog;
- GList *l;
- ESelectionModel *esm;
- ETable *et;
-
- dialog = g_new0 (AddressbookDialog, 1);
-
- dialog->gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, NULL);
- dialog->shell = shell;
-
- dialog->sourcesTable = glade_xml_get_widget (dialog->gui, "sourcesTable");
- et = e_table_scrolled_get_table (E_TABLE_SCROLLED(dialog->sourcesTable));
- gtk_signal_connect (GTK_OBJECT (et), "double_click",
- GTK_SIGNAL_FUNC (sources_table_double_click), dialog);
-
- dialog->sourcesModel = gtk_object_get_data (GTK_OBJECT (dialog->sourcesTable), "model");
-
- dialog->addSource = glade_xml_get_widget (dialog->gui, "addSource");
- gtk_signal_connect (GTK_OBJECT(dialog->addSource), "clicked",
- GTK_SIGNAL_FUNC (add_source_clicked),
- dialog);
-
- dialog->editSource = glade_xml_get_widget (dialog->gui, "editSource");
- gtk_signal_connect (GTK_OBJECT(dialog->editSource), "clicked",
- GTK_SIGNAL_FUNC (edit_source_clicked),
- dialog);
-
- dialog->deleteSource = glade_xml_get_widget (dialog->gui, "deleteSource");
- gtk_signal_connect (GTK_OBJECT(dialog->deleteSource), "clicked",
- GTK_SIGNAL_FUNC (delete_source_clicked),
- dialog);
-
- l = addressbook_storage_get_sources ();
- for (; l != NULL; l = l->next) {
- AddressbookSource *source;
-
- source = addressbook_source_copy ((AddressbookSource*)l->data);
-
- e_table_memory_store_insert (E_TABLE_MEMORY_STORE (dialog->sourcesModel),
- -1, source, source->name, source->host);
- }
-
- esm = e_table_get_selection_model (et);
- gtk_signal_connect (GTK_OBJECT (esm), "selection_changed",
- GTK_SIGNAL_FUNC (sources_selection_changed), dialog);
-
- sources_selection_changed (esm, dialog);
-
- dialog->page = glade_xml_get_widget (dialog->gui, "addressbook-sources");
-
- return dialog;
-}
-
-static ETableMemoryStoreColumnInfo sources_table_columns[] = {
- E_TABLE_MEMORY_STORE_STRING,
- E_TABLE_MEMORY_STORE_STRING,
- E_TABLE_MEMORY_STORE_TERMINATOR
-};
-
-GtkWidget*
-addressbook_dialog_create_sources_table (char *name, char *string1, char *string2, int num1, int num2)
-{
- GtkWidget *table;
- ETableModel *model;
-
- model = e_table_memory_store_new (sources_table_columns);
-
- table = e_table_scrolled_new_from_spec_file (model,
- NULL,
- EVOLUTION_ETSPECDIR "/addressbook-config.etspec",
- NULL);
-
- gtk_object_set_data (GTK_OBJECT (table), "model", model);
-
- return table;
-}
-#endif /* HAVE_LDAP */
-
-static EvolutionConfigControl *
-ldap_config_control_new (GNOME_Evolution_Shell shell)
-{
- GtkWidget *control_widget;
- EvolutionConfigControl *control;
-
-#ifdef HAVE_LDAP
- AddressbookDialog *dialog;
-
- dialog = ldap_dialog_new (shell);
-
- control_widget = dialog->page;
-
- gtk_widget_ref (control_widget);
-
- gtk_container_remove (GTK_CONTAINER (control_widget->parent), control_widget);
-#else
- control_widget = gtk_label_new (_("LDAP was not enabled in this build of Evolution"));
- gtk_widget_set_sensitive (control_widget, FALSE);
- gtk_widget_show (control_widget);
-#endif
-
- control = evolution_config_control_new (control_widget);
-
-#ifdef HAVE_LDAP
- dialog->config_control = control;
- gtk_signal_connect (GTK_OBJECT (dialog->config_control), "apply",
- GTK_SIGNAL_FUNC (ldap_config_control_apply_callback), dialog);
- gtk_signal_connect (GTK_OBJECT (dialog->config_control), "destroy",
- GTK_SIGNAL_FUNC (ldap_config_control_destroy_callback), dialog);
-
- gtk_widget_unref (dialog->page);
-#endif
-
- return control;
-}
-
-
-/* Implementation of the factory for the configuration control. */
-
-static BonoboGenericFactory *factory = NULL;
-
-static BonoboObject *
-config_control_factory_fn (BonoboGenericFactory *factory,
- const char *component_id,
- void *data)
-{
- GNOME_Evolution_Shell shell;
- EvolutionConfigControl *control;
-
- shell = (GNOME_Evolution_Shell) data;
-
- if (!strcmp (component_id, LDAP_CONFIG_CONTROL_ID)) {
- control = ldap_config_control_new (shell);
- } else {
- control = NULL;
- g_assert_not_reached ();
- }
-
- return BONOBO_OBJECT (control);
-}
-
-gboolean
-addressbook_config_register_factory (GNOME_Evolution_Shell shell)
-{
- g_return_val_if_fail (shell != CORBA_OBJECT_NIL, FALSE);
-
- factory = bonobo_generic_factory_new_multi (CONFIG_CONTROL_FACTORY_ID,
- config_control_factory_fn,
- shell);
-
- if (factory != NULL) {
- return TRUE;
- } else {
- g_warning ("Cannot register factory %s", CONFIG_CONTROL_FACTORY_ID);
- return FALSE;
- }
-}
-
-void
-addressbook_config_create_new_source (const char *new_source, GtkWidget *parent)
-{
-#ifdef HAVE_LDAP
-#if 0
- AddressbookSourceDialog *dialog;
- GladeXML *gui;
-
- gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, NULL);
-
- dialog = addressbook_source_dialog (gui, NULL, parent);
-
- e_utf8_gtk_entry_set_text (GTK_ENTRY (dialog->name), new_source);
-
- gnome_dialog_close_hides (GNOME_DIALOG(dialog->dialog), TRUE);
-
- dialog->id = gnome_dialog_run_and_close (GNOME_DIALOG (dialog->dialog));
-
- gtk_object_unref (GTK_OBJECT (dialog->gui));
-
- if (dialog->id == 0) {
- /* Ok was clicked */
- addressbook_storage_add_source (addressbook_source_copy(dialog->source));
- addressbook_storage_write_sources();
- }
-#endif
-#endif /* HAVE_LDAP */
-}
-
-#ifdef STANDALONE
-int
-main(int argc, char **argv)
-{
- AddressbookDialog *dialog;
-
- gnome_init_with_popt_table ("evolution-addressbook", "0.0",
- argc, argv, oaf_popt_options, 0, NULL);
-
- glade_gnome_init ();
-
- bindtextdomain (PACKAGE, EVOLUTION_LOCALEDIR);
- textdomain (PACKAGE);
-
-#if 0
- g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
-#endif
-
- gtk_widget_push_visual (gdk_rgb_get_visual ());
- gtk_widget_push_colormap (gdk_rgb_get_cmap ());
-
- dialog = ldap_dialog_new (NULL);
-
- gtk_widget_show (glade_xml_get_widget (dialog->gui, "addressbook-sources-window"));
-
- gtk_main();
-
- return 0;
-}
-#endif
diff --git a/addressbook/gui/component/addressbook-config.etspec b/addressbook/gui/component/addressbook-config.etspec
deleted file mode 100644
index e30d11f1f8..0000000000
--- a/addressbook/gui/component/addressbook-config.etspec
+++ /dev/null
@@ -1,9 +0,0 @@
-<ETableSpecification cursor-mode="line">
- <ETableColumn model_col= "0" _title="Account Name" expansion="1.0" minimum_width="20" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col= "1" _title="Server Name" expansion="1.0" minimum_width="20" resizable="true" cell="string" compare="string"/>
- <ETableState>
- <column source="0"/>
- <column source="1"/>
- <grouping></grouping>
- </ETableState>
-</ETableSpecification>
diff --git a/addressbook/gui/component/addressbook-config.h b/addressbook/gui/component/addressbook-config.h
deleted file mode 100644
index 668c55bbd3..0000000000
--- a/addressbook/gui/component/addressbook-config.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* addressbook-storage.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:
- * Chris Toshok <toshok@ximian.com>
- * Chris Lahey <clahey@ximian.com>
- **/
-
-#ifndef __ADDRESSBOOK_CONFIG_H__
-#define __ADDRESSBOOK_CONFIG_H__
-
-#include "addressbook-storage.h"
-
-void addressbook_config_create_new_source (const char *new_source,
- GtkWidget *parent);
-
-gboolean addressbook_config_register_factory (GNOME_Evolution_Shell shell);
-
-#endif /* __ADDRESSBOOK_CONFIG_H__ */
diff --git a/addressbook/gui/component/addressbook-factory.c b/addressbook/gui/component/addressbook-factory.c
deleted file mode 100644
index 6f675894e0..0000000000
--- a/addressbook/gui/component/addressbook-factory.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * sample-control-factory.c
- *
- * Copyright 1999, Ximian, Inc.
- *
- * Author:
- * Nat Friedman (nat@nat.org)
- *
- */
-
-#include <config.h>
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-init.h>
-#include <liboaf/liboaf.h>
-#include <bonobo/bonobo-main.h>
-#include <libgnomevfs/gnome-vfs-init.h>
-#include <glade/glade.h>
-#include <gal/widgets/e-cursors.h>
-#include <e-util/e-passwords.h>
-
-#include <camel/camel.h>
-
-#ifdef GTKHTML_HAVE_GCONF
-#include <gconf/gconf.h>
-#endif
-
-#include "addressbook.h"
-#include "addressbook-component.h"
-#include "e-address-widget.h"
-#include "e-address-popup.h"
-#include "addressbook/gui/widgets/e-minicard-control.h"
-#include "select-names/e-select-names-factory.h"
-
-
-static void
-init_corba (int *argc, char **argv)
-{
- gnome_init_with_popt_table ("evolution-addressbook", "0.0",
- *argc, argv, oaf_popt_options, 0, NULL);
-
- oaf_init (*argc, argv);
-}
-
-static void
-init_bonobo (int argc, char **argv)
-{
- if (bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE)
- g_error (_("Could not initialize Bonobo"));
-
-#ifdef GTKHTML_HAVE_GCONF
- gconf_init (argc, argv, NULL);
-#endif
-
- glade_gnome_init ();
-}
-
-int
-main (int argc, char **argv)
-{
- bindtextdomain (PACKAGE, EVOLUTION_LOCALEDIR);
- textdomain (PACKAGE);
-
- free (malloc (5));
-
- init_corba (&argc, argv);
-
- init_bonobo (argc, argv);
-
- if (!gnome_vfs_init ())
- g_error (_("Could not initialize gnome-vfs"));
-
- /* FIXME: Messy names here. This file should be `main.c'. `addressbook.c' should
- be `addressbook-control-factory.c' and the functions should be called
- `addressbook_control_factory_something()'. And `addressbook-component.c'
- should be `addressbook-component-factory.c'. */
-
- addressbook_factory_init ();
- addressbook_component_factory_init ();
-
- e_select_names_factory_init ();
-
- e_minicard_control_factory_init ();
-
- e_address_widget_factory_init ();
- e_address_popup_factory_init ();
-
- e_cursors_init();
-
- e_passwords_init("Addressbook");
-
-#if 0
- g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
-#endif
-
- /*g_thread_init (NULL);*/
- camel_type_init ();
-
- gtk_widget_push_visual (gdk_rgb_get_visual ());
- gtk_widget_push_colormap (gdk_rgb_get_cmap ());
-
- g_print ("Evolution Addressbook up and running\n");
-
- bonobo_main ();
-
- return 0;
-}
diff --git a/addressbook/gui/component/addressbook-storage.c b/addressbook/gui/component/addressbook-storage.c
deleted file mode 100644
index dcff420a63..0000000000
--- a/addressbook/gui/component/addressbook-storage.c
+++ /dev/null
@@ -1,705 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* e-ldap-storage.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.
- *
- * Author: Chris Toshok
- */
-
-/* The addressbook-sources.xml file goes like this:
-
- <?xml version="1.0"?>
- <addressbooks>
- <contactserver>
- <name>LDAP Server</name>
- <host>ldap.server.com</host>
- <port>389</port>
- <rootdn></rootdn>
- <authmethod>simple</authmethod>
- <emailaddr>toshok@blubag.com</emailaddr>
- <limit>100</limit>
- <rememberpass/>
- </contactserver>
- </addressbooks>
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "addressbook-storage.h"
-
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <gnome-xml/parser.h>
-#include <gnome-xml/xmlmemory.h>
-
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnome/gnome-util.h>
-#include <bonobo/bonobo-object.h>
-
-#include <gal/util/e-unicode-i18n.h>
-#include <gal/util/e-util.h>
-#include <gal/util/e-xml-utils.h>
-#include <libgnome/gnome-i18n.h>
-
-#include "evolution-shell-component.h"
-
-#include "addressbook-config.h"
-
-#define ADDRESSBOOK_SOURCES_XML "addressbook-sources.xml"
-
-#ifdef HAVE_LDAP
-static gboolean load_source_data (const char *file_path);
-#endif
-
-static gboolean save_source_data (const char *file_path);
-static void deregister_storage (void);
-
-static GList *sources;
-static EvolutionStorage *storage;
-static char *storage_path;
-static GNOME_Evolution_Shell corba_shell;
-
-void
-addressbook_storage_setup (EvolutionShellComponent *shell_component,
- const char *evolution_homedir)
-{
- EvolutionShellClient *shell_client;
-
- shell_client = evolution_shell_component_get_owner (shell_component);
- if (shell_client == CORBA_OBJECT_NIL) {
- g_warning ("We have no shell!?");
- return;
- }
-
- corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client));
-
- sources = NULL;
-
- if (storage_path)
- g_free (storage_path);
- storage_path = g_concat_dir_and_file (evolution_homedir, ADDRESSBOOK_SOURCES_XML);
-#ifdef HAVE_LDAP
- if (!load_source_data (storage_path))
- deregister_storage ();
-#endif
-}
-
-#ifdef HAVE_LDAP
-static void
-notify_listener (const Bonobo_Listener listener,
- GNOME_Evolution_Storage_Result corba_result)
-{
- CORBA_any any;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- any._type = TC_GNOME_Evolution_Storage_Result;
- any._value = &corba_result;
-
- Bonobo_Listener_event (listener, "result", &any, &ev);
-
- CORBA_exception_free (&ev);
-}
-
-static void
-remove_ldap_folder (EvolutionStorage *storage, const Bonobo_Listener listener,
- const CORBA_char *path, const CORBA_char *physical_uri,
- gpointer data)
-{
-
- addressbook_storage_remove_source (path + 1);
- addressbook_storage_write_sources();
-
- notify_listener (listener, GNOME_Evolution_Storage_OK);
-}
-
-static void
-create_ldap_folder (EvolutionStorage *storage, const Bonobo_Listener listener,
- const CORBA_char *path, const CORBA_char *type,
- const CORBA_char *description, const CORBA_char *parent_physical_uri,
- gpointer data)
-{
- if (strcmp (type, "contacts")) {
- notify_listener (listener, GNOME_Evolution_Storage_UNSUPPORTED_TYPE);
- return;
- }
-
- if (strcmp (parent_physical_uri, "")) {/* ldap servers can't have subfolders */
- notify_listener (listener, GNOME_Evolution_Storage_INVALID_URI);
- return;
- }
- addressbook_config_create_new_source (path + 1, NULL);
-
- notify_listener (listener, GNOME_Evolution_Storage_OK);
-}
-#endif
-
-
-EvolutionStorage *
-addressbook_get_other_contact_storage (void)
-{
-#ifdef HAVE_LDAP
- EvolutionStorageResult result;
-
- if (storage == NULL) {
- storage = evolution_storage_new (U_("Other Contacts"), FALSE);
- gtk_signal_connect (GTK_OBJECT (storage),
- "remove_folder",
- GTK_SIGNAL_FUNC(remove_ldap_folder), NULL);
- gtk_signal_connect (GTK_OBJECT (storage),
- "create_folder",
- GTK_SIGNAL_FUNC(create_ldap_folder), NULL);
- result = evolution_storage_register_on_shell (storage, corba_shell);
- switch (result) {
- case EVOLUTION_STORAGE_OK:
- break;
- case EVOLUTION_STORAGE_ERROR_GENERIC :
- g_warning("register_storage: generic error");
- break;
- case EVOLUTION_STORAGE_ERROR_CORBA :
- g_warning("register_storage: corba error");
- break;
- case EVOLUTION_STORAGE_ERROR_ALREADYREGISTERED :
- g_warning("register_storage: already registered error");
- break;
- case EVOLUTION_STORAGE_ERROR_EXISTS :
- g_warning("register_storage: already exists error");
- break;
- default:
- g_warning("register_storage: other error");
- break;
- }
- }
-#endif
-
- return storage;
-}
-
-static void
-deregister_storage (void)
-{
- if (evolution_storage_deregister_on_shell (storage, corba_shell) !=
- EVOLUTION_STORAGE_OK) {
- g_warning("couldn't deregister storage");
- }
-
- storage = NULL;
-}
-
-#ifdef HAVE_LDAP
-static char *
-get_string_value (xmlNode *node,
- const char *name)
-{
- xmlNode *p;
- xmlChar *xml_string;
- char *retval;
-
- p = e_xml_get_child_by_name (node, (xmlChar *) name);
- if (p == NULL)
- return NULL;
-
- p = e_xml_get_child_by_name (p, (xmlChar *) "text");
- if (p == NULL) /* there's no text between the tags, return the empty string */
- return g_strdup("");
-
- xml_string = xmlNodeListGetString (node->doc, p, 1);
- retval = g_strdup ((char *) xml_string);
- xmlFree (xml_string);
-
- return retval;
-}
-
-static int
-get_integer_value (xmlNode *node,
- const char *name,
- int defval)
-{
- xmlNode *p;
- xmlChar *xml_string;
- int retval;
-
- p = e_xml_get_child_by_name (node, (xmlChar *) name);
- if (p == NULL)
- return defval;
-
- p = e_xml_get_child_by_name (p, (xmlChar *) "text");
- if (p == NULL) /* there's no text between the tags, return the default */
- return defval;
-
- xml_string = xmlNodeListGetString (node->doc, p, 1);
- retval = atoi (xml_string);
- xmlFree (xml_string);
-
- return retval;
-}
-#endif
-
-static char *
-ldap_unparse_auth (AddressbookLDAPAuthType auth_type)
-{
- switch (auth_type) {
- case ADDRESSBOOK_LDAP_AUTH_NONE:
- return "none";
- case ADDRESSBOOK_LDAP_AUTH_SIMPLE_EMAIL:
- return "ldap/simple-email";
- case ADDRESSBOOK_LDAP_AUTH_SIMPLE_BINDDN:
- return "ldap/simple-binddn";
- default:
- g_assert(0);
- return "none";
- }
-}
-
-#ifdef HAVE_LDAP
-static AddressbookLDAPAuthType
-ldap_parse_auth (const char *auth)
-{
- if (!auth)
- return ADDRESSBOOK_LDAP_AUTH_NONE;
-
- if (!strcmp (auth, "ldap/simple-email") || !strcmp (auth, "simple"))
- return ADDRESSBOOK_LDAP_AUTH_SIMPLE_EMAIL;
- else if (!strcmp (auth, "ldap/simple-binddn"))
- return ADDRESSBOOK_LDAP_AUTH_SIMPLE_BINDDN;
- else
- return ADDRESSBOOK_LDAP_AUTH_NONE;
-}
-#endif
-
-static char *
-ldap_unparse_scope (AddressbookLDAPScopeType scope_type)
-{
- switch (scope_type) {
- case ADDRESSBOOK_LDAP_SCOPE_BASE:
- return "base";
- case ADDRESSBOOK_LDAP_SCOPE_ONELEVEL:
- return "one";
- case ADDRESSBOOK_LDAP_SCOPE_SUBTREE:
- return "sub";
- default:
- g_assert(0);
- return "";
- }
-}
-
-#ifdef HAVE_LDAP
-static AddressbookLDAPScopeType
-ldap_parse_scope (const char *scope)
-{
- if (!scope)
- return ADDRESSBOOK_LDAP_SCOPE_SUBTREE; /* XXX good default? */
-
- if (!strcmp (scope, "base"))
- return ADDRESSBOOK_LDAP_SCOPE_BASE;
- else if (!strcmp (scope, "one"))
- return ADDRESSBOOK_LDAP_SCOPE_ONELEVEL;
- else
- return ADDRESSBOOK_LDAP_SCOPE_SUBTREE;
-}
-#endif
-
-static char *
-ldap_unparse_ssl (AddressbookLDAPSSLType ssl_type)
-{
- switch (ssl_type) {
- case ADDRESSBOOK_LDAP_SSL_NEVER:
- return "never";
- case ADDRESSBOOK_LDAP_SSL_WHENEVER_POSSIBLE:
- return "whenever_possible";
- case ADDRESSBOOK_LDAP_SSL_ALWAYS:
- return "always";
- default:
- g_assert(0);
- return "";
- }
-}
-
-#ifdef HAVE_LDAP
-static AddressbookLDAPSSLType
-ldap_parse_ssl (const char *ssl)
-{
- if (!ssl)
- return ADDRESSBOOK_LDAP_SSL_WHENEVER_POSSIBLE; /* XXX good default? */
-
- if (!strcmp (ssl, "always"))
- return ADDRESSBOOK_LDAP_SSL_ALWAYS;
- else if (!strcmp (ssl, "never"))
- return ADDRESSBOOK_LDAP_SSL_NEVER;
- else
- return ADDRESSBOOK_LDAP_SSL_WHENEVER_POSSIBLE;
-}
-#endif
-
-const char*
-addressbook_storage_auth_type_to_string (AddressbookLDAPAuthType auth_type)
-{
- return ldap_unparse_auth (auth_type);
-}
-
-void
-addressbook_storage_init_source_uri (AddressbookSource *source)
-{
- GString *str;
-
- if (source->uri)
- g_free (source->uri);
-
- str = g_string_new ("ldap://");
-
- g_string_sprintfa (str, "%s:%s/%s?"/*trigraph prevention*/"?%s",
- source->host, source->port, source->rootdn, ldap_unparse_scope (source->scope));
-
- g_string_sprintfa (str, ";limit=%d", source->limit);
-
- g_string_sprintfa (str, ";ssl=%s", ldap_unparse_ssl (source->ssl));
-
-#if 0
- g_string_sprintfa (str, ";timeout=%d", source->timeout);
-#endif
-
- source->uri = str->str;
-
- g_string_free (str, FALSE);
-}
-
-#ifdef HAVE_LDAP
-static gboolean
-load_source_data (const char *file_path)
-{
- xmlDoc *doc;
- xmlNode *root;
- xmlNode *child;
-
- addressbook_get_other_contact_storage();
-
- tryagain:
- doc = xmlParseFile (file_path);
- if (doc == NULL) {
- /* Check to see if a addressbook-sources.xml.new file
- exists. If it does, rename it and try loading it */
- char *new_path = g_strdup_printf ("%s.new", file_path);
- struct stat sb;
-
- if (stat (new_path, &sb) == 0) {
- int rv;
-
- rv = rename (new_path, file_path);
- g_free (new_path);
-
- if (rv < 0) {
- g_error ("Failed to rename %s: %s\n",
- file_path,
- strerror(errno));
- return FALSE;
- } else
- goto tryagain;
- }
-
- g_free (new_path);
- return FALSE;
- }
-
- root = xmlDocGetRootElement (doc);
- if (root == NULL || strcmp (root->name, "addressbooks") != 0) {
- xmlFreeDoc (doc);
- return FALSE;
- }
-
- for (child = root->childs; child; child = child->next) {
- char *path;
- AddressbookSource *source;
-
- source = g_new0 (AddressbookSource, 1);
-
- if (!strcmp (child->name, "contactserver")) {
- source->port = get_string_value (child, "port");
- source->host = get_string_value (child, "host");
- source->rootdn = get_string_value (child, "rootdn");
- source->scope = ldap_parse_scope (get_string_value (child, "scope"));
- source->auth = ldap_parse_auth (get_string_value (child, "authmethod"));
- source->ssl = ldap_parse_ssl (get_string_value (child, "ssl"));
- source->email_addr = get_string_value (child, "emailaddr");
- source->binddn = get_string_value (child, "binddn");
- source->limit = get_integer_value (child, "limit", 100);
- }
- else {
- g_warning ("unknown node '%s' in %s", child->name, file_path);
- g_free (source);
- continue;
- }
-
- addressbook_storage_init_source_uri (source);
-
- source->name = get_string_value (child, "name");
- source->description = get_string_value (child, "description");
-
- path = g_strdup_printf ("/%s", source->name);
- evolution_storage_new_folder (storage, path, source->name,
- "contacts/ldap", source->uri,
- source->description, NULL, 0, FALSE, 0);
-
- sources = g_list_append (sources, source);
-
- g_free (path);
- }
-
- if (g_list_length (sources) == 0)
- deregister_storage();
-
- xmlFreeDoc (doc);
- return TRUE;
-}
-#endif
-
-static void
-ldap_source_foreach(AddressbookSource *source, xmlNode *root)
-{
- xmlNode *source_root = xmlNewNode (NULL,
- (xmlChar *) "contactserver");
-
- xmlAddChild (root, source_root);
-
- xmlNewChild (source_root, NULL, (xmlChar *) "name",
- (xmlChar *) source->name);
- xmlNewChild (source_root, NULL, (xmlChar *) "description",
- (xmlChar *) source->description);
-
- xmlNewChild (source_root, NULL, (xmlChar *) "port",
- (xmlChar *) source->port);
- xmlNewChild (source_root, NULL, (xmlChar *) "host",
- (xmlChar *) source->host);
- xmlNewChild (source_root, NULL, (xmlChar *) "rootdn",
- (xmlChar *) source->rootdn);
- xmlNewChild (source_root, NULL, (xmlChar *) "scope",
- (xmlChar *) ldap_unparse_scope(source->scope));
- xmlNewChild (source_root, NULL, (xmlChar *) "authmethod",
- (xmlChar *) ldap_unparse_auth(source->auth));
- xmlNewChild (source_root, NULL, (xmlChar *) "ssl",
- (xmlChar *) ldap_unparse_ssl(source->ssl));
-
- if (source->limit != 100) {
- char *string;
- string = g_strdup_printf ("%d", source->limit);
- xmlNewChild (source_root, NULL, (xmlChar *) "limit",
- (xmlChar *) string);
- g_free (string);
- }
-
- if (source->auth != ADDRESSBOOK_LDAP_AUTH_NONE) {
- if (source->auth == ADDRESSBOOK_LDAP_AUTH_SIMPLE_BINDDN)
- xmlNewChild (source_root, NULL, (xmlChar *) "binddn",
- (xmlChar *) source->binddn);
- else
- xmlNewChild (source_root, NULL, (xmlChar *) "emailaddr",
- (xmlChar *) source->email_addr);
-
- if (source->remember_passwd)
- xmlNewChild (source_root, NULL, (xmlChar *) "rememberpass",
- NULL);
- }
-}
-
-static gboolean
-save_source_data (const char *file_path)
-{
- xmlDoc *doc;
- xmlNode *root;
- int fd, rv;
- xmlChar *buf;
- int buf_size;
- char *new_path = g_strdup_printf ("%s.new", file_path);
-
- doc = xmlNewDoc ((xmlChar *) "1.0");
- root = xmlNewDocNode (doc, NULL, (xmlChar *) "addressbooks", NULL);
- xmlDocSetRootElement (doc, root);
-
- g_list_foreach (sources, (GFunc)ldap_source_foreach, root);
-
- fd = open (new_path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
- fchmod (fd, 0600);
-
- xmlDocDumpMemory (doc, &buf, &buf_size);
-
- if (buf == NULL) {
- g_error ("Failed to write %s: xmlBufferCreate() == NULL", file_path);
- return FALSE;
- }
-
- rv = write (fd, buf, buf_size);
- xmlFree (buf);
- close (fd);
-
- if (0 > rv) {
- g_error ("Failed to write new %s: %s\n", file_path, strerror(errno));
- unlink (new_path);
- return FALSE;
- }
- else {
- if (0 > rename (new_path, file_path)) {
- g_error ("Failed to rename %s: %s\n", file_path, strerror(errno));
- unlink (new_path);
- return FALSE;
- }
- return TRUE;
- }
-}
-
-void
-addressbook_storage_add_source (AddressbookSource *source)
-{
- char *path;
-
- sources = g_list_append (sources, source);
-
- /* And then to the ui */
- addressbook_get_other_contact_storage();
- path = g_strdup_printf ("/%s", source->name);
- evolution_storage_new_folder (storage, path, source->name, "contacts/ldap",
- source->uri, source->description, NULL, 0, FALSE, 0);
-
- g_free (path);
-}
-
-void
-addressbook_storage_remove_source (const char *name)
-{
- char *path;
- AddressbookSource *source = NULL;
- GList *l;
-
- /* remove it from our hashtable */
- for (l = sources; l; l = l->next) {
- AddressbookSource *s = l->data;
- if (!strcmp (s->name, name)) {
- source = s;
- break;
- }
- }
-
- if (!source)
- return;
-
- sources = g_list_remove_link (sources, l);
- g_list_free_1 (l);
-
- addressbook_source_free (source);
-
- /* and then from the ui */
- path = g_strdup_printf ("/%s", name);
- evolution_storage_removed_folder (storage, path);
-
- if (g_list_length (sources) == 0)
- deregister_storage ();
-
- g_free (path);
-}
-
-GList *
-addressbook_storage_get_sources ()
-{
- return sources;
-}
-
-AddressbookSource *
-addressbook_storage_get_source_by_uri (const char *uri)
-{
- GList *l;
-
- for (l = sources; l ; l = l->next) {
- AddressbookSource *source = l->data;
- if (!strcmp (uri, source->uri))
- return source;
- }
-
- return NULL;
-}
-
-void
-addressbook_source_free (AddressbookSource *source)
-{
- g_free (source->name);
- g_free (source->description);
- g_free (source->uri);
- g_free (source->host);
- g_free (source->port);
- g_free (source->rootdn);
- g_free (source->email_addr);
- g_free (source->binddn);
-
- g_free (source);
-}
-
-static void
-addressbook_source_foreach (AddressbookSource *source, gpointer data)
-{
- char *path = g_strdup_printf ("/%s", source->name);
-
- evolution_storage_removed_folder (storage, path);
-
- g_free (path);
-
- addressbook_source_free (source);
-}
-
-void
-addressbook_storage_clear_sources (void)
-{
- g_list_foreach (sources, (GFunc)addressbook_source_foreach, NULL);
- g_list_free (sources);
- deregister_storage ();
- sources = NULL;
-}
-
-void
-addressbook_storage_write_sources (void)
-{
- save_source_data (storage_path);
-}
-
-AddressbookSource *
-addressbook_source_copy (const AddressbookSource *source)
-{
- AddressbookSource *copy;
-
- copy = g_new0 (AddressbookSource, 1);
- copy->name = g_strdup (source->name);
- copy->description = g_strdup (source->description);
- copy->uri = g_strdup (source->uri);
-
- copy->host = g_strdup (source->host);
- copy->port = g_strdup (source->port);
- copy->rootdn = g_strdup (source->rootdn);
- copy->scope = source->scope;
- copy->auth = source->auth;
- copy->ssl = source->ssl;
- copy->email_addr = g_strdup (source->email_addr);
- copy->binddn = g_strdup (source->binddn);
- copy->remember_passwd = source->remember_passwd;
- copy->limit = source->limit;
-
- return copy;
-}
diff --git a/addressbook/gui/component/addressbook-storage.h b/addressbook/gui/component/addressbook-storage.h
deleted file mode 100644
index 541d8096f7..0000000000
--- a/addressbook/gui/component/addressbook-storage.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* addressbook-storage.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.
- *
- * Author: Chris Toshok
- */
-
-#ifndef __ADDRESSBOOK_STORAGE_H__
-#define __ADDRESSBOOK_STORAGE_H__
-
-#include "evolution-shell-component.h"
-#include "evolution-storage.h"
-
-typedef enum {
- ADDRESSBOOK_LDAP_AUTH_NONE,
- ADDRESSBOOK_LDAP_AUTH_SIMPLE_EMAIL,
- ADDRESSBOOK_LDAP_AUTH_SIMPLE_BINDDN,
-} AddressbookLDAPAuthType;
-
-typedef enum {
- ADDRESSBOOK_LDAP_SCOPE_ONELEVEL,
- ADDRESSBOOK_LDAP_SCOPE_BASE,
- ADDRESSBOOK_LDAP_SCOPE_SUBTREE,
- ADDRESSBOOK_LDAP_SCOPE_LAST
-} AddressbookLDAPScopeType;
-
-typedef enum {
- ADDRESSBOOK_LDAP_SSL_ALWAYS,
- ADDRESSBOOK_LDAP_SSL_WHENEVER_POSSIBLE,
- ADDRESSBOOK_LDAP_SSL_NEVER
-} AddressbookLDAPSSLType;
-
-typedef struct {
- char *name;
- char *description;
- char *host;
- char *port;
- char *rootdn;
- AddressbookLDAPScopeType scope;
- AddressbookLDAPAuthType auth;
- AddressbookLDAPSSLType ssl;
- char *email_addr; /* used in AUTH_SIMPLE_EMAIL */
- char *binddn; /* used in AUTH_SIMPLE_BINDDN */
- gboolean remember_passwd;
- int limit;
-
- char *uri; /* filled in from the above */
-} AddressbookSource;
-
-void addressbook_storage_setup (EvolutionShellComponent *shell_component,
- const char *evolution_homedir);
-
-EvolutionStorage *addressbook_get_other_contact_storage (void);
-GList *addressbook_storage_get_sources (void);
-AddressbookSource *addressbook_storage_get_source_by_uri (const char *uri);
-void addressbook_storage_clear_sources (void);
-void addressbook_storage_write_sources (void);
-AddressbookSource *addressbook_source_copy (const AddressbookSource *source);
-void addressbook_source_free (AddressbookSource *source);
-void addressbook_storage_init_source_uri (AddressbookSource *source);
-
-void addressbook_storage_add_source (AddressbookSource *source);
-void addressbook_storage_remove_source (const char *name);
-const char* addressbook_storage_auth_type_to_string (AddressbookLDAPAuthType auth_type);
-
-#endif /* __ADDRESSBOOK_STORAGE_H__ */
diff --git a/addressbook/gui/component/addressbook.c b/addressbook/gui/component/addressbook.c
deleted file mode 100644
index 23997a9984..0000000000
--- a/addressbook/gui/component/addressbook.c
+++ /dev/null
@@ -1,1192 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * addressbook.c:
- *
- * Author:
- * Chris Lahey (clahey@ximian.com)
- *
- * (C) 2000 Ximian, Inc.
- */
-
-#include <config.h>
-
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-stock.h>
-#include <libgnomeui/gnome-uidefs.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <bonobo/bonobo-exception.h>
-#include <gal/util/e-util.h>
-#include <gal/widgets/e-unicode.h>
-
-#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/printing/e-contact-print.h"
-
-#include <ebook/e-book.h>
-#include <ebook/e-book-util.h>
-#include <widgets/misc/e-search-bar.h>
-#include <widgets/misc/e-filter-bar.h>
-
-/* This is used for the addressbook status bar */
-#define EVOLUTION_CONTACTS_PROGRESS_IMAGE "evolution-contacts-mini.png"
-static GdkPixbuf *progress_icon[2] = { NULL, NULL };
-
-#define d(x)
-
-#define PROPERTY_FOLDER_URI "folder_uri"
-
-#define PROPERTY_FOLDER_URI_IDX 1
-
-typedef struct {
- gint refs;
- EAddressbookView *view;
- ESearchBar *search;
- gint ecml_changed_id;
- GtkWidget *vbox;
- EvolutionActivityClient *activity;
- BonoboControl *control;
- BonoboPropertyBag *properties;
- char *uri;
- char *passwd;
- gboolean ignore_search_changes;
-} AddressbookView;
-
-static void addressbook_view_ref (AddressbookView *);
-static void addressbook_view_unref (AddressbookView *);
-
-static void addressbook_authenticate (EBook *book, gboolean previous_failure,
- AddressbookSource *source, EBookCallback cb, gpointer closure);
-
-static void
-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);
-}
-
-static void
-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);
-}
-
-static void
-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));
-}
-
-static void
-delete_contact_cb (BonoboUIComponent *uih, void *user_data, const char *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- if (view->view) {
- if (e_contact_editor_confirm_delete (GTK_WINDOW (view->view)))
- e_addressbook_view_delete_selection(view->view);
- }
-}
-
-static void
-print_cb (BonoboUIComponent *uih, void *user_data, const char *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- e_addressbook_view_print(view->view);
-}
-
-static void
-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);
-}
-
-static void
-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);
-}
-
-static void
-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);
-}
-
-static void
-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);
-}
-
-static void
-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);
-}
-
-static void
-select_all_contacts_cb (BonoboUIComponent *uih, void *user_data, const char *path)
-{
- AddressbookView *view = (AddressbookView *) user_data;
- if (view->view)
- e_addressbook_view_select_all (view->view);
-}
-
-static void
-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);
-}
-
-static void
-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);
-}
-
-static void
-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);
-}
-
-static void
-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);
-}
-
-static void
-forget_passwords_cb (BonoboUIComponent *uih, void *user_data, const char *path)
-{
- e_passwords_forget_passwords();
-}
-
-static void
-update_command_state (EAddressbookView *eav, AddressbookView *view)
-{
- BonoboUIComponent *uic;
-
- if (view->view == NULL)
- return;
-
- addressbook_view_ref (view);
-
- uic = bonobo_control_get_ui_component (view->control);
-
- if (bonobo_ui_component_get_container (uic) != CORBA_OBJECT_NIL) {
- bonobo_ui_component_set_prop (uic,
- "/commands/ContactsSaveAsVCard",
- "sensitive",
- e_addressbook_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);
-
- /* Print Contact */
- bonobo_ui_component_set_prop (uic,
- "/commands/ContactsPrint",
- "sensitive",
- e_addressbook_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);
-
- /* Delete Contact */
- bonobo_ui_component_set_prop (uic,
- "/commands/ContactDelete",
- "sensitive",
- e_addressbook_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);
- bonobo_ui_component_set_prop (uic,
- "/commands/ContactsCopy",
- "sensitive",
- e_addressbook_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);
- bonobo_ui_component_set_prop (uic,
- "/commands/ContactsSelectAll",
- "sensitive",
- e_addressbook_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);
-
- bonobo_ui_component_set_prop (uic,
- "/commands/ContactsSendMessageToContact",
- "sensitive",
- e_addressbook_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);
- bonobo_ui_component_set_prop (uic,
- "/commands/ContactsCopyToFolder",
- "sensitive",
- e_addressbook_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);
- }
-
- addressbook_view_unref (view);
-}
-
-static void
-change_view_type (AddressbookView *view, EAddressbookViewType view_type)
-{
- gtk_object_set (GTK_OBJECT (view->view), "type", view_type, NULL);
-}
-
-static BonoboUIVerb verbs [] = {
- BONOBO_UI_UNSAFE_VERB ("ContactsPrint", print_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsPrintPreview", print_preview_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsSaveAsVCard", save_contact_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsView", view_contact_cb),
- BONOBO_UI_UNSAFE_VERB ("ToolSearch", search_cb),
-
- BONOBO_UI_UNSAFE_VERB ("ContactDelete", delete_contact_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactStop", stop_loading_cb),
-
- BONOBO_UI_UNSAFE_VERB ("ContactsCut", cut_contacts_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsCopy", copy_contacts_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsPaste", paste_contacts_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsSelectAll", select_all_contacts_cb),
-
- BONOBO_UI_UNSAFE_VERB ("ContactsSendContactToOther", send_contact_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsSendMessageToContact", send_contact_to_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsMoveToFolder", move_contact_to_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsCopyToFolder", copy_contact_to_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactsForgetPasswords", forget_passwords_cb),
-
- BONOBO_UI_VERB_END
-};
-
-static EPixmap pixmaps [] = {
- E_PIXMAP ("/menu/File/FileOps/ContactsSaveAsVCard", "save-as-16.png"),
- E_PIXMAP ("/menu/File/Print/ContactsPrint", "print.xpm"),
- E_PIXMAP ("/menu/File/Print/ContactsPrintPreview", "print-preview.xpm"),
-
- E_PIXMAP ("/menu/EditPlaceholder/Edit/ContactsCut", "16_cut.png"),
- E_PIXMAP ("/menu/EditPlaceholder/Edit/ContactsCopy", "16_copy.png"),
- E_PIXMAP ("/menu/EditPlaceholder/Edit/ContactsPaste", "16_paste.png"),
- E_PIXMAP ("/menu/EditPlaceholder/Edit/ContactDelete", "evolution-trash-mini.png"),
-
- E_PIXMAP ("/menu/Tools/ComponentPlaceholder/ToolSearch", "search-16.png"),
-
- E_PIXMAP ("/Toolbar/ContactsPrint", "buttons/print.png"),
- E_PIXMAP ("/Toolbar/ContactDelete", "buttons/delete-message.png"),
-
- E_PIXMAP_END
-};
-
-static void
-control_activate (BonoboControl *control,
- BonoboUIComponent *uic,
- AddressbookView *view)
-{
- Bonobo_UIContainer remote_ui_container;
-
- remote_ui_container = bonobo_control_get_remote_ui_container (control);
- bonobo_ui_component_set_container (uic, remote_ui_container);
- bonobo_object_release_unref (remote_ui_container, NULL);
-
- e_search_bar_set_ui_component (view->search, uic);
-
- bonobo_ui_component_add_verb_list_with_data (
- uic, verbs, view);
-
- bonobo_ui_component_freeze (uic, NULL);
-
- bonobo_ui_util_set_ui (uic, EVOLUTION_DATADIR,
- "evolution-addressbook.xml",
- "evolution-addressbook");
-
- e_addressbook_view_setup_menus (view->view, uic);
-
- e_pixmaps_update (uic, pixmaps);
-
- bonobo_ui_component_thaw (uic, NULL);
-
- update_command_state (view->view, view);
-}
-
-static void
-control_activate_cb (BonoboControl *control,
- gboolean activate,
- AddressbookView *view)
-{
- BonoboUIComponent *uic;
-
- uic = bonobo_control_get_ui_component (control);
- g_assert (uic != NULL);
-
- if (activate) {
-
- control_activate (control, uic, view);
- if (activate && view->view && view->view->model)
- e_addressbook_model_force_folder_bar_message (view->view->model);
-
- } else {
- bonobo_ui_component_unset_container (uic);
- e_addressbook_view_discard_menus (view->view);
- }
-}
-
-static void
-addressbook_view_ref (AddressbookView *view)
-{
- g_assert (view->refs > 0);
- ++view->refs;
-}
-
-static void
-addressbook_view_unref (AddressbookView *view)
-{
- g_assert (view->refs > 0);
- --view->refs;
- if (view->refs == 0) {
- g_free (view);
- }
-}
-
-static ECategoriesMasterList *
-get_master_list (void)
-{
- static ECategoriesMasterList *category_list = NULL;
-
- if (category_list == NULL)
- category_list = e_categories_master_list_wombat_new ();
- return category_list;
-}
-
-static void
-addressbook_view_clear (AddressbookView *view)
-{
- EBook *book;
-
- if (view->uri && view->view) {
- gtk_object_get(GTK_OBJECT(view->view),
- "book", &book,
- NULL);
- gtk_object_unref (GTK_OBJECT (book));
- }
-
- if (view->properties) {
- bonobo_object_unref (BONOBO_OBJECT(view->properties));
- view->properties = NULL;
- }
-
- if (view->view) {
- gtk_widget_destroy (GTK_WIDGET (view->view));
- view->view = NULL;
- }
-
- g_free(view->passwd);
- view->passwd = NULL;
-
- g_free(view->uri);
- view->uri = NULL;
-
- if (view->refs == 0)
- g_free(view);
-
- if (view->ecml_changed_id != 0) {
- gtk_signal_disconnect (GTK_OBJECT(get_master_list()),
- view->ecml_changed_id);
- view->ecml_changed_id = 0;
- }
-}
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- AddressbookView *view = closure;
-
- if (status == E_BOOK_STATUS_SUCCESS) {
- gtk_object_set(GTK_OBJECT(view->view),
- "book", book,
- NULL);
- }
- else {
- GtkWidget *warning_dialog, *label;
- AddressbookSource *source = NULL;
-
- warning_dialog = gnome_dialog_new (
- _("Unable to open addressbook"),
- GNOME_STOCK_BUTTON_CLOSE,
- NULL);
-
- if (!strncmp (view->uri, "file:", 5)) {
- label = gtk_label_new (
- _("We were unable to open this addressbook. Please check that the\n"
- "path exists and that you have permission to access it."));
- }
- else {
- source = addressbook_storage_get_source_by_uri (view->uri);
-
- if (source) {
- /* special case for ldap: contact folders so we can tell the user about openldap */
-#if HAVE_LDAP
- label = gtk_label_new (
- _("We were unable to open this addressbook. This either\n"
- "means you have entered an incorrect URI, or the LDAP server\n"
- "is unreachable."));
-#else
- label = gtk_label_new (
- _("This version of Evolution does not have LDAP support\n"
- "compiled in to it. If you want to use LDAP in Evolution\n"
- "you must compile the program from the CVS sources after\n"
- "retrieving OpenLDAP from the link below.\n"));
-#endif
- }
- else {
- /* other network folders */
- label = gtk_label_new (
- _("We were unable to open this addressbook. This either\n"
- "means you have entered an incorrect URI, or the server\n"
- "is unreachable."));
- }
- }
-
- gtk_misc_set_alignment(GTK_MISC(label),
- 0, .5);
- gtk_label_set_justify(GTK_LABEL(label),
- GTK_JUSTIFY_LEFT);
-
- gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (warning_dialog)->vbox),
- label, TRUE, TRUE, 0);
- gtk_widget_show (label);
-
-#ifndef HAVE_LDAP
- if (source) {
- GtkWidget *href;
- href = gnome_href_new ("http://www.openldap.org/", "OpenLDAP at http://www.openldap.org/");
- gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (warning_dialog)->vbox),
- href, FALSE, FALSE, 0);
- gtk_widget_show (href);
- }
-#endif
- gnome_dialog_run (GNOME_DIALOG (warning_dialog));
-
- gtk_object_destroy (GTK_OBJECT (warning_dialog));
- }
-}
-
-static void
-destroy_callback(GtkWidget *widget, gpointer data)
-{
- AddressbookView *view = data;
- if (view->view && view->view->model && view->view->model->book_view)
- e_book_view_stop (view->view->model->book_view);
- addressbook_view_clear (view);
- addressbook_view_unref (view);
-}
-
-static void
-get_prop (BonoboPropertyBag *bag,
- BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
-{
- AddressbookView *view = user_data;
-
- switch (arg_id) {
-
- case PROPERTY_FOLDER_URI_IDX:
- if (view && view->uri)
- BONOBO_ARG_SET_STRING (arg, view->uri);
- else
- BONOBO_ARG_SET_STRING (arg, "");
- break;
-
- default:
- g_warning ("Unhandled arg %d\n", arg_id);
- }
-}
-
-typedef struct {
- EBookCallback cb;
- char *clean_uri;
- AddressbookSource *source;
- gpointer closure;
-} LoadUriData;
-
-static void
-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) {
- /* the user clicked cancel in the password dialog */
- gnome_warning_dialog (_("Accessing LDAP Server anonymously"));
- data->cb (book, E_BOOK_STATUS_SUCCESS, data->closure);
- g_free (data->clean_uri);
- g_free (data);
- return;
- }
- else {
- e_passwords_forget_password (data->clean_uri);
- addressbook_authenticate (book, TRUE, data->source, load_uri_auth_cb, closure);
- return;
- }
- }
-
- data->cb (book, status, data->closure);
-
- g_free (data->clean_uri);
- g_free (data);
-}
-
-static void
-addressbook_authenticate (EBook *book, gboolean previous_failure, AddressbookSource *source,
- EBookCallback cb, gpointer closure)
-{
- LoadUriData *load_uri_data = closure;
- const char *password;
- char *pass_dup = NULL;
- char *semicolon;
-
- load_uri_data->clean_uri = g_strdup (e_book_get_uri (book));
-
- semicolon = strchr (load_uri_data->clean_uri, ';');
-
- if (semicolon)
- *semicolon = '\0';
-
- password = e_passwords_get_password (load_uri_data->clean_uri);
-
- if (!password) {
- char *prompt;
- gboolean remember;
- char *failed_auth;
-
- if (previous_failure) {
- failed_auth = _("Failed to authenticate.\n");
- }
- else {
- failed_auth = "";
- }
-
-
- if (source->auth == ADDRESSBOOK_LDAP_AUTH_SIMPLE_BINDDN)
- prompt = g_strdup_printf (_("%sEnter password for %s (user %s)"),
- failed_auth, source->name, source->binddn);
- else
- prompt = g_strdup_printf (_("%sEnter password for %s (user %s)"),
- failed_auth, source->name, source->email_addr);
- remember = source->remember_passwd;
- pass_dup = e_passwords_ask_password (prompt, load_uri_data->clean_uri, prompt, TRUE,
- E_PASSWORDS_REMEMBER_FOREVER, &remember,
- NULL);
- if (remember != source->remember_passwd) {
- source->remember_passwd = remember;
- addressbook_storage_write_sources ();
- }
- g_free (prompt);
- }
-
- if (password || pass_dup) {
- char *user;
-
- if (source->auth == ADDRESSBOOK_LDAP_AUTH_SIMPLE_BINDDN)
- user = source->binddn;
- else
- 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);
- g_free (pass_dup);
- return;
- }
- else {
- /* they hit cancel */
- cb (book, E_BOOK_STATUS_CANCELLED, closure);
- }
-}
-
-static void
-load_uri_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- LoadUriData *load_uri_data = closure;
-
- if (status == E_BOOK_STATUS_SUCCESS && book != NULL) {
-
- /* check if the addressbook needs authentication */
-
- load_uri_data->source = addressbook_storage_get_source_by_uri (e_book_get_uri (book));
-
- if (load_uri_data->source &&
- load_uri_data->source->auth != ADDRESSBOOK_LDAP_AUTH_NONE) {
-
- addressbook_authenticate (book, FALSE, load_uri_data->source,
- load_uri_auth_cb, closure);
-
- return;
- }
- }
-
- load_uri_data->cb (book, status, load_uri_data->closure);
- g_free (load_uri_data);
-}
-
-gboolean
-addressbook_load_uri (EBook *book, const char *uri,
- EBookCallback cb, gpointer closure)
-{
- LoadUriData *load_uri_data = g_new0 (LoadUriData, 1);
- gboolean rv;
-
- load_uri_data->cb = cb;
- load_uri_data->closure = closure;
-
- rv = e_book_load_uri (book, uri, load_uri_cb, load_uri_data);
-
- if (!rv)
- g_free (load_uri_data);
-
- return rv;
-}
-
-gboolean
-addressbook_load_default_book (EBook *book, EBookCallback cb, gpointer closure)
-{
- LoadUriData *load_uri_data = g_new (LoadUriData, 1);
- gboolean rv;
-
- load_uri_data->cb = cb;
- load_uri_data->closure = closure;
-
- rv = e_book_load_default_book (book, load_uri_cb, load_uri_data);
-
- if (!rv)
- g_free (load_uri_data);
-
- return rv;
-}
-
-static void
-set_prop (BonoboPropertyBag *bag,
- const BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
-{
- AddressbookView *view = user_data;
-
- char *uri_data;
- EBook *book;
-
- switch (arg_id) {
-
- case PROPERTY_FOLDER_URI_IDX:
- gtk_object_get(GTK_OBJECT(view->view),
- "book", &book,
- NULL);
- if (view->uri) {
- /* we've already had a uri set on this view, so unload it */
- e_book_unload_uri (book);
- g_free (view->uri);
- } else {
- book = e_book_new ();
- }
-
- view->uri = g_strdup(BONOBO_ARG_GET_STRING (arg));
-
- uri_data = e_book_expand_uri (view->uri);
-
- if (! addressbook_load_uri (book, uri_data, book_open_cb, view))
- printf ("error calling load_uri!\n");
-
- g_free(uri_data);
-
- break;
-
- default:
- g_warning ("Unhandled arg %d\n", arg_id);
- break;
- }
-}
-
-enum {
- ESB_FULL_NAME,
- ESB_EMAIL,
- ESB_CATEGORY,
- ESB_ANY,
- ESB_ADVANCED
-};
-
-static ESearchBarItem addressbook_search_option_items[] = {
- { N_("Name begins with"), ESB_FULL_NAME, NULL },
- { N_("Email begins with"), ESB_EMAIL, NULL },
- { N_("Category is"), ESB_CATEGORY, NULL }, /* We attach subitems below */
- { N_("Any field contains"), ESB_ANY, NULL },
- { N_("Advanced..."), ESB_ADVANCED, NULL },
- { NULL, -1, NULL }
-};
-
-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;
- char *search_word, *search_query;
- const char *category_name;
- int search_type, subid;
-
- if (view->ignore_search_changes) {
- return;
- }
-
- gtk_object_get(GTK_OBJECT(esb),
- "text", &search_word,
- "item_id", &search_type,
- NULL);
-
- if (search_type == ESB_ADVANCED) {
- gtk_widget_show(e_addressbook_search_dialog_new(view->view));
- }
- else {
- if ((search_word && strlen (search_word)) || search_type == ESB_CATEGORY) {
- GString *s = g_string_new ("");
- e_sexp_encode_string (s, search_word);
- switch (search_type) {
- case ESB_ANY:
- search_query = g_strdup_printf ("(contains \"x-evolution-any-field\" %s)",
- s->str);
- break;
- case ESB_FULL_NAME:
- search_query = g_strdup_printf ("(beginswith \"full_name\" %s)",
- s->str);
- break;
- case ESB_EMAIL:
- search_query = g_strdup_printf ("(beginswith \"email\" %s)",
- s->str);
- break;
- case ESB_CATEGORY:
- subid = e_search_bar_get_subitem_id (esb);
-
- if (subid < 0 || subid == G_MAXINT) {
- /* match everything */
- search_query = g_strdup ("(contains \"x-evolution-any-field\" \"\")");
- } else {
- master_list = get_master_list ();
- category_name = e_categories_master_list_nth (master_list, subid);
- search_query = g_strdup_printf ("(is \"category\" \"%s\")", category_name);
- }
- break;
- default:
- search_query = g_strdup ("(contains \"x-evolution-any-field\" \"\")");
- break;
- }
- g_string_free (s, TRUE);
- } else
- search_query = g_strdup ("(contains \"x-evolution-any-field\" \"\")");
-
- if (search_query)
- gtk_object_set (GTK_OBJECT(view->view),
- "query", search_query,
- NULL);
-
- g_free (search_query);
- }
-
- g_free (search_word);
-}
-
-static void
-addressbook_query_changed (ESearchBar *esb, AddressbookView *view)
-{
- int search_type;
-
- gtk_object_get(GTK_OBJECT(esb),
- "item_id", &search_type,
- NULL);
-
- if (search_type == ESB_ADVANCED) {
- gtk_widget_show(e_addressbook_search_dialog_new(view->view));
- }
-}
-
-static GNOME_Evolution_ShellView
-retrieve_shell_view_interface_from_control (BonoboControl *control)
-{
- Bonobo_ControlFrame control_frame;
- GNOME_Evolution_ShellView shell_view_interface;
- CORBA_Environment ev;
-
- shell_view_interface = gtk_object_get_data (GTK_OBJECT (control),
- "shell_view_interface");
-
- if (shell_view_interface)
- return shell_view_interface;
-
- control_frame = bonobo_control_get_control_frame (control);
-
- if (control_frame == NULL)
- return CORBA_OBJECT_NIL;
-
- CORBA_exception_init (&ev);
- shell_view_interface = Bonobo_Unknown_queryInterface (control_frame,
- "IDL:GNOME/Evolution/ShellView:1.0",
- &ev);
- CORBA_exception_free (&ev);
-
- if (shell_view_interface != CORBA_OBJECT_NIL)
- gtk_object_set_data (GTK_OBJECT (control),
- "shell_view_interface",
- shell_view_interface);
- else
- g_warning ("Control frame doesn't have Evolution/ShellView.");
-
- return shell_view_interface;
-}
-
-static void
-set_status_message (EAddressbookView *eav, const char *message, AddressbookView *view)
-{
-
- if (!message || !*message) {
- if (view->activity) {
- gtk_object_unref (GTK_OBJECT (view->activity));
- view->activity = NULL;
- }
- }
- else if (!view->activity) {
- int display;
- char *clientid = g_strdup_printf ("%p", view);
-
- if (progress_icon[0] == NULL)
- progress_icon[0] = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_CONTACTS_PROGRESS_IMAGE);
-
- view->activity = evolution_activity_client_new (addressbook_component_get_shell_client(), clientid,
- progress_icon, message, TRUE, &display);
-
- g_free (clientid);
- }
- else {
- evolution_activity_client_update (view->activity, message, -1.0);
- }
-
-}
-
-static void
-search_result (EAddressbookView *eav, EBookViewStatus status, AddressbookView *view)
-{
- char *str = NULL;
-
- switch (status) {
- case E_BOOK_VIEW_STATUS_SUCCESS:
- return;
- case E_BOOK_VIEW_STATUS_SIZE_LIMIT_EXCEEDED:
- str = _("More cards matched this query than either the server is \n"
- "configured to return or Evolution is configured to display.\n"
- "Please make your search more specific or raise the result limit in\n"
- "the directory server preferences for this addressbook.");
- break;
- case E_BOOK_VIEW_STATUS_TIME_LIMIT_EXCEEDED:
- str = _("The time to execute this query exceeded the server limit or the limit\n"
- "you have configured for this addressbook. Please make your search\n"
- "more specific or raise the time limit in the directory server\n"
- "preferences for this addressbook.");
- break;
- case E_BOOK_VIEW_STATUS_INVALID_QUERY:
- str = _("The backend for this addressbook was unable to parse this query.");
- break;
- case E_BOOK_VIEW_STATUS_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:
- str = _("This query did not complete successfully.");
- break;
- }
-
- if (str)
- gnome_warning_dialog (str);
-}
-
-static void
-set_folder_bar_label (EAddressbookView *eav, const char *message, AddressbookView *view)
-{
- CORBA_Environment ev;
- GNOME_Evolution_ShellView shell_view_interface;
-
- CORBA_exception_init (&ev);
-
- shell_view_interface = retrieve_shell_view_interface_from_control (view->control);
- if (!shell_view_interface) {
- CORBA_exception_free (&ev);
- return;
- }
-
- d(g_message("Updating via ShellView"));
-
- if (message == NULL || message[0] == 0) {
- GNOME_Evolution_ShellView_setFolderBarLabel (shell_view_interface,
- "",
- &ev);
- }
- else {
- GNOME_Evolution_ShellView_setFolderBarLabel (shell_view_interface,
- message,
- &ev);
- }
-
- if (BONOBO_EX (&ev))
- g_warning ("Exception in label update: %s",
- bonobo_exception_get_text (&ev));
-
- CORBA_exception_free (&ev);
-}
-
-/* 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)
-{
- const ESearchBarSubitem *subitem_a = a;
- const ESearchBarSubitem *subitem_b = b;
-
- return strcoll (subitem_a->text, subitem_b->text);
-}
-
-static void
-make_suboptions (AddressbookView *view)
-{
- ESearchBarSubitem *subitems;
- ECategoriesMasterList *master_list;
- gint i, N;
-
- master_list = get_master_list ();
- N = e_categories_master_list_count (master_list);
- subitems = g_new (ESearchBarSubitem, N+2);
-
- subitems[0].id = G_MAXINT;
- subitems[0].text = g_strdup (_("Any Category"));
- subitems[0].translate = FALSE;
-
- for (i=0; i<N; ++i) {
- const char *category = e_categories_master_list_nth (master_list, i);
-
- subitems[i+1].id = i;
- subitems[i+1].text = e_utf8_to_locale_string (category);
- subitems[i+1].translate = FALSE;
- }
- subitems[N+1].id = -1;
- subitems[N+1].text = NULL;
-
- qsort (subitems + 1, N, sizeof (subitems[0]), compare_subitems);
-
- e_search_bar_set_suboption (view->search, ESB_CATEGORY, subitems);
-}
-
-static void
-ecml_changed (ECategoriesMasterList *ecml, AddressbookView *view)
-{
- make_suboptions (view);
-}
-
-static void
-connect_master_list_changed (AddressbookView *view)
-{
- view->ecml_changed_id =
- gtk_signal_connect (GTK_OBJECT (get_master_list()), "changed",
- GTK_SIGNAL_FUNC (ecml_changed), view);
-}
-
-BonoboControl *
-addressbook_factory_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;
- view->ignore_search_changes = FALSE;
-
- view->vbox = gtk_vbox_new (FALSE, 0);
-
- gtk_signal_connect (GTK_OBJECT (view->vbox), "destroy",
- GTK_SIGNAL_FUNC (destroy_callback),
- (gpointer) view);
-
- /* Create the control. */
- view->control = bonobo_control_new (view->vbox);
-
- view->search = E_SEARCH_BAR (e_search_bar_new (NULL, addressbook_search_option_items));
- make_suboptions (view);
- connect_master_list_changed (view);
-
- gtk_box_pack_start (GTK_BOX (view->vbox), GTK_WIDGET (view->search),
- FALSE, FALSE, 0);
- gtk_signal_connect (GTK_OBJECT (view->search), "query_changed",
- GTK_SIGNAL_FUNC (addressbook_query_changed), view);
- gtk_signal_connect (GTK_OBJECT (view->search), "search_activated",
- GTK_SIGNAL_FUNC (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,
- TRUE, TRUE, 0);
-
- /* create the initial view */
- change_view_type (view, E_ADDRESSBOOK_VIEW_MINICARD);
-
- gtk_widget_show (frame);
- gtk_widget_show (view->vbox);
- gtk_widget_show (GTK_WIDGET(view->view));
- gtk_widget_show (GTK_WIDGET(view->search));
-
- view->properties = bonobo_property_bag_new (get_prop, set_prop, view);
-
- 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_control_set_properties (view->control,
- view->properties);
-
- gtk_signal_connect (GTK_OBJECT (view->view),
- "status_message",
- GTK_SIGNAL_FUNC(set_status_message),
- view);
-
- gtk_signal_connect (GTK_OBJECT (view->view),
- "search_result",
- GTK_SIGNAL_FUNC(search_result),
- view);
-
- gtk_signal_connect (GTK_OBJECT (view->view),
- "folder_bar_message",
- GTK_SIGNAL_FUNC(set_folder_bar_label),
- view);
-
- gtk_signal_connect (GTK_OBJECT (view->view),
- "command_state_change",
- GTK_SIGNAL_FUNC(update_command_state),
- view);
-
- gtk_signal_connect (GTK_OBJECT (view->view),
- "alphabet_state_change",
- GTK_SIGNAL_FUNC(alphabet_state_changed),
- view);
-
- view->uri = NULL;
-
- gtk_signal_connect (GTK_OBJECT (view->control), "activate",
- control_activate_cb, view);
-
- return view->control;
-}
-
-static BonoboObject *
-addressbook_factory (BonoboGenericFactory *Factory, void *closure)
-{
- return BONOBO_OBJECT (addressbook_factory_new_control ());
-}
-
-void
-addressbook_factory_init (void)
-{
- static BonoboGenericFactory *addressbook_control_factory = NULL;
-
- if (addressbook_control_factory != NULL)
- return;
-
- addressbook_control_factory = bonobo_generic_factory_new (
- "OAFIID:GNOME_Evolution_Addressbook_ControlFactory",
- addressbook_factory, NULL);
-
- if (addressbook_control_factory == NULL) {
- g_error ("I could not register a Addressbook factory.");
- }
-}
-
diff --git a/addressbook/gui/component/addressbook.h b/addressbook/gui/component/addressbook.h
deleted file mode 100644
index 6fb82b710d..0000000000
--- a/addressbook/gui/component/addressbook.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __ADDRESSBOOK_H__
-#define __ADDRESSBOOK_H__
-
-#include <bonobo/bonobo-control.h>
-#include <bonobo-conf/bonobo-config-database.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-moniker-util.h>
-#include <ebook/e-book.h>
-
-Bonobo_ConfigDatabase addressbook_config_database (CORBA_Environment *ev);
-
-/* use this instead of e_book_load_uri everywhere where you want the
- authentication to be handled for you. */
-gboolean addressbook_load_uri (EBook *book, const char *uri, EBookCallback cb, gpointer closure);
-gboolean addressbook_load_default_book (EBook *book, EBookCallback open_response, gpointer closure);
-
-BonoboControl *addressbook_factory_new_control (void);
-void addressbook_factory_init (void);
-
-#endif /* __ADDRESSBOOK_H__ */
diff --git a/addressbook/gui/component/e-address-popup.c b/addressbook/gui/component/e-address-popup.c
deleted file mode 100644
index 553ba642c8..0000000000
--- a/addressbook/gui/component/e-address-popup.c
+++ /dev/null
@@ -1,1279 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-address-popup.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.
- */
-
-/*
- * This file is too big and this widget is too complicated. Forgive me.
- */
-
-#include <config.h>
-#include "addressbook.h"
-#include "e-address-popup.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 <gal/widgets/e-unicode.h>
-#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-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>
-
-/*
- * 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
- * we really need it to be).
- */
-
-typedef struct _MiniWizard MiniWizard;
-struct _MiniWizard {
- GtkWidget *body;
-
- GtkWidget *vbox;
- GtkWidget *ok_button;
- GtkWidget *cancel_button;
-
- void (*ok_cb) (MiniWizard *, gpointer);
- void (*cleanup_cb) (gpointer);
- gpointer closure;
-
- void (*destroy_cb) (MiniWizard *, gpointer);
- gpointer destroy_closure;
-};
-
-static void
-mini_wizard_container_add (MiniWizard *wiz, GtkWidget *w)
-{
- GList *iter = gtk_container_children (GTK_CONTAINER (wiz->vbox));
- while (iter != NULL) {
- GtkWidget *oldw = (GtkWidget *) iter->data;
- iter = g_list_next (iter);
- gtk_container_remove (GTK_CONTAINER (wiz->vbox), oldw);
- gtk_widget_destroy (oldw);
- }
- gtk_container_add (GTK_CONTAINER (wiz->vbox), w);
-}
-
-static void
-mini_wizard_destroy (MiniWizard *wiz)
-{
- if (wiz->cleanup_cb)
- wiz->cleanup_cb (wiz->closure);
- wiz->cleanup_cb = NULL;
-
- if (wiz->destroy_cb)
- wiz->destroy_cb (wiz, wiz->destroy_closure);
-}
-
-static void
-mini_wizard_ok_cb (GtkWidget *b, gpointer closure)
-{
- MiniWizard *wiz = (MiniWizard *) closure;
-
- gpointer old_closure = wiz->closure;
- void (*old_cleanup) (gpointer) = wiz->cleanup_cb;
-
- wiz->cleanup_cb = NULL;
-
- if (wiz->ok_cb)
- wiz->ok_cb (wiz, wiz->closure);
-
- if (old_cleanup)
- old_cleanup (old_closure);
-
-}
-
-static void
-mini_wizard_cancel_cb (GtkWidget *b, gpointer closure)
-{
- mini_wizard_destroy ((MiniWizard *) closure);
-}
-
-static void
-mini_wizard_destroy_cb (GtkWidget *w, gpointer closure)
-{
- MiniWizard *wiz = (MiniWizard *) closure;
- if (wiz->cleanup_cb)
- wiz->cleanup_cb (wiz->closure);
- g_free (wiz);
-}
-
-static MiniWizard *
-mini_wizard_new (void)
-{
- MiniWizard *wiz = g_new (MiniWizard, 1);
- GtkWidget *hbox;
-
- wiz->body = gtk_vbox_new (FALSE, 2);
- wiz->vbox = gtk_vbox_new (FALSE, 2);
- wiz->ok_button = gnome_stock_button (GNOME_STOCK_BUTTON_OK);
- wiz->cancel_button = gnome_stock_button (GNOME_STOCK_BUTTON_CANCEL);
-
- wiz->ok_cb = NULL;
- wiz->cleanup_cb = NULL;
- wiz->closure = NULL;
-
- wiz->destroy_cb = NULL;
- wiz->destroy_closure = NULL;
-
- hbox = gtk_hbox_new (FALSE, 2);
- gtk_box_pack_start (GTK_BOX (hbox), wiz->ok_button, TRUE, FALSE, 2);
- gtk_box_pack_start (GTK_BOX (hbox), wiz->cancel_button, TRUE, FALSE, 2);
-
- gtk_box_pack_start (GTK_BOX (wiz->body), wiz->vbox, TRUE, TRUE, 2);
- gtk_box_pack_start (GTK_BOX (wiz->body), gtk_hseparator_new (), FALSE, TRUE, 2);
- gtk_box_pack_start (GTK_BOX (wiz->body), hbox, FALSE, TRUE, 2);
-
- gtk_widget_show_all (wiz->body);
-
- gtk_signal_connect (GTK_OBJECT (wiz->ok_button),
- "clicked",
- GTK_SIGNAL_FUNC (mini_wizard_ok_cb),
- wiz);
- gtk_signal_connect (GTK_OBJECT (wiz->cancel_button),
- "clicked",
- GTK_SIGNAL_FUNC (mini_wizard_cancel_cb),
- wiz);
- gtk_signal_connect (GTK_OBJECT (wiz->body),
- "destroy",
- GTK_SIGNAL_FUNC (mini_wizard_destroy_cb),
- wiz);
-
- return wiz;
-
-}
-
-
-
-/*
- * 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.
- */
-
-#define EMPTY_ENTRY N_("(none)")
-
-typedef struct _EMailMenu EMailMenu;
-struct _EMailMenu {
- GtkWidget *option_menu;
- GList *options;
- gchar *current_selection;
-};
-
-static void
-email_menu_free (EMailMenu *menu)
-{
- if (menu == NULL)
- return;
-
- g_list_foreach (menu->options, (GFunc) g_free, NULL);
- g_list_free (menu->options);
- g_free (menu);
-}
-
-static EMailMenu *
-email_menu_new (void)
-{
- EMailMenu *menu = g_new (EMailMenu, 1);
-
- menu->option_menu = gtk_option_menu_new ();
- menu->options = NULL;
- menu->current_selection = NULL;
-
- gtk_option_menu_set_menu (GTK_OPTION_MENU (menu->option_menu), gtk_menu_new ());
-
- return menu;
-}
-
-static void
-menu_activate_cb (GtkWidget *w, gpointer closure)
-{
- EMailMenu *menu = (EMailMenu *) closure;
- gchar *addr = (gchar *) gtk_object_get_data (GTK_OBJECT (w), "addr");
-
- menu->current_selection = addr;
-}
-
-static void
-email_menu_add_option (EMailMenu *menu, const gchar *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_item = gtk_menu_item_new_with_label (addr);
- gtk_object_set_data (GTK_OBJECT (menu_item), "addr", addr_cpy);
- gtk_widget_show_all (menu_item);
- gtk_menu_append (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (menu->option_menu))), menu_item);
-
- gtk_signal_connect (GTK_OBJECT (menu_item),
- "activate",
- menu_activate_cb,
- menu);
-}
-
-static void
-email_menu_add_options_from_card (EMailMenu *menu, ECard *card, const gchar *extra_addr)
-{
- ECardSimple *simple;
-
- g_return_if_fail (card && E_IS_CARD (card));
-
- simple = e_card_simple_new (card);
-
- /* 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, EMPTY_ENTRY);
-
- gtk_object_unref (GTK_OBJECT (simple));
-}
-
-static void
-email_menu_set_option (EMailMenu *menu, const gchar *addr)
-{
- guint count = 0;
- GList *iter;
-
- g_return_if_fail (menu != NULL);
-
- if (addr == NULL) {
- email_menu_set_option (menu, EMPTY_ENTRY);
- return;
- }
-
- iter = menu->options;
- while (iter && strcmp (addr, (gchar *) iter->data)) {
- ++count;
- iter = g_list_next (iter);
- }
-
- if (iter) {
- gtk_option_menu_set_history (GTK_OPTION_MENU (menu->option_menu), count);
- menu->current_selection = (gchar *) iter->data;
- }
-}
-
-#ifdef UNDEFINED_FUNCTIONS_SHOULD_PLEASE_BE_INCLUDED
-static void
-email_menu_unset_option (EMailMenu *menu, const gchar *addr)
-{
- GList *iter;
-
- g_return_if_fail (menu != NULL);
- g_return_if_fail (addr != NULL);
-
- if (menu->current_selection == NULL || strcmp (addr, menu->current_selection))
- return;
-
- iter = menu->options;
- while (iter && strcmp (addr, (gchar *) iter->data)) {
- iter = g_list_next (iter);
- }
- if (iter) {
- iter = g_list_next (iter);
- if (iter) {
- email_menu_set_option (menu, (gchar *) iter->data);
- } else {
- email_menu_set_option (menu, EMPTY_ENTRY);
- }
- }
-}
-#endif
-
-
-
-typedef struct _EMailTable EMailTable;
-struct _EMailTable {
- GtkWidget *table;
- ECard *card;
- EMailMenu *primary;
- EMailMenu *email2;
- EMailMenu *email3;
-};
-
-static void
-email_table_cleanup_cb (gpointer closure)
-{
- EMailTable *et = (EMailTable *) closure;
-
- if (et == NULL)
- return;
-
- gtk_object_unref (GTK_OBJECT (et->card));
- email_menu_free (et->primary);
- email_menu_free (et->email2);
- email_menu_free (et->email3);
-
- g_free (et);
-}
-
-static void
-email_table_from_card (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));
- gtk_object_unref (GTK_OBJECT (simple));
-}
-
-static void
-email_table_to_card (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);
-
- 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);
-
- 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);
- gtk_object_unref (GTK_OBJECT (simple));
-}
-
-static void
-email_table_save_card_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- ECard *card = E_CARD (closure);
-
- if (book) {
- e_book_commit_card (book, card, NULL, NULL);
- gtk_object_unref (GTK_OBJECT (book));
- }
- gtk_object_unref (GTK_OBJECT (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 ();
- if (!addressbook_load_default_book (book, email_table_save_card_cb, closure)) {
- gtk_object_unref (GTK_OBJECT (book));
- email_table_save_card_cb (NULL, E_BOOK_STATUS_OTHER_ERROR, closure);
- }
-
- return 0;
-}
-
-static void
-email_table_ok_cb (MiniWizard *wiz, gpointer closure)
-{
- EMailTable *et = (EMailTable *) closure;
-
- email_table_to_card (et);
-
- gtk_object_ref (GTK_OBJECT (et->card));
- gtk_idle_add (add_card_idle_cb, et->card);
-
- mini_wizard_destroy (wiz);
-}
-
-static void
-email_table_init (MiniWizard *wiz, ECard *card, const gchar *extra_address)
-{
- EMailTable *et;
-
- gchar *name_str;
- gint xpad, ypad;
- GtkAttachOptions label_x_opts, label_y_opts;
- GtkAttachOptions menu_x_opts, menu_y_opts;
-
- g_return_if_fail (card && E_IS_CARD (card));
-
- et = g_new (EMailTable, 1);
-
- et->card = card;
- gtk_object_ref (GTK_OBJECT (et->card));
-
- et->table = gtk_table_new (4, 2, FALSE);
-
- et->primary = email_menu_new ();
- 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_table_from_card (et);
-
- label_x_opts = GTK_FILL;
- label_y_opts = GTK_FILL;
- menu_x_opts = GTK_EXPAND | GTK_FILL;
- menu_y_opts = GTK_EXPAND | GTK_FILL;
- xpad = 3;
- ypad = 3;
-
- name_str = e_card_name_to_string (et->card->name);
- gtk_table_attach (GTK_TABLE (et->table),
- gtk_label_new (name_str),
- 0, 2, 0, 1,
- label_x_opts, label_y_opts, xpad, ypad);
- g_free (name_str);
-
- gtk_table_attach (GTK_TABLE (et->table),
- gtk_label_new (_("Primary Email")),
- 0, 1, 1, 2,
- label_x_opts, label_y_opts, xpad, ypad);
-
- gtk_table_attach (GTK_TABLE (et->table),
- et->primary->option_menu,
- 1, 2, 1, 2,
- menu_x_opts, menu_y_opts, xpad, ypad);
-
- gtk_table_attach (GTK_TABLE (et->table),
- gtk_label_new (_("Email 2")),
- 0, 1, 2, 3,
- label_x_opts, label_y_opts, xpad, ypad);
-
- gtk_table_attach (GTK_TABLE (et->table),
- et->email2->option_menu,
- 1, 2, 2, 3,
- menu_x_opts, menu_y_opts, xpad, ypad);
-
- gtk_table_attach (GTK_TABLE (et->table),
- gtk_label_new (_("Email 3")),
- 0, 1, 3, 4,
- label_x_opts, label_y_opts, xpad, ypad);
-
- gtk_table_attach (GTK_TABLE (et->table),
- et->email3->option_menu,
- 1, 2, 3, 4,
- menu_x_opts, menu_y_opts, xpad, ypad);
-
- gtk_widget_show_all (et->primary->option_menu);
- gtk_widget_show_all (et->email2->option_menu);
- gtk_widget_show_all (et->email3->option_menu);
-
- gtk_widget_show_all (et->table);
- mini_wizard_container_add (wiz, et->table);
- wiz->ok_cb = email_table_ok_cb;
- wiz->cleanup_cb = email_table_cleanup_cb;
- wiz->closure = et;
-}
-
-/*
- * This code is for the little UI thing that lets you pick from a set of cards
- * and decide which one you want to add the e-mail address to.
- */
-
-typedef struct _CardPicker CardPicker;
-struct _CardPicker {
- GtkWidget *body;
- GtkWidget *clist;
- GList *cards;
- gchar *new_name;
- gchar *new_email;
-
- gint current_row;
-};
-
-static void
-card_picker_row_select_cb (GtkCList *clist, gint row, gint col, GdkEventButton *ev, gpointer closure)
-{
- MiniWizard *wiz = (MiniWizard *) closure;
- CardPicker *pick = (CardPicker *) wiz->closure;
- pick->current_row = row;
- gtk_widget_set_sensitive (wiz->ok_button, TRUE);
-}
-
-static void
-card_picker_row_unselect_cb (GtkCList *clist, gint row, gint col, GdkEventButton *ev, gpointer closure)
-{
- MiniWizard *wiz = (MiniWizard *) closure;
- CardPicker *pick = (CardPicker *) wiz->closure;
- pick->current_row = -1;
- gtk_widget_set_sensitive (wiz->ok_button, FALSE);
-}
-
-static void
-card_picker_ok_cb (MiniWizard *wiz, gpointer closure)
-{
- CardPicker *pick = (CardPicker *) closure;
- g_return_if_fail (pick->current_row >= 0);
-
- if (pick->current_row == 0) {
- e_contact_quick_add (pick->new_name, pick->new_email, NULL, NULL);
- mini_wizard_destroy (wiz);
- } else {
- ECard *card = (ECard *) g_list_nth_data (pick->cards, pick->current_row-1);
- email_table_init (wiz, card, pick->new_email);
- }
-}
-
-static void
-card_picker_cleanup_cb (gpointer closure)
-{
- CardPicker *pick = (CardPicker *) closure;
-
- g_list_foreach (pick->cards, (GFunc) gtk_object_unref, NULL);
- g_list_free (pick->cards);
-
- g_free (pick->new_name);
- g_free (pick->new_email);
-}
-
-static void
-card_picker_init (MiniWizard *wiz, const GList *cards, const gchar *new_name, const gchar *new_email)
-{
- CardPicker *pick;
- gchar *str;
- GtkWidget *w, *swin;
-
- pick = g_new (CardPicker, 1);
-
- pick->body = gtk_vbox_new (FALSE, 2);
-
- pick->clist = gtk_clist_new (1);
- gtk_clist_set_column_title (GTK_CLIST (pick->clist), 0, _("Select an Action"));
- gtk_clist_column_titles_show (GTK_CLIST (pick->clist));
- gtk_clist_set_selection_mode (GTK_CLIST (pick->clist), GTK_SELECTION_SINGLE);
-
- gtk_clist_freeze (GTK_CLIST (pick->clist));
-
- str = g_strdup_printf (_("Create a new contact \"%s\""), new_name);
- gtk_clist_append (GTK_CLIST (pick->clist), &str);
- g_free (str);
-
- pick->cards = NULL;
- while (cards) {
- ECard *card = (ECard *) cards->data;
- gchar *name_str = e_card_name_to_string (card->name);
-
- pick->cards = g_list_append (pick->cards, card);
- gtk_object_ref (GTK_OBJECT (card));
-
- str = g_strdup_printf (_("Add address to existing contact \"%s\""), name_str);
- gtk_clist_append (GTK_CLIST (pick->clist), &str);
- g_free (name_str);
- g_free (str);
-
- cards = g_list_next (cards);
- }
-
- gtk_clist_thaw (GTK_CLIST (pick->clist));
-
- pick->new_name = g_strdup (new_name);
- pick->new_email = g_strdup (new_email);
-
- pick->current_row = -1;
- 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;
-
- gtk_signal_connect (GTK_OBJECT (pick->clist),
- "select-row",
- GTK_SIGNAL_FUNC (card_picker_row_select_cb),
- wiz);
- gtk_signal_connect (GTK_OBJECT (pick->clist),
- "unselect-row",
- GTK_SIGNAL_FUNC (card_picker_row_unselect_cb),
- wiz);
-
- /* Build our widget */
-
- w = gtk_label_new (new_email);
- gtk_box_pack_start (GTK_BOX (pick->body), w, FALSE, TRUE, 3);
-
- swin = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swin), pick->clist);
-
- gtk_box_pack_start (GTK_BOX (pick->body), swin, TRUE, TRUE, 2);
- gtk_widget_show_all (pick->body);
-
-
- /* Put it in our mini-wizard */
-
- wiz->closure = pick;
- mini_wizard_container_add (wiz, pick->body);
-}
-
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-
-/*
- * The code for the actual EAddressPopup widget begins here.
- */
-
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-
-
-static GtkObjectClass *parent_class;
-
-static void e_address_popup_destroy (GtkObject *);
-static void e_address_popup_query (EAddressPopup *);
-
-
-static void
-e_address_popup_class_init (EAddressPopupClass *klass)
-{
- GtkObjectClass *object_class = (GtkObjectClass *) klass;
-
- parent_class = GTK_OBJECT_CLASS (gtk_type_class (gtk_event_box_get_type ()));
-
- object_class->destroy = e_address_popup_destroy;
-}
-
-static void
-e_address_popup_init (EAddressPopup *pop)
-{
- pop->transitory = TRUE;
-}
-
-static void
-e_address_popup_cleanup (EAddressPopup *pop)
-{
- if (pop->card) {
- gtk_object_unref (GTK_OBJECT (pop->card));
- pop->card = NULL;
- }
-
- if (pop->scheduled_refresh) {
- gtk_timeout_remove (pop->scheduled_refresh);
- pop->scheduled_refresh = 0;
- }
-
- if (pop->query_tag) {
- e_book_simple_query_cancel (pop->book, pop->query_tag);
- pop->query_tag = 0;
- }
-
- if (pop->book) {
- gtk_object_unref (GTK_OBJECT (pop->book));
- pop->book = NULL;
- }
-
- g_free (pop->name);
- pop->name = NULL;
-
- g_free (pop->email);
- pop->email = NULL;
-}
-
-static void
-e_address_popup_destroy (GtkObject *obj)
-{
- EAddressPopup *pop = E_ADDRESS_POPUP (obj);
-
- e_address_popup_cleanup (pop);
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- GTK_OBJECT_CLASS (parent_class)->destroy (obj);
-}
-
-GtkType
-e_address_popup_get_type (void)
-{
- static GtkType pop_type = 0;
-
- if (!pop_type) {
- GtkTypeInfo pop_info = {
- "EAddressPopup",
- sizeof (EAddressPopup),
- sizeof (EAddressPopupClass),
- (GtkClassInitFunc) e_address_popup_class_init,
- (GtkObjectInitFunc) e_address_popup_init,
- NULL, NULL,
- (GtkClassInitFunc) NULL
- };
-
- pop_type = gtk_type_unique (gtk_event_box_get_type (), &pop_info);
- }
-
- return pop_type;
-}
-
-static void
-e_address_popup_refresh_names (EAddressPopup *pop)
-{
- if (pop->name_widget) {
- if (pop->name && *pop->name) {
- gchar *s = e_utf8_to_gtk_string (pop->name_widget, pop->name);
- gtk_label_set_text (GTK_LABEL (pop->name_widget), s);
- g_free (s);
- gtk_widget_show (pop->name_widget);
- } else {
- gtk_widget_hide (pop->name_widget);
- }
- }
-
- if (pop->email_widget) {
- if (pop->email && *pop->email) {
- gchar *s = e_utf8_to_gtk_string (pop->email_widget, pop->email);
- gtk_label_set_text (GTK_LABEL (pop->email_widget), s);
- g_free (s);
- gtk_widget_show (pop->email_widget);
- } else {
- gtk_widget_hide (pop->email_widget);
- }
- }
-
- e_address_popup_query (pop);
-}
-
-static gint
-refresh_timeout_cb (gpointer ptr)
-{
- EAddressPopup *pop = E_ADDRESS_POPUP (ptr);
- e_address_popup_refresh_names (pop);
- pop->scheduled_refresh = 0;
- return 0;
-}
-
-static void
-e_address_popup_schedule_refresh (EAddressPopup *pop)
-{
- if (pop->scheduled_refresh == 0)
- pop->scheduled_refresh = gtk_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)
-{
- gchar *lt, *gt = NULL;
-
- g_return_val_if_fail (pop && E_IS_ADDRESS_POPUP (pop), FALSE);
-
- if (txt == NULL)
- return FALSE;
-
- lt = strchr (txt, '<');
- if (lt)
- gt = strchr (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);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-void
-e_address_popup_set_name (EAddressPopup *pop, const gchar *name)
-{
- g_return_if_fail (pop && E_IS_ADDRESS_POPUP (pop));
-
- /* We only allow the name to be set once. */
- if (pop->name)
- return;
-
- if (!e_address_popup_set_free_form (pop, name)) {
- pop->name = g_strdup (name);
- if (pop->name)
- g_strstrip (pop->name);
- }
-
- e_address_popup_schedule_refresh (pop);
-}
-
-void
-e_address_popup_set_email (EAddressPopup *pop, const gchar *email)
-{
- g_return_if_fail (pop && E_IS_ADDRESS_POPUP (pop));
-
- /* We only allow the e-mail to be set once. */
- if (pop->email)
- return;
-
- if (!e_address_popup_set_free_form (pop, email)) {
- pop->email = g_strdup (email);
- if (pop->email)
- g_strstrip (pop->email);
- }
-
- e_address_popup_schedule_refresh (pop);
-}
-
-void
-e_address_popup_construct (EAddressPopup *pop)
-{
- GtkWidget *vbox, *name_holder;
- GdkColor color = { 0x0, 0xffff, 0xffff, 0xffff };
-
- g_return_if_fail (pop && E_IS_ADDRESS_POPUP (pop));
-
- pop->main_vbox = gtk_vbox_new (FALSE, 0);
-
- /* Build Generic View */
-
- name_holder = gtk_event_box_new ();
- vbox = gtk_vbox_new (FALSE, 2);
- pop->name_widget = gtk_label_new ("");
- pop->email_widget = gtk_label_new ("");
-
- gtk_box_pack_start (GTK_BOX (vbox), pop->name_widget, TRUE, TRUE, 2);
- gtk_box_pack_start (GTK_BOX (vbox), pop->email_widget, TRUE, TRUE, 2);
- gtk_container_add (GTK_CONTAINER (name_holder), GTK_WIDGET (vbox));
-
- if (gdk_colormap_alloc_color (gtk_widget_get_colormap (GTK_WIDGET (name_holder)), &color, FALSE, TRUE)) {
- GtkStyle *style = gtk_style_copy (gtk_widget_get_style (GTK_WIDGET (name_holder)));
- style->bg[0] = color;
- gtk_widget_set_style (GTK_WIDGET (name_holder), style);
- gtk_style_unref (style);
- }
-
- pop->generic_view = gtk_frame_new (NULL);
- gtk_container_add (GTK_CONTAINER (pop->generic_view), name_holder);
- gtk_box_pack_start (GTK_BOX (pop->main_vbox), pop->generic_view, TRUE, TRUE, 0);
- gtk_widget_show_all (pop->generic_view);
-
- pop->query_msg = gtk_label_new (_("Querying Addressbook..."));
- 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);
-
-
- /* Final assembly */
-
- gtk_container_add (GTK_CONTAINER (pop), pop->main_vbox);
- gtk_widget_show (pop->main_vbox);
-
- gtk_container_set_border_width (GTK_CONTAINER (vbox), 3);
- gtk_container_set_border_width (GTK_CONTAINER (pop), 2);
-}
-
-GtkWidget *
-e_address_popup_new (void)
-{
- EAddressPopup *pop = gtk_type_new (E_ADDRESS_POPUP_TYPE);
- e_address_popup_construct (pop);
- return GTK_WIDGET (pop);
-}
-
-static void
-emit_event (EAddressPopup *pop, const char *event)
-{
- if (pop->es) {
- BonoboArg *arg;
-
- arg = bonobo_arg_new (BONOBO_ARG_BOOLEAN);
- BONOBO_ARG_SET_BOOLEAN (arg, TRUE);
- bonobo_event_source_notify_listeners_full (pop->es,
- "GNOME/Evolution/Addressbook/AddressPopup",
- "Event",
- event,
- arg, NULL);
- bonobo_arg_release (arg);
- }
-}
-
-static void
-contact_editor_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- EAddressPopup *pop = E_ADDRESS_POPUP (closure);
- EContactEditor *ce = e_addressbook_show_contact_editor (book, pop->card, FALSE, TRUE);
- e_address_popup_cleanup (pop);
- emit_event (pop, "Destroy");
- e_contact_editor_raise (ce);
-}
-
-static void
-edit_contact_info_cb (EAddressPopup *pop)
-{
- EBook *book;
- emit_event (pop, "Hide");
-
- book = e_book_new ();
- if (!addressbook_load_default_book (book, contact_editor_cb, pop)) {
- gtk_object_unref (GTK_OBJECT (book));
- contact_editor_cb (NULL, E_BOOK_STATUS_OTHER_ERROR, pop);
- }
-}
-
-static void
-e_address_popup_cardify (EAddressPopup *pop, ECard *card)
-{
- 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);
-
- pop->card = card;
- gtk_object_ref (GTK_OBJECT (pop->card));
-
- e_minicard_widget_set_card (E_MINICARD_WIDGET (pop->minicard_view), card);
- gtk_widget_show (pop->minicard_view);
- gtk_widget_hide (pop->generic_view);
-
- b = gtk_button_new_with_label (_("Edit Contact Info"));
- gtk_box_pack_start (GTK_BOX (pop->main_vbox), b, TRUE, TRUE, 0);
- gtk_signal_connect_object (GTK_OBJECT (b),
- "clicked",
- GTK_SIGNAL_FUNC (edit_contact_info_cb),
- GTK_OBJECT (pop));
- gtk_widget_show (b);
-}
-
-static void
-add_contacts_cb (EAddressPopup *pop)
-{
- if (pop->email && *pop->email) {
- if (pop->name && *pop->name)
- e_contact_quick_add (pop->name, pop->email, NULL, NULL);
- else
- e_contact_quick_add_free_form (pop->email, NULL, NULL);
-
- }
- e_address_popup_cleanup (pop);
- emit_event (pop, "Destroy");
-}
-
-static void
-e_address_popup_no_matches (EAddressPopup *pop)
-{
- GtkWidget *b;
-
- g_return_if_fail (pop && E_IS_ADDRESS_POPUP (pop));
-
- b = gtk_button_new_with_label (_("Add to Contacts"));
- gtk_box_pack_start (GTK_BOX (pop->main_vbox), b, TRUE, TRUE, 0);
- gtk_signal_connect_object (GTK_OBJECT (b),
- "clicked",
- GTK_SIGNAL_FUNC (add_contacts_cb),
- GTK_OBJECT (pop));
- gtk_widget_show (b);
-}
-
-static void
-wizard_destroy_cb (MiniWizard *wiz, gpointer closure)
-{
- gtk_widget_destroy (GTK_WIDGET (closure));
-}
-
-static void
-popup_size_allocate_cb (GtkWidget *widget, GtkAllocation *alloc, gpointer user_data)
-{
- gint x, y, w, h, xmax, ymax;
-
- xmax = gdk_screen_width ();
- ymax = gdk_screen_height ();
-
- if (gtk_object_get_data (GTK_OBJECT (widget), "size_allocate") == NULL) {
- gdk_window_get_pointer (NULL, &x, &y, NULL);
- w = alloc->width;
- h = alloc->height;
- x = CLAMP (x - w/2, 0, xmax - w);
- y = CLAMP (y - h/2, 0, ymax - h);
- gtk_widget_set_uposition (widget, x, y);
- gtk_object_set_data (GTK_OBJECT (widget), "size_allocate", widget);
- }
-}
-
-static void
-e_address_popup_ambiguous_email_add (EAddressPopup *pop, const GList *cards)
-{
- MiniWizard *wiz = mini_wizard_new ();
- GtkWidget *win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-
- wiz->destroy_cb = wizard_destroy_cb;
- wiz->destroy_closure = win;
-
- gtk_window_set_title (GTK_WINDOW (win), _("Merge E-Mail Address"));
- gtk_signal_connect (GTK_OBJECT (win),
- "size_allocate",
- GTK_SIGNAL_FUNC (popup_size_allocate_cb),
- NULL);
-
- /* FIXME: This hard-wired size is evil. */
- gtk_widget_set_usize (win, 275, 170);
-
- card_picker_init (wiz, cards, pop->name, pop->email);
-
- e_address_popup_cleanup (pop);
- emit_event (pop, "Destroy");
-
- gtk_container_add (GTK_CONTAINER (win), wiz->body);
- gtk_widget_show_all (win);
-}
-
-static void
-e_address_popup_multiple_matches (EAddressPopup *pop, const GList *cards)
-{
- pop->multiple_matches = TRUE;
-
- e_address_popup_ambiguous_email_add (pop, cards);
-}
-
-/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
-
-/*
- * Addressbook Query Fun
- */
-
-static void
-name_only_query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
-{
- EAddressPopup *pop;
-
- if (status != E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS)
- return;
-
- pop = E_ADDRESS_POPUP (closure);
-
- pop->query_tag = 0;
-
- if (cards == NULL) {
- e_address_popup_no_matches (pop);
- } else {
- e_address_popup_ambiguous_email_add (pop, cards);
- }
-}
-
-static void
-query_cb (EBook *book, EBookSimpleQueryStatus status, const GList *cards, gpointer closure)
-{
- EAddressPopup *pop;
-
- if (status != E_BOOK_SIMPLE_QUERY_STATUS_SUCCESS)
- return;
-
- pop = E_ADDRESS_POPUP (closure);
-
- pop->query_tag = 0;
- gtk_widget_hide (pop->query_msg);
-
- if (cards == 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);
- } else {
- e_address_popup_no_matches (pop);
- }
-
- } else {
- if (g_list_length ((GList *) cards) == 1)
- e_address_popup_cardify (pop, E_CARD (cards->data));
- else
- e_address_popup_multiple_matches (pop, cards);
- }
-}
-
-static void
-start_query (EBook *book, EBookStatus status, gpointer closure)
-{
- EAddressPopup *pop = E_ADDRESS_POPUP (closure);
-
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_address_popup_no_matches (pop);
- return;
- }
-
- if (pop->query_tag)
- e_book_simple_query_cancel (book, pop->query_tag);
-
- if (pop->book != book) {
- gtk_object_ref (GTK_OBJECT (book));
- if (pop->book)
- gtk_object_unref (GTK_OBJECT (pop->book));
- pop->book = book;
- }
-
- pop->query_tag = e_book_name_and_email_query (book, pop->name, pop->email, query_cb, pop);
-
- gtk_object_unref (GTK_OBJECT (pop));
-}
-
-static void
-e_address_popup_query (EAddressPopup *pop)
-{
- EBook *book;
-
- g_return_if_fail (pop && E_IS_ADDRESS_POPUP (pop));
-
- book = e_book_new ();
- gtk_object_ref (GTK_OBJECT (pop));
-
- if (!addressbook_load_default_book (book, start_query, pop)) {
- gtk_object_unref (GTK_OBJECT (book));
- start_query (NULL, E_BOOK_STATUS_OTHER_ERROR, pop);
- }
-}
-
-/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
-
-enum {
- PROPERTY_NAME,
- PROPERTY_EMAIL,
- PROPERTY_TRANSITORY
-};
-
-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);
-
- switch (arg_id) {
-
- case PROPERTY_NAME:
- e_address_popup_set_name (pop, BONOBO_ARG_GET_STRING (arg));
- break;
-
- case PROPERTY_EMAIL:
- e_address_popup_set_email (pop, BONOBO_ARG_GET_STRING (arg));
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-static void
-get_prop (BonoboPropertyBag *bag, BonoboArg *arg, guint arg_id, CORBA_Environment *ev, gpointer user_data)
-{
- EAddressPopup *pop = E_ADDRESS_POPUP (user_data);
-
- switch (arg_id) {
-
- case PROPERTY_NAME:
- BONOBO_ARG_SET_STRING (arg, pop->name);
- break;
-
- case PROPERTY_EMAIL:
- BONOBO_ARG_SET_STRING (arg, pop->email);
- break;
-
- case PROPERTY_TRANSITORY:
- BONOBO_ARG_SET_BOOLEAN (arg, pop->transitory);
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-static BonoboControl *
-e_address_popup_factory_new_control (void)
-{
- BonoboControl *control;
- BonoboPropertyBag *bag;
- EAddressPopup *addy;
- GtkWidget *w;
-
- w = e_address_popup_new ();
- addy = E_ADDRESS_POPUP (w);
-
- control = bonobo_control_new (w);
- gtk_widget_show (w);
-
- bag = bonobo_property_bag_new (get_prop, set_prop, w);
- bonobo_property_bag_add (bag, "name", PROPERTY_NAME,
- BONOBO_ARG_STRING, NULL, NULL,
- BONOBO_PROPERTY_WRITEABLE | BONOBO_PROPERTY_READABLE);
-
- bonobo_property_bag_add (bag, "email", PROPERTY_EMAIL,
- BONOBO_ARG_STRING, NULL, NULL,
- BONOBO_PROPERTY_WRITEABLE | BONOBO_PROPERTY_READABLE);
-
- bonobo_property_bag_add (bag, "transitory", PROPERTY_TRANSITORY,
- BONOBO_ARG_BOOLEAN, NULL, NULL,
- BONOBO_PROPERTY_READABLE);
-
- bonobo_control_set_properties (control, bag);
- bonobo_object_unref (BONOBO_OBJECT (bag));
-
- addy->es = bonobo_event_source_new ();
- bonobo_object_add_interface (BONOBO_OBJECT (control),
- BONOBO_OBJECT (addy->es));
-
- return control;
-}
-
-static BonoboObject *
-e_address_popup_factory (BonoboGenericFactory *factory, gpointer user_data)
-{
- return BONOBO_OBJECT (e_address_popup_factory_new_control ());
-}
-
-void
-e_address_popup_factory_init (void)
-{
- static BonoboGenericFactory *factory = NULL;
-
- if (factory != NULL)
- return;
-
- factory = bonobo_generic_factory_new ("OAFIID:GNOME_Evolution_Addressbook_AddressPopupFactory",
- e_address_popup_factory, NULL);
-
- if (factory == NULL)
- g_error ("I could not register an AddressPopup factory.");
-}
diff --git a/addressbook/gui/component/e-address-popup.h b/addressbook/gui/component/e-address-popup.h
deleted file mode 100644
index b648b79d4f..0000000000
--- a/addressbook/gui/component/e-address-popup.h
+++ /dev/null
@@ -1,89 +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 <libgnome/gnome-defs.h>
-#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-card.h>
-#include <bonobo/bonobo-event-source.h>
-
-BEGIN_GNOME_DECLS
-
-#define E_ADDRESS_POPUP_TYPE (e_address_popup_get_type ())
-#define E_ADDRESS_POPUP(o) (GTK_CHECK_CAST ((o), E_ADDRESS_POPUP_TYPE, EAddressPopup))
-#define E_ADDRESS_POPUP_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), E_ADDRESS_POPUP_TYPE, EAddressPopupClass))
-#define E_IS_ADDRESS_POPUP(o) (GTK_CHECK_TYPE ((o), E_ADDRESS_POPUP_TYPE))
-#define E_IS_ADDRESS_POPUP_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_ADDRESS_POPUP_TYPE))
-
-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;
-};
-
-GtkType 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);
-
-void e_address_popup_factory_init (void);
-
-END_GNOME_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 d01999d34f..0000000000
--- a/addressbook/gui/component/e-address-widget.c
+++ /dev/null
@@ -1,576 +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 <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 = GTK_OBJECT_CLASS (gtk_type_class (gtk_event_box_get_type ()));
-
- 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);
- g_free (addr->email);
-
- if (addr->query_tag)
- e_book_simple_query_cancel (common_book, addr->query_tag);
-
- if (addr->query_idle_tag)
- gtk_idle_remove (addr->query_idle_tag);
-}
-
-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;
-}
-
-GtkType
-e_address_widget_get_type (void)
-{
- static GtkType aw_type = 0;
-
- if (!aw_type) {
- GtkTypeInfo aw_info = {
- "EAddressWidget",
- sizeof (EAddressWidget),
- sizeof (EAddressWidgetClass),
- (GtkClassInitFunc) e_address_widget_class_init,
- (GtkObjectInitFunc) e_address_widget_init,
- NULL, NULL, /* reserved... but for what sinister purpose? */
- (GtkClassInitFunc) NULL
- };
-
- aw_type = gtk_type_unique (gtk_event_box_get_type (), &aw_info);
- }
-
- 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 = gtk_type_new (e_address_widget_get_type ());
- 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)
- gtk_object_unref (GTK_OBJECT (addr->card));
- addr->card = card;
- gtk_object_ref (GTK_OBJECT (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;
- gtk_object_ref (GTK_OBJECT (common_book));
- } else
- gtk_object_unref (GTK_OBJECT (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 = gtk_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);
-}
-
-/*
- *
- * 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;
- }
-}
-
-static 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, bag);
- bonobo_object_unref (BONOBO_OBJECT (bag));
-
- return control;
-}
-
-static BonoboObject *
-e_address_widget_factory (BonoboGenericFactory *factory, gpointer user_data)
-{
- return BONOBO_OBJECT (e_address_widget_factory_new_control ());
-}
-
-void
-e_address_widget_factory_init (void)
-{
- static BonoboGenericFactory *factory = NULL;
-
- if (factory != NULL)
- return;
-
- factory = bonobo_generic_factory_new ("OAFIID:GNOME_Evolution_Addressbook_AddressWidgetFactory",
- e_address_widget_factory, NULL);
-
- if (factory == NULL)
- g_error ("I could not register an AddressWidget factory.");
-}
-
diff --git a/addressbook/gui/component/e-address-widget.h b/addressbook/gui/component/e-address-widget.h
deleted file mode 100644
index 535e51028c..0000000000
--- a/addressbook/gui/component/e-address-widget.h
+++ /dev/null
@@ -1,102 +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 <libgnome/gnome-defs.h>
-#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-book-util.h>
-#include <addressbook/backend/ebook/e-card.h>
-
-BEGIN_GNOME_DECLS
-
-#define E_ADDRESS_WIDGET_TYPE (e_address_widget_get_type ())
-#define E_ADDRESS_WIDGET(o) (GTK_CHECK_CAST ((o), E_ADDRESS_WIDGET_TYPE, EAddressWidget))
-#define E_ADDRESS_WIDGET_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), E_ADDRESS_WIDGET_TYPE, EAddressWidgetClass))
-#define E_IS_ADDRESS_WIDGET(o) (GTK_CHECK_TYPE ((o), E_ADDRESS_WIDGET_TYPE))
-#define E_IS_ADDRESS_WIDGET_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_ADDRESS_WIDGET_TYPE))
-
-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;
-};
-
-GtkType 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);
-
-
-void e_address_widget_factory_init (void);
-
-
-
-END_GNOME_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 5d9b053934..0000000000
--- a/addressbook/gui/component/e-cardlist-model.c
+++ /dev/null
@@ -1,229 +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 <gnome-xml/tree.h>
-#include <gnome-xml/parser.h>
-#include <gnome-xml/xmlmemory.h>
-#include "e-cardlist-model.h"
-
-#define PARENT_TYPE e_table_model_get_type()
-
-static void
-e_cardlist_model_destroy(GtkObject *object)
-{
- ECardlistModel *model = E_CARDLIST_MODEL(object);
- int i;
-
- for ( i = 0; i < model->data_count; i++ ) {
- gtk_object_unref(GTK_OBJECT(model->data[i]));
- }
- g_free(model->data);
-}
-
-/* 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);
- ECard *card;
- 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);
- gtk_object_get(GTK_OBJECT(e_cardlist_model->data[row]),
- "card", &card,
- NULL);
-
- 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));
- gtk_object_ref(GTK_OBJECT(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));
- gtk_object_unref(GTK_OBJECT(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 (GtkObjectClass *object_class)
-{
- ETableModelClass *model_class = (ETableModelClass *) object_class;
-
- object_class->destroy = e_cardlist_model_destroy;
-
- 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 (GtkObject *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;
- gtk_object_get(GTK_OBJECT(model->data[row]),
- "card", &card,
- NULL);
- gtk_object_ref(GTK_OBJECT(card));
- return card;
- }
- return NULL;
-}
-
-GtkType
-e_cardlist_model_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type){
- GtkTypeInfo info = {
- "ECardlistModel",
- sizeof (ECardlistModel),
- sizeof (ECardlistModelClass),
- (GtkClassInitFunc) e_cardlist_model_class_init,
- (GtkObjectInitFunc) e_cardlist_model_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
-
- return type;
-}
-
-ETableModel *
-e_cardlist_model_new (void)
-{
- ECardlistModel *et;
-
- et = gtk_type_new (e_cardlist_model_get_type ());
-
- 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 0b9a7a2265..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_CARDLIST_MODEL_TYPE (e_cardlist_model_get_type ())
-#define E_CARDLIST_MODEL(o) (GTK_CHECK_CAST ((o), E_CARDLIST_MODEL_TYPE, ECardlistModel))
-#define E_CARDLIST_MODEL_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_CARDLIST_MODEL_TYPE, ECardlistModelClass))
-#define E_IS_CARDLIST_MODEL(o) (GTK_CHECK_TYPE ((o), E_CARDLIST_MODEL_TYPE))
-#define E_IS_CARDLIST_MODEL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CARDLIST_MODEL_TYPE))
-
-typedef struct {
- ETableModel parent;
-
- /* item specific fields */
- ECardSimple **data;
- int data_count;
-} ECardlistModel;
-
-
-typedef struct {
- ETableModelClass parent_class;
-} ECardlistModelClass;
-
-
-GtkType 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/ldap-config.glade b/addressbook/gui/component/ldap-config.glade
deleted file mode 100644
index 82c2d5d8b5..0000000000
--- a/addressbook/gui/component/ldap-config.glade
+++ /dev/null
@@ -1,5819 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>addressbook-config-mockup</name>
- <program_name>addressbook-config-mockup</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>../../../art</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
-</project>
-
-<widget>
- <class>GnomeDialog</class>
- <name>Add/Edit Attribute Mappings--Simple Version</name>
- <visible>False</visible>
- <title>Add (or Edit) Attribute Mappings</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>True</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>dialog-vbox4</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>dialog-action_area4</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button37</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button39</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox30</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox66</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap35</name>
- <filename>ldap.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label283</name>
- <label>Please select an Evolution attribute and an
-LDAP attribute to associate with it.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator8</name>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table18</name>
- <border_width>3</border_width>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label284</name>
- <label>_Evolution attribute:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>combo-entry2</default_focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label285</name>
- <label>_LDAP attribute:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>combo-entry3</default_focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCombo</class>
- <name>combo4</name>
- <value_in_list>False</value_in_list>
- <ok_if_empty>True</ok_if_empty>
- <case_sensitive>False</case_sensitive>
- <use_arrows>True</use_arrows>
- <use_arrows_always>False</use_arrows_always>
- <items></items>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <child_name>GtkCombo:entry</child_name>
- <name>combo-entry2</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
-
- <widget>
- <class>GtkCombo</class>
- <name>combo5</name>
- <value_in_list>False</value_in_list>
- <ok_if_empty>True</ok_if_empty>
- <case_sensitive>False</case_sensitive>
- <use_arrows>True</use_arrows>
- <use_arrows_always>False</use_arrows_always>
- <items></items>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <child_name>GtkCombo:entry</child_name>
- <name>combo-entry3</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GnomeDialog</class>
- <name>Add/Edit Attribute Mappings-- Multiple Selection Version</name>
- <visible>False</visible>
- <title>Add (or Edit) Attribute Mappings</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <default_width>393</default_width>
- <default_height>324</default_height>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>vbox31</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>hbuttonbox9</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button40</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button41</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox32</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox67</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap36</name>
- <filename>ldap.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label286</name>
- <label>Please select and Evolution attribute and an
-LDAP attribute to associate with it.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator9</name>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table19</name>
- <border_width>3</border_width>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label287</name>
- <label>_Evolution attribute:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>entry32</default_focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCombo</class>
- <name>combo6</name>
- <value_in_list>False</value_in_list>
- <ok_if_empty>True</ok_if_empty>
- <case_sensitive>False</case_sensitive>
- <use_arrows>True</use_arrows>
- <use_arrows_always>False</use_arrows_always>
- <items></items>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <child_name>GtkCombo:entry</child_name>
- <name>entry32</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label288</name>
- <label>_LDAP attributes:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>7.45058e-09</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow6</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>clist4</name>
- <can_focus>True</can_focus>
- <columns>2</columns>
- <column_widths>163,80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>True</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label289</name>
- <label>Attribute</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label290</name>
- <label>Select</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>account-editor-window</name>
- <visible>False</visible>
- <title>account-editor</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox37</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkNotebook</class>
- <name>account-editor-notebook</name>
- <can_focus>True</can_focus>
- <show_tabs>True</show_tabs>
- <show_border>True</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>account-editor-general-vbox</name>
- <border_width>6</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox100</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label431</name>
- <label>_Display name:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment45</name>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xscale>0.9</xscale>
- <yscale>1</yscale>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <name>account-editor-display-name-entry</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator12</name>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label331</name>
- <label>General</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>account-editor-connecting-vbox</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label334</name>
- <label>Connecting</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>account-editor-searching-vbox</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label344</name>
- <label>Searching</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>account-editor-objectclasses-vbox</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>account-editor-objectclasses-label</name>
- <label>Objectclasses</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>account-editor-mappings-vbox</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>account-editor-mappings-label</name>
- <label>Mappings</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>account-editor-dn-customization-vbox</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>account-editor-dn-customization-label</name>
- <label>DN Customization</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator10</name>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox120</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkNotebook</class>
- <name>account-editor-advanced-button-notebook</name>
- <show_tabs>False</show_tabs>
- <show_border>False</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <name>hbuttonbox21</name>
- <layout_style>GTK_BUTTONBOX_START</layout_style>
- <spacing>0</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
-
- <widget>
- <class>GtkButton</class>
- <name>account-editor-fewer-options-button</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>&lt;&lt; Fewer Options</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label554</name>
- <label>label554</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHButtonBox</class>
- <name>hbuttonbox28</name>
- <layout_style>GTK_BUTTONBOX_START</layout_style>
- <spacing>0</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
-
- <widget>
- <class>GtkButton</class>
- <name>account-editor-more-options-button</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_More Options &gt;&gt;</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label555</name>
- <label>label555</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHButtonBox</class>
- <name>hbuttonbox20</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>0</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>account-editor-ok-button</name>
- <sensitive>False</sensitive>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>account-editor-apply-button</name>
- <sensitive>False</sensitive>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_APPLY</stock_button>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>account-editor-close-button</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CLOSE</stock_button>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>account-druid-window</name>
- <visible>False</visible>
- <title>account-druid</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GnomeDruid</class>
- <name>account-druid</name>
-
- <widget>
- <class>GnomeDruidPageStart</class>
- <name>druidpagestart1</name>
- <title>LDAP Configuration Assistant</title>
- <text>This assistant will help you to access online directory services
-using LDAP (Lightweight Directory Access Protocol) servers.
-
-Adding a new LDAP server requires some specialized information
-about the server. Please contact your system administrator if you
-need help finding this information.</text>
- <title_color>255,255,255</title_color>
- <text_color>0,0,0</text_color>
- <background_color>0,0,0</background_color>
- <logo_background_color>0,0,0</logo_background_color>
- <textbox_color>255,255,255</textbox_color>
- <logo_image>ldap.png</logo_image>
- <watermark_image>xstdruidbg-3.png</watermark_image>
- </widget>
-
- <widget>
- <class>GnomeDruidPageStandard</class>
- <name>add-server-druid-info-page</name>
- <title>Step 1: Server Information</title>
- <title_color>255,255,255</title_color>
- <background_color>0,0,0</background_color>
- <logo_background_color>0,0,0</logo_background_color>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDruidPageStandard:vbox</child_name>
- <name>druid-vbox1</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>account-druid-general-vbox</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label158</name>
- <label>The first step in configuring an LDAP server is to provide its name, and your log in
-information. Please ask your system administrator if you are unsure of this information.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>3</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator2</name>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GnomeDruidPageStandard</class>
- <name>add-server-druid-connecting-page</name>
- <title>Step 2: Connecting to Server</title>
- <title_color>255,255,255</title_color>
- <background_color>0,0,0</background_color>
- <logo_background_color>0,0,0</logo_background_color>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDruidPageStandard:vbox</child_name>
- <name>druid-vbox2</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>account-druid-connecting-vbox</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label174</name>
- <label>Now, you must specify how you want to connect to the LDAP server. The SSL (Secure Sockets Layer)
-and TLS (Transport Layer Security) protocols are used by some servers to cryptographically protect
-your connection. Ask your system administrator if your LDAP server uses these protocols.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>3</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator3</name>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GnomeDruidPageStandard</class>
- <name>add-server-druid-searching-page</name>
- <title>Step 3: Searching the Directory</title>
- <title_color>255,255,255</title_color>
- <background_color>0,0,0</background_color>
- <logo_background_color>0,0,0</logo_background_color>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDruidPageStandard:vbox</child_name>
- <name>vbox23</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>account-druid-searching-vbox</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label254</name>
- <label>The options on this page control how many entries should be included in your
-searches, and how long a search should take. Ask your system administrator if you
-need to change these options.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator7</name>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GnomeDruidPageStandard</class>
- <name>add-server-druid-display-name-page</name>
- <title>Step 4: Display Name</title>
- <title_color>255,255,255</title_color>
- <background_color>0,0,0</background_color>
- <logo_background_color>0,0,0</logo_background_color>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDruidPageStandard:vbox</child_name>
- <name>druid-vbox5</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox21</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label198</name>
- <label>Specifying a display name is the last required step in configuring an LDAP server.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>3</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator5</name>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table15</name>
- <border_width>3</border_width>
- <rows>1</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <name>druid-display-name-entry</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label199</name>
- <label>_Display name:</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>druid-display-name-entry</default_focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkNotebook</class>
- <name>notebook15</name>
- <show_tabs>False</show_tabs>
- <show_border>False</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox41</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap21</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label207</name>
- <label>This is the name for this server that will appear in your Evolution folder list.
-It is for display purposes only. </label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label208</name>
- <label>label163</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox42</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap22</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label215</name>
- <label>Selecting this option will let you change Evolution's default settings for LDAP
-searches, and for creating and editing contacts. </label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label210</name>
- <label>label164</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GnomeDruidPageFinish</class>
- <name>add-server-druid-finish-page</name>
- <title>Finished</title>
- <text>Congratulations, you are finished setting up this LDAP server. You
-are now ready to access this directory.
-
-Please click the &quot;Finish&quot; button to save the settings you have entered here.</text>
- <background_color>0,0,0</background_color>
- <logo_background_color>0,0,0</logo_background_color>
- <textbox_color>255,255,255</textbox_color>
- <text_color>0,0,0</text_color>
- <title_color>255,255,255</title_color>
- <watermark_image>xstdruidbg-3.png</watermark_image>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>edit_server_window_simple</name>
- <visible>False</visible>
- <title>edit_server_window_simple</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox67</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkNotebook</class>
- <name>notebook25</name>
- <can_focus>True</can_focus>
- <show_tabs>True</show_tabs>
- <show_border>True</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox68</name>
- <border_width>6</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox121</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label484</name>
- <label>_Display name:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment52</name>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xscale>0.9</xscale>
- <yscale>1</yscale>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry54</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator13</name>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table32</name>
- <border_width>3</border_width>
- <rows>3</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label485</name>
- <label>_Server name:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>entry55</default_focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label486</name>
- <label>_Log in method:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label487</name>
- <label>Distinguished _name:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>entry56</default_focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry55</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment53</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>optionmenu18</name>
- <can_focus>True</can_focus>
- <items>Anonymously
-Using email address
-Using distinguished name (DN)
-</items>
- <initial_choice>2</initial_choice>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry56</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkNotebook</class>
- <name>notebook26</name>
- <show_tabs>False</show_tabs>
- <show_border>False</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox122</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap66</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label488</name>
- <label>This is the full name of your ldap server. For example, &quot;ldap.mycompany.com&quot;.</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label489</name>
- <label>label163</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox123</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap67</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label490</name>
- <label>label168</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label491</name>
- <label>label164</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox124</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap68</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label492</name>
- <label>label169</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label493</name>
- <label>label165</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>Placeholder</class>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label494</name>
- <label>label214</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox125</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap69</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label495</name>
- <label>This is the name for this server that will appear in your Evolution folder list.
-It is for display purposes only. </label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label496</name>
- <label>label452</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label497</name>
- <label>General</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox69</name>
- <border_width>6</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkTable</class>
- <name>table33</name>
- <border_width>3</border_width>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label498</name>
- <label>_Port number:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment54</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox70</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>radiobutton9</name>
- <can_focus>True</can_focus>
- <label>_Always</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>radiobutton10</name>
- <can_focus>True</can_focus>
- <label>_If necessary </label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>radiobutton11</name>
- <can_focus>True</can_focus>
- <label>_Don't use SSL/TLS</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment55</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkPixmap</class>
- <name>pixmap70</name>
- <filename>gnome-hint.png</filename>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <build_insensitive>True</build_insensitive>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment56</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkCombo</class>
- <name>combo8</name>
- <value_in_list>False</value_in_list>
- <ok_if_empty>True</ok_if_empty>
- <case_sensitive>False</case_sensitive>
- <use_arrows>True</use_arrows>
- <use_arrows_always>False</use_arrows_always>
- <items>380
-666
-1234
-</items>
-
- <widget>
- <class>GtkEntry</class>
- <child_name>GtkCombo:entry</child_name>
- <name>entry57</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text>380</text>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label499</name>
- <label>U_se SSL/TLS:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>7.45058e-09</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkNotebook</class>
- <name>notebook27</name>
- <show_tabs>False</show_tabs>
- <show_border>False</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox126</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap71</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label500</name>
- <label>This is the port on the LDAP server that Evolution will try to connect to. A
-list of standard ports has been provided. Ask your system administrator
-what port you should specify.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label501</name>
- <label>label163</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox127</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap72</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label502</name>
- <label>Selecting this option means that Evolution will only connect to your LDAP server if
-your LDAP server supports SSL or TLS.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label503</name>
- <label>label398</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox128</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap73</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label504</name>
- <label>Selecting this option means that Evolution will only try to use SSL/TLS if you are in a
-insecure environment. For example, if you and your LDAP server are behind a firewall
-at work, then Evolution doesn't need to use SSL/TLS because your connection is already
-secure.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label505</name>
- <label>label396</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox129</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap74</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label506</name>
- <label>Selecting this option means that your server does not support either SSL or TLS. This
-means that your connection will be insecure, and that you will be vulnerable to security
-exploits. </label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label507</name>
- <label>label397</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label508</name>
- <label>Connecting</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox71</name>
- <border_width>6</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkTable</class>
- <name>table34</name>
- <border_width>3</border_width>
- <rows>4</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label509</name>
- <label>_Search base:</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label510</name>
- <label>S_earch scope: </label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment57</name>
- <xalign>7.45058e-09</xalign>
- <yalign>7.45058e-09</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>optionmenu19</name>
- <can_focus>True</can_focus>
- <items>Sub
-One
-</items>
- <initial_choice>0</initial_choice>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox130</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry58</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button90</name>
- <can_focus>True</can_focus>
- <label> S_how Supported Bases </label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label511</name>
- <label>_Timeout (minutes):</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>1</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment58</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>1</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox131</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label512</name>
- <label>1:00</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHScale</class>
- <name>hscale5</name>
- <can_focus>True</can_focus>
- <draw_value>False</draw_value>
- <value_pos>GTK_POS_LEFT</value_pos>
- <digits>0</digits>
- <policy>GTK_UPDATE_DELAYED</policy>
- <value>3</value>
- <lower>1</lower>
- <upper>5</upper>
- <step>0.5</step>
- <page>1</page>
- <page_size>0</page_size>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label513</name>
- <label>5:00</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>3</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label514</name>
- <label>Selected:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label515</name>
- <label>2:30</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label516</name>
- <label>_Download limit:</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment59</name>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox132</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkSpinButton</class>
- <name>spinbutton5</name>
- <can_focus>True</can_focus>
- <climb_rate>1</climb_rate>
- <digits>0</digits>
- <numeric>False</numeric>
- <update_policy>GTK_UPDATE_ALWAYS</update_policy>
- <snap>False</snap>
- <wrap>False</wrap>
- <value>100</value>
- <lower>0</lower>
- <upper>10000</upper>
- <step>1</step>
- <page>10</page>
- <page_size>10</page_size>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label517</name>
- <label>cards</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkNotebook</class>
- <name>notebook28</name>
- <show_tabs>False</show_tabs>
- <show_border>False</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox133</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap75</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label518</name>
- <label>The search base is the distinguished name (DN) of the entry where your searches will
-begin. If you leave this blank, the search will begin at the root of the directory tree.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label519</name>
- <label>label163</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox134</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap76</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label520</name>
- <label>The search scope defines how deep you would like the search to extend down the
-directory tree. A search scope of &quot;sub&quot; will include all entries below your search base.
-A search scope of &quot;one&quot; will only include the entries one level beneath your base.
-</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label521</name>
- <label>label164</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox135</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap77</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label522</name>
- <label>This option controls how long a search will be run.</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label523</name>
- <label>label165</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox136</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap78</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label524</name>
- <label>This is the maximum number of entries to download. Setting this number to be
-too large will slow down your addressbook.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label525</name>
- <label>label166</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label526</name>
- <label>Searching</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator14</name>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox142</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <name>hbuttonbox25</name>
- <layout_style>GTK_BUTTONBOX_START</layout_style>
- <spacing>0</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button100</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_More Options &gt;&gt;</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHButtonBox</class>
- <name>hbuttonbox26</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>0</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button101</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button102</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_APPLY</stock_button>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button103</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CLOSE</stock_button>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GnomeDialog</class>
- <name>addressbook-sources-window</name>
- <visible>False</visible>
- <title>Addressbook Sources</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <default_width>355</default_width>
- <default_height>285</default_height>
- <allow_shrink>True</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>addressbook-sources-vbox</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>hbuttonbox27</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button104</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button105</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_APPLY</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button106</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CLOSE</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>addressbook-sources</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>Custom</class>
- <name>sourcesTable</name>
- <creation_function>addressbook_dialog_create_sources_table</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 11 Apr 2002 00:31:02 GMT</last_modification_time>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox73</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label529</name>
- <label>
-</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkVButtonBox</class>
- <name>vbuttonbox18</name>
- <layout_style>GTK_BUTTONBOX_START</layout_style>
- <spacing>0</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>addSource</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_Add</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>editSource</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_Edit</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>deleteSource</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>De_lete</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>general-tab-window</name>
- <visible>False</visible>
- <title>general-tab</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>general-tab</name>
- <border_width>6</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkTable</class>
- <name>table36</name>
- <border_width>3</border_width>
- <rows>3</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label534</name>
- <label>_Server name:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>server-name-entry</default_focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label535</name>
- <label>_Log in method:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>server-name-entry</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment63</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>auth-optionmenu</name>
- <can_focus>True</can_focus>
- <items>Anonymously
-Using email address
-Using distinguished name (DN)
-</items>
- <initial_choice>0</initial_choice>
- </widget>
- </widget>
-
- <widget>
- <class>GtkNotebook</class>
- <name>auth-label-notebook</name>
- <sensitive>False</sensitive>
- <show_tabs>False</show_tabs>
- <show_border>False</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label553</name>
- <label>Email Address:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label546</name>
- <label>label546</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label536</name>
- <label>Distinguished _name:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label547</name>
- <label>label547</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
-
- <widget>
- <class>GtkNotebook</class>
- <name>auth-entry-notebook</name>
- <sensitive>False</sensitive>
- <show_tabs>False</show_tabs>
- <show_border>False</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <name>email-entry</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label549</name>
- <label>label549</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>dn-entry</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label550</name>
- <label>label550</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkNotebook</class>
- <name>general-tab-help</name>
- <show_tabs>False</show_tabs>
- <show_border>False</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox145</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap79</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label537</name>
- <label>This is the full name of your ldap server. For example, &quot;ldap.mycompany.com&quot;.</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label538</name>
- <label>label163</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox146</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap80</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label539</name>
- <label>Evolution will use this email address to authenticate you with the server</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label540</name>
- <label>label164</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox147</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap81</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label541</name>
- <label>Evolution will use this DN to authenticate you with the server</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label542</name>
- <label>label165</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label552</name>
- <label>This is the method evolution will use to authenticate you. Note that setting this to &quot;Email Address&quot; requires anonymous access to your ldap server.</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>True</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label551</name>
- <label>label551</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox148</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap82</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label544</name>
- <label>This is the name for this server that will appear in your Evolution folder list.
-It is for display purposes only. </label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label545</name>
- <label>label452</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>connecting-tab-window</name>
- <visible>False</visible>
- <title>connecting-tab</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>connecting-tab</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkTable</class>
- <name>table14</name>
- <border_width>3</border_width>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label175</name>
- <label>_Port number:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment23</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkPixmap</class>
- <name>pixmap11</name>
- <filename>gnome-hint.png</filename>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <build_insensitive>True</build_insensitive>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment21</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkCombo</class>
- <name>port-combo</name>
- <value_in_list>False</value_in_list>
- <ok_if_empty>True</ok_if_empty>
- <case_sensitive>False</case_sensitive>
- <use_arrows>True</use_arrows>
- <use_arrows_always>False</use_arrows_always>
- <items>389
-636
-3268
-</items>
-
- <widget>
- <class>GtkEntry</class>
- <child_name>GtkCombo:entry</child_name>
- <name>entry27</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text>389</text>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label176</name>
- <label>U_se SSL/TLS:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment60</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>ssl-optionmenu</name>
- <can_focus>True</can_focus>
- <items>Always
-Whenever Possible
-Never
-</items>
- <initial_choice>1</initial_choice>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkNotebook</class>
- <name>connecting-tab-help</name>
- <show_tabs>False</show_tabs>
- <show_border>False</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox30</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap7</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label178</name>
- <label>This is the port on the LDAP server that Evolution will try to connect to. A
-list of standard ports has been provided. Ask your system administrator
-what port you should specify.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label179</name>
- <label>label163</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox31</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap8</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label395</name>
- <label>Selecting this option means that Evolution will only connect to your LDAP server if
-your LDAP server supports SSL or TLS.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label398</name>
- <label>label398</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox91</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap43</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label399</name>
- <label>Selecting this option means that Evolution will only try to use SSL/TLS if you are in a
-insecure environment. For example, if you and your LDAP server are behind a firewall
-at work, then Evolution doesn't need to use SSL/TLS because your connection is already
-secure.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label396</name>
- <label>label396</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox92</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap44</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label400</name>
- <label>Selecting this option means that your server does not support either SSL or TLS. This
-means that your connection will be insecure, and that you will be vulnerable to security
-exploits. </label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label397</name>
- <label>label397</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>searching-tab-window</name>
- <visible>False</visible>
- <title>searching-tab</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>searching-tab</name>
- <border_width>6</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkTable</class>
- <name>table30</name>
- <border_width>3</border_width>
- <rows>4</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label455</name>
- <label>_Search base:</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label456</name>
- <label>S_earch scope: </label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment49</name>
- <xalign>7.45058e-09</xalign>
- <yalign>7.45058e-09</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>scope-optionmenu</name>
- <can_focus>True</can_focus>
- <items>One
-Sub
-</items>
- <initial_choice>0</initial_choice>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox109</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <name>rootdn-entry</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>rootdn-button</name>
- <can_focus>True</can_focus>
- <label> S_how Supported Bases </label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label457</name>
- <label>_Timeout (minutes):</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>1</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment50</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>1</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox110</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label458</name>
- <label>1:00</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHScale</class>
- <name>timeout-scale</name>
- <can_focus>True</can_focus>
- <draw_value>False</draw_value>
- <value_pos>GTK_POS_LEFT</value_pos>
- <digits>0</digits>
- <policy>GTK_UPDATE_DELAYED</policy>
- <value>3</value>
- <lower>1</lower>
- <upper>5</upper>
- <step>0.5</step>
- <page>1</page>
- <page_size>0</page_size>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label459</name>
- <label>5:00</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>3</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label460</name>
- <label>Selected:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label461</name>
- <label>2:30</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label462</name>
- <label>_Download limit:</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment51</name>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox111</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkSpinButton</class>
- <name>download-limit-spinbutton</name>
- <can_focus>True</can_focus>
- <climb_rate>1</climb_rate>
- <digits>0</digits>
- <numeric>False</numeric>
- <update_policy>GTK_UPDATE_ALWAYS</update_policy>
- <snap>False</snap>
- <wrap>False</wrap>
- <value>100</value>
- <lower>0</lower>
- <upper>10000</upper>
- <step>1</step>
- <page>10</page>
- <page_size>10</page_size>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label463</name>
- <label>cards</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkNotebook</class>
- <name>searching-tab-help</name>
- <show_tabs>False</show_tabs>
- <show_border>False</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox112</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap60</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label464</name>
- <label>The search base is the distinguished name (DN) of the entry where your searches will
-begin. If you leave this blank, the search will begin at the root of the directory tree.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label465</name>
- <label>label163</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox113</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap61</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label466</name>
- <label>The search scope defines how deep you would like the search to extend down the
-directory tree. A search scope of &quot;sub&quot; will include all entries below your search base.
-A search scope of &quot;one&quot; will only include the entries one level beneath your base.
-</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label467</name>
- <label>label164</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox114</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap62</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label468</name>
- <label>This option controls how long a search will be run.</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label469</name>
- <label>label165</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox115</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap63</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label470</name>
- <label>This is the maximum number of entries to download. Setting this number to be
-too large will slow down your addressbook.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label471</name>
- <label>label166</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>objectclasses-tab-window</name>
- <visible>False</visible>
- <title>objectclasses-tab</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>objectclasses-tab</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox93</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox51</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label405</name>
- <label>Objectclasses Used on Server:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>objectclasses-server-table</name>
- <creation_function>objectclasses_create_server_table</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Tue, 16 Apr 2002 17:09:21 GMT</last_modification_time>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox52</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label407</name>
- <label>
-</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkVButtonBox</class>
- <name>vbuttonbox15</name>
- <layout_style>GTK_BUTTONBOX_START</layout_style>
- <spacing>1</spacing>
- <child_min_width>47</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>objectclasses-add-button</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_Add -&gt;</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>objectclasses-remove-button</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>&lt;- _Remove</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox53</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label408</name>
- <label>Objectclasses Used in Evolution:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>objectclasses-evolution-table</name>
- <creation_function>objectclasses_create_evolution_table</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Tue, 16 Apr 2002 17:09:43 GMT</last_modification_time>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHButtonBox</class>
- <name>hbuttonbox16</name>
- <border_width>6</border_width>
- <layout_style>GTK_BUTTONBOX_DEFAULT_STYLE</layout_style>
- <spacing>0</spacing>
- <child_min_width>87</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>objectclasses-default-button</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>R_estore Defaults</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>mappings-tab-window</name>
- <visible>False</visible>
- <title>mappings-tab</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>mappings-tab</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox94</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox55</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow21</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>clist18</name>
- <can_focus>True</can_focus>
- <columns>2</columns>
- <column_widths>146,80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>True</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label411</name>
- <label>Evolution Attribute</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label412</name>
- <label>Associated LDAP Attribute</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox56</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label413</name>
- <label>
-</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkVButtonBox</class>
- <name>vbuttonbox16</name>
- <layout_style>GTK_BUTTONBOX_DEFAULT_STYLE</layout_style>
- <spacing>0</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button71</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_Add Mapping</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button72</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_Edit Mapping</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button73</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_Delete Mapping</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHButtonBox</class>
- <name>hbuttonbox17</name>
- <layout_style>GTK_BUTTONBOX_DEFAULT_STYLE</layout_style>
- <spacing>30</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button74</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>Re_store Defaults</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GtkWindow</class>
- <name>dn-customization-tab-window</name>
- <visible>False</visible>
- <title>dn-customization-tab</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>dn-customization-tab</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkNotebook</class>
- <name>notebook24</name>
- <show_tabs>False</show_tabs>
- <show_border>False</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox116</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap64</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label473</name>
- <label>To add an attribute to the DN, select it from the list and click the &quot;Add Attribute&quot; button.
-Any values that you add to the DN will become required values for any new contacts
-that you add to the directory on the LDAP server. </label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label474</name>
- <label>label163</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox117</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GnomePixmap</class>
- <name>pixmap65</name>
- <filename>gnome-hint.png</filename>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label475</name>
- <label>Selecting this option will let you change Evolution's default settings for LDAP
-searches, and for creating and editting contacts. </label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label476</name>
- <label>label164</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table31</name>
- <border_width>3</border_width>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox64</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>False</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label477</name>
- <label></label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkVButtonBox</class>
- <name>vbuttonbox17</name>
- <layout_style>GTK_BUTTONBOX_START</layout_style>
- <spacing>10</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button78</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_Add to DN</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow22</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>clist19</name>
- <can_focus>True</can_focus>
- <columns>2</columns>
- <column_widths>152,80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>True</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label478</name>
- <label>LDAP Attribute</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label479</name>
- <label>Corresponding Evolution Attribute</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox118</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label480</name>
- <label>_Distinguished Name (DN):</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>entry53</default_focus_target>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry53</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHButtonBox</class>
- <name>hbuttonbox18</name>
- <layout_style>GTK_BUTTONBOX_DEFAULT_STYLE</layout_style>
- <spacing>0</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>False</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button79</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_Restore Defaults</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GnomeDialog</class>
- <name>supported-bases-dialog</name>
- <visible>False</visible>
- <title>Supported Search Bases</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <default_width>300</default_width>
- <default_height>200</default_height>
- <allow_shrink>True</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>dialog-vbox5</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>dialog-action_area5</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button107</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button109</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>supported-bases-table</name>
- <creation_function>supported_bases_create_table</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Fri, 12 Apr 2002 20:06:45 GMT</last_modification_time>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/addressbook/gui/component/select-names/.cvsignore b/addressbook/gui/component/select-names/.cvsignore
deleted file mode 100644
index cd669499fa..0000000000
--- a/addressbook/gui/component/select-names/.cvsignore
+++ /dev/null
@@ -1,12 +0,0 @@
-.deps
-.libs
-.pure
-Makefile
-Makefile.in
-*.lo
-*.la
-Evolution-Addressbook-SelectNames-stubs.c
-Evolution-Addressbook-SelectNames-skels.c
-Evolution-Addressbook-SelectNames-common.c
-Evolution-Addressbook-SelectNames.h
-GNOME_Evolution_Addressbook_SelectNames.oaf
diff --git a/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl b/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl
deleted file mode 100644
index f25279bb38..0000000000
--- a/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * CORBA interface for the SelectNames dialog.
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc.
- */
-
-#include <Bonobo.idl>
-
-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,
- 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;
- string title;
- };
-
- typedef sequence<Section> SectionList;
-
- exception DuplicateID {};
- exception SectionNotFound {};
-
- void addSection (in string id, in string title)
- raises (DuplicateID);
- void addSectionWithLimit (in string id, in string title, in short limit)
- raises (DuplicateID);
-
- Bonobo::Control getEntryBySection (in string section_id)
- raises (SectionNotFound);
-
- void activateDialog (in string section_id);
- };
-
-
-};
-};
-};
diff --git a/addressbook/gui/component/select-names/GNOME_Evolution_Addressbook_SelectNames.oaf.in b/addressbook/gui/component/select-names/GNOME_Evolution_Addressbook_SelectNames.oaf.in
deleted file mode 100644
index 7f26e2aaed..0000000000
--- a/addressbook/gui/component/select-names/GNOME_Evolution_Addressbook_SelectNames.oaf.in
+++ /dev/null
@@ -1,29 +0,0 @@
-<oaf_info>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_SelectNamesFactory"
- type="exe"
- location="evolution-addressbook">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory for the Addressbook's name selection interface"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Addressbook_SelectNames"
- type="factory"
- location="OAFIID:GNOME_Evolution_Addressbook_SelectNamesFactory">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/Addressbook/SelectNames"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Evolution's addressbook name selection interface."/>
-
-</oaf_server>
-
-</oaf_info> \ No newline at end of file
diff --git a/addressbook/gui/component/select-names/Makefile.am b/addressbook/gui/component/select-names/Makefile.am
deleted file mode 100644
index b417f18678..0000000000
--- a/addressbook/gui/component/select-names/Makefile.am
+++ /dev/null
@@ -1,90 +0,0 @@
-# CORBA stuff
-
-idldir = $(datadir)/idl
-
-idl_DATA = \
- Evolution-Addressbook-SelectNames.idl
-
-IDL_GENERATED = \
- Evolution-Addressbook-SelectNames.h \
- Evolution-Addressbook-SelectNames-common.c \
- Evolution-Addressbook-SelectNames-skels.c \
- Evolution-Addressbook-SelectNames-stubs.c
-
-Evolution-Addressbook-SelectNames-impl.o: Evolution-Addressbook-SelectNames.h
-
-$(IDL_GENERATED): $(idl_DATA)
- $(ORBIT_IDL) -I $(srcdir) -I $(datadir)/idl `$(GNOME_CONFIG) --cflags idl` \
- $(srcdir)/Evolution-Addressbook-SelectNames.idl
-
-oafdir = $(datadir)/oaf
-
-oaf_in_files = GNOME_Evolution_Addressbook_SelectNames.oaf.in
-oaf_DATA = $(oaf_in_files:.oaf.in=.oaf)
-
-@XML_I18N_MERGE_OAF_RULE@
-
-
-INCLUDES = \
- -DG_LOG_DOMAIN=\"evolution-addressbook\" \
- -I$(top_srcdir) \
- -I$(top_builddir) \
- -I$(top_srcdir)/shell \
- -I$(top_builddir)/shell \
- -I$(top_srcdir)/widgets/e-text \
- -I$(top_srcdir)/widgets/e-table \
- -I$(top_srcdir)/addressbook/gui/minicard \
- -I$(top_srcdir)/addressbook/gui/widgets \
- -I$(top_srcdir)/addressbook/contact-editor \
- -I$(top_srcdir)/addressbook/backend \
- -I$(top_builddir)/addressbook/backend \
- -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
- -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
- -DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \
- -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
- -DCAMEL_PROVIDERDIR=\""$(providerdir)"\" \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
-
-lib_LTLIBRARIES = libeselectnames.la
-
-libeselectnames_la_SOURCES = \
- $(IDL_GENERATED) \
- e-select-names-bonobo.c \
- e-select-names-bonobo.h \
- e-select-names-completion.c \
- e-select-names-completion.h \
- e-select-names-factory.c \
- e-select-names-factory.h \
- e-select-names-manager.c \
- e-select-names-manager.h \
- e-select-names-model.c \
- e-select-names-model.h \
- e-select-names-popup.c \
- e-select-names-popup.h \
- e-select-names-table-model.c \
- e-select-names-table-model.h \
- 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
-
-gladedir = $(datadir)/evolution/glade
-glade_DATA = select-names.glade
-
-etspecdir = $(datadir)/evolution/etspec
-etspec_DATA = e-select-names.etspec
-
-EXTRA_DIST = \
- $(glade_DATA) \
- $(oaf_in_files) \
- $(oaf_DATA) \
- $(idl_DATA) \
- $(etspec_DATA)
-
-BUILT_SOURCES = $(IDL_GENERATED)
-CLEANFILES = $(BUILT_SOURCES)
-
-dist-hook:
- cd $(distdir); rm -f $(BUILT_SOURCES)
diff --git a/addressbook/gui/component/select-names/e-select-names-bonobo.c b/addressbook/gui/component/select-names/e-select-names-bonobo.c
deleted file mode 100644
index 4a32790cd4..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-bonobo.c
+++ /dev/null
@@ -1,521 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* e-select-names-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.
- *
- * Author: Ettore Perazzoli
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "e-select-names-bonobo.h"
-#include "e-simple-card-bonobo.h"
-
-#include <bonobo/bonobo-property-bag.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-event-source.h>
-
-#include <gal/util/e-util.h>
-#include <gal/e-text/e-entry.h>
-
-#include "Evolution-Addressbook-SelectNames.h"
-
-#include "e-select-names-manager.h"
-#include "e-select-names-model.h"
-#include "e-select-names-text-model.h"
-#include "e-select-names-completion.h"
-
-
-
-#define PARENT_TYPE bonobo_object_get_type ()
-static BonoboObjectClass *parent_class = NULL;
-
-struct _ESelectNamesBonoboPrivate {
- ESelectNamesManager *manager;
- BonoboEventSource *event_source;
-};
-
-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
-};
-typedef enum _EntryPropertyID EntryPropertyID;
-
-
-/* PropertyBag implementation for the entry widgets. */
-
-static void
-entry_get_property_fn (BonoboPropertyBag *bag,
- BonoboArg *arg,
- unsigned int arg_id,
- CORBA_Environment *ev,
- void *user_data)
-{
- GtkWidget *w;
-
- w = GTK_WIDGET (user_data);
-
- switch (arg_id) {
- case ENTRY_PROPERTY_ID_TEXT:
- {
- ETextModel *text_model;
- text_model = E_TEXT_MODEL (gtk_object_get_data (GTK_OBJECT (w), "select_names_text_model"));
- g_assert (text_model != NULL);
-
- BONOBO_ARG_SET_STRING (arg, e_text_model_get_text (text_model));
- break;
- }
-
- case ENTRY_PROPERTY_ID_ADDRESSES:
- {
- ESelectNamesModel *model;
- char *text;
-
- model = E_SELECT_NAMES_MODEL (gtk_object_get_data (GTK_OBJECT (w), "select_names_model"));
- g_assert (model != NULL);
-
- text = e_select_names_model_get_address_text (model, ", ");
- BONOBO_ARG_SET_STRING (arg, text);
- g_free (text);
- }
- break;
-
- case ENTRY_PROPERTY_ID_DESTINATIONS:
- {
- ESelectNamesModel *model;
- char *text;
-
- model = E_SELECT_NAMES_MODEL (gtk_object_get_data (GTK_OBJECT (w), "select_names_model"));
- g_assert (model != NULL);
-
- text = e_select_names_model_export_destinationv (model);
- BONOBO_ARG_SET_STRING (arg, text);
- g_free (text);
- }
- 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 (gtk_object_get_data (GTK_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);
- gtk_object_unref (GTK_OBJECT (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;
- comp = E_SELECT_NAMES_COMPLETION (gtk_object_get_data (GTK_OBJECT (w), "completion_handler"));
- g_assert (comp != NULL);
-
- BONOBO_ARG_SET_BOOLEAN (arg, e_select_names_completion_get_match_contact_lists (comp));
- break;
- }
-
- case ENTRY_PROPERTY_ID_ENTRY_CHANGED:
- /* This is a read-only property. */
- g_assert_not_reached ();
- break;
-
- default:
- break;
- }
-}
-
-static void
-entry_set_property_fn (BonoboPropertyBag *bag,
- const BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
-{
- GtkWidget *w;
-
- w = GTK_WIDGET (user_data);
-
- switch (arg_id) {
-
- case ENTRY_PROPERTY_ID_TEXT:
- case ENTRY_PROPERTY_ID_ADDRESSES:
- {
- ESelectNamesModel *model;
- model = E_SELECT_NAMES_MODEL (gtk_object_get_data (GTK_OBJECT (w), "select_names_model"));
- 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);
- break;
- }
-
- case ENTRY_PROPERTY_ID_DESTINATIONS:
- {
- ESelectNamesModel *model;
- model = E_SELECT_NAMES_MODEL (gtk_object_get_data (GTK_OBJECT (w), "select_names_model"));
- 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);
- break;
- }
-
- case ENTRY_PROPERTY_ID_ALLOW_CONTACT_LISTS:
- {
- ESelectNamesCompletion *comp;
- comp = E_SELECT_NAMES_COMPLETION (gtk_object_get_data (GTK_OBJECT (w), "completion_handler"));
- g_assert (comp != NULL);
-
- e_select_names_completion_set_match_contact_lists (comp, BONOBO_ARG_GET_BOOLEAN (arg));
- break;
- }
-
- case ENTRY_PROPERTY_ID_ENTRY_CHANGED:
- gtk_object_set_data (GTK_OBJECT (w), "entry_property_id_changed", GUINT_TO_POINTER (1));
- break;
-
- default:
- break;
- }
-}
-
-
-/* CORBA interface implementation. */
-
-static POA_GNOME_Evolution_Addressbook_SelectNames__vepv SelectNames_vepv;
-
-static POA_GNOME_Evolution_Addressbook_SelectNames *
-create_servant (void)
-{
- POA_GNOME_Evolution_Addressbook_SelectNames *servant;
- CORBA_Environment ev;
-
- servant = (POA_GNOME_Evolution_Addressbook_SelectNames *) g_new0 (BonoboObjectServant, 1);
- servant->vepv = &SelectNames_vepv;
-
- CORBA_exception_init (&ev);
-
- POA_GNOME_Evolution_Addressbook_SelectNames__init ((PortableServer_Servant) servant, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_free (servant);
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- CORBA_exception_free (&ev);
-
- return servant;
-}
-
-static void
-impl_SelectNames_add_section (PortableServer_Servant servant,
- const CORBA_char *id,
- const CORBA_char *title,
- CORBA_Environment *ev)
-{
- BonoboObject *bonobo_object;
- ESelectNamesBonobo *select_names;
- ESelectNamesBonoboPrivate *priv;
-
- bonobo_object = bonobo_object_from_servant (servant);
- select_names = E_SELECT_NAMES_BONOBO (bonobo_object);
- priv = select_names->priv;
-
- e_select_names_manager_add_section (priv->manager, id, title);
-}
-
-static void
-impl_SelectNames_add_section_with_limit (PortableServer_Servant servant,
- const CORBA_char *id,
- const CORBA_char *title,
- CORBA_short limit,
- CORBA_Environment *ev)
-{
- BonoboObject *bonobo_object;
- ESelectNamesBonobo *select_names;
- ESelectNamesBonoboPrivate *priv;
-
- bonobo_object = bonobo_object_from_servant (servant);
- select_names = E_SELECT_NAMES_BONOBO (bonobo_object);
- priv = select_names->priv;
-
- e_select_names_manager_add_section_with_limit (priv->manager, id, title, limit);
-}
-
-static void
-entry_changed (GtkWidget *widget, BonoboControl *control)
-{
- gboolean changed = GPOINTER_TO_UINT (gtk_object_get_data (GTK_OBJECT (widget), "entry_property_id_changed"));
-
- if (!changed)
- bonobo_control_set_property (control, "entry_changed", TRUE, NULL);
-}
-
-static void
-manager_changed_cb (ESelectNamesManager *manager, const gchar *section_id, gint changed_working_copy, gpointer closure)
-{
- ESelectNamesBonobo *select_names = E_SELECT_NAMES_BONOBO (closure);
- BonoboArg *arg;
-
- arg = bonobo_arg_new (BONOBO_ARG_STRING);
- BONOBO_ARG_SET_STRING (arg, section_id);
-
- bonobo_event_source_notify_listeners_full (select_names->priv->event_source,
- "GNOME/Evolution",
- "changed",
- changed_working_copy ? "working_copy" : "model",
- arg, NULL);
-
- bonobo_arg_release (arg);
-}
-
-static void
-manager_ok_cb (ESelectNamesManager *manager, gpointer closure)
-{
- ESelectNamesBonobo *select_names = E_SELECT_NAMES_BONOBO (closure);
- BonoboArg *arg;
-
- arg = bonobo_arg_new (BONOBO_ARG_NULL);
-
- bonobo_event_source_notify_listeners_full (select_names->priv->event_source,
- "GNOME/Evolution",
- "ok",
- "dialog",
- arg,
- NULL);
-
- bonobo_arg_release (arg);
-}
-
-static Bonobo_Control
-impl_SelectNames_get_entry_for_section (PortableServer_Servant servant,
- const CORBA_char *section_id,
- CORBA_Environment *ev)
-{
- BonoboObject *bonobo_object;
- ESelectNamesBonobo *select_names;
- ESelectNamesBonoboPrivate *priv;
- GtkWidget *entry_widget;
- BonoboControl *control;
- BonoboPropertyBag *property_bag;
-
- bonobo_object = bonobo_object_from_servant (servant);
- select_names = E_SELECT_NAMES_BONOBO (bonobo_object);
- priv = select_names->priv;
-
- entry_widget = e_select_names_manager_create_entry (priv->manager, section_id);
- gtk_widget_show (entry_widget);
-
- if (entry_widget == NULL) {
- CORBA_exception_set (ev,
- CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Addressbook_SelectNames_SectionNotFound,
- NULL);
- return CORBA_OBJECT_NIL;
- }
-
- control = bonobo_control_new (entry_widget);
-
- property_bag = bonobo_property_bag_new (entry_get_property_fn, entry_set_property_fn, entry_widget);
- bonobo_property_bag_add (property_bag, "text", ENTRY_PROPERTY_ID_TEXT,
- BONOBO_ARG_STRING, NULL, NULL,
- BONOBO_PROPERTY_READABLE | BONOBO_PROPERTY_WRITEABLE);
- bonobo_property_bag_add (property_bag, "addresses", ENTRY_PROPERTY_ID_ADDRESSES,
- BONOBO_ARG_STRING, NULL, NULL,
- BONOBO_PROPERTY_READABLE | BONOBO_PROPERTY_WRITEABLE);
- 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);
- bonobo_property_bag_add (property_bag, "entry_changed", ENTRY_PROPERTY_ID_ENTRY_CHANGED,
- BONOBO_ARG_BOOLEAN, NULL, NULL,
- BONOBO_PROPERTY_WRITEABLE);
-
- bonobo_control_set_properties (control, property_bag);
-
- gtk_signal_connect (GTK_OBJECT (entry_widget), "changed", GTK_SIGNAL_FUNC (entry_changed), control);
-
- return CORBA_Object_duplicate (bonobo_object_corba_objref (BONOBO_OBJECT (control)), ev);
-}
-
-static void
-impl_SelectNames_activate_dialog (PortableServer_Servant servant,
- const CORBA_char *section_id,
- CORBA_Environment *ev)
-{
- BonoboObject *bonobo_object;
- ESelectNamesBonobo *select_names;
- ESelectNamesBonoboPrivate *priv;
-
- bonobo_object = bonobo_object_from_servant (servant);
- select_names = E_SELECT_NAMES_BONOBO (bonobo_object);
- priv = select_names->priv;
-
- e_select_names_manager_activate_dialog (priv->manager, section_id);
-}
-
-
-/* GtkObject methods. */
-
-static void
-impl_destroy (GtkObject *object)
-{
- ESelectNamesBonobo *select_names;
- ESelectNamesBonoboPrivate *priv;
-
- select_names = E_SELECT_NAMES_BONOBO (object);
- priv = select_names->priv;
-
- if (priv->manager->names) {
- gtk_widget_destroy (GTK_WIDGET (priv->manager->names));
- priv->manager->names = NULL;
- }
-
- gtk_object_unref (GTK_OBJECT (priv->manager));
-
- g_free (priv);
-}
-
-
-static void
-corba_class_init ()
-{
- POA_GNOME_Evolution_Addressbook_SelectNames__vepv *vepv;
- POA_GNOME_Evolution_Addressbook_SelectNames__epv *epv;
- PortableServer_ServantBase__epv *base_epv;
-
- base_epv = g_new0 (PortableServer_ServantBase__epv, 1);
- base_epv->_private = NULL;
- base_epv->finalize = NULL;
- base_epv->default_POA = NULL;
-
- epv = g_new0 (POA_GNOME_Evolution_Addressbook_SelectNames__epv, 1);
- epv->addSection = impl_SelectNames_add_section;
- epv->addSectionWithLimit = impl_SelectNames_add_section_with_limit;
- epv->getEntryBySection = impl_SelectNames_get_entry_for_section;
- epv->activateDialog = impl_SelectNames_activate_dialog;
-
- vepv = &SelectNames_vepv;
- vepv->Bonobo_Unknown_epv = bonobo_object_get_epv ();
- vepv->GNOME_Evolution_Addressbook_SelectNames_epv = epv;
-}
-
-static void
-class_init (ESelectNamesBonoboClass *klass)
-{
- GtkObjectClass *object_class;
-
- object_class = GTK_OBJECT_CLASS (klass);
- parent_class = gtk_type_class (bonobo_object_get_type ());
-
- object_class->destroy = impl_destroy;
-
- corba_class_init ();
-}
-
-static void
-init (ESelectNamesBonobo *select_names)
-{
- ESelectNamesBonoboPrivate *priv;
-
- priv = g_new (ESelectNamesBonoboPrivate, 1);
-
- priv->manager = e_select_names_manager_new ();
- priv->event_source = NULL;
-
- gtk_signal_connect (GTK_OBJECT (priv->manager),
- "changed",
- GTK_SIGNAL_FUNC (manager_changed_cb),
- select_names);
-
- gtk_signal_connect (GTK_OBJECT (priv->manager),
- "ok",
- GTK_SIGNAL_FUNC (manager_ok_cb),
- select_names);
-
- select_names->priv = priv;
-}
-
-
-void
-e_select_names_bonobo_construct (ESelectNamesBonobo *select_names,
- GNOME_Evolution_Addressbook_SelectNames corba_object)
-{
- g_return_if_fail (select_names != NULL);
- g_return_if_fail (E_IS_SELECT_NAMES_BONOBO (select_names));
-
- bonobo_object_construct (BONOBO_OBJECT (select_names), corba_object);
-
- g_assert (select_names->priv->event_source == NULL);
- select_names->priv->event_source = bonobo_event_source_new ();
- bonobo_object_add_interface (BONOBO_OBJECT (select_names), BONOBO_OBJECT (select_names->priv->event_source));
-}
-
-ESelectNamesBonobo *
-e_select_names_bonobo_new (void)
-{
- POA_GNOME_Evolution_Addressbook_SelectNames *servant;
- GNOME_Evolution_Addressbook_SelectNames corba_object;
- ESelectNamesBonobo *select_names;
-
- servant = create_servant ();
- if (servant == NULL)
- return NULL;
-
- select_names = gtk_type_new (e_select_names_bonobo_get_type ());
-
- corba_object = bonobo_object_activate_servant (BONOBO_OBJECT (select_names), servant);
- e_select_names_bonobo_construct (select_names, corba_object);
-
- return select_names;
-}
-
-
-E_MAKE_TYPE (e_select_names_bonobo, "ESelectNamesBonobo", ESelectNamesBonobo, class_init, init, PARENT_TYPE)
diff --git a/addressbook/gui/component/select-names/e-select-names-bonobo.h b/addressbook/gui/component/select-names/e-select-names-bonobo.h
deleted file mode 100644
index f254dd6e94..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-bonobo.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* e-select-names-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.
- *
- * Author: Ettore Perazzoli
- */
-
-#ifndef __E_SELECT_NAMES_BONOBO_H__
-#define __E_SELECT_NAMES_BONOBO_H__
-
-#include <bonobo/bonobo-object.h>
-
-#include "Evolution-Addressbook-SelectNames.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define E_TYPE_SELECT_NAMES_BONOBO (e_select_names_bonobo_get_type ())
-#define E_SELECT_NAMES_BONOBO(obj) (GTK_CHECK_CAST ((obj), E_TYPE_SELECT_NAMES_BONOBO, ESelectNamesBonobo))
-#define E_SELECT_NAMES_BONOBO_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_SELECT_NAMES_BONOBO, ESelectNamesBonoboClass))
-#define E_IS_SELECT_NAMES_BONOBO(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_SELECT_NAMES_BONOBO))
-#define E_IS_SELECT_NAMES_BONOBO_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_SELECT_NAMES_BONOBO))
-
-
-typedef struct _ESelectNamesBonobo ESelectNamesBonobo;
-typedef struct _ESelectNamesBonoboPrivate ESelectNamesBonoboPrivate;
-typedef struct _ESelectNamesBonoboClass ESelectNamesBonoboClass;
-
-struct _ESelectNamesBonobo {
- BonoboObject parent;
-
- ESelectNamesBonoboPrivate *priv;
-};
-
-struct _ESelectNamesBonoboClass {
- BonoboObjectClass parent_class;
-};
-
-
-GtkType e_select_names_bonobo_get_type (void);
-void e_select_names_bonobo_construct (ESelectNamesBonobo *select_names,
- GNOME_Evolution_Addressbook_SelectNames corba_object);
-ESelectNamesBonobo *e_select_names_bonobo_new (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __E_SELECT_NAMES_BONOBO_H__ */
diff --git a/addressbook/gui/component/select-names/e-select-names-completion.c b/addressbook/gui/component/select-names/e-select-names-completion.c
deleted file mode 100644
index f905cf872c..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-completion.c
+++ /dev/null
@@ -1,1312 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-select-names-completion.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-select-names-completion.h"
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-
-#include <gtk/gtksignal.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-util.h>
-
-#include <gal/unicode/gunicode.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>
-
-#define MINIMUM_QUERY_LENGTH 3
-
-typedef struct {
- EBook *book;
- guint book_view_tag;
- EBookView *book_view;
- ESelectNamesCompletion *comp;
- guint card_added_tag;
- guint seq_complete_tag;
- gboolean sequence_complete_received;
-} ESelectNamesCompletionBookData;
-
-struct _ESelectNamesCompletionPrivate {
-
- ESelectNamesTextModel *text_model;
-
- GList *book_data;
- gint books_not_ready;
- gint pending_completion_seq;
-
- gchar *waiting_query;
- gint waiting_pos, waiting_limit;
- gchar *query_text;
-
- gchar *cached_query_text;
- GList *cached_cards;
- gboolean cache_complete;
-
- gboolean match_contact_lists;
- gboolean primary_only;
-
- gboolean can_fail_due_to_too_many_hits; /* like LDAP, for example... */
-};
-
-static void e_select_names_completion_class_init (ESelectNamesCompletionClass *);
-static void e_select_names_completion_init (ESelectNamesCompletion *);
-static void e_select_names_completion_destroy (GtkObject *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_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);
-
-static void e_select_names_completion_handle_request (ECompletion *, const gchar *txt, gint pos, gint limit);
-static void e_select_names_completion_end (ECompletion *);
-
-static GtkObjectClass *parent_class;
-
-static FILE *out;
-
-/*
- *
- * Query builders
- *
- */
-
-typedef gchar *(*BookQuerySExp) (ESelectNamesCompletion *);
-typedef ECompletionMatch *(*BookQueryMatchTester) (ESelectNamesCompletion *, EDestination *);
-
-static void
-our_match_destroy (ECompletionMatch *match)
-{
- gtk_object_unref (GTK_OBJECT (match->user_data));
-}
-
-static ECompletionMatch *
-make_match (EDestination *dest, const gchar *menu_form, double score)
-{
- ECompletionMatch *match;
- ECard *card = e_destination_get_card (dest);
-
- match = e_completion_match_new (e_destination_get_name (dest), menu_form, score);
-
- e_completion_match_set_text (match, e_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))) {
- gtk_object_unref (GTK_OBJECT (match));
- return NULL;
- }
-
- /* 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_minor = e_destination_get_email_num (dest);
-
- match->user_data = dest;
- gtk_object_ref (GTK_OBJECT (dest));
-
- match->destroy = our_match_destroy;
-
- return match;
-}
-
-/*
- * Nickname query
- */
-
-static gchar *
-sexp_nickname (ESelectNamesCompletion *comp)
-{
- gchar *query = g_strdup_printf ("(beginswith \"nickname\" \"%s\")", comp->priv->query_text);
-
- return query;
-}
-
-static ECompletionMatch *
-match_nickname (ESelectNamesCompletion *comp, EDestination *dest)
-{
- ECompletionMatch *match = NULL;
- gint len;
- ECard *card = e_destination_get_card (dest);
- double score;
-
- if (card->nickname == NULL)
- return NULL;
-
- len = g_utf8_strlen (comp->priv->query_text, -1);
- if (card->nickname && !g_utf8_strncasecmp (comp->priv->query_text, card->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 */
- score *= 10;
-
- name = e_destination_get_name (dest);
- if (name && *name)
- str = g_strdup_printf ("'%s' %s <%s>", card->nickname, name, e_destination_get_email (dest));
- else
- str = g_strdup_printf ("'%s' <%s>", card->nickname, e_destination_get_email (dest));
-
- match = make_match (dest, str, score);
- g_free (str);
- }
-
- return match;
-}
-
-/*
- * E-Mail Query
- */
-
-static gchar *
-sexp_email (ESelectNamesCompletion *comp)
-{
- return g_strdup_printf ("(beginswith \"email\" \"%s\")", comp->priv->query_text);
-}
-
-static ECompletionMatch *
-match_email (ESelectNamesCompletion *comp, EDestination *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);
- double score;
-
- if (email
- && !g_utf8_strncasecmp (comp->priv->query_text, email, len)
- && !e_destination_is_evolution_list (dest)) {
-
- gchar *str;
-
- score = len * 2; /* 2 points for each matching character */
-
- if (name && *name)
- str = g_strdup_printf ("<%s> %s", email, name);
- else
- str = g_strdup (email);
-
- match = make_match (dest, str, score);
-
- g_free (str);
-
- return match;
- }
-
- return NULL;
-}
-
-/*
- * Name Query
- */
-
-static gchar *
-name_style_query (ESelectNamesCompletion *comp, const gchar *field)
-{
- if (comp && comp->priv->query_text && *comp->priv->query_text) {
- gchar *cpy = g_strdup (comp->priv->query_text), *c;
- gchar **strv;
- gchar *query;
- gint i, count=0;
-
- for (c = cpy; *c; ++c) {
- if (*c == ',')
- *c = ' ';
- }
-
- strv = g_strsplit (cpy, " ", 0);
- for (i=0; strv[i]; ++i) {
- gchar *old;
- ++count;
- g_strstrip (strv[i]);
- old = strv[i];
- strv[i] = g_strdup_printf ("(beginswith \"%s\" \"%s\")", field, old);
- g_free (old);
- }
-
- if (count == 1) {
- query = strv[0];
- strv[0] = NULL;
- } else {
- gchar *joined = g_strjoinv (" ", strv);
- query = g_strdup_printf ("(and %s)", joined);
- g_free (joined);
- }
-
- g_free (cpy);
- g_strfreev (strv);
-
- return query;
- }
-
- return NULL;
-}
-
-static gchar *
-sexp_name (ESelectNamesCompletion *comp)
-{
- return name_style_query (comp, "full_name");
-}
-
-static ECompletionMatch *
-match_name (ESelectNamesCompletion *comp, EDestination *dest)
-{
- ECompletionMatch *final_match = NULL;
- gchar *menu_text = NULL;
- ECard *card;
- const gchar *email;
- gint match_len = 0;
- ECardMatchType match;
- ECardMatchPart first_match;
- double score = 0;
- gboolean have_given, have_additional, have_family;
-
- card = e_destination_get_card (dest);
-
- if (card->name == NULL)
- return NULL;
-
- email = e_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);
-
- if (match <= E_CARD_MATCH_NONE)
- return NULL;
-
- score = match_len * 3; /* three points per match character */
-
-#if 0
- if (card->nickname) {
- /* We massively boost the score if the nickname exists and is the same as one of the "real" names. This keeps the
- nickname from matching ahead of the real name for this card. */
- len = strlen (card->nickname);
- if ((card->name->given && !g_utf8_strncasecmp (card->name->given, card->nickname, MIN (strlen (card->name->given), len)))
- || (card->name->family && !g_utf8_strncasecmp (card->name->family, card->nickname, MIN (strlen (card->name->family), len)))
- || (card->name->additional && !g_utf8_strncasecmp (card->name->additional, card->nickname, MIN (strlen (card->name->additional), len))))
- score *= 100;
- }
-#endif
-
- have_given = card->name->given && *card->name->given;
- have_additional = card->name->additional && *card->name->additional;
- have_family = card->name->family && *card->name->family;
-
- if (e_card_evolution_list (card)) {
-
- menu_text = e_card_name_to_string (card->name);
-
- } else if (first_match == E_CARD_MATCH_PART_GIVEN_NAME) {
-
- if (have_family)
- menu_text = g_strdup_printf ("%s %s <%s>", card->name->given, card->name->family, email);
- else
- menu_text = g_strdup_printf ("%s <%s>", card->name->given, email);
-
- } else if (first_match == E_CARD_MATCH_PART_ADDITIONAL_NAME) {
-
- if (have_given) {
-
- menu_text = g_strdup_printf ("%s%s%s, %s <%s>",
- card->name->additional,
- have_family ? " " : "",
- have_family ? card->name->family : "",
- card->name->given,
- email);
- } else {
-
- menu_text = g_strdup_printf ("%s%s%s <%s>",
- card->name->additional,
- have_family ? " " : "",
- have_family ? card->name->family : "",
- email);
- }
-
- } else if (first_match == E_CARD_MATCH_PART_FAMILY_NAME) {
-
- if (have_given)
- menu_text = g_strdup_printf ("%s, %s%s%s <%s>",
- card->name->family,
- card->name->given,
- have_additional ? " " : "",
- have_additional ? card->name->additional : "",
- email);
- else
- menu_text = g_strdup_printf ("%s <%s>", card->name->family, email);
-
- } else { /* something funny happened */
-
- menu_text = g_strdup_printf ("<%s> ???", email);
-
- }
-
- if (menu_text) {
- g_strstrip (menu_text);
- final_match = make_match (dest, menu_text, score);
- g_free (menu_text);
- }
-
- return final_match;
-}
-
-/*
- * File As Query
- */
-
-static gchar *
-sexp_file_as (ESelectNamesCompletion *comp)
-{
- return name_style_query (comp, "file_as");
-}
-
-static ECompletionMatch *
-match_file_as (ESelectNamesCompletion *comp, EDestination *dest)
-{
- const gchar *name;
- const gchar *email;
- gchar *cpy, **strv, *menu_text;
- gint i, len;
- double score = 0.00001;
- ECompletionMatch *match;
-
- name = e_destination_get_name (dest);
- email = e_destination_get_email (dest);
-
- if (!(name && *name))
- return NULL;
-
- cpy = g_strdup (comp->priv->query_text);
- strv = g_strsplit (cpy, " ", 0);
-
- for (i=0; strv[i] && score > 0; ++i) {
- len = g_utf8_strlen (strv[i], -1);
- if (!g_utf8_strncasecmp (name, strv[i], len))
- score += len; /* one point per character of the match */
- else
- score = 0;
- }
-
- g_free (cpy);
- g_strfreev (strv);
-
- if (score <= 0)
- return NULL;
-
- menu_text = g_strdup_printf ("%s <%s>", name, email);
- g_strstrip (menu_text);
- match = make_match (dest, menu_text, score);
- g_free (menu_text);
-
- return match;
-}
-
-/*
- * Initials Query
- */
-
-static gchar *
-sexp_initials (ESelectNamesCompletion *comp)
-{
- return NULL;
-}
-
-static ECompletionMatch *
-match_initials (ESelectNamesCompletion *comp, EDestination *dest)
-{
- return NULL;
-}
-
-
-typedef struct _BookQuery BookQuery;
-struct _BookQuery {
- gboolean primary;
- BookQuerySExp builder;
- BookQueryMatchTester tester;
-};
-
-static BookQuery book_queries[] = {
- { TRUE, sexp_nickname, match_nickname},
- { TRUE, sexp_email, match_email },
- { TRUE, sexp_name, match_name },
- { TRUE, sexp_file_as, match_file_as },
- { FALSE, sexp_initials, match_initials }
-};
-static gint book_query_count = sizeof (book_queries) / sizeof (BookQuery);
-
-/*
- * Build up a big compound sexp corresponding to all of our queries.
- */
-static gchar *
-book_query_sexp (ESelectNamesCompletion *comp)
-{
- gint i, j, count = 0;
- gchar **queryv, *query;
-
- g_return_val_if_fail (comp && E_IS_SELECT_NAMES_COMPLETION (comp), NULL);
-
- if (! (comp->priv->query_text && *comp->priv->query_text))
- return NULL;
-
- if (comp->priv->primary_only) {
- for (i=0; i<book_query_count; ++i)
- if (book_queries[i].primary)
- ++count;
- } else {
- count = book_query_count;
- }
-
- queryv = g_new0 (gchar *, count+1);
- for (i=0, j=0; i<count; ++i) {
- queryv[j] = book_queries[i].builder (comp);
- if (queryv[j])
- ++j;
- }
-
- if (j == 0) {
- query = NULL;
- } else if (j == 1) {
- query = queryv[0];
- queryv[0] = NULL;
- } else {
- gchar *tmp = g_strjoinv (" ", queryv);
- query = g_strdup_printf ("(or %s)", tmp);
- g_free (tmp);
- }
-
- for (i=0; i<count; ++i)
- g_free (queryv[i]);
- g_free (queryv);
-
- return query;
-}
-
-/*
- * Sweep across all of our query rules and find the best score/match
- * string that applies to a given destination.
- */
-static ECompletionMatch *
-book_query_score (ESelectNamesCompletion *comp, EDestination *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);
-
- if (! (comp->priv->query_text && *comp->priv->query_text))
- return NULL;
-
- for (i=0; i<book_query_count; ++i) {
-
- ECompletionMatch *this_match = NULL;
-
- if (book_queries[i].primary || !comp->priv->primary_only) {
- if (book_queries[i].tester && e_destination_get_card (dest)) {
- this_match = book_queries[i].tester (comp, dest);
- }
-
- if (this_match) {
- if (best_match == NULL || this_match->score > best_match->score) {
- e_completion_match_unref (best_match);
- best_match = this_match;
- } else {
- e_completion_match_unref (this_match);
- }
- }
- }
- }
-
- return best_match;
-}
-
-static void
-book_query_process_card_list (ESelectNamesCompletion *comp, const GList *cards)
-{
- while (cards) {
- ECard *card = E_CARD (cards->data);
-
- if (e_card_evolution_list (card)) {
-
- if (comp->priv->match_contact_lists) {
-
- EDestination *dest = e_destination_new ();
- ECompletionMatch *match;
- e_destination_set_card (dest, card, 0);
- 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);
- }
- gtk_object_unref (GTK_OBJECT (dest));
-
- }
-
- } 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;
-
- e_destination_set_card (dest, card, i);
- email = e_destination_get_email (dest);
-
- if (email && *email) {
-
- 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);
- }
- }
-
- gtk_object_unref (GTK_OBJECT (dest));
- }
- }
-
- cards = g_list_next (cards);
- }
-}
-
-#if 0
-static gchar *
-initials_query_match_cb (QueryInfo *qi, ECard *card, double *score)
-{
- gint len;
- gchar f='\0', m='\0', l='\0'; /* initials */
- gchar cf, cm, cl;
-
- len = strlen (qi->comp->priv->query_text);
-
- if (len == 2) {
-
- f = qi->comp->priv->query_text[0];
- m = '\0';
- l = qi->comp->priv->query_text[1];
-
- } else if (len == 3) {
-
- f = qi->comp->priv->query_text[0];
- m = qi->comp->priv->query_text[1];
- l = qi->comp->priv->query_text[2];
-
- } else {
- return NULL;
- }
-
- cf = card->name->given ? *card->name->given : '\0';
- cm = card->name->additional ? *card->name->additional : '\0';
- cl = card->name->family ? *card->name->family : '\0';
-
- if (f && isupper ((gint) f))
- f = tolower ((gint) f);
- if (m && isupper ((gint) m))
- m = tolower ((gint) m);
- if (l && isupper ((gint) l))
- l = tolower ((gint) l);
-
- if (cf && isupper ((gint) cf))
- cf = tolower ((gint) cf);
- if (cm && isupper ((gint) cm))
- cm = tolower ((gint) cm);
- if (cl && isupper ((gint) cl))
- cl = tolower ((gint) cl);
-
- if ((f == '\0' || (f == cf)) && (m == '\0' || (m == cm)) && (l == '\0' || (l == cl))) {
- if (score)
- *score = 3;
- if (m)
- return g_strdup_printf ("%s %s %s", card->name->given, card->name->additional, card->name->family);
- else
- return g_strdup_printf ("%s %s", card->name->given, card->name->family);
- }
-
- return NULL;
-}
-
-static gboolean
-start_initials_query (ESelectNamesCompletion *comp)
-{
- gint len;
- gchar *query;
-
- if (comp && comp->priv->query_text && *(comp->priv->query_text)) {
-
- len = strlen (comp->priv->query_text);
- if (len < 2 || len > 3)
- return FALSE;
-
- query = g_strdup_printf ("(contains \"x-evolution-any-field\" \"%c\")", *(comp->priv->query_text));
- query_info_start (comp, comp->priv->query_text, query, initials_query_match_cb);
- g_free (query);
- return TRUE;
- }
-
- return FALSE;
-}
-#endif
-
-
-/*
- *
- * ESelectNamesCompletion code
- *
- */
-
-
-GtkType
-e_select_names_completion_get_type (void)
-{
- static GtkType select_names_complete_type = 0;
-
- if (!select_names_complete_type) {
- GtkTypeInfo select_names_complete_info = {
- "ESelectNamesCompletion",
- sizeof (ESelectNamesCompletion),
- sizeof (ESelectNamesCompletionClass),
- (GtkClassInitFunc) e_select_names_completion_class_init,
- (GtkObjectInitFunc) e_select_names_completion_init,
- NULL, NULL, /* reserved */
- (GtkClassInitFunc) NULL
- };
-
- select_names_complete_type = gtk_type_unique (e_completion_get_type (), &select_names_complete_info);
- }
-
- return select_names_complete_type;
-}
-
-static void
-e_select_names_completion_class_init (ESelectNamesCompletionClass *klass)
-{
- GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
- ECompletionClass *completion_class = E_COMPLETION_CLASS (klass);
-
- parent_class = GTK_OBJECT_CLASS (gtk_type_class (e_completion_get_type ()));
-
- object_class->destroy = e_select_names_completion_destroy;
-
- completion_class->request_completion = e_select_names_completion_handle_request;
- completion_class->end_completion = e_select_names_completion_end;
-
- if (getenv ("EVO_DEBUG_SELECT_NAMES_COMPLETION")) {
- out = fopen ("/tmp/evo-debug-select-names-completion", "w");
- if (out)
- setvbuf (out, NULL, _IONBF, 0);
- }
-}
-
-static void
-e_select_names_completion_init (ESelectNamesCompletion *comp)
-{
- comp->priv = g_new0 (struct _ESelectNamesCompletionPrivate, 1);
- comp->priv->match_contact_lists = TRUE;
-}
-
-static void
-e_select_names_completion_clear_book_data (ESelectNamesCompletion *comp)
-{
- GList *l;
-
- for (l = comp->priv->book_data; l; l = l->next) {
- ESelectNamesCompletionBookData *book_data = l->data;
-
- if (book_data->card_added_tag) {
- gtk_signal_disconnect (GTK_OBJECT (book_data->book_view), book_data->card_added_tag);
- book_data->card_added_tag = 0;
- }
-
- if (book_data->seq_complete_tag) {
- gtk_signal_disconnect (GTK_OBJECT (book_data->book_view), book_data->seq_complete_tag);
- book_data->seq_complete_tag = 0;
- }
-
- gtk_object_unref (GTK_OBJECT (book_data->book));
-
- if (book_data->book_view) {
- e_book_view_stop (book_data->book_view);
- gtk_object_unref (GTK_OBJECT (book_data->book_view));
- }
-
- g_free (book_data);
- }
- g_list_free (comp->priv->book_data);
- comp->priv->book_data = NULL;
-}
-
-static void
-e_select_names_completion_destroy (GtkObject *object)
-{
- ESelectNamesCompletion *comp = E_SELECT_NAMES_COMPLETION (object);
-
- if (comp->priv->text_model)
- gtk_object_unref (GTK_OBJECT (comp->priv->text_model));
-
- e_select_names_completion_clear_book_data (comp);
-
- g_free (comp->priv->waiting_query);
- g_free (comp->priv->query_text);
-
- g_free (comp->priv->cached_query_text);
- g_list_foreach (comp->priv->cached_cards, (GFunc)gtk_object_unref, NULL);
- g_list_free (comp->priv->cached_cards);
-
- g_free (comp->priv);
-
- if (parent_class->destroy)
- parent_class->destroy (object);
-}
-
-
-/*
- *
- * EBook/EBookView Callbacks & Query Stuff
- *
- */
-
-static gchar *
-clean_query_text (const gchar *s)
-{
- gchar *q = g_new (gchar, strlen(s)+1), *t;
-
- t = q;
- while (*s) {
- if (*s != ',' && *s != '"') {
- *t = *s;
- ++t;
- }
- ++s;
- }
- *t = '\0';
-
- g_strstrip (q);
-
- return q;
-}
-
-static void
-e_select_names_completion_clear_cache (ESelectNamesCompletion *comp)
-{
- g_free (comp->priv->cached_query_text);
- comp->priv->cached_query_text = NULL;
-
- g_list_foreach (comp->priv->cached_cards, (GFunc)gtk_object_unref, NULL);
- g_list_free (comp->priv->cached_cards);
- comp->priv->cached_cards = NULL;
-}
-
-static void
-e_select_names_completion_got_book_view_cb (EBook *book, EBookStatus status, EBookView *view, gpointer user_data)
-{
- ESelectNamesCompletion *comp;
- ESelectNamesCompletionBookData *book_data;
-
- if (status != E_BOOK_STATUS_SUCCESS)
- return;
-
- book_data = (ESelectNamesCompletionBookData*)user_data;
- comp = book_data->comp;
-
- book_data->book_view_tag = 0;
-
- if (book_data->card_added_tag) {
- gtk_signal_disconnect (GTK_OBJECT (book_data->book_view), book_data->card_added_tag);
- book_data->card_added_tag = 0;
- }
- if (book_data->seq_complete_tag) {
- gtk_signal_disconnect (GTK_OBJECT (book_data->book_view), book_data->seq_complete_tag);
- book_data->seq_complete_tag = 0;
- }
-
- gtk_object_ref (GTK_OBJECT (view));
- if (book_data->book_view) {
- e_book_view_stop (book_data->book_view);
- gtk_object_unref (GTK_OBJECT (book_data->book_view));
- }
- book_data->book_view = view;
-
- book_data->card_added_tag =
- gtk_signal_connect (GTK_OBJECT (view),
- "card_added",
- GTK_SIGNAL_FUNC (e_select_names_completion_card_added_cb),
- book_data);
-
- book_data->seq_complete_tag =
- gtk_signal_connect (GTK_OBJECT (view),
- "sequence_complete",
- GTK_SIGNAL_FUNC (e_select_names_completion_seq_complete_cb),
- book_data);
- book_data->sequence_complete_received = FALSE;
- comp->priv->pending_completion_seq++;
-}
-
-static void
-e_select_names_completion_card_added_cb (EBookView *book_view, const GList *cards, gpointer user_data)
-{
- ESelectNamesCompletionBookData *book_data = user_data;
- ESelectNamesCompletion *comp = book_data->comp;
-
- if (e_completion_searching (E_COMPLETION (comp))) {
- book_query_process_card_list (comp, cards);
-
- /* Save the list of matching cards. */
- while (cards) {
- comp->priv->cached_cards = g_list_prepend (comp->priv->cached_cards, cards->data);
- gtk_object_ref (GTK_OBJECT (cards->data));
- cards = g_list_next (cards);
- }
- }
-}
-
-static void
-e_select_names_completion_seq_complete_cb (EBookView *book_view, EBookViewStatus status, gpointer user_data)
-{
- ESelectNamesCompletionBookData *book_data = user_data;
- ESelectNamesCompletion *comp = E_SELECT_NAMES_COMPLETION(book_data->comp);
-
- /*
- * We aren't searching, but the addressbook has changed -- clear our card cache so that
- * future completion requests will take the changes into account.
- */
- if (! e_completion_searching (E_COMPLETION (comp))) {
- e_select_names_completion_clear_cache (comp);
- return;
- }
-
- if (!book_data->sequence_complete_received) {
- book_data->sequence_complete_received = TRUE;
- comp->priv->pending_completion_seq --;
- if (comp->priv->pending_completion_seq > 0)
- return;
- }
-
- if (comp->priv->cached_query_text
- && !comp->priv->cache_complete
- && !strcmp (comp->priv->cached_query_text, comp->priv->query_text))
- comp->priv->cache_complete = TRUE;
-
- g_free (comp->priv->query_text);
- comp->priv->query_text = NULL;
-
- if (out)
- fprintf (out, "ending search\n");
-
- e_completion_end_search (E_COMPLETION (comp)); /* That's all folks! */
-
- /* Need to launch a new completion if another one is pending. */
- if (comp->priv->waiting_query) {
- gchar *s = comp->priv->waiting_query;
- comp->priv->waiting_query = NULL;
- e_completion_begin_search (E_COMPLETION (comp), s, comp->priv->waiting_pos, comp->priv->waiting_limit);
- g_free (s);
- }
-}
-
-static void
-e_select_names_completion_stop_query (ESelectNamesCompletion *comp)
-{
- GList *l;
-
- g_return_if_fail (comp && E_IS_SELECT_NAMES_COMPLETION (comp));
-
- if (out)
- fprintf (out, "stopping query\n");
-
- if (comp->priv->waiting_query) {
- if (out)
- fprintf (out, "stopped waiting query\n");
- g_free (comp->priv->waiting_query);
- comp->priv->waiting_query = NULL;
- }
-
- g_free (comp->priv->query_text);
- comp->priv->query_text = NULL;
-
- for (l = comp->priv->book_data; l; l = l->next) {
- ESelectNamesCompletionBookData *book_data = l->data;
- if (book_data->book_view_tag) {
- if (out)
- fprintf (out, "cancelled book view creation\n");
- e_book_cancel (book_data->book, book_data->book_view_tag);
- book_data->book_view_tag = 0;
- }
- if (book_data->book_view) {
- if (out)
- fprintf (out, "disconnecting book view signals\n");
-
- if (book_data->card_added_tag) {
- gtk_signal_disconnect (GTK_OBJECT (book_data->book_view), book_data->card_added_tag);
- book_data->card_added_tag = 0;
- }
- if (book_data->seq_complete_tag) {
- gtk_signal_disconnect (GTK_OBJECT (book_data->book_view), book_data->seq_complete_tag);
- book_data->seq_complete_tag = 0;
- }
-
- if (out)
- fprintf (out, "unrefed book view\n");
-
- e_book_view_stop (book_data->book_view);
- gtk_object_unref (GTK_OBJECT (book_data->book_view));
- book_data->book_view = NULL;
- }
- }
-
- /* Clear the cache, which may contain partial results. */
- e_select_names_completion_clear_cache (comp);
-
-}
-
-static void
-e_select_names_completion_start_query (ESelectNamesCompletion *comp, const gchar *query_text)
-{
- g_return_if_fail (comp && E_IS_SELECT_NAMES_COMPLETION (comp));
- g_return_if_fail (query_text);
-
- e_select_names_completion_stop_query (comp); /* Stop any prior queries. */
-
- if (comp->priv->books_not_ready == 0) {
- gchar *sexp;
-
- if (strlen (query_text) < MINIMUM_QUERY_LENGTH)
- return;
-
-
- g_free (comp->priv->query_text);
- comp->priv->query_text = g_strdup (query_text);
-
- g_free (comp->priv->cached_query_text);
- comp->priv->cached_query_text = g_strdup (query_text);
- comp->priv->cache_complete = FALSE;
-
- sexp = book_query_sexp (comp);
- if (sexp && *sexp) {
- GList *l;
-
- if (out)
- fprintf (out, "\n\n**** starting query: \"%s\"\n", comp->priv->query_text);
-
- for (l = comp->priv->book_data; l; l = l->next) {
- ESelectNamesCompletionBookData *book_data = l->data;
- book_data->book_view_tag = e_book_get_completion_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 {
- g_free (comp->priv->query_text);
- comp->priv->query_text = NULL;
- }
- g_free (sexp);
-
- } else {
-
- comp->priv->waiting_query = g_strdup (query_text);
-
- }
-}
-
-static void
-e_select_names_completion_do_query (ESelectNamesCompletion *comp, const gchar *query_text, gint pos, gint limit)
-{
- gchar *clean;
- gboolean query_is_still_running, can_reuse_cached_cards;
- GList *l;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (E_IS_SELECT_NAMES_COMPLETION (comp));
-
- clean = clean_query_text (query_text);
- if (! (clean && *clean)) {
- g_free (clean);
- e_completion_end_search (E_COMPLETION (comp));
- return;
- }
-
- query_is_still_running = FALSE;
- for (l = comp->priv->book_data; l; l = l->next) {
- ESelectNamesCompletionBookData *book_data = l->data;
- query_is_still_running = book_data->book_view_tag;
- if (query_is_still_running)
- break;
- }
-
- if (out) {
- fprintf (out, "do_query: %s => %s\n", query_text, clean);
- if (query_is_still_running)
- fprintf (out, "a query is still running!\n");
- }
- if (comp->priv->cached_query_text && out)
- fprintf (out, "cached: %s\n", comp->priv->cached_query_text);
-
- can_reuse_cached_cards = (comp->priv->cached_query_text
- && comp->priv->cache_complete
- && (!comp->priv->can_fail_due_to_too_many_hits || comp->priv->cached_cards != NULL)
- && (strlen (comp->priv->cached_query_text) <= strlen (clean))
- && !g_utf8_strncasecmp (comp->priv->cached_query_text, clean, strlen (comp->priv->cached_query_text)));
-
-
- if (can_reuse_cached_cards) {
-
- if (out)
- fprintf (out, "can reuse cached card!\n");
-
- if (query_is_still_running) {
- g_free (comp->priv->waiting_query);
- comp->priv->waiting_query = clean;
- comp->priv->waiting_pos = pos;
- comp->priv->waiting_limit = limit;
- if (out)
- fprintf (out, "waiting for running query to complete: %s\n", comp->priv->waiting_query);
- return;
- }
-
- g_free (comp->priv->query_text);
- comp->priv->query_text = clean;
- if (out)
- fprintf (out, "using existing query info: %s (vs %s)\n", comp->priv->query_text, comp->priv->cached_query_text);
- book_query_process_card_list (comp, comp->priv->cached_cards);
- e_completion_end_search (E_COMPLETION (comp));
- return;
- }
-
- e_select_names_completion_start_query (comp, clean);
- g_free (clean);
-}
-
-
-/*
- *
- * Completion Search Override - a Framework for Christian-Resurrection-Holiday Edible-Chicken-Ova
- *
- */
-
-typedef struct _SearchOverride SearchOverride;
-struct _SearchOverride {
- const gchar *trigger;
- const gchar *text[4];
-};
-static SearchOverride override[] = {
- { "why?", { "\"I must create a system, or be enslaved by another man's.\"",
- " -- Wiliam Blake, \"Jerusalem\"",
- NULL } },
- { "easter-egg?", { "What were you expecting, a flight simulator?", NULL } },
- { NULL, { NULL } } };
-
-static gboolean
-search_override_check (SearchOverride *over, const gchar *text)
-{
- /* The g_utf8_validate is needed because as of 2001-06-11,
- * EText doesn't translate from locale->UTF8 when you paste
- * into it.
- */
- if (over == NULL || text == NULL || !g_utf8_validate (text, -1, NULL))
- return FALSE;
-
- return !g_utf8_strcasecmp (over->trigger, text);
-}
-
-
-/*
- *
- * Completion Callbacks
- *
- */
-
-static void
-e_select_names_completion_handle_request (ECompletion *comp, const gchar *text, gint pos, gint limit)
-{
- ESelectNamesCompletion *selcomp = E_SELECT_NAMES_COMPLETION (comp);
- const gchar *str;
- gint index, j;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (E_IS_SELECT_NAMES_COMPLETION (comp));
- g_return_if_fail (text != NULL);
-
- if (out) {
- fprintf (out, "\n\n**** requesting completion\n");
- fprintf (out, "text=\"%s\" pos=%d limit=%d\n", text, pos, limit);
- }
-
- e_select_names_model_text_pos (selcomp->priv->text_model->source,
- selcomp->priv->text_model->seplen,
- pos, &index, NULL, NULL);
- str = index >= 0 ? e_select_names_model_get_string (selcomp->priv->text_model->source, index) : NULL;
-
- if (out)
- fprintf (out, "index=%d str=\"%s\"\n", index, str);
-
- if (str == NULL || *str == '\0') {
- if (out)
- fprintf (out, "aborting empty query\n");
- e_completion_end_search (comp);
- return;
- }
-
- for (j=0; override[j].trigger; ++j) {
- if (search_override_check (&(override[j]), str)) {
- gint k;
-
- for (k=0; override[j].text[k]; ++k) {
- ECompletionMatch *match = g_new (ECompletionMatch, 1);
- e_completion_match_construct (match);
- e_completion_match_set_text (match, text, override[j].text[k]);
- match->score = 1 / (double) (k + 1);
- e_completion_found_match (comp, match);
- }
-
- e_completion_end_search (comp);
- return;
- }
- }
-
- e_select_names_completion_do_query (selcomp, str, pos, limit);
-}
-
-static void
-e_select_names_completion_end (ECompletion *comp)
-{
- g_return_if_fail (comp != NULL);
- g_return_if_fail (E_IS_COMPLETION (comp));
-
- if (out)
- fprintf (out, "completion ended\n");
-}
-
-static void
-check_capabilities (ESelectNamesCompletion *comp, EBook *book)
-{
- gchar *cap = e_book_get_static_capabilities (book);
- comp->priv->can_fail_due_to_too_many_hits = !strcmp (cap, "net");
- if (comp->priv->can_fail_due_to_too_many_hits) {
- g_message ("using LDAP source for completion!");
- }
- g_free (cap);
-}
-
-#if 0
-static void
-e_select_names_completion_book_ready (EBook *book, EBookStatus status, ESelectNamesCompletion *comp)
-{
- comp->priv->books_not_ready--;
-
- g_return_if_fail (E_IS_BOOK (book));
- g_return_if_fail (E_IS_SELECT_NAMES_COMPLETION (comp));
-
- check_capabilities (comp, book);
-
- /* If waiting_query is non-NULL, someone tried to start a query before the book was ready.
- Now that it is, get started. */
- if (comp->priv->books_not_ready == 0 && comp->priv->waiting_query) {
- e_select_names_completion_start_query (comp, comp->priv->waiting_query);
- g_free (comp->priv->waiting_query);
- comp->priv->waiting_query = NULL;
- }
-
- gtk_object_unref (GTK_OBJECT (comp)); /* post-async unref */
-}
-#endif
-
-
-/*
- *
- * Our Pseudo-Constructor
- *
- */
-
-ECompletion *
-e_select_names_completion_new (ESelectNamesTextModel *text_model)
-{
- ESelectNamesCompletion *comp;
-
- g_return_val_if_fail (E_IS_SELECT_NAMES_TEXT_MODEL (text_model), NULL);
-
- comp = (ESelectNamesCompletion *) gtk_type_new (e_select_names_completion_get_type ());
-
- comp->priv->text_model = text_model;
- gtk_object_ref (GTK_OBJECT (text_model));
-
- return E_COMPLETION (comp);
-}
-
-void
-e_select_names_completion_add_book (ESelectNamesCompletion *comp, EBook *book)
-{
- ESelectNamesCompletionBookData *book_data;
-
- g_return_if_fail (book != NULL);
-
- book_data = g_new0 (ESelectNamesCompletionBookData, 1);
- book_data->book = book;
- book_data->comp = comp;
- check_capabilities (comp, book);
- gtk_object_ref (GTK_OBJECT (book_data->book));
- comp->priv->book_data = g_list_append (comp->priv->book_data, book_data);
-
- /* if the user is typing as we're adding books, restart the
- query after the new book has been added */
- if (comp->priv->query_text && *comp->priv->query_text) {
- char *query_text = g_strdup (comp->priv->query_text);
- e_select_names_completion_stop_query (comp);
- e_select_names_completion_start_query (comp, query_text);
- g_free (query_text);
- }
-}
-
-void
-e_select_names_completion_clear_books (ESelectNamesCompletion *comp)
-{
- e_select_names_completion_stop_query (comp);
- e_select_names_completion_clear_book_data (comp);
-}
-
-gboolean
-e_select_names_completion_get_match_contact_lists (ESelectNamesCompletion *comp)
-{
- g_return_val_if_fail (E_IS_SELECT_NAMES_COMPLETION (comp), FALSE);
- return comp->priv->match_contact_lists;
-}
-
-
-void
-e_select_names_completion_set_match_contact_lists (ESelectNamesCompletion *comp, gboolean x)
-{
- g_return_if_fail (E_IS_SELECT_NAMES_COMPLETION (comp));
- comp->priv->match_contact_lists = x;
-}
-
diff --git a/addressbook/gui/component/select-names/e-select-names-completion.h b/addressbook/gui/component/select-names/e-select-names-completion.h
deleted file mode 100644
index ae5a8db471..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-completion.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-select-names-completion.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_SELECT_NAMES_COMPLETION_H
-#define E_SELECT_NAMES_COMPLETION_H
-
-#include <gal/e-text/e-completion.h>
-#include <addressbook/backend/ebook/e-book.h>
-#include "e-select-names-text-model.h"
-
-BEGIN_GNOME_DECLS
-
-#define E_SELECT_NAMES_COMPLETION_TYPE (e_select_names_completion_get_type ())
-#define E_SELECT_NAMES_COMPLETION(o) (GTK_CHECK_CAST ((o), E_SELECT_NAMES_COMPLETION_TYPE, ESelectNamesCompletion))
-#define E_SELECT_NAMES_COMPLETION_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), E_SELECT_NAMES_COMPLETION_TYPE, ESelectNamesCompletionClass))
-#define E_IS_SELECT_NAMES_COMPLETION(o) (GTK_CHECK_TYPE ((o), E_SELECT_NAMES_COMPLETION_TYPE))
-#define E_IS_SELECT_NAMES_COMPLETION_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_SELECT_NAMES_COMPLETION_TYPE))
-
-typedef struct _ESelectNamesCompletion ESelectNamesCompletion;
-typedef struct _ESelectNamesCompletionClass ESelectNamesCompletionClass;
-struct _ESelectNamesCompletionPrivate;
-
-struct _ESelectNamesCompletion {
- ECompletion parent;
-
- struct _ESelectNamesCompletionPrivate *priv;
-};
-
-struct _ESelectNamesCompletionClass {
- ECompletionClass parent_class;
-
-};
-
-GtkType e_select_names_completion_get_type (void);
-
-ECompletion *e_select_names_completion_new (ESelectNamesTextModel *);
-void e_select_names_completion_add_book (ESelectNamesCompletion *, EBook *);
-void e_select_names_completion_clear_books (ESelectNamesCompletion *);
-gboolean e_select_names_completion_get_match_contact_lists (ESelectNamesCompletion *);
-void e_select_names_completion_set_match_contact_lists (ESelectNamesCompletion *, gboolean);
-
-END_GNOME_DECLS
-
-#endif /* E_SELECT_NAMES_COMPLETION_H */
-
diff --git a/addressbook/gui/component/select-names/e-select-names-factory.c b/addressbook/gui/component/select-names/e-select-names-factory.c
deleted file mode 100644
index d6560d6366..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-factory.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* e-select-names-factory.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.
- *
- * Author: Ettore Perazzoli
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <bonobo/bonobo-generic-factory.h>
-
-#include "e-select-names-bonobo.h"
-#include "e-select-names-factory.h"
-
-
-#define COMPONENT_FACTORY_ID "OAFIID:GNOME_Evolution_Addressbook_SelectNamesFactory"
-
-static BonoboGenericFactory *factory = NULL;
-
-
-static BonoboObject *
-factory_fn (BonoboGenericFactory *factory,
- void *closure)
-{
- return BONOBO_OBJECT (e_select_names_bonobo_new ());
-}
-
-
-gboolean
-e_select_names_factory_init (void)
-{
- if (factory != NULL)
- return TRUE;
-
- factory = bonobo_generic_factory_new (COMPONENT_FACTORY_ID, factory_fn, NULL);
-
- if (factory == NULL)
- return FALSE;
-
- return TRUE;
-}
diff --git a/addressbook/gui/component/select-names/e-select-names-factory.h b/addressbook/gui/component/select-names/e-select-names-factory.h
deleted file mode 100644
index 0fe85c8361..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-factory.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* e-select-names-factory.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.
- *
- * Author: Ettore Perazzoli
- */
-
-#ifndef _E_SECELT_NAMES_FACTORY_H
-#define _E_SECELT_NAMES_FACTORY_H
-
-#include <glib.h>
-
-gboolean e_select_names_factory_init (void);
-
-#endif
diff --git a/addressbook/gui/component/select-names/e-select-names-manager.c b/addressbook/gui/component/select-names/e-select-names-manager.c
deleted file mode 100644
index 9bc06b52d9..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-manager.c
+++ /dev/null
@@ -1,740 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- * Jon Trowbridge <trow@ximian.com.
- *
- * Copyright (C) 2000, 2001 Ximian, Inc.
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <gal/e-text/e-entry.h>
-
-#include <libgnome/gnome-i18n.h>
-#include "e-select-names-manager.h"
-#include "e-select-names-model.h"
-#include "e-select-names-text-model.h"
-#include "e-select-names.h"
-#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/gui/component/addressbook.h>
-#include <bonobo-conf/bonobo-config-database.h>
-#include <bonobo/bonobo-object.h>
-#include <bonobo/bonobo-moniker-util.h>
-
-enum {
- CHANGED,
- OK,
- CANCEL,
- LAST_SIGNAL
-};
-
-static guint e_select_names_manager_signals[LAST_SIGNAL] = { 0 };
-
-
-typedef struct {
- char *id;
- char *title;
- ESelectNamesModel *model;
- ESelectNamesModel *original_model;
- ESelectNamesManager *manager;
- guint changed_tag;
-} ESelectNamesManagerSection;
-
-typedef struct {
- char *id;
- EEntry *entry;
- ESelectNamesManager *manager;
- ESelectNamesModel *model;
- ECompletion *comp;
- guint cleaning_tag;
-} ESelectNamesManagerEntry;
-
-static void e_select_names_manager_init (ESelectNamesManager *manager);
-static void e_select_names_manager_class_init (ESelectNamesManagerClass *klass);
-
-static void e_select_names_manager_destroy (GtkObject *object);
-
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-
-/* ESelectNamesManagerSection routines */
-
-static void
-section_model_changed_cb (ESelectNamesModel *model, gpointer closure)
-{
- ESelectNamesManagerSection *section = closure;
- gtk_signal_emit (GTK_OBJECT (section->manager),
- e_select_names_manager_signals[CHANGED],
- section->id,
- FALSE);
-}
-
-static ESelectNamesManagerSection *
-e_select_names_manager_section_new (ESelectNamesManager *manager,
- const gchar *id,
- const gchar *title,
- ESelectNamesModel *model)
-{
- ESelectNamesManagerSection *section;
-
- g_return_val_if_fail (E_IS_SELECT_NAMES_MANAGER (manager), NULL);
- g_return_val_if_fail (E_IS_SELECT_NAMES_MODEL (model), NULL);
-
- section = g_new0 (ESelectNamesManagerSection, 1);
-
- section->id = g_strdup (id);
- section->title = g_strdup (title);
-
- section->manager = manager;
-
- section->model = model;
- gtk_object_ref (GTK_OBJECT (section->model));
- section->changed_tag =
- gtk_signal_connect (GTK_OBJECT (section->model),
- "changed",
- GTK_SIGNAL_FUNC (section_model_changed_cb),
- section);
-
- return section;
-}
-
-static void
-e_select_names_manager_section_free (ESelectNamesManagerSection *section)
-{
- if (section == NULL)
- return;
-
- g_free (section->id);
- g_free (section->title);
-
- if (section->model) {
- gtk_signal_disconnect (GTK_OBJECT (section->model), section->changed_tag);
- gtk_object_unref (GTK_OBJECT (section->model));
- }
-
- if (section->original_model) {
- gtk_object_unref (GTK_OBJECT (section->original_model));
- }
-
- g_free (section);
-}
-
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-
-/* ESelectNamesManagerEntry routines */
-
-static ESelectNamesManagerEntry *
-get_entry_info (EEntry *entry)
-{
- g_return_val_if_fail (E_IS_ENTRY (entry), NULL);
- return (ESelectNamesManagerEntry *) gtk_object_get_data (GTK_OBJECT (entry), "entry_info");
-}
-
-static void
-popup_cb (EEntry *eentry, GdkEventButton *ev, gint pos, gpointer user_data)
-{
- ESelectNamesTextModel *text_model;
-
- gtk_object_get (GTK_OBJECT (eentry),
- "model", &text_model,
- NULL);
- g_assert (E_IS_SELECT_NAMES_TEXT_MODEL (text_model));
-
- e_select_names_popup (text_model, ev, pos);
-}
-
-#if 0
-static gboolean
-clean_cb (gpointer ptr)
-{
- ESelectNamesManagerEntry *entry = ptr;
-
- e_select_names_model_clean (entry->model, TRUE);
- entry->cleaning_tag = 0;
- return FALSE;
-}
-#endif
-
-static gint
-focus_in_cb (GtkWidget *w, GdkEventFocus *ev, gpointer user_data)
-{
- ESelectNamesManagerEntry *entry = user_data;
-
- if (entry->cleaning_tag) {
- gtk_timeout_remove (entry->cleaning_tag);
- entry->cleaning_tag = 0;
- }
-
- e_select_names_model_cancel_cardify_all (entry->model);
-
- return FALSE;
-}
-
-static gint
-focus_out_cb (GtkWidget *w, GdkEventFocus *ev, gpointer user_data)
-{
-#if 0
- /* XXX fix me */
- ESelectNamesManagerEntry *entry = 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);
- if (entry->cleaning_tag == 0)
- entry->cleaning_tag = gtk_timeout_add (100, clean_cb, entry);
- }
-#endif
- return FALSE;
-}
-
-static void
-completion_popup_cb (EEntry *w, gint visible, gpointer user_data)
-{
-#if 0
- /* XXX fix me */
- 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);
-#endif
-}
-
-static void
-completion_handler (EEntry *entry, ECompletionMatch *match)
-{
- ESelectNamesManagerEntry *mgr_entry;
- ESelectNamesTextModel *text_model;
- EDestination *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);
-
- /* Sometimes I really long for garbage collection. Reference
- counting makes you feel 31337, but sometimes it is just a
- bitch. */
- gtk_object_ref (GTK_OBJECT (dest));
-
- gtk_object_get (GTK_OBJECT (entry),
- "model", &text_model,
- NULL);
- g_assert (E_IS_SELECT_NAMES_TEXT_MODEL (text_model));
-
- pos = e_entry_get_position (entry);
- e_select_names_model_text_pos (mgr_entry->model, text_model->seplen, pos, &i, NULL, NULL);
- e_select_names_model_replace (mgr_entry->model, i, dest);
- e_select_names_model_name_pos (mgr_entry->model, text_model->seplen, i, &start_pos, &len);
- e_entry_set_position (entry, start_pos+len);
-}
-
-static ESelectNamesManagerEntry *
-e_select_names_manager_entry_new (ESelectNamesManager *manager, ESelectNamesModel *model, const gchar *id)
-{
- ESelectNamesManagerEntry *entry;
- ETextModel *text_model;
- GList *l;
-
- g_return_val_if_fail (E_IS_SELECT_NAMES_MANAGER (manager), NULL);
- g_return_val_if_fail (E_IS_SELECT_NAMES_MODEL (model), NULL);
-
- entry = g_new0 (ESelectNamesManagerEntry, 1);
-
- entry->id = g_strdup (id);
-
- entry->entry = E_ENTRY (e_entry_new ());
- text_model = e_select_names_text_model_new (model);
- gtk_object_set(GTK_OBJECT(entry->entry),
- "model", text_model, /* The entry takes ownership of the text model */
- "editable", TRUE,
- "use_ellipsis", TRUE,
- "allow_newlines", FALSE,
- NULL);
-
- gtk_object_ref (GTK_OBJECT (entry->entry));
-
- entry->comp = e_select_names_completion_new (E_SELECT_NAMES_TEXT_MODEL (text_model));
-
- for (l = manager->completion_books; l; l = l->next) {
- EBook *book = l->data;
- e_select_names_completion_add_book (E_SELECT_NAMES_COMPLETION(entry->comp), book);
- }
-
- e_entry_enable_completion_full (entry->entry, entry->comp, 100, completion_handler);
-
- entry->manager = manager;
-
- entry->model = model;
- gtk_object_ref (GTK_OBJECT (model));
-
- gtk_signal_connect (GTK_OBJECT (entry->entry),
- "popup",
- GTK_SIGNAL_FUNC (popup_cb),
- entry);
-
- gtk_signal_connect (GTK_OBJECT (entry->entry->canvas),
- "focus_in_event",
- GTK_SIGNAL_FUNC (focus_in_cb),
- entry);
-
- gtk_signal_connect (GTK_OBJECT (entry->entry->canvas),
- "focus_out_event",
- GTK_SIGNAL_FUNC (focus_out_cb),
- entry);
-
- gtk_signal_connect (GTK_OBJECT (entry->entry),
- "completion_popup",
- GTK_SIGNAL_FUNC (completion_popup_cb),
- entry);
-
- gtk_object_set_data (GTK_OBJECT (entry->entry), "entry_info", entry);
- gtk_object_set_data (GTK_OBJECT (entry->entry), "select_names_model", model);
- gtk_object_set_data (GTK_OBJECT (entry->entry), "select_names_text_model", text_model);
- gtk_object_set_data (GTK_OBJECT (entry->entry), "completion_handler", entry->comp);
-
- return entry;
-}
-
-static void
-e_select_names_manager_entry_free (ESelectNamesManagerEntry *entry)
-{
- if (entry == NULL)
- return;
-
- g_free (entry->id);
- gtk_object_unref (GTK_OBJECT (entry->model));
- gtk_object_unref (GTK_OBJECT (entry->entry));
-
- if (entry->cleaning_tag)
- gtk_timeout_remove (entry->cleaning_tag);
-
- g_free (entry);
-}
-
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-
-static void
-e_select_names_manager_save_models (ESelectNamesManager *manager)
-{
- GList *iter;
-
- for (iter = manager->sections; iter != NULL; iter = g_list_next (iter)) {
- ESelectNamesManagerSection *section = iter->data;
-
- if (section->original_model == NULL && section->model != NULL)
- section->original_model = e_select_names_model_duplicate (section->model);
-
- }
-}
-
-static void
-e_select_names_manager_revert_to_saved_models (ESelectNamesManager *manager)
-{
- GList *iter;
-
- for (iter = manager->sections; iter != NULL; iter = g_list_next (iter)) {
- ESelectNamesManagerSection *section = iter->data;
- if (section->model && section->original_model) {
- e_select_names_model_overwrite_copy (section->model, section->original_model);
- gtk_object_unref (GTK_OBJECT (section->original_model));
- section->original_model = NULL;
- }
- }
-}
-
-static void
-e_select_names_manager_discard_saved_models (ESelectNamesManager *manager)
-{
- GList *iter;
-
- for (iter = manager->sections; iter != NULL; iter = g_list_next (iter)) {
- ESelectNamesManagerSection *section = iter->data;
- if (section->original_model) {
- gtk_object_unref (GTK_OBJECT (section->original_model));
- section->original_model = NULL;
- }
- }
-}
-
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-
-
-static void
-open_book_cb (EBook *book, EBookStatus status, ESelectNamesManager *manager)
-{
- if (status == E_BOOK_STATUS_SUCCESS) {
- GList *l;
- for (l = manager->entries; l; l = l->next) {
- ESelectNamesManagerEntry *entry = l->data;
- e_select_names_completion_add_book (E_SELECT_NAMES_COMPLETION(entry->comp), book);
- }
-
- manager->completion_books = g_list_append (manager->completion_books, book);
- gtk_object_ref (GTK_OBJECT (book));
- }
-
- gtk_object_unref (GTK_OBJECT (manager)); /* unref ourself (matches ref before the load_uri call below) */
-}
-
-static void
-load_completion_books (ESelectNamesManager *manager)
-{
- EFolderListItem *folders = e_folder_list_parse_xml (manager->cached_folder_list);
- EFolderListItem *f;
-
- for (f = folders; f && f->physical_uri; f++) {
- char *uri;
- EBook *book = e_book_new ();
- gtk_object_ref (GTK_OBJECT (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);
- }
- e_folder_list_free_items (folders);
-}
-
-static void
-read_completion_books_from_db (ESelectNamesManager *manager)
-{
- Bonobo_ConfigDatabase db;
- CORBA_Environment ev;
- char *val;
-
- CORBA_exception_init (&ev);
-
- db = addressbook_config_database (&ev);
-
- val = bonobo_config_get_string (db, "/Addressbook/Completion/uris", &ev);
-
- CORBA_exception_free (&ev);
-
- if (val) {
- g_free (manager->cached_folder_list);
- manager->cached_folder_list = val;
- load_completion_books(manager);
- }
-}
-
-static void
-uris_listener (BonoboListener *listener, char *event_name,
- CORBA_any *any, CORBA_Environment *ev,
- gpointer user_data)
-{
- ESelectNamesManager *manager = E_SELECT_NAMES_MANAGER (user_data);
- GList *l;
- Bonobo_ConfigDatabase db;
- char *val;
-
- db = addressbook_config_database (NULL);
-
- val = bonobo_config_get_string (db, "/Addressbook/Completion/uris", NULL);
-
- if (val) {
- if (!manager->cached_folder_list || strcmp (val, manager->cached_folder_list)) {
- for (l = manager->entries; l; l = l->next) {
- ESelectNamesManagerEntry *entry = l->data;
- e_select_names_completion_clear_books (E_SELECT_NAMES_COMPLETION (entry->comp));
- }
-
- g_list_foreach (manager->completion_books, (GFunc)gtk_object_unref, NULL);
- g_list_free (manager->completion_books);
- manager->completion_books = NULL;
-
- g_free (manager->cached_folder_list);
- manager->cached_folder_list = val;
- load_completion_books (manager);
- }
- }
-}
-
-/**
- * e_select_names_manager_new:
- * @VCard: a string in vCard format
- *
- * Returns: a new #ESelectNamesManager that wraps the @VCard.
- */
-ESelectNamesManager *
-e_select_names_manager_new (void)
-{
- ESelectNamesManager *manager = E_SELECT_NAMES_MANAGER(gtk_type_new(e_select_names_manager_get_type()));
- Bonobo_ConfigDatabase db;
-
- db = addressbook_config_database (NULL);
-
- manager->listener_id = bonobo_event_source_client_add_listener (db, uris_listener,
- "Bonobo/ConfigDatabase:change/Addressbook/Completion:",
- NULL,
- manager);
-
- read_completion_books_from_db (manager);
-
- return manager;
-}
-
-
-/*
- * ESelectNamesManager lifecycle management and vcard loading/saving.
- */
-
-
-void
-e_select_names_manager_add_section (ESelectNamesManager *manager,
- const char *id,
- const char *title)
-{
- g_return_if_fail (E_IS_SELECT_NAMES_MANAGER (manager));
- g_return_if_fail (id != NULL);
- g_return_if_fail (title != NULL);
-
- e_select_names_manager_add_section_with_limit (manager, id, title, -1);
-}
-
-void
-e_select_names_manager_add_section_with_limit (ESelectNamesManager *manager,
- const char *id,
- const char *title,
- gint limit)
-{
- ESelectNamesManagerSection *section;
- ESelectNamesModel *model;
-
- g_return_if_fail (E_IS_SELECT_NAMES_MANAGER (manager));
- g_return_if_fail (id != NULL);
- g_return_if_fail (title != NULL);
-
- model = e_select_names_model_new ();
- e_select_names_model_set_limit (model, limit);
-
- section = e_select_names_manager_section_new (manager, id, title, model);
-
- manager->sections = g_list_append (manager->sections, section);
-
- gtk_object_unref (GTK_OBJECT (model));
-}
-
-ESelectNamesModel *
-e_select_names_manager_get_source (ESelectNamesManager *manager,
- const char *id)
-{
- GList *iter;
-
- g_return_val_if_fail (E_IS_SELECT_NAMES_MANAGER (manager), NULL);
- g_return_val_if_fail (id != NULL, NULL);
-
- for (iter = manager->sections; iter != NULL; iter = g_list_next (iter)) {
- ESelectNamesManagerSection *section = iter->data;
- if (!strcmp (section->id, id))
- return section->model;
- }
- return NULL;
-}
-
-GtkWidget *
-e_select_names_manager_create_entry (ESelectNamesManager *manager, const char *id)
-{
- GList *iter;
-
- g_return_val_if_fail (E_IS_SELECT_NAMES_MANAGER (manager), NULL);
- g_return_val_if_fail (id != NULL, NULL);
-
- for (iter = manager->sections; iter != NULL; iter = g_list_next (iter)) {
- ESelectNamesManagerSection *section = iter->data;
- if (!strcmp(section->id, id)) {
- ESelectNamesManagerEntry *entry;
-
- entry = e_select_names_manager_entry_new (manager, section->model, section->id);
- manager->entries = g_list_append (manager->entries, entry);
-
- return GTK_WIDGET(entry->entry);
- }
- }
-
- return NULL;
-}
-
-static void
-e_select_names_clicked(ESelectNames *dialog, gint button, ESelectNamesManager *manager)
-{
- gnome_dialog_close(GNOME_DIALOG(dialog));
-
- switch(button) {
- case 0:
- e_select_names_manager_discard_saved_models (manager);
- gtk_signal_emit (GTK_OBJECT (manager), e_select_names_manager_signals[OK]);
- break;
-
- case 1:
- e_select_names_manager_revert_to_saved_models (manager);
- gtk_signal_emit (GTK_OBJECT (manager), e_select_names_manager_signals[CANCEL]);
- break;
- }
-}
-
-void
-e_select_names_manager_activate_dialog (ESelectNamesManager *manager,
- const char *id)
-{
- g_return_if_fail (E_IS_SELECT_NAMES_MANAGER (manager));
- g_return_if_fail (id != NULL);
-
- if (manager->names) {
-
- g_assert (GTK_WIDGET_REALIZED (GTK_WIDGET (manager->names)));
- e_select_names_set_default (manager->names, id);
- gdk_window_show (GTK_WIDGET (manager->names)->window);
- gdk_window_raise (GTK_WIDGET (manager->names)->window);
-
- } else {
-
- GList *iter;
-
- manager->names = E_SELECT_NAMES (e_select_names_new ());
-
- for (iter = manager->sections; iter != NULL; iter = g_list_next (iter)) {
- ESelectNamesManagerSection *section = iter->data;
- e_select_names_add_section (manager->names, section->id, section->title, section->model);
- }
-
- e_select_names_set_default (manager->names, id);
-
- gtk_signal_connect(GTK_OBJECT(manager->names),
- "clicked",
- GTK_SIGNAL_FUNC(e_select_names_clicked),
- manager);
-
- gtk_signal_connect(GTK_OBJECT(manager->names),
- "destroy",
- GTK_SIGNAL_FUNC(gtk_widget_destroyed),
- &manager->names);
-
- gtk_widget_show(GTK_WIDGET(manager->names));
- }
-
- e_select_names_manager_save_models (manager);
-}
-
-/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
-
-static void
-e_select_names_manager_init (ESelectNamesManager *manager)
-{
- manager->sections = NULL;
- manager->entries = NULL;
- manager->completion_books = NULL;
- manager->cached_folder_list = NULL;
-}
-
-static void
-e_select_names_manager_destroy (GtkObject *object)
-{
- ESelectNamesManager *manager;
-
- manager = E_SELECT_NAMES_MANAGER (object);
-
- if (manager->names) {
- gtk_widget_destroy (GTK_WIDGET (manager->names));
- manager->names = NULL;
- }
-
- g_list_foreach (manager->sections, (GFunc) e_select_names_manager_section_free, NULL);
- g_list_free (manager->sections);
- manager->sections = NULL;
-
- g_list_foreach (manager->entries, (GFunc) e_select_names_manager_entry_free, NULL);
- g_list_free (manager->entries);
- manager->entries = NULL;
-
- g_list_foreach (manager->completion_books, (GFunc) gtk_object_unref, NULL);
- g_list_free (manager->completion_books);
- manager->completion_books = NULL;
-
- bonobo_event_source_client_remove_listener (addressbook_config_database (NULL), manager->listener_id, NULL);
-
- g_free (manager->cached_folder_list);
-}
-
-static void
-e_select_names_manager_class_init (ESelectNamesManagerClass *klass)
-{
- GtkObjectClass *object_class;
-
- object_class = GTK_OBJECT_CLASS(klass);
-
- object_class->destroy = e_select_names_manager_destroy;
-
- e_select_names_manager_signals[CHANGED] =
- gtk_signal_new ("changed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ESelectNamesManagerClass, changed),
- gtk_marshal_NONE__POINTER_INT,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_POINTER,
- GTK_TYPE_INT);
-
- e_select_names_manager_signals[OK] =
- gtk_signal_new ("ok",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ESelectNamesManagerClass, ok),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- e_select_names_manager_signals[CANCEL] =
- gtk_signal_new ("cancel",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ESelectNamesManagerClass, cancel),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, e_select_names_manager_signals, LAST_SIGNAL);
-}
-
-/**
- * e_select_names_manager_get_type:
- * @void:
- *
- * Registers the &ESelectNamesManager class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the &ESelectNamesManager class.
- **/
-GtkType
-e_select_names_manager_get_type (void)
-{
- static GtkType manager_type = 0;
-
- if (!manager_type) {
- GtkTypeInfo manager_info = {
- "ESelectNamesManager",
- sizeof (ESelectNamesManager),
- sizeof (ESelectNamesManagerClass),
- (GtkClassInitFunc) e_select_names_manager_class_init,
- (GtkObjectInitFunc) e_select_names_manager_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- manager_type = gtk_type_unique (gtk_object_get_type (), &manager_info);
- }
-
- return manager_type;
-}
-
-
-
diff --git a/addressbook/gui/component/select-names/e-select-names-manager.h b/addressbook/gui/component/select-names/e-select-names-manager.h
deleted file mode 100644
index af57bd3a61..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-manager.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc.
- */
-
-#ifndef __E_SELECT_NAMES_MANAGER_H__
-#define __E_SELECT_NAMES_MANAGER_H__
-
-#include <stdio.h>
-#include <time.h>
-#include <gtk/gtkobject.h>
-#include <e-util/e-list.h>
-#include "e-select-names.h"
-
-#define E_TYPE_SELECT_NAMES_MANAGER (e_select_names_manager_get_type ())
-#define E_SELECT_NAMES_MANAGER(obj) (GTK_CHECK_CAST ((obj), E_TYPE_SELECT_NAMES_MANAGER, ESelectNamesManager))
-#define E_SELECT_NAMES_MANAGER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_SELECT_NAMES_MANAGER, ESelectNamesManagerClass))
-#define E_IS_SELECT_NAMES_MANAGER(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_SELECT_NAMES_MANAGER))
-#define E_IS_SELECT_NAMES_MANAGER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_SELECT_NAMES_MANAGER))
-
-typedef struct _ESelectNamesManager ESelectNamesManager;
-typedef struct _ESelectNamesManagerClass ESelectNamesManagerClass;
-
-struct _ESelectNamesManager {
- GtkObject object;
-
- GList *sections;
- GList *entries;
-
- ESelectNames *names;
-
- GList *completion_books;
-
- Bonobo_EventSource_ListenerId listener_id;
-
- char *cached_folder_list;
-};
-
-struct _ESelectNamesManagerClass {
- GtkObjectClass parent_class;
-
- void (*changed) (ESelectNamesManager *, const gchar *section_id, gint changed_working_copy);
- void (*ok) (ESelectNamesManager *);
- void (*cancel) (ESelectNamesManager *);
-};
-
-ESelectNamesManager *e_select_names_manager_new (void);
-void e_select_names_manager_add_section (ESelectNamesManager *manager,
- const char *id,
- const char *title);
-void e_select_names_manager_add_section_with_limit (ESelectNamesManager *manager,
- const char *id,
- const char *title,
- gint limit);
-ESelectNamesModel *e_select_names_manager_get_source (ESelectNamesManager *manager,
- const char *id);
-GtkWidget *e_select_names_manager_create_entry (ESelectNamesManager *manager,
- const char *id);
-void e_select_names_manager_activate_dialog (ESelectNamesManager *manager,
- const char *id);
-/* Standard Gtk function */
-GtkType e_select_names_manager_get_type (void);
-
-#endif /* ! __E_SELECT_NAMES_MANAGER_H__ */
diff --git a/addressbook/gui/component/select-names/e-select-names-model.c b/addressbook/gui/component/select-names/e-select-names-model.c
deleted file mode 100644
index fadb8c21a0..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-model.c
+++ /dev/null
@@ -1,889 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- * Jon Trowbidge <trow@ximian.com>
- *
- * Copyright (C) 2000, 2001 Ximian, Inc.
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <gtk/gtkmarshal.h>
-#include <gtk/gtksignal.h>
-
-#include <gal/util/e-util.h>
-
-#include "e-select-names-model.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
-
-#define MAX_LENGTH 2047
-
-
-enum {
- E_SELECT_NAMES_MODEL_CHANGED,
- E_SELECT_NAMES_MODEL_RESIZED,
- E_SELECT_NAMES_MODEL_LAST_SIGNAL
-};
-
-static guint e_select_names_model_signals[E_SELECT_NAMES_MODEL_LAST_SIGNAL] = { 0 };
-
-/* Object argument IDs */
-enum {
- ARG_0,
- ARG_CARD,
-};
-
-enum {
- NAME_DATA_BLANK,
- NAME_DATA_CARD,
- NAME_DATA_STRING
-};
-
-enum {
- NAME_FORMAT_GIVEN_FIRST,
- NAME_FORMAT_FAMILY_FIRST
-};
-
-struct _ESelectNamesModelPrivate {
- gchar *id;
- gchar *title;
-
- GList *data; /* of EDestination */
-
- gint limit;
-
- gint freeze_count;
- gboolean pending_changed;
-};
-
-
-static void e_select_names_model_init (ESelectNamesModel *model);
-static void e_select_names_model_class_init (ESelectNamesModelClass *klass);
-
-static void e_select_names_model_destroy (GtkObject *object);
-static void e_select_names_model_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_select_names_model_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-
-GtkType
-e_select_names_model_get_type (void)
-{
- static GtkType model_type = 0;
-
- if (!model_type) {
- GtkTypeInfo model_info = {
- "ESelectNamesModel",
- sizeof (ESelectNamesModel),
- sizeof (ESelectNamesModelClass),
- (GtkClassInitFunc) e_select_names_model_class_init,
- (GtkObjectInitFunc) e_select_names_model_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- model_type = gtk_type_unique (gtk_object_get_type (), &model_info);
- }
-
- return model_type;
-}
-
-typedef void (*GtkSignal_NONE__INT_INT_INT) (GtkObject *object, gint arg1, gint arg2, gint arg3, gpointer user_data);
-static void
-local_gtk_marshal_NONE__INT_INT_INT (GtkObject *object,
- GtkSignalFunc func,
- gpointer func_data,
- GtkArg *args)
-{
- GtkSignal_NONE__INT_INT_INT rfunc;
- rfunc = (GtkSignal_NONE__INT_INT_INT) func;
- (* rfunc) (object,
- GTK_VALUE_INT(args[0]),
- GTK_VALUE_INT(args[1]),
- GTK_VALUE_INT(args[2]),
- func_data);
-}
-
-
-static void
-e_select_names_model_class_init (ESelectNamesModelClass *klass)
-{
- GtkObjectClass *object_class;
-
- object_class = GTK_OBJECT_CLASS(klass);
-
- e_select_names_model_signals[E_SELECT_NAMES_MODEL_CHANGED] =
- gtk_signal_new ("changed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ESelectNamesModelClass, changed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- e_select_names_model_signals[E_SELECT_NAMES_MODEL_RESIZED] =
- gtk_signal_new ("resized",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (ESelectNamesModelClass, resized),
- local_gtk_marshal_NONE__INT_INT_INT,
- GTK_TYPE_NONE, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_INT);
-
- gtk_object_class_add_signals (object_class, e_select_names_model_signals, E_SELECT_NAMES_MODEL_LAST_SIGNAL);
-
- gtk_object_add_arg_type ("ESelectNamesModel::card",
- GTK_TYPE_OBJECT, GTK_ARG_READWRITE, ARG_CARD);
-
- klass->changed = NULL;
-
- object_class->destroy = e_select_names_model_destroy;
- object_class->get_arg = e_select_names_model_get_arg;
- object_class->set_arg = e_select_names_model_set_arg;
-}
-
-/**
- * e_select_names_model_init:
- */
-static void
-e_select_names_model_init (ESelectNamesModel *model)
-{
- model->priv = g_new0 (struct _ESelectNamesModelPrivate, 1);
-
- model->priv->limit = -1;
-}
-
-static void
-e_select_names_model_destroy (GtkObject *object)
-{
- ESelectNamesModel *model = E_SELECT_NAMES_MODEL (object);
-
- g_free (model->priv->title);
- g_free (model->priv->id);
-
- g_list_foreach (model->priv->data, (GFunc) gtk_object_unref, NULL);
- g_list_free (model->priv->data);
-
- g_free (model->priv);
-
-}
-
-
-/* Set_arg handler for the model */
-static void
-e_select_names_model_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- ESelectNamesModel *model;
-
- model = E_SELECT_NAMES_MODEL (object);
-
- switch (arg_id) {
- case ARG_CARD:
- break;
- default:
- return;
- }
-}
-
-/* Get_arg handler for the model */
-static void
-e_select_names_model_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- ESelectNamesModel *model;
-
- model = E_SELECT_NAMES_MODEL (object);
-
- switch (arg_id) {
- case ARG_CARD:
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
-}
-
-
-static void
-e_select_names_model_changed (ESelectNamesModel *model)
-{
- if (model->priv->freeze_count > 0) {
- model->priv->pending_changed = TRUE;
- } else {
- gtk_signal_emit (GTK_OBJECT(model), e_select_names_model_signals[E_SELECT_NAMES_MODEL_CHANGED]);
- model->priv->pending_changed = FALSE;
- }
-}
-
-static void
-destination_changed_proxy (EDestination *dest, gpointer closure)
-{
- e_select_names_model_changed (E_SELECT_NAMES_MODEL (closure));
-}
-
-/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
-
-ESelectNamesModel *
-e_select_names_model_new (void)
-{
- ESelectNamesModel *model;
- model = E_SELECT_NAMES_MODEL (gtk_type_new (e_select_names_model_get_type ()));
- return model;
-}
-
-ESelectNamesModel *
-e_select_names_model_duplicate (ESelectNamesModel *old)
-{
- ESelectNamesModel *model = E_SELECT_NAMES_MODEL(gtk_type_new(e_select_names_model_get_type()));
- GList *iter;
-
- model->priv->id = g_strdup (old->priv->id);
- 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));
- e_select_names_model_append (model, dup);
- }
-
- model->priv->limit = old->priv->limit;
-
- return model;
-}
-
-gchar *
-e_select_names_model_get_textification (ESelectNamesModel *model, const char *separator)
-{
- gchar *text;
-
- g_return_val_if_fail (model != NULL, NULL);
- g_return_val_if_fail (E_IS_SELECT_NAMES_MODEL (model), NULL);
- g_return_val_if_fail (separator && *separator, NULL);
-
- if (model->priv->data == NULL) {
-
- text = g_strdup ("");
-
- } else {
- gchar **strv = g_new0 (gchar *, g_list_length (model->priv->data)+1);
- gint i = 0;
- GList *iter = model->priv->data;
-
- while (iter) {
- EDestination *dest = E_DESTINATION (iter->data);
- strv[i] = (gchar *) e_destination_get_textrep (dest);
- ++i;
- iter = g_list_next (iter);
- }
-
- text = g_strjoinv (separator, strv);
-
- if (strlen(text) > MAX_LENGTH) {
- text[MAX_LENGTH] = '\0';
- text = g_realloc (text, MAX_LENGTH + 1);
- }
-
- g_free (strv);
-
- }
-
- return text;
-}
-
-gchar *
-e_select_names_model_get_address_text (ESelectNamesModel *model, const char *separator)
-{
- gchar *addr_text;
-
- g_return_val_if_fail (model != NULL, NULL);
- g_return_val_if_fail (E_IS_SELECT_NAMES_MODEL (model), NULL);
- g_return_val_if_fail (separator && *separator, NULL);
-
- if (model->priv->data == NULL) {
-
- addr_text = g_strdup ("");
-
- } else {
- gchar **strv = g_new0 (gchar *, g_list_length (model->priv->data)+1);
- gint i = 0;
- GList *iter = model->priv->data;
-
- while (iter) {
- EDestination *dest = E_DESTINATION (iter->data);
- strv[i] = (gchar *) e_destination_get_address (dest);
- if (strv[i])
- ++i;
- iter = g_list_next (iter);
- }
-
- addr_text = g_strjoinv (separator, strv);
-
- g_free (strv);
-
- }
-
- return addr_text;
-}
-
-gint
-e_select_names_model_count (ESelectNamesModel *model)
-{
- g_return_val_if_fail (model != NULL, 0);
- g_return_val_if_fail (E_IS_SELECT_NAMES_MODEL (model), 0);
-
- return g_list_length (model->priv->data);
-}
-
-gint
-e_select_names_model_get_limit (ESelectNamesModel *model)
-{
- g_return_val_if_fail (model != NULL, 0);
- g_return_val_if_fail (E_IS_SELECT_NAMES_MODEL (model), 0);
-
- return model->priv->limit;
-}
-
-void
-e_select_names_model_set_limit (ESelectNamesModel *model, gint limit)
-{
- g_return_if_fail (model != NULL);
- g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
-
- model->priv->limit = MAX (limit, -1);
-}
-
-gboolean
-e_select_names_model_at_limit (ESelectNamesModel *model)
-{
- g_return_val_if_fail (model != NULL, TRUE);
- g_return_val_if_fail (E_IS_SELECT_NAMES_MODEL (model), TRUE);
-
- return model->priv->limit >= 0 && g_list_length (model->priv->data) >= model->priv->limit;
-}
-
-const EDestination *
-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));
-}
-
-gchar *
-e_select_names_model_export_destinationv (ESelectNamesModel *model)
-{
- EDestination **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);
-
- for (i=0, j = model->priv->data; j != NULL; j = g_list_next (j)) {
- EDestination *dest = E_DESTINATION (j->data);
-
- if (dest)
- destv[i++] = dest;
- }
-
- str = e_destination_exportv (destv);
- g_free (destv);
-
- return str;
-}
-
-static
-void send_changed (EDestination *dest, ECard *card, gpointer closure)
-{
- ESelectNamesModel *model = closure;
- e_select_names_model_changed (model);
-}
-
-void
-e_select_names_model_import_destinationv (ESelectNamesModel *model,
- gchar *destinationv)
-{
- EDestination **destv;
- gint i;
-
- g_return_if_fail (model && E_IS_SELECT_NAMES_MODEL (model));
-
- destv = e_destination_importv (destinationv);
-
- e_select_names_model_delete_all (model);
-
- if (destv == NULL)
- return;
-
- for (i = 0; destv[i]; i++) {
- e_destination_use_card (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)
-{
- const EDestination *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;
-
-}
-
-const gchar *
-e_select_names_model_get_string (ESelectNamesModel *model, gint index)
-{
- const EDestination *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_textrep (dest) : "";
-}
-
-static void
-connect_destination (ESelectNamesModel *model, EDestination *dest)
-{
- gtk_signal_connect (GTK_OBJECT (dest),
- "changed",
- destination_changed_proxy,
- model);
-}
-
-static void
-disconnect_destination (ESelectNamesModel *model, EDestination *dest)
-{
- gtk_signal_disconnect_by_func (GTK_OBJECT (dest), destination_changed_proxy, model);
-}
-
-gboolean
-e_select_names_model_contains (ESelectNamesModel *model, const EDestination *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);
-
- for (iter = model->priv->data; iter != NULL; iter = g_list_next (iter)) {
- if (iter->data != NULL && e_destination_equal (dest, E_DESTINATION (iter->data)))
- return TRUE;
- }
-
- return FALSE;
-}
-
-void
-e_select_names_model_insert (ESelectNamesModel *model, gint index, EDestination *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));
-
- if (e_select_names_model_at_limit (model)) {
- /* FIXME: This is bad. */
- gtk_object_unref (GTK_OBJECT (dest));
- return;
- }
-
- connect_destination (model, dest);
-
- model->priv->data = g_list_insert (model->priv->data, dest, index);
-
- gtk_object_ref (GTK_OBJECT (dest));
- gtk_object_sink (GTK_OBJECT (dest));
-
- e_select_names_model_changed (model);
-}
-
-void
-e_select_names_model_append (ESelectNamesModel *model, EDestination *dest)
-{
- g_return_if_fail (model && E_IS_SELECT_NAMES_MODEL (model));
- g_return_if_fail (dest && E_IS_DESTINATION (dest));
-
- if (e_select_names_model_at_limit (model)) {
- /* FIXME: This is bad. */
- gtk_object_unref (GTK_OBJECT (dest));
- return;
- }
-
- connect_destination (model, dest);
-
- model->priv->data = g_list_append (model->priv->data, dest);
-
- gtk_object_ref (GTK_OBJECT (dest));
- gtk_object_sink (GTK_OBJECT (dest));
-
- e_select_names_model_changed (model);
-}
-
-void
-e_select_names_model_replace (ESelectNamesModel *model, gint index, EDestination *dest)
-{
- GList *node;
- const gchar *new_str, *old_str;
- gint old_strlen=0, new_strlen=0;
-
- 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));
-
- new_str = e_destination_get_textrep (dest);
- new_strlen = new_str ? strlen (new_str) : 0;
-
- if (model->priv->data == NULL) {
-
- connect_destination (model, dest);
-
- model->priv->data = g_list_append (model->priv->data, dest);
- gtk_object_ref (GTK_OBJECT (dest));
- gtk_object_sink (GTK_OBJECT (dest));
-
- } else {
-
- node = g_list_nth (model->priv->data, index);
-
- if (node->data != dest) {
-
- disconnect_destination (model, E_DESTINATION (node->data));
- connect_destination (model, dest);
-
- old_str = e_destination_get_textrep (E_DESTINATION (node->data));
- old_strlen = old_str ? strlen (old_str) : 0;
-
- gtk_object_unref (GTK_OBJECT (node->data));
-
- node->data = dest;
- gtk_object_ref (GTK_OBJECT (dest));
- gtk_object_sink (GTK_OBJECT (dest));
- }
- }
-
- e_select_names_model_changed (model);
-
- gtk_signal_emit (GTK_OBJECT (model), e_select_names_model_signals[E_SELECT_NAMES_MODEL_RESIZED],
- index, old_strlen, new_strlen);
-}
-
-void
-e_select_names_model_delete (ESelectNamesModel *model, gint index)
-{
- GList *node;
- EDestination *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);
-
- disconnect_destination (model, dest);
- gtk_object_unref (GTK_OBJECT (dest));
-
- model->priv->data = g_list_remove_link (model->priv->data, node);
- g_list_free_1 (node);
-
- e_select_names_model_changed (model);
-}
-
-void
-e_select_names_model_clean (ESelectNamesModel *model, gboolean clean_last_entry)
-{
- GList *iter, *next;
- gboolean changed = FALSE;
-
- g_return_if_fail (model != NULL && E_IS_SELECT_NAMES_MODEL (model));
-
- iter = model->priv->data;
-
- while (iter) {
- EDestination *dest;
-
- next = g_list_next (iter);
-
- if (next == NULL && !clean_last_entry)
- break;
-
- dest = iter->data ? E_DESTINATION (iter->data) : NULL;
-
- if (dest == NULL || e_destination_is_empty (dest)) {
- if (dest) {
- disconnect_destination (model, dest);
- gtk_object_unref (GTK_OBJECT (dest));
- }
- model->priv->data = g_list_remove_link (model->priv->data, iter);
- g_list_free_1 (iter);
- changed = TRUE;
- }
-
- iter = next;
- }
-
- if (changed)
- e_select_names_model_changed (model);
-}
-
-static void
-delete_all_iter (gpointer data, gpointer closure)
-{
- disconnect_destination (E_SELECT_NAMES_MODEL (closure), E_DESTINATION (data));
- gtk_object_unref (GTK_OBJECT (data));
-}
-
-void
-e_select_names_model_delete_all (ESelectNamesModel *model)
-{
- g_return_if_fail (model != NULL && E_IS_SELECT_NAMES_MODEL (model));
-
- g_list_foreach (model->priv->data, delete_all_iter, model);
- g_list_free (model->priv->data);
- model->priv->data = NULL;
-
- e_select_names_model_changed (model);
-}
-
-void
-e_select_names_model_overwrite_copy (ESelectNamesModel *dest, ESelectNamesModel *src)
-{
- gint i, len;
-
- g_return_if_fail (dest && E_IS_SELECT_NAMES_MODEL (dest));
- g_return_if_fail (src && E_IS_SELECT_NAMES_MODEL (src));
-
- if (src == dest)
- return;
-
- 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);
- if (d)
- e_select_names_model_append (dest, e_destination_copy (d));
- }
-}
-
-void
-e_select_names_model_merge (ESelectNamesModel *dest, ESelectNamesModel *src)
-{
- gint i, len;
-
- g_return_if_fail (E_IS_SELECT_NAMES_MODEL (dest));
- g_return_if_fail (E_IS_SELECT_NAMES_MODEL (src));
-
- if (src == dest)
- return;
-
- len = e_select_names_model_count (src);
- for (i = 0; i < len; ++i) {
- const EDestination *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));
- }
-}
-
-void
-e_select_names_model_name_pos (ESelectNamesModel *model, gint seplen, gint index, gint *pos, gint *length)
-{
- gint rp = 0, i, len = 0;
- GList *iter;
- const gchar *str;
-
- g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
- g_return_if_fail (seplen > 0);
-
- i = 0;
- iter = model->priv->data;
- while (iter && i <= index) {
- rp += len + (i > 0 ? seplen : 0);
- str = e_destination_get_textrep (E_DESTINATION (iter->data));
- len = str ? strlen (str) : 0;
- ++i;
- iter = g_list_next (iter);
- }
-
- if (i <= index) {
- rp = -1;
- len = 0;
- }
-
- if (pos)
- *pos = rp;
- if (length)
- *length = len;
-}
-
-void
-e_select_names_model_text_pos (ESelectNamesModel *model, gint seplen, gint pos, gint *index, gint *start_pos, gint *length)
-{
- GList *iter;
- const gchar *str;
- gint len = 0, i = 0, sp = 0, adj = 0;
-
- g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
- g_return_if_fail (seplen > 0);
-
- iter = model->priv->data;
-
- while (iter != NULL) {
- str = e_destination_get_textrep (E_DESTINATION (iter->data));
- len = str ? strlen (str) : 0;
-
- if (sp <= pos && pos <= sp + len + adj) {
- break;
- }
-
- sp += len + adj + 1;
- adj = seplen-1;
- ++i;
-
- iter = g_list_next (iter);
- }
-
- if (i != 0)
- sp += seplen-1; /* skip past "magic space" */
-
- if (iter == NULL) {
-#if 0
- g_print ("text_pos ended NULL\n");
-#endif
- i = -1;
- sp = -1;
- len = 0;
- } else {
-#if 0
- g_print ("text_pos got index %d\n", i);
-#endif
- }
-
- if (index)
- *index = i;
- if (start_pos)
- *start_pos = sp;
- if (length)
- *length = len;
-}
-
-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)
-{
- GList *iter;
-
- g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
- 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)) {
-
- if (delay > 0)
- e_destination_cardify_delayed (dest, book, delay);
- else
- e_destination_cardify (dest, book);
- }
- }
-}
-
-void
-e_select_names_model_cancel_cardify_all (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);
- }
-}
-
-void
-e_select_names_model_freeze (ESelectNamesModel *model)
-{
- g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
-
- ++model->priv->freeze_count;
-}
-
-void
-e_select_names_model_thaw (ESelectNamesModel *model)
-{
- g_return_if_fail (E_IS_SELECT_NAMES_MODEL (model));
- g_return_if_fail (model->priv->freeze_count > 0);
-
- --model->priv->freeze_count;
- if (model->priv->pending_changed)
- e_select_names_model_changed (model);
-}
diff --git a/addressbook/gui/component/select-names/e-select-names-model.h b/addressbook/gui/component/select-names/e-select-names-model.h
deleted file mode 100644
index 9179eb676d..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-model.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- * Jon Trowbridge <trow@ximian.com>
- *
- * Copyright (C) 2000, 2001 Ximian, Inc.
- */
-
-#ifndef __E_SELECT_NAMES_MODEL_H__
-#define __E_SELECT_NAMES_MODEL_H__
-
-#include <time.h>
-#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>
-
-#define E_TYPE_SELECT_NAMES_MODEL (e_select_names_model_get_type ())
-#define E_SELECT_NAMES_MODEL(obj) (GTK_CHECK_CAST ((obj), E_TYPE_SELECT_NAMES_MODEL, ESelectNamesModel))
-#define E_SELECT_NAMES_MODEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_SELECT_NAMES_MODEL, ESelectNamesModelClass))
-#define E_IS_SELECT_NAMES_MODEL(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_SELECT_NAMES_MODEL))
-#define E_IS_SELECT_NAMES_MODEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_SELECT_NAMES_MODEL))
-
-typedef struct _ESelectNamesModel ESelectNamesModel;
-typedef struct _ESelectNamesModelClass ESelectNamesModelClass;
-struct _ESelectNamesModelPrivate;
-
-struct _ESelectNamesModel {
- GtkObject object;
-
- struct _ESelectNamesModelPrivate *priv;
-};
-
-struct _ESelectNamesModelClass {
- GtkObjectClass parent_class;
-
- void (*changed) (ESelectNamesModel *model);
- void (*resized) (ESelectNamesModel *model, gint index, gint old_len, gint new_len);
-};
-
-GtkType e_select_names_model_get_type (void);
-
-ESelectNamesModel *e_select_names_model_new (void);
-ESelectNamesModel *e_select_names_model_duplicate (ESelectNamesModel *old);
-
-gchar *e_select_names_model_get_textification (ESelectNamesModel *model, const char *separator);
-gchar *e_select_names_model_get_address_text (ESelectNamesModel *model, const char *separator);
-
-gint e_select_names_model_count (ESelectNamesModel *model);
-gint e_select_names_model_get_limit (ESelectNamesModel *model);
-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,
- gchar *destinationv);
-ECard *e_select_names_model_get_card (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);
-
-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_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);
-void e_select_names_model_merge (ESelectNamesModel *dest, ESelectNamesModel *src);
-
-void e_select_names_model_clean (ESelectNamesModel *model, gboolean clean_last_entry);
-
-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);
-
-/* 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. */
-void e_select_names_model_freeze (ESelectNamesModel *model);
-void e_select_names_model_thaw (ESelectNamesModel *model);
-
-
-#endif /* ! __E_SELECT_NAMES_MODEL_H__ */
diff --git a/addressbook/gui/component/select-names/e-select-names-popup.c b/addressbook/gui/component/select-names/e-select-names-popup.c
deleted file mode 100644
index 927bdff769..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-popup.c
+++ /dev/null
@@ -1,564 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-select-names-popup.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 <stdio.h>
-#include <string.h>
-
-#include <glib.h>
-#include <gtk/gtkcheckmenuitem.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-app-helper.h>
-#include <libgnomeui/gnome-popup-menu.h>
-#include <gal/widgets/e-unicode.h>
-
-#include <addressbook/backend/ebook/e-book-util.h>
-#include <addressbook/gui/contact-editor/e-contact-editor.h>
-#include <addressbook/gui/contact-editor/e-contact-quick-add.h>
-#include "e-addressbook-util.h"
-#include "e-select-names-popup.h"
-
-typedef struct _PopupInfo PopupInfo;
-struct _PopupInfo {
- ESelectNamesTextModel *text_model;
- const EDestination *dest;
- gint pos;
- gint index;
-};
-
-static PopupInfo *
-popup_info_new (ESelectNamesTextModel *text_model, const EDestination *dest, gint pos, gint index)
-{
- PopupInfo *info = g_new0 (PopupInfo, 1);
- info->text_model = text_model;
- info->dest = dest;
- info->pos = pos;
- info->index = index;
-
- if (text_model)
- gtk_object_ref (GTK_OBJECT (text_model));
-
- if (dest)
- gtk_object_ref (GTK_OBJECT (dest));
-
- return info;
-}
-
-static void
-popup_info_free (PopupInfo *info)
-{
- if (info) {
-
- if (info->text_model)
- gtk_object_unref (GTK_OBJECT (info->text_model));
-
- if (info->dest)
- gtk_object_unref (GTK_OBJECT (info->dest));
-
- g_free (info);
- }
-}
-
-static void
-popup_info_cleanup (GtkWidget *w, gpointer info)
-{
- popup_info_free ((PopupInfo *) info);
-}
-
-/* You are in a maze of twisty little callbacks, all alike... */
-
-static void
-make_contact_editor_cb (EBook *book, gpointer user_data)
-{
- if (book) {
- EDestination *dest = E_DESTINATION (user_data);
- ECard *card;
-
- card = (ECard *) e_destination_get_card (dest);
- if (e_card_evolution_list (card)) {
- EContactListEditor *ce;
- ce = e_addressbook_show_contact_list_editor (book, card, FALSE, TRUE);
- e_contact_list_editor_raise (ce);
- }
- else {
- EContactEditor *ce;
- ce = e_addressbook_show_contact_editor (book, card, FALSE, TRUE);
- e_contact_editor_raise (ce);
- }
- gtk_object_unref (GTK_OBJECT (dest));
- }
-}
-
-static void
-edit_contact_info_cb (GtkWidget *w, gpointer user_data)
-{
- PopupInfo *info = (PopupInfo *) user_data;
- if (info == NULL)
- return;
-
- gtk_object_ref (GTK_OBJECT (info->dest));
- e_book_use_default_book (make_contact_editor_cb, (gpointer) info->dest);
-}
-
-static void
-change_email_num_cb (GtkWidget *w, gpointer user_data)
-{
- PopupInfo *info = (PopupInfo *) user_data;
- gint n;
- EDestination *dest;
-
- if (info == NULL)
- return;
-
- if (! GTK_CHECK_MENU_ITEM (w)->active)
- return;
-
- n = GPOINTER_TO_INT (gtk_object_get_data (GTK_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);
- e_select_names_model_replace (info->text_model->source, info->index, dest);
-
- }
-}
-
-static void
-remove_recipient_cb (GtkWidget *w, gpointer user_data)
-{
- PopupInfo *info = (PopupInfo *) user_data;
- e_select_names_model_delete (info->text_model->source, info->index);
-}
-
-static void
-add_remove_recipient (GnomeUIInfo *uiinfo, PopupInfo *info)
-{
- uiinfo->type = GNOME_APP_UI_ITEM;
- uiinfo->label = _("Remove");
- uiinfo->moreinfo = remove_recipient_cb;
-}
-
-static void
-remove_all_recipients_cb (GtkWidget *w, gpointer user_data)
-{
- PopupInfo *info = (PopupInfo *) user_data;
- e_select_names_model_delete_all (info->text_model->source);
-}
-
-static void
-add_remove_all_recipients (GnomeUIInfo *uiinfo, PopupInfo *info)
-{
- uiinfo->type = GNOME_APP_UI_ITEM;
- uiinfo->label = _("Remove All");
- uiinfo->moreinfo = remove_all_recipients_cb;
-}
-
-static void
-toggle_html_mail_cb (GtkWidget *w, gpointer user_data)
-{
- PopupInfo *info = (PopupInfo *) user_data;
- GtkCheckMenuItem *item = GTK_CHECK_MENU_ITEM (w);
- const EDestination *dest;
-
- if (info == NULL)
- return;
-
- dest = info->dest;
-
- item = GTK_CHECK_MENU_ITEM (item);
- e_destination_set_html_mail_pref ((EDestination *) dest, item->active);
-}
-
-static void
-add_html_mail (GnomeUIInfo *uiinfo, PopupInfo *info)
-{
- uiinfo->type = GNOME_APP_UI_TOGGLEITEM;
- uiinfo->label = _("Send HTML Mail?");
- uiinfo->moreinfo = toggle_html_mail_cb;
-}
-
-static void
-init_html_mail (GnomeUIInfo *uiinfo, PopupInfo *info)
-{
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (uiinfo->widget),
- e_destination_get_html_mail_pref (info->dest));
- gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (uiinfo->widget), TRUE);
-
-}
-
-static void
-set_uiinfo_label (GnomeUIInfo *uiinfo, const gchar *str)
-{
- GtkWidget *label;
- gchar *label_txt;
- GList *item_children;
-
- label_txt = e_utf8_to_locale_string (str);
- item_children = gtk_container_children (GTK_CONTAINER (uiinfo->widget));
- label = item_children->data;
- g_list_free (item_children);
- gtk_label_set_text (GTK_LABEL (label), label_txt);
- g_free (label_txt);
-}
-
-#define ARBITRARY_UIINFO_LIMIT 64
-static GtkWidget *
-popup_menu_card (PopupInfo *info)
-{
- GnomeUIInfo uiinfo[ARBITRARY_UIINFO_LIMIT];
- GnomeUIInfo radioinfo[ARBITRARY_UIINFO_LIMIT];
- gboolean using_radio = FALSE;
- ECard *card;
- gint i=0;
- GtkWidget *pop;
- EIterator *iterator;
- gint html_toggle;
- gint mail_label = -1;
- const gchar *mail_label_str = NULL;
-
- /*
- * Build up our GnomeUIInfo array.
- */
-
- memset (uiinfo, 0, sizeof (uiinfo));
- memset (radioinfo, 0, sizeof (radioinfo));
-
- card = e_destination_get_card (info->dest);
-
- /* Use an empty label for now, we'll fill it later.
- If we set uiinfo label to contact name here, gnome_popup_menu_new
- could screw it up trying make a "translation". */
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = "";
- ++i;
-
- uiinfo[i].type = GNOME_APP_UI_SEPARATOR;
- ++i;
-
- if (card->email) {
-
- if (e_list_length (card->email) > 1) {
- gint j = 0;
-
- using_radio = TRUE;
-
- iterator = e_list_get_iterator (card->email);
- for (e_iterator_reset (iterator); e_iterator_is_valid (iterator); e_iterator_next (iterator)) {
- gchar *label = (gchar *)e_iterator_get (iterator);
- if (label && *label) {
- radioinfo[j].label = "";
- radioinfo[j].type = GNOME_APP_UI_ITEM;
- radioinfo[j].moreinfo = change_email_num_cb;
- ++j;
- }
- }
- gtk_object_unref (GTK_OBJECT (iterator));
-
- radioinfo[j].type = GNOME_APP_UI_ENDOFINFO;
-
- uiinfo[i].type = GNOME_APP_UI_RADIOITEMS;
- uiinfo[i].moreinfo = radioinfo;
- ++i;
-
- } else {
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = "";
- mail_label_str = e_destination_get_email (info->dest);
- mail_label = i;
- ++i;
- }
-
- uiinfo[i].type = GNOME_APP_UI_SEPARATOR;
- ++i;
- }
-
- add_html_mail (&(uiinfo[i]), info);
- html_toggle = i;
- ++i;
-
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = N_("Edit Contact Info");
- uiinfo[i].moreinfo = edit_contact_info_cb;
- ++i;
-
- add_remove_recipient (&(uiinfo[i]), info);
- ++i;
-
- add_remove_all_recipients (&(uiinfo[i]), info);
- ++i;
-
- uiinfo[i].type = GNOME_APP_UI_ENDOFINFO;
-
- /*
- * Now do something with it...
- */
-
- pop = gnome_popup_menu_new (uiinfo);
-
- init_html_mail (&(uiinfo[html_toggle]), info);
-
- /* Properly handle the names & e-mail addresses so that they don't get leaked and so that
- underscores are interpreted as key accelerators. This sucks. */
-
- set_uiinfo_label (&(uiinfo[0]), e_destination_get_name (info->dest));
-
- if (mail_label >= 0) {
- set_uiinfo_label (&(uiinfo[mail_label]), e_destination_get_email (info->dest));
- }
-
- if (using_radio) {
- gint n = e_destination_get_email_num (info->dest);
- gint j = 0;
- iterator = e_list_get_iterator (card->email);
- for (e_iterator_reset (iterator); e_iterator_is_valid (iterator); e_iterator_next (iterator)) {
- gchar *label = (gchar *)e_iterator_get (iterator);
- if (label && *label) {
- set_uiinfo_label (&(radioinfo[j]), label);
-
- gtk_object_set_data (GTK_OBJECT (radioinfo[j].widget), "number", GINT_TO_POINTER (j));
-
- if (j == n)
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (radioinfo[n].widget), TRUE);
-
- ++j;
- }
- }
- gtk_object_unref (GTK_OBJECT (iterator));
- }
-
- return pop;
-}
-
-static GtkWidget *
-popup_menu_list (PopupInfo *info)
-{
- GnomeUIInfo uiinfo[ARBITRARY_UIINFO_LIMIT];
- GtkWidget *pop;
- const gchar *str;
- gchar *gs;
- gint i = 0, subcount = 0, max_subcount = 10;
- ECard *card;
- EIterator *iterator;
-
- memset (uiinfo, 0, sizeof (uiinfo));
-
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = "";
- ++i;
-
- uiinfo[i].type = GNOME_APP_UI_SEPARATOR;
- ++i;
-
- card = e_destination_get_card (info->dest);
-
- if (card->email) {
-
- iterator = e_list_get_iterator (card->email);
- for (e_iterator_reset (iterator); e_iterator_is_valid (iterator) && subcount < max_subcount; e_iterator_next (iterator)) {
- gchar *label = (gchar *) e_iterator_get (iterator);
- if (label && *label) {
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = "";
- ++i;
- ++subcount;
- }
- }
- if (e_iterator_is_valid (iterator)) {
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = "";
- ++i;
- }
-
- uiinfo[i].type = GNOME_APP_UI_SEPARATOR;
- ++i;
-
- gtk_object_unref (GTK_OBJECT (iterator));
- }
-
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = N_("Edit Contact List");
- uiinfo[i].moreinfo = edit_contact_info_cb;
- ++i;
-
- add_remove_recipient (&(uiinfo[i]), info);
- ++i;
-
- add_remove_all_recipients (&(uiinfo[i]), info);
- ++i;
-
- uiinfo[i].type = GNOME_APP_UI_ENDOFINFO;
-
- pop = gnome_popup_menu_new (uiinfo);
-
- /* Now set labels properly. */
-
- str = e_destination_get_name (info->dest);
- if (!(str && *str))
- str = _("Unnamed Contact List");
- set_uiinfo_label (&(uiinfo[0]), str);
-
- if (card->email) {
-
- iterator = e_list_get_iterator (card->email);
- i = 2;
- for (e_iterator_reset (iterator); e_iterator_is_valid (iterator) && subcount < max_subcount; e_iterator_next (iterator)) {
- gchar *label = (gchar *) e_iterator_get (iterator);
- if (label && *label) {
- EDestination *subdest = e_destination_import (label);
- set_uiinfo_label (&(uiinfo[i]), e_destination_get_address (subdest));
- ++i;
- gtk_object_unref (GTK_OBJECT (subdest));
- }
- }
- if (e_iterator_is_valid (iterator)) {
- gs = g_strdup_printf (N_("(%d not shown)"), e_list_length (card->email) - max_subcount);
- set_uiinfo_label (&(uiinfo[i]), gs);
- g_free (gs);
- }
-
- gtk_object_unref (GTK_OBJECT (iterator));
- }
-
-
- return pop;
-}
-
-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);
-}
-
-static GtkWidget *
-popup_menu_nocard (PopupInfo *info)
-{
- GnomeUIInfo uiinfo[ARBITRARY_UIINFO_LIMIT];
- gint i=0;
- GtkWidget *pop;
- const gchar *str;
- gint html_toggle;
-
- memset (uiinfo, 0, sizeof (uiinfo));
-
- /* Use an empty label for now, we'll fill it later.
- If we set uiinfo label to contact name here, gnome_popup_menu_new
- could screw it up trying make a "translation". */
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = "";
- ++i;
-
- uiinfo[i].type = GNOME_APP_UI_SEPARATOR;
- ++i;
-
- add_html_mail (&(uiinfo[i]), info);
- html_toggle = i;
- ++i;
-
- uiinfo[i].type = GNOME_APP_UI_ITEM;
- uiinfo[i].label = _("Add to Contacts");
- uiinfo[i].moreinfo = quick_add_cb;
- ++i;
-
- add_remove_recipient (&(uiinfo[i]), info);
- ++i;
-
- add_remove_all_recipients (&(uiinfo[i]), info);
- ++i;
-
- uiinfo[i].type = GNOME_APP_UI_ENDOFINFO;
-
- pop = gnome_popup_menu_new (uiinfo);
-
- init_html_mail (&(uiinfo[html_toggle]), info);
-
- /* Now set label of the first item to contact name */
- str = e_destination_get_name (info->dest);
- if (! (str && *str))
- str = e_destination_get_email (info->dest);
- if (! (str && *str))
- str = _("Unnamed Contact");
-
- set_uiinfo_label (&(uiinfo[0]), str);
-
- return pop;
-}
-
-void
-e_select_names_popup (ESelectNamesTextModel *text_model, GdkEventButton *ev, gint pos)
-{
- ESelectNamesModel *model;
- GtkWidget *popup;
- PopupInfo *info;
- const EDestination *dest;
- ECard *card;
- gint index;
-
- g_return_if_fail (E_IS_SELECT_NAMES_TEXT_MODEL (text_model));
- g_return_if_fail (ev);
- g_return_if_fail (0 <= pos);
-
- model = text_model->source;
-
- e_select_names_model_text_pos (model, text_model->seplen, pos, &index, NULL, NULL);
- if (index < 0 || index >= e_select_names_model_count (model))
- return;
-
- dest = e_select_names_model_get_destination (model, index);
- if (e_destination_is_empty (dest))
- return;
-
- card = e_destination_get_card (dest);
-
- info = popup_info_new (text_model, dest, pos, index);
-
- if (e_destination_contains_card (dest)) {
- if (e_destination_is_evolution_list (dest))
- popup = popup_menu_list (info);
- else
- popup = popup_menu_card (info);
- } else {
- popup = popup_menu_nocard (info);
- }
-
- if (popup) {
- /* Clean up our info item after we've made our selection. */
- gtk_signal_connect (GTK_OBJECT (popup),
- "selection-done",
- GTK_SIGNAL_FUNC (popup_info_cleanup),
- info);
-
- gnome_popup_menu_do_popup (popup, NULL, NULL, ev, info);
-
- } else {
-
- popup_info_free (info);
-
- }
-}
diff --git a/addressbook/gui/component/select-names/e-select-names-popup.h b/addressbook/gui/component/select-names/e-select-names-popup.h
deleted file mode 100644
index 09cd29da18..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-popup.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-select-names-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_SELECT_NAMES_POPUP_H__
-#define __E_SELECT_NAMES_POPUP_H__
-
-#include "e-select-names-text-model.h"
-
-void e_select_names_popup (ESelectNamesTextModel *text_model, GdkEventButton *ev, gint pos);
-
-#endif /* __E_SELECT_NAMES_POPUP_H__ */
-
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
deleted file mode 100644
index a4faf69503..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-table-model.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <gtk/gtksignal.h>
-#include <gal/util/e-util.h>
-
-#include "e-select-names-table-model.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
-
-/* Object argument IDs */
-enum {
- ARG_0,
- ARG_SOURCE,
-};
-
-static void e_select_names_table_model_init (ESelectNamesTableModel *model);
-static void e_select_names_table_model_class_init (ESelectNamesTableModelClass *klass);
-
-static void e_select_names_table_model_destroy (GtkObject *object);
-static void e_select_names_table_model_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_select_names_table_model_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-
-static void e_select_names_table_model_model_changed (ESelectNamesModel *source,
- ESelectNamesTableModel *model);
-
-
-static void
-e_select_names_table_model_add_source (ESelectNamesTableModel *model,
- ESelectNamesModel *source)
-{
- model->source = source;
- if (model->source)
- gtk_object_ref(GTK_OBJECT(model->source));
- model->source_changed_id = gtk_signal_connect(GTK_OBJECT(model->source), "changed",
- GTK_SIGNAL_FUNC(e_select_names_table_model_model_changed),
- model);
-}
-
-static void
-e_select_names_table_model_drop_source (ESelectNamesTableModel *model)
-{
- if (model->source_changed_id)
- gtk_signal_disconnect(GTK_OBJECT(model->source), model->source_changed_id);
- if (model->source)
- gtk_object_unref(GTK_OBJECT(model->source));
- model->source = NULL;
- model->source_changed_id = 0;
-}
-
-/**
- * e_select_names_table_model_get_type:
- * @void:
- *
- * Registers the &ESelectNamesTableModel class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the &ESelectNamesTableModel class.
- **/
-GtkType
-e_select_names_table_model_get_type (void)
-{
- static GtkType model_type = 0;
-
- if (!model_type) {
- GtkTypeInfo model_info = {
- "ESelectNamesTableModel",
- sizeof (ESelectNamesTableModel),
- sizeof (ESelectNamesTableModelClass),
- (GtkClassInitFunc) e_select_names_table_model_class_init,
- (GtkObjectInitFunc) e_select_names_table_model_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- model_type = gtk_type_unique (e_table_model_get_type (), &model_info);
- }
-
- return model_type;
-}
-
-/**
- * e_select_names_table_model_new:
- * @VCard: a string in vCard format
- *
- * Returns: a new #ESelectNamesTableModel that wraps the @VCard.
- */
-ETableModel *
-e_select_names_table_model_new (ESelectNamesModel *source)
-{
- ETableModel *model = E_TABLE_MODEL(gtk_type_new(e_select_names_table_model_get_type()));
- gtk_object_set(GTK_OBJECT(model),
- "source", source,
- NULL);
- return model;
-}
-
-static void
-fill_in_info (ESelectNamesTableModel *model)
-{
- if (model->source) {
- int count = e_select_names_model_count (model->source);
- gint i;
-
- model->count = count;
- 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;
-
- 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 (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);
- if (model->data[i].email == 0)
- model->data[i].email = g_strdup("");
- gtk_object_unref(GTK_OBJECT(simple));
- } else {
- const gchar *name = e_destination_get_name (dest);
- const gchar *email = e_destination_get_email (dest);
-
- model->data[i].name = g_strdup (name && *name ? name : email);
- model->data[i].email = g_strdup (email);
- }
- }
- } else {
- model->count = 0;
- }
-}
-
-static void
-clear_info (ESelectNamesTableModel *model)
-{
- int i;
- for (i = 0; i < model->count; i++) {
- g_free(model->data[i].name);
- g_free(model->data[i].email);
- }
- g_free(model->data);
- model->data = NULL;
- model->count = -1;
-}
-
-/*
- * ESelectNamesTableModel lifecycle management and vcard loading/saving.
- */
-
-static void
-e_select_names_table_model_destroy (GtkObject *object)
-{
- ESelectNamesTableModel *model;
-
- model = E_SELECT_NAMES_TABLE_MODEL (object);
-
- e_select_names_table_model_drop_source (model);
- clear_info(model);
-}
-
-/* This function returns the number of columns in our ETableModel. */
-static int
-e_select_names_table_model_col_count (ETableModel *etc)
-{
- return 2;
-}
-
-/* This function returns the number of rows in our ETableModel. */
-static int
-e_select_names_table_model_row_count (ETableModel *etc)
-{
- ESelectNamesTableModel *e_select_names_table_model = E_SELECT_NAMES_TABLE_MODEL(etc);
- if (e_select_names_table_model->count == -1) {
- if (e_select_names_table_model->source) {
- fill_in_info(e_select_names_table_model);
- } else {
- return 0;
- }
- }
- return e_select_names_table_model->count;
-}
-
-/* This function returns the value at a particular point in our ETableModel. */
-static void *
-e_select_names_table_model_value_at (ETableModel *etc, int col, int row)
-{
- ESelectNamesTableModel *e_select_names_table_model = E_SELECT_NAMES_TABLE_MODEL(etc);
- if (e_select_names_table_model->data == NULL) {
- fill_in_info(e_select_names_table_model);
- }
- switch (col) {
- case 0:
- if (e_select_names_table_model->data[row].name == NULL) {
- fill_in_info(e_select_names_table_model);
- }
- return e_select_names_table_model->data[row].name;
- break;
- case 1:
- if (e_select_names_table_model->data[row].email == NULL) {
- fill_in_info(e_select_names_table_model);
- }
- return e_select_names_table_model->data[row].email;
- break;
- }
- return "";
-}
-
-/* This function sets the value at a particular point in our ETableModel. */
-static void
-e_select_names_table_model_set_value_at (ETableModel *etc, int col, int row, const void *val)
-{
-}
-
-/* This function returns whether a particular cell is editable. */
-static gboolean
-e_select_names_table_model_is_cell_editable (ETableModel *etc, int col, int row)
-{
- return FALSE;
-}
-
-/* This function duplicates the value passed to it. */
-static void *
-e_select_names_table_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_select_names_table_model_free_value (ETableModel *etc, int col, void *value)
-{
- g_free(value);
-}
-
-static void *
-e_select_names_table_model_initialize_value (ETableModel *etc, int col)
-{
- return g_strdup("");
-}
-
-static gboolean
-e_select_names_table_model_value_is_empty (ETableModel *etc, int col, const void *value)
-{
- return !(value && *(char *)value);
-}
-
-static char *
-e_select_names_table_model_value_to_string (ETableModel *etc, int col, const void *value)
-{
- return g_strdup(value);
-}
-
-static void
-e_select_names_table_model_model_changed (ESelectNamesModel *source,
- ESelectNamesTableModel *model)
-{
- e_table_model_pre_change(E_TABLE_MODEL(model));
- clear_info(model);
- e_table_model_changed(E_TABLE_MODEL(model));
-}
-
-/* Set_arg handler for the model */
-static void
-e_select_names_table_model_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- ESelectNamesTableModel *model;
-
- model = E_SELECT_NAMES_TABLE_MODEL (object);
-
- switch (arg_id) {
- case ARG_SOURCE:
- e_select_names_table_model_drop_source (model);
- e_select_names_table_model_add_source (model, E_SELECT_NAMES_MODEL(GTK_VALUE_OBJECT (*arg)));
- break;
- default:
- return;
- }
-}
-
-/* Get_arg handler for the model */
-static void
-e_select_names_table_model_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- ESelectNamesTableModel *model;
-
- model = E_SELECT_NAMES_TABLE_MODEL (object);
-
- switch (arg_id) {
- case ARG_SOURCE:
- GTK_VALUE_OBJECT(*arg) = GTK_OBJECT(model->source);
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
-}
-
-/**
- * e_select_names_table_model_init:
- */
-static void
-e_select_names_table_model_init (ESelectNamesTableModel *model)
-{
- model->source = NULL;
- model->source_changed_id = 0;
-
- model->count = -1;
- model->data = NULL;
-}
-
-static void
-e_select_names_table_model_class_init (ESelectNamesTableModelClass *klass)
-{
- GtkObjectClass *object_class;
- ETableModelClass *table_model_class;
-
- object_class = GTK_OBJECT_CLASS(klass);
- table_model_class = E_TABLE_MODEL_CLASS(klass);
-
- gtk_object_add_arg_type ("ESelectNamesTableModel::source",
- GTK_TYPE_OBJECT, GTK_ARG_READWRITE, ARG_SOURCE);
-
- object_class->destroy = e_select_names_table_model_destroy;
- object_class->get_arg = e_select_names_table_model_get_arg;
- object_class->set_arg = e_select_names_table_model_set_arg;
-
- table_model_class->column_count = e_select_names_table_model_col_count;
- table_model_class->row_count = e_select_names_table_model_row_count;
- table_model_class->value_at = e_select_names_table_model_value_at;
- table_model_class->set_value_at = e_select_names_table_model_set_value_at;
- table_model_class->is_cell_editable = e_select_names_table_model_is_cell_editable;
- table_model_class->duplicate_value = e_select_names_table_model_duplicate_value;
- table_model_class->free_value = e_select_names_table_model_free_value;
- table_model_class->initialize_value = e_select_names_table_model_initialize_value;
- table_model_class->value_is_empty = e_select_names_table_model_value_is_empty;
- table_model_class->value_to_string = e_select_names_table_model_value_to_string;
-}
diff --git a/addressbook/gui/component/select-names/e-select-names-table-model.h b/addressbook/gui/component/select-names/e-select-names-table-model.h
deleted file mode 100644
index f917ff17d8..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-table-model.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * Copyright (C) 2000 Ximian, Inc.
- */
-
-#ifndef __E_SELECT_NAMES_TABLE_MODEL_H__
-#define __E_SELECT_NAMES_TABLE_MODEL_H__
-
-#include <time.h>
-#include <stdio.h>
-#include <gtk/gtkobject.h>
-#include <gal/e-table/e-table-model.h>
-#include "e-select-names-model.h"
-
-#define E_TYPE_SELECT_NAMES_TABLE_MODEL (e_select_names_table_model_get_type ())
-#define E_SELECT_NAMES_TABLE_MODEL(obj) (GTK_CHECK_CAST ((obj), E_TYPE_SELECT_NAMES_TABLE_MODEL, ESelectNamesTableModel))
-#define E_SELECT_NAMES_TABLE_MODEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_SELECT_NAMES_TABLE_MODEL, ESelectNamesTableModelClass))
-#define E_IS_SELECT_NAMES_TABLE_MODEL(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_SELECT_NAMES_TABLE_MODEL))
-#define E_IS_SELECT_NAMES_TABLE_MODEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_SELECT_NAMES_TABLE_MODEL))
-
-typedef struct {
- char *name;
- char *email;
-} ESelectNamesTableModelData;
-
-typedef struct _ESelectNamesTableModel ESelectNamesTableModel;
-typedef struct _ESelectNamesTableModelClass ESelectNamesTableModelClass;
-
-struct _ESelectNamesTableModel {
- ETableModel parent;
-
- ESelectNamesModel *source;
- int source_changed_id;
-
- int count;
- ESelectNamesTableModelData *data; /* This is used as an array. */
-};
-
-struct _ESelectNamesTableModelClass {
- ETableModelClass parent_class;
-};
-
-ETableModel *e_select_names_table_model_new (ESelectNamesModel *source);
-
-/* Standard Gtk function */
-GtkType e_select_names_table_model_get_type (void);
-
-#endif /* ! __E_SELECT_NAMES_TABLE_MODEL_H__ */
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
deleted file mode 100644
index 9c108868b9..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-text-model.c
+++ /dev/null
@@ -1,786 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- * Jon Trowbridge <trow@ximian.com>
- *
- * Copyright (C) 2000, 2001 Ximian, Inc.
- */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include <gal/e-text/e-text-model-repos.h>
-
-#include <addressbook/gui/contact-editor/e-contact-editor.h>
-#include "e-select-names-text-model.h"
-#include "e-addressbook-util.h"
-
-static FILE *out = NULL; /* stream for debugging spew */
-
-/* Object argument IDs */
-enum {
- ARG_0,
- ARG_SOURCE,
-};
-
-static void e_select_names_text_model_class_init (ESelectNamesTextModelClass *klass);
-static void e_select_names_text_model_init (ESelectNamesTextModel *model);
-static void e_select_names_text_model_destroy (GtkObject *object);
-static void e_select_names_text_model_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_select_names_text_model_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-
-static void e_select_names_text_model_set_source (ESelectNamesTextModel *model, ESelectNamesModel *source);
-
-static const gchar *e_select_names_text_model_get_text (ETextModel *model);
-static void e_select_names_text_model_set_text (ETextModel *model, const gchar *text);
-static void e_select_names_text_model_insert (ETextModel *model, gint position, const gchar *text);
-static void e_select_names_text_model_insert_length (ETextModel *model, gint position, const gchar *text, gint length);
-static void e_select_names_text_model_delete (ETextModel *model, gint position, gint length);
-
-static gint e_select_names_text_model_obj_count (ETextModel *model);
-static const gchar *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);
-
-
-static ETextModelClass *parent_class;
-#define PARENT_TYPE e_text_model_get_type()
-
-/**
- * e_select_names_text_model_get_type:
- * @void:
- *
- * Registers the &ESelectNamesTextModel class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the &ESelectNamesTextModel class.
- **/
-GtkType
-e_select_names_text_model_get_type (void)
-{
- static GtkType model_type = 0;
-
- if (!model_type) {
- GtkTypeInfo model_info = {
- "ESelectNamesTextModel",
- sizeof (ESelectNamesTextModel),
- sizeof (ESelectNamesTextModelClass),
- (GtkClassInitFunc) e_select_names_text_model_class_init,
- (GtkObjectInitFunc) e_select_names_text_model_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- model_type = gtk_type_unique (PARENT_TYPE, &model_info);
- }
-
- return model_type;
-}
-
-static void
-e_select_names_text_model_class_init (ESelectNamesTextModelClass *klass)
-{
- GtkObjectClass *object_class;
- ETextModelClass *text_model_class;
-
- object_class = GTK_OBJECT_CLASS(klass);
- text_model_class = E_TEXT_MODEL_CLASS(klass);
-
- parent_class = gtk_type_class(PARENT_TYPE);
-
- gtk_object_add_arg_type ("ESelectNamesTextModel::source",
- GTK_TYPE_OBJECT, GTK_ARG_READWRITE, ARG_SOURCE);
-
- object_class->destroy = e_select_names_text_model_destroy;
- object_class->get_arg = e_select_names_text_model_get_arg;
- object_class->set_arg = e_select_names_text_model_set_arg;
-
- text_model_class->get_text = e_select_names_text_model_get_text;
- text_model_class->set_text = e_select_names_text_model_set_text;
- text_model_class->insert = e_select_names_text_model_insert;
- text_model_class->insert_length = e_select_names_text_model_insert_length;
- text_model_class->delete = e_select_names_text_model_delete;
-
- text_model_class->obj_count = e_select_names_text_model_obj_count;
- text_model_class->get_nth_obj = e_select_names_text_model_get_nth_obj;
- text_model_class->object_activated = e_select_names_text_model_activate_obj;
-
- if (getenv ("EVO_DEBUG_SELECT_NAMES_TEXT_MODEL")) {
- out = fopen ("/tmp/evo-debug-select-names-text-model", "w");
- if (out)
- setvbuf (out, NULL, _IONBF, 0);
- }
-}
-
-static void
-dump_model (ESelectNamesTextModel *text_model)
-{
- ESelectNamesModel *model = text_model->source;
- gint i;
-
- if (out == NULL)
- return;
-
- fprintf (out, "\n*** Model State: count=%d\n", e_select_names_model_count (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>" : "");
- fprintf (out, "\n");
-}
-
-static void
-e_select_names_text_model_init (ESelectNamesTextModel *model)
-{
- const gchar *default_sep;
-
- model->last_magic_comma_pos = -1;
-
- if (getenv ("EVOLUTION_DISABLE_MAGIC_COMMA"))
- default_sep = ",";
- else
- default_sep = ", ";
-
- e_select_names_text_model_set_separator (model, default_sep);
-}
-
-static void
-e_select_names_text_model_destroy (GtkObject *object)
-{
- ESelectNamesTextModel *model;
-
- model = E_SELECT_NAMES_TEXT_MODEL (object);
-
- g_free (model->text);
- g_free (model->sep);
-
- e_select_names_text_model_set_source (model, NULL);
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy)
- GTK_OBJECT_CLASS(parent_class)->destroy(object);
-}
-
-static void
-e_select_names_text_model_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- ESelectNamesTextModel *model;
-
- model = E_SELECT_NAMES_TEXT_MODEL (object);
-
- switch (arg_id) {
- case ARG_SOURCE:
- e_select_names_text_model_set_source(model, E_SELECT_NAMES_MODEL (GTK_VALUE_OBJECT (*arg)));
- break;
- default:
- return;
- }
-}
-
-static void
-e_select_names_text_model_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- ESelectNamesTextModel *model;
-
- model = E_SELECT_NAMES_TEXT_MODEL (object);
-
- switch (arg_id) {
- case ARG_SOURCE:
- GTK_VALUE_OBJECT(*arg) = GTK_OBJECT(model->source);
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
-}
-
-static void
-resize_cb (ESelectNamesModel *source, gint index, gint old_len, gint new_len, ETextModel *model)
-{
- EReposDeleteShift repos_del;
- EReposInsertShift repos_ins;
- gint pos;
- gint seplen = E_SELECT_NAMES_TEXT_MODEL (model)->seplen;
-
- e_select_names_model_name_pos (source, seplen, index, &pos, NULL);
-
- if (new_len < old_len) {
-
- repos_del.model = model;
- repos_del.pos = pos;
- repos_del.len = old_len - new_len;
- e_text_model_reposition (model, e_repos_delete_shift, &repos_del);
-
- } else if (old_len < new_len) {
-
- repos_ins.model = model;
- repos_ins.pos = pos;
- repos_ins.len = new_len - old_len;
- e_text_model_reposition (model, e_repos_insert_shift, &repos_ins);
-
- }
-}
-
-static void
-changed_cb (ETextModel *model)
-{
- ESelectNamesTextModel *text_model = E_SELECT_NAMES_TEXT_MODEL (model);
-
- g_free (text_model->text);
- text_model->text = NULL;
-
- e_text_model_changed (model);
-}
-
-
-static void
-e_select_names_text_model_set_source (ESelectNamesTextModel *model,
- ESelectNamesModel *source)
-{
- if (source == model->source)
- return;
-
- if (model->source) {
- gtk_signal_disconnect (GTK_OBJECT (model->source), model->source_changed_id);
- gtk_signal_disconnect (GTK_OBJECT (model->source), model->source_resize_id);
- gtk_object_unref (GTK_OBJECT (model->source));
- }
-
- model->source = source;
-
- if (model->source) {
- gtk_object_ref (GTK_OBJECT (model->source));
- model->source_changed_id = gtk_signal_connect_object (GTK_OBJECT(model->source),
- "changed",
- GTK_SIGNAL_FUNC (changed_cb),
- GTK_OBJECT (model));
- model->source_resize_id = gtk_signal_connect (GTK_OBJECT(model->source),
- "resized",
- GTK_SIGNAL_FUNC (resize_cb),
- model);
- }
-}
-
-ETextModel *
-e_select_names_text_model_new (ESelectNamesModel *source)
-{
- ETextModel *model = E_TEXT_MODEL (gtk_type_new (e_select_names_text_model_get_type()));
- e_select_names_text_model_set_source (E_SELECT_NAMES_TEXT_MODEL (model), source);
- return model;
-}
-
-void
-e_select_names_text_model_set_separator (ESelectNamesTextModel *model, const char *sep)
-{
- g_return_if_fail (E_IS_SELECT_NAMES_TEXT_MODEL (model));
- g_return_if_fail (sep && *sep);
-
- g_free (model->sep);
- model->sep = g_strdup (sep);
- model->seplen = strlen (sep);
-}
-
-static const gchar *
-e_select_names_text_model_get_text (ETextModel *model)
-{
- ESelectNamesTextModel *snm = E_SELECT_NAMES_TEXT_MODEL(model);
-
- if (snm == NULL)
- return "";
- else if (snm->text == NULL)
- snm->text = e_select_names_model_get_textification (snm->source, snm->sep);
-
- return snm->text;
-}
-
-static void
-e_select_names_text_model_set_text (ETextModel *model, const gchar *text)
-{
- ESelectNamesTextModel *snm = E_SELECT_NAMES_TEXT_MODEL(model);
-
- e_select_names_model_delete_all (snm->source);
- e_select_names_text_model_insert (model, 0, text);
-}
-
-static void
-e_select_names_text_model_insert (ETextModel *model, gint position, const gchar *text)
-{
- e_select_names_text_model_insert_length (model, position, text, strlen (text));
-}
-
-static void
-e_select_names_text_model_insert_length (ETextModel *model, gint pos, const gchar *text, gint length)
-{
- ESelectNamesTextModel *text_model = E_SELECT_NAMES_TEXT_MODEL (model);
- ESelectNamesModel *source = text_model->source;
-
- gint i;
-
- if (out) {
- gchar *tmp = g_strndup (text, length);
- fprintf (out, ">> insert \"%s\" (len=%d) at %d\n", tmp, length, pos);
- g_free (tmp);
- }
-
- pos = CLAMP (pos, 0, strlen (e_select_names_model_get_textification (source, text_model->sep)));
-
- /* We want to control all cursor motions ourselves, rather than taking hints
- from the ESelectNamesModel. */
- gtk_signal_handler_block (GTK_OBJECT (source), text_model->source_resize_id);
-
- /* We handle this one character at a time. */
-
- for (i = 0; i < length && text[i]; ++i) {
- gint index, start_pos, text_len;
- gboolean inside_quote = FALSE;
-
- text_model->last_magic_comma_pos = -1;
-
- if (out)
- fprintf (out, "processing [%c]\n", text[i]);
-
- e_select_names_model_text_pos (source, text_model->seplen, pos, &index, &start_pos, &text_len);
-
- if (out)
- fprintf (out, "index=%d start_pos=%d text_len=%d\n", index, start_pos, text_len);
-
- if (text[i] == *text_model->sep && index >= 0) { /* Is this a quoted or an unquoted separator we are dealing with? */
- const EDestination *dest = e_select_names_model_get_destination (source, index);
- if (dest) {
- const gchar *str = e_destination_get_textrep (dest);
- gint j;
- if (out)
- fprintf (out, "str=%s pos=%d\n", str, pos);
- for (j=0; j<pos-start_pos && str[j]; ++j)
- if (str[j] == '"') {
- inside_quote = !inside_quote;
- if (out)
- fprintf (out, "flip to %d at %d\n", start_pos+j, inside_quote);
- }
- }
- if (out)
- fprintf (out, inside_quote ? "inside quote\n" : "not inside quote\n");
- }
-
-
- if (text[i] == *text_model->sep && !inside_quote) {
-
- /* This is the case of hitting , first thing in an empty entry */
- 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 ());
-
- repos.model = model;
- repos.pos = -1; /* At end */
- e_text_model_reposition (model, e_repos_absolute, &repos);
-
-
- } else if (pos <= start_pos || pos == start_pos + text_len) {
- EReposInsertShift repos;
- gint ins_point = index;
-
- if (text_len != 0 && pos == start_pos + text_len)
- ++ins_point;
-
- /* Block adjacent blank cards. */
- if (! ((ins_point < e_select_names_model_count (source) &&
- (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 ());
-
- repos.model = model;
- repos.pos = pos;
- repos.len = text_model->seplen;
- e_text_model_reposition (model, e_repos_insert_shift, &repos);
- pos += text_model->seplen;
- }
-
- } else {
- EReposInsertShift repos;
- gint offset = MAX (pos - start_pos, 0);
- 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 ();
-
- e_destination_set_raw (d1, str1);
- e_destination_set_raw (d2, str2);
-
- e_select_names_model_replace (source, index, d1);
- e_select_names_model_insert (source, index+1, d2);
-
- g_free (str1);
- g_free (str2);
-
- repos.model = model;
- repos.pos = pos;
- repos.len = text_model->seplen;
- e_text_model_reposition (model, e_repos_insert_shift, &repos);
- pos += text_model->seplen;
- }
-
- if (text_model->seplen > 1)
- text_model->last_magic_comma_pos = pos;
-
- } else {
- EReposInsertShift repos;
- gint offset = MAX (pos - start_pos, 0);
- const gchar *str;
- gchar *new_str = NULL;
- gint this_length = 1;
- gboolean whitespace = isspace ((gint) text[i]);
-
- str = index >= 0 ? e_select_names_model_get_string (source, index) : NULL;
- if (str && *str) {
- if (pos <= start_pos) {
- if (whitespace) {
- /* swallow leading whitespace */
- this_length = 0;
- } else {
- /* Adjust for our "magic white space" */
- /* FIXME: This code does the wrong thing if seplen > 2 */
- new_str = g_strdup_printf("%c%s%s", text[i], pos < start_pos ? " " : "", str);
- if (pos < start_pos)
- ++this_length;
- }
- } else {
- new_str = g_strdup_printf ("%.*s%c%s", offset, str, text[i], str + offset);
- }
- } else {
- if (whitespace) {
- /* swallow leading whitespace */
- this_length = 0;
- } else {
- new_str = g_strdup_printf ("%c", text[i]);
- }
- }
-
- if (new_str) {
-
- 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);
- e_select_names_model_replace (source, index, dest);
-
- /* e_select_names_model_replace (source, index, dest); */
-
- if (this_length > 0) {
- repos.model = model;
- repos.pos = pos;
- repos.len = this_length;
- e_text_model_reposition (model, e_repos_insert_shift, &repos);
-
- pos += this_length;
- }
-
- g_free (new_str);
- }
- }
- }
-
- dump_model (text_model);
-
- gtk_signal_handler_unblock (GTK_OBJECT (source), text_model->source_resize_id);
-}
-
-
-static void
-e_select_names_text_model_delete (ETextModel *model, gint pos, gint length)
-{
- ESelectNamesTextModel *text_model = E_SELECT_NAMES_TEXT_MODEL (model);
- ESelectNamesModel *source = text_model->source;
- gint index, start_pos, text_len, offset;
-
- if (out) {
- const gchar *str = e_select_names_model_get_textification (source, text_model->sep);
- gint i, len;
-
- fprintf (out, ">> delete %d at pos %d\n", length, pos);
-
- len = strlen (str);
- for (i=0; i<pos && i<len; ++i)
- fprintf (out, "%c", str[i]);
- fprintf (out, "[");
- for (i=pos; i<pos+length && i<len; ++i)
- fprintf (out, "%c", str[i]);
- fprintf (out, "]");
- for (i=pos+length; i<len; ++i)
- fprintf (out, "%c", str[i]);
- fprintf (out, "\n");
- }
-
- if (length < 0)
- return;
-
- if (text_model->last_magic_comma_pos == pos+1 && length == 1) {
- pos -= text_model->seplen-1;
- if (pos >= 0)
- length = text_model->seplen;
- text_model->last_magic_comma_pos = -1;
- }
-
- e_select_names_model_text_pos (source, text_model->seplen, pos, &index, &start_pos, &text_len);
-
- if (out)
- fprintf (out, "index=%d, start_pos=%d, text_len=%d\n", index, start_pos, text_len);
-
- /* We want to control all cursor motions ourselves, rather than taking hints
- from the ESelectNamesModel. */
- gtk_signal_handler_block (GTK_OBJECT (source), E_SELECT_NAMES_TEXT_MODEL (model)->source_resize_id);
-
- /* First, we handle a few tricky cases. */
-
- if (pos < start_pos) {
- EReposAbsolute repos;
-
- repos.model = model;
- repos.pos = pos;
- e_text_model_reposition (model, e_repos_absolute, &repos);
-
- length -= start_pos - pos;
-
- if (length > 0)
- e_select_names_text_model_delete (model, start_pos, length);
- goto finished;
- }
-
- if (pos == start_pos + text_len) {
- /* We are positioned right at the end of an entry, possibly right in front of a comma. */
-
- if (index+1 < e_select_names_model_count (source)) {
- EReposDeleteShift repos;
- EDestination *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;
-
- while (str1 && *str1 && isspace ((gint) *str1))
- ++str1;
- while (str2 && *str2 && isspace ((gint) *str2))
- ++str2;
-
- if (str1 && str2)
- new_str = g_strdup_printf ("%s%s%s", str1, text_model->sep+1, str2);
- else if (str1)
- new_str = g_strdup (str1);
- else if (str2)
- new_str = g_strdup (str2);
- else
- new_str = g_strdup ("");
-
- if (out)
- fprintf (out, "joining \"%s\" and \"%s\" to \"%s\"\n", str1, str2, new_str);
-
- e_select_names_model_delete (source, index+1);
-
- new_dest = e_destination_new ();
- e_destination_set_raw (new_dest, new_str);
- e_select_names_model_replace (source, index, new_dest);
- g_free (new_str);
-
- repos.model = model;
- repos.pos = pos;
- repos.len = text_model->seplen;
-
- e_text_model_reposition (model, e_repos_delete_shift, &repos);
-
- if (length > 1)
- e_select_names_text_model_delete (model, pos, length-1);
- } else {
- /* If we are at the end of the last entry (which we must be if we end up in this block),
- we can just do nothing. So this else-block is here just to give us a place to
- put this comment. */
- }
-
- goto finished;
- }
-
- if (pos + length > start_pos + text_len) {
- /* Uh oh... our changes straddle two objects. */
-
- if (pos == start_pos) { /* Delete the whole thing */
- EReposDeleteShift repos;
-
- e_select_names_model_delete (source, index);
-
- if (out)
- fprintf (out, "deleted all of %d\n", index);
-
- repos.model = model;
- repos.pos = pos;
- repos.len = text_len + text_model->seplen;
-
- e_text_model_reposition (model, e_repos_delete_shift, &repos);
-
- length -= text_len + text_model->seplen;
- if (length > 0)
- e_select_names_text_model_delete (model, pos, length);
-
- } else {
- /* Delete right up to the end, and then call e_select_names_text_model_delete again
- to finish the job. */
- gint len1, len2;
-
- len1 = text_len - (pos - start_pos);
- len2 = length - len1;
-
- if (out)
- fprintf (out, "two-stage delete: %d, %d\n", len1, len2);
-
-
- e_select_names_text_model_delete (model, pos, len1);
- e_select_names_text_model_delete (model, pos, len2);
- }
-
- goto finished;
- }
-
- /* Our changes are confined to just one entry. */
- if (length > 0) {
- const gchar *str;
- gchar *new_str;
-
- offset = pos - start_pos;
-
- str = e_select_names_model_get_string (source, index);
- new_str = str ? g_strdup_printf ("%.*s%s", offset, str, str + offset + length) : NULL;
-
- if (new_str) {
- EReposDeleteShift repos;
- 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);
- e_select_names_model_replace (source, index, dest);
-
- if (out)
- fprintf (out, "new_str: \"%s\"\n", new_str);
-
- g_free (new_str);
-
- repos.model = model;
- repos.pos = pos;
- repos.len = length;
-
- e_text_model_reposition (model, e_repos_delete_shift, &repos);
-
- } else {
- EReposDeleteShift repos;
-
- e_select_names_model_delete (source, index);
-
- if (out)
- fprintf (out, "deleted %d\n", index);
-
-
- repos.model = model;
- repos.pos = pos;
- repos.len = text_model->seplen;
-
- e_text_model_reposition (model, e_repos_delete_shift, &repos);
- }
- }
-
- finished:
- E_SELECT_NAMES_TEXT_MODEL (model)->last_magic_comma_pos = -1;
- gtk_signal_handler_unblock (GTK_OBJECT (source), E_SELECT_NAMES_TEXT_MODEL (model)->source_resize_id);
- dump_model (E_SELECT_NAMES_TEXT_MODEL (model));
-}
-
-static gint
-e_select_names_text_model_obj_count (ETextModel *model)
-{
- ESelectNamesModel *source = E_SELECT_NAMES_TEXT_MODEL (model)->source;
- gint i, count;
-
- count = i = e_select_names_model_count (source);
- while (i > 0) {
- const EDestination *dest;
- --i;
- dest = e_select_names_model_get_destination (source, i);
- if (e_destination_get_card (dest) == NULL)
- --count;
- }
-
- return count;
-}
-
-static gint
-nth_obj_index (ESelectNamesModel *source, gint n)
-{
- gint i, N;
-
- i = 0;
- 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))
- --n;
- ++i;
- } while (n >= 0 && i < N);
-
- if (i <= N)
- --i;
- else
- i = -1;
-
- return i;
-}
-
-static const gchar *
-e_select_names_text_model_get_nth_obj (ETextModel *model, gint n, gint *len)
-{
- ESelectNamesTextModel *text_model = E_SELECT_NAMES_TEXT_MODEL (model);
- ESelectNamesModel *source = text_model->source;
- gint i, pos;
-
- i = nth_obj_index (source, n);
- if (i < 0)
- return NULL;
-
- e_select_names_model_name_pos (source, text_model->seplen, i, &pos, len);
- if (pos < 0)
- return NULL;
-
- if (text_model->text == NULL)
- text_model->text = e_select_names_model_get_textification (source, text_model->sep);
- return text_model->text + pos;
-}
-
-static void
-e_select_names_text_model_activate_obj (ETextModel *model, gint n)
-{
- ESelectNamesModel *source = E_SELECT_NAMES_TEXT_MODEL (model)->source;
- ECard *card;
- 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);
-
- /* present read-only contact editor when someone double clicks from here */
- if (e_card_evolution_list (card)) {
- EContactListEditor *ce;
- ce = e_addressbook_show_contact_list_editor (e_card_get_book(card), card, 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);
- e_contact_editor_raise (ce);
- }
-}
-
-
-
diff --git a/addressbook/gui/component/select-names/e-select-names-text-model.h b/addressbook/gui/component/select-names/e-select-names-text-model.h
deleted file mode 100644
index 29ab727368..0000000000
--- a/addressbook/gui/component/select-names/e-select-names-text-model.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- * Jon Trowbridge <trow@ximian.com>
- *
- * Copyright (C) 2000, 2001 Ximian, Inc.
- */
-
-#ifndef __E_SELECT_NAMES_TEXT_MODEL_H__
-#define __E_SELECT_NAMES_TEXT_MODEL_H__
-
-#include <time.h>
-#include <stdio.h>
-#include <gtk/gtkobject.h>
-#include <gal/e-text/e-text-model.h>
-#include "e-select-names-model.h"
-
-#define E_TYPE_SELECT_NAMES_TEXT_MODEL (e_select_names_text_model_get_type ())
-#define E_SELECT_NAMES_TEXT_MODEL(obj) (GTK_CHECK_CAST ((obj), E_TYPE_SELECT_NAMES_TEXT_MODEL, ESelectNamesTextModel))
-#define E_SELECT_NAMES_TEXT_MODEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_SELECT_NAMES_TEXT_MODEL, ESelectNamesTextModelClass))
-#define E_IS_SELECT_NAMES_TEXT_MODEL(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_SELECT_NAMES_TEXT_MODEL))
-#define E_IS_SELECT_NAMES_TEXT_MODEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_SELECT_NAMES_TEXT_MODEL))
-
-typedef struct _ESelectNamesTextModel ESelectNamesTextModel;
-typedef struct _ESelectNamesTextModelClass ESelectNamesTextModelClass;
-
-struct _ESelectNamesTextModel {
- ETextModel parent;
-
- ESelectNamesModel *source;
- gint source_changed_id;
- gint source_resize_id;
-
- gchar *text;
-
- gchar *sep;
- gint seplen;
-
- gint last_magic_comma_pos;
-};
-
-struct _ESelectNamesTextModelClass {
- ETextModelClass parent_class;
-};
-
-ETextModel *e_select_names_text_model_new (ESelectNamesModel *source);
-void e_select_names_text_model_set_separator (ESelectNamesTextModel *model, const char *sep);
-
-/* Standard Gtk function */
-GtkType e_select_names_text_model_get_type (void);
-
-#endif /* ! __E_SELECT_NAMES_TEXT_MODEL_H__ */
diff --git a/addressbook/gui/component/select-names/e-select-names.c b/addressbook/gui/component/select-names/e-select-names.c
deleted file mode 100644
index e1251fe0f6..0000000000
--- a/addressbook/gui/component/select-names/e-select-names.c
+++ /dev/null
@@ -1,899 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-select-names.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 <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-stock.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <libgnomeui/gnome-dialog-util.h>
-
-#include <gal/e-table/e-table-simple.h>
-#include <gal/e-table/e-table-without.h>
-#include <gal/widgets/e-font.h>
-#include <gal/widgets/e-popup-menu.h>
-
-#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/gui/component/addressbook-component.h>
-#include <addressbook/gui/component/addressbook-storage.h>
-#include <addressbook/gui/component/addressbook.h>
-#include <shell/evolution-shell-client.h>
-#include <shell/evolution-folder-selector-button.h>
-
-#include "e-select-names.h"
-#include <addressbook/backend/ebook/e-card-simple.h>
-#include "e-select-names-text-model.h"
-#include <gal/widgets/e-categories-master-list-option-menu.h>
-#include <gal/widgets/e-unicode.h>
-#include <gal/e-text/e-entry.h>
-#include <e-util/e-categories-master-list-wombat.h>
-
-static void e_select_names_init (ESelectNames *card);
-static void e_select_names_class_init (ESelectNamesClass *klass);
-static void e_select_names_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_select_names_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_select_names_destroy (GtkObject *object);
-static void update_query (GtkWidget *widget, ESelectNames *e_select_names);
-
-extern EvolutionShellClient *global_shell_client;
-
-static GnomeDialogClass *parent_class = NULL;
-#define PARENT_TYPE gnome_dialog_get_type()
-
-/* The arguments we take */
-enum {
- ARG_0,
-};
-
-typedef struct {
- char *title;
- ESelectNamesModel *source;
- ESelectNamesTextModel *text_model;
- ESelectNames *names;
- GtkWidget *label;
- GtkWidget *button;
-} ESelectNamesChild;
-
-GtkType
-e_select_names_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type) {
- static const GtkTypeInfo info =
- {
- "ESelectNames",
- sizeof (ESelectNames),
- sizeof (ESelectNamesClass),
- (GtkClassInitFunc) e_select_names_class_init,
- (GtkObjectInitFunc) e_select_names_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
-
- return type;
-}
-
-static void
-e_select_names_class_init (ESelectNamesClass *klass)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass*) klass;
-
- parent_class = gtk_type_class (PARENT_TYPE);
-
- object_class->set_arg = e_select_names_set_arg;
- object_class->get_arg = e_select_names_get_arg;
- object_class->destroy = e_select_names_destroy;
-}
-
-GtkWidget *e_addressbook_create_ebook_table(char *name, char *string1, char *string2, int num1, int num2);
-GtkWidget *e_addressbook_create_folder_selector(char *name, char *string1, char *string2, int num1, int num2);
-
-static void
-set_book(EBook *book, EBookStatus status, ESelectNames *esn)
-{
- gtk_object_set(GTK_OBJECT(esn->model),
- "book", book,
- NULL);
- update_query (NULL, esn);
- gtk_object_unref(GTK_OBJECT(book));
- gtk_object_unref(GTK_OBJECT(esn->model));
- gtk_object_unref(GTK_OBJECT(esn));
-}
-
-static void
-addressbook_model_set_uri(ESelectNames *e_select_names, EAddressbookModel *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);
- if (book) {
- const gchar *current_uri = e_book_get_uri (book);
- if (current_uri && !strcmp (book_uri, current_uri)) {
- g_free (book_uri);
- return;
- }
- }
-
- book = e_book_new();
-
- gtk_object_ref(GTK_OBJECT(e_select_names));
- gtk_object_ref(GTK_OBJECT(model));
- addressbook_load_uri(book, book_uri, (EBookCallback) set_book, e_select_names);
-
- g_free (book_uri);
-}
-
-static void *
-card_key (ECard *card)
-{
- EBook *book;
- const gchar *book_uri;
-
- if (card == NULL)
- return NULL;
-
- g_assert (E_IS_CARD (card));
-
- book = e_card_get_book (card);
- 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));
-}
-
-static void
-sync_one_model (gpointer k, gpointer val, gpointer closure)
-{
- ETableWithout *etw = E_TABLE_WITHOUT (closure);
- ESelectNamesChild *child = val;
- ESelectNamesModel *model = child->source;
- gint i, count;
- ECard *card;
- 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);
- e_table_without_hide (etw, key);
- g_free (key);
- }
- }
-}
-
-static void
-sync_table_and_models (ESelectNamesModel *triggering_model, ESelectNames *esl)
-{
- e_table_without_show_all (E_TABLE_WITHOUT (esl->without));
- g_hash_table_foreach (esl->children, sync_one_model, esl->without);
-}
-
-static void
-real_add_address_cb (int model_row, gpointer closure)
-{
- ESelectNamesChild *child = closure;
- ESelectNames *names = child->names;
- ECard *card;
- EDestination *dest = e_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);
-
- if (card != NULL) {
- e_destination_set_card (dest, card, 0);
-
- e_select_names_model_append (child->source, dest);
- e_select_names_model_clean (child->source, FALSE);
-
- gtk_object_unref(GTK_OBJECT(card));
- }
-}
-
-static void
-real_add_address(ESelectNames *names, ESelectNamesChild *child)
-{
- e_select_names_model_freeze (child->source);
- e_table_selected_row_foreach(e_table_scrolled_get_table(names->table),
- real_add_address_cb, child);
- e_select_names_model_thaw (child->source);
-}
-
-static void
-add_address(ETable *table, int row, int col, GdkEvent *event, ESelectNames *names)
-{
- ESelectNamesChild *child;
-
- child = g_hash_table_lookup(names->children, names->def);
- if (child) {
- real_add_address(names, child);
- }
-}
-
-static void
-sensitize_button (gpointer key, gpointer data, gpointer user_data)
-{
- gboolean *sensitive = user_data;
- ESelectNamesChild *child = data;
-
- gtk_widget_set_sensitive (child->button, *sensitive);
-}
-
-static void
-selection_change (ETable *table, ESelectNames *names)
-{
- gboolean sensitive;
-
- sensitive = e_table_selected_count (table) > 0;
-
- g_hash_table_foreach (names->children, sensitize_button, &sensitive);
-}
-
-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);
- gtk_object_unref (GTK_OBJECT (card));
- return key;
-}
-
-static void *
-esn_dup_key_fn (const void *key, void *closure)
-{
- void *dup = (void *) g_strdup ((const gchar *) key);
- return dup;
-}
-
-static void
-esn_free_gotten_key_fn (void *key, void *closure)
-{
- g_free (key);
-}
-
-static void
-esn_free_duped_key_fn (void *key, void *closure)
-{
- g_free (key);
-}
-
-GtkWidget *
-e_addressbook_create_ebook_table(char *name, char *string1, char *string2, int num1, int num2)
-{
- ETableModel *adapter;
- ETableModel *without;
- EAddressbookModel *model;
- GtkWidget *table;
- char *spec;
-
- model = e_addressbook_model_new ();
- adapter = E_TABLE_MODEL (e_addressbook_table_adapter_new (model));
-
- gtk_object_set(GTK_OBJECT(model),
- "editable", FALSE,
- NULL);
-
- without = e_table_without_new (adapter,
- g_str_hash,
- g_str_equal,
- esn_get_key_fn,
- esn_dup_key_fn,
- esn_free_gotten_key_fn,
- esn_free_duped_key_fn,
- model);
-
- table = e_table_scrolled_new_from_spec_file (without,
- NULL,
- EVOLUTION_ETSPECDIR "/e-select-names.etspec",
- NULL);
-
- gtk_object_set_data(GTK_OBJECT(table), "adapter", adapter);
- gtk_object_set_data(GTK_OBJECT(table), "without", without);
- gtk_object_set_data(GTK_OBJECT(table), "model", model);
-
- return table;
-}
-
-GtkWidget *
-e_addressbook_create_folder_selector(char *name, char *string1, char *string2, int num1, int num2)
-{
- return (GtkWidget *)gtk_type_new (EVOLUTION_TYPE_FOLDER_SELECTOR_BUTTON);
-}
-
-static void
-folder_selected (EvolutionFolderSelectorButton *button, GNOME_Evolution_Folder *folder,
- ESelectNames *e_select_names)
-{
- addressbook_model_set_uri(e_select_names, e_select_names->model, folder->physicalUri);
-}
-
-static void
-update_query (GtkWidget *widget, ESelectNames *e_select_names)
-{
- char *category = "";
- char *search = "";
- char *query;
- char *q_array[4];
- int i;
- if (e_select_names->categories) {
- category = e_categories_master_list_option_menu_get_category (E_CATEGORIES_MASTER_LIST_OPTION_MENU (e_select_names->categories));
- }
- if (e_select_names->select_entry) {
- search = gtk_entry_get_text (GTK_ENTRY (e_select_names->select_entry));
- }
- i = 0;
- q_array[i++] = "(contains \"email\" \"\")";
- if (category && *category)
- q_array[i++] = g_strdup_printf ("(is \"category\" \"%s\")", category);
- if (search && *search)
- q_array[i++] = g_strdup_printf ("(or (beginswith \"email\" \"%s\") "
- " (beginswith \"full_name\" \"%s\") "
- " (beginswith \"nickname\" \"%s\")"
- " (beginswith \"file_as\" \"%s\"))",
- search, search, search, search);
- q_array[i++] = NULL;
- if (i > 2) {
- char *temp = g_strjoinv (" ", q_array);
- query = g_strdup_printf ("(and %s)", temp);
- g_free (temp);
- } else {
- query = g_strdup (q_array[0]);
- }
- gtk_object_set (GTK_OBJECT (e_select_names->model),
- "query", query,
- NULL);
- for (i = 1; q_array[i]; i++) {
- g_free (q_array[i]);
- }
- g_free (query);
-}
-
-static void
-status_message (EAddressbookModel *model, const gchar *message, ESelectNames *e_select_names)
-{
- if (message == NULL)
- gtk_label_set_text (GTK_LABEL (e_select_names->status_message), "");
- else
- gtk_label_set_text (GTK_LABEL (e_select_names->status_message), message);
-}
-
-static void
-categories_changed (GtkWidget *widget, gint value, ESelectNames *e_select_names)
-{
- update_query (widget, e_select_names);
-}
-
-static void
-select_entry_changed (GtkWidget *widget, ESelectNames *e_select_names)
-{
- if (e_select_names->select_entry) {
- char *select_string = gtk_entry_get_text (GTK_ENTRY (e_select_names->select_entry));
- char *select_strcoll_string = g_utf8_collate_key (select_string, -1);
- int count;
- ETable *table;
- int i;
-
- table = e_table_scrolled_get_table (e_select_names->table);
-
- count = e_table_model_row_count (e_select_names->without);
-
- for (i = 0; i < count; i++) {
- 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,
- model_row),
- -1);
- if (strcmp (select_strcoll_string, row_strcoll_string) <= 0) {
- g_free (row_strcoll_string);
- break;
- }
- g_free (row_strcoll_string);
- }
- g_free (select_strcoll_string);
- if (i == count)
- i --;
-
- if (count > 0) {
- i = e_table_view_to_model_row (table, i);
- e_table_set_cursor_row (table, i);
- }
- }
-}
-
-GtkWidget *e_select_names_create_categories (gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2);
-
-GtkWidget *
-e_select_names_create_categories (gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2)
-{
- ECategoriesMasterList *ecml;
- GtkWidget *option_menu;
-
- ecml = e_categories_master_list_wombat_new ();
- option_menu = e_categories_master_list_option_menu_new (ecml);
- gtk_object_unref (GTK_OBJECT (ecml));
-
- return option_menu;
-}
-
-static void
-clear_widget (GtkWidget *w, gpointer user_data)
-{
- GtkWidget **widget_ref = user_data;
- *widget_ref = NULL;
-}
-
-static void
-e_select_names_init (ESelectNames *e_select_names)
-{
- GladeXML *gui;
- GtkWidget *widget, *button;
- const char *selector_types[] = { "contacts/*", NULL };
- char *filename;
- char *uri;
- char *contacts_uri, *contacts_path;
- Bonobo_ConfigDatabase db;
-
- db = addressbook_config_database (NULL);
-
- gui = glade_xml_new (EVOLUTION_GLADEDIR "/select-names.glade", NULL);
- e_select_names->gui = gui;
-
- e_select_names->children = g_hash_table_new(g_str_hash, g_str_equal);
- e_select_names->child_count = 0;
- e_select_names->def = NULL;
-
- widget = glade_xml_get_widget(gui, "table-top");
- if (!widget) {
- return;
- }
- gtk_widget_ref(widget);
- gtk_widget_unparent(widget);
- gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(e_select_names)->vbox), widget, TRUE, TRUE, 0);
- gtk_widget_unref(widget);
-
- gnome_dialog_append_buttons(GNOME_DIALOG(e_select_names),
- GNOME_STOCK_BUTTON_OK,
- GNOME_STOCK_BUTTON_CANCEL,
- NULL);
- gnome_dialog_set_default(GNOME_DIALOG(e_select_names), 0);
-
- gtk_window_set_title(GTK_WINDOW(e_select_names), _("Select Contacts from Addressbook"));
- gtk_window_set_policy(GTK_WINDOW(e_select_names), FALSE, TRUE, FALSE);
-
- e_select_names->table = E_TABLE_SCROLLED(glade_xml_get_widget(gui, "table-source"));
- e_select_names->model = gtk_object_get_data(GTK_OBJECT(e_select_names->table), "model");
- e_select_names->adapter = gtk_object_get_data(GTK_OBJECT(e_select_names->table), "adapter");
- e_select_names->without = gtk_object_get_data(GTK_OBJECT(e_select_names->table), "without");
-
- e_select_names->status_message = glade_xml_get_widget (gui, "status-message");
- if (e_select_names->status_message && !GTK_IS_LABEL (e_select_names->status_message))
- e_select_names->status_message = NULL;
- if (e_select_names->status_message) {
- gtk_signal_connect (GTK_OBJECT (e_select_names->model), "status_message",
- GTK_SIGNAL_FUNC (status_message), e_select_names);
- gtk_signal_connect(GTK_OBJECT(e_select_names->status_message), "destroy",
- GTK_SIGNAL_FUNC(clear_widget), &e_select_names->status_message);
- }
-
- e_select_names->categories = glade_xml_get_widget (gui, "custom-categories");
- if (e_select_names->categories && !E_IS_CATEGORIES_MASTER_LIST_OPTION_MENU (e_select_names->categories))
- e_select_names->categories = NULL;
- if (e_select_names->categories) {
- gtk_signal_connect(GTK_OBJECT(e_select_names->categories), "changed",
- GTK_SIGNAL_FUNC(categories_changed), e_select_names);
- gtk_signal_connect(GTK_OBJECT(e_select_names->categories), "destroy",
- GTK_SIGNAL_FUNC(clear_widget), &e_select_names->categories);
- }
-
- e_select_names->select_entry = glade_xml_get_widget (gui, "entry-select");
- if (e_select_names->select_entry && !GTK_IS_ENTRY (e_select_names->select_entry))
- e_select_names->select_entry = NULL;
- if (e_select_names->select_entry) {
- gtk_signal_connect(GTK_OBJECT(e_select_names->select_entry), "changed",
- GTK_SIGNAL_FUNC(select_entry_changed), e_select_names);
- gtk_signal_connect(GTK_OBJECT(e_select_names->select_entry), "activate",
- GTK_SIGNAL_FUNC(update_query), e_select_names);
- gtk_signal_connect(GTK_OBJECT(e_select_names->select_entry), "destroy",
- GTK_SIGNAL_FUNC(clear_widget), &e_select_names->select_entry);
- }
-
- button = glade_xml_get_widget (gui, "button-find");
- if (button && GTK_IS_BUTTON (button))
- gtk_signal_connect(GTK_OBJECT(button), "clicked",
- GTK_SIGNAL_FUNC(update_query), e_select_names);
-
- contacts_path = bonobo_config_get_string_with_default (db, "/DefaultFolders/contacts_path",
- "evolution:/local/Contacts",
- NULL);
-
- filename = gnome_util_prepend_user_home("evolution/local/Contacts");
- uri = g_strdup_printf("file://%s", filename);
-
- contacts_uri = bonobo_config_get_string_with_default (db, "/DefaultFolders/contacts_uri",
- uri,
- NULL);
-
- g_free (filename);
- g_free (uri);
-
- button = glade_xml_get_widget (gui, "folder-selector");
- evolution_folder_selector_button_construct (EVOLUTION_FOLDER_SELECTOR_BUTTON (button),
- global_shell_client,
- _("Find contact in"),
- contacts_path,
- selector_types);
- if (button && EVOLUTION_IS_FOLDER_SELECTOR_BUTTON (button))
- gtk_signal_connect(GTK_OBJECT(button), "selected",
- GTK_SIGNAL_FUNC(folder_selected), e_select_names);
-
- gtk_signal_connect (GTK_OBJECT (e_table_scrolled_get_table (e_select_names->table)), "double_click",
- GTK_SIGNAL_FUNC (add_address), e_select_names);
- gtk_signal_connect (GTK_OBJECT (e_table_scrolled_get_table (e_select_names->table)), "selection_change",
- GTK_SIGNAL_FUNC (selection_change), e_select_names);
- selection_change (e_table_scrolled_get_table (e_select_names->table), e_select_names);
-
- addressbook_model_set_uri(e_select_names, e_select_names->model, contacts_uri);
-
- g_free (contacts_uri);
- g_free (contacts_path);
-}
-
-static void e_select_names_child_free(char *key, ESelectNamesChild *child, ESelectNames *e_select_names)
-{
- gtk_signal_disconnect_by_func (GTK_OBJECT (child->source), GTK_SIGNAL_FUNC (sync_table_and_models), e_select_names);
- g_free(child->title);
- gtk_object_unref(GTK_OBJECT(child->text_model));
- gtk_object_unref(GTK_OBJECT(child->source));
- g_free(key);
- g_free(child);
-}
-
-static void
-e_select_names_destroy (GtkObject *object)
-{
- ESelectNames *e_select_names = E_SELECT_NAMES(object);
-
- gtk_object_unref(GTK_OBJECT(e_select_names->gui));
- g_hash_table_foreach(e_select_names->children, (GHFunc) e_select_names_child_free, e_select_names);
- g_hash_table_destroy(e_select_names->children);
- gtk_object_unref(GTK_OBJECT(e_select_names->without));
- gtk_object_unref(GTK_OBJECT(e_select_names->adapter));
- gtk_object_unref(GTK_OBJECT(e_select_names->model));
-
- g_free(e_select_names->def);
-
- (*(GTK_OBJECT_CLASS(parent_class))->destroy)(object);
-}
-
-GtkWidget*
-e_select_names_new (void)
-{
- GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_select_names_get_type ()));
- return widget;
-}
-
-static void
-e_select_names_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
-{
- ESelectNames *editor;
-
- editor = E_SELECT_NAMES (o);
-
- switch (arg_id){
- default:
- return;
- }
-}
-
-static void
-e_select_names_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- ESelectNames *e_select_names;
-
- e_select_names = E_SELECT_NAMES (object);
-
- switch (arg_id) {
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
-}
-
-static void
-button_clicked(GtkWidget *button, ESelectNamesChild *child)
-{
- real_add_address(child->names, child);
-}
-
-#if 0
-static void
-remove_address(ETable *table, int row, int col, GdkEvent *event, ESelectNamesChild *child)
-{
- e_select_names_model_delete (child->source, row);
-}
-#endif
-
-struct _RightClickData {
- ESelectNamesChild *child;
- int index;
-};
-typedef struct _RightClickData RightClickData;
-
-#if 0
-static GSList *selected_rows = NULL;
-
-static void
-etable_selection_foreach_cb (int row, void *data)
-{
- /* Build a list of rows in reverse order, then remove them,
- necessary because otherwise it'll start trying to delete
- rows out of index in ETableModel */
- selected_rows = g_slist_prepend (selected_rows, GINT_TO_POINTER (row));
-}
-
-static void
-selected_rows_foreach_cb (void *row, void *data)
-{
- ESelectNamesChild *child = data;
-
- remove_address (NULL, GPOINTER_TO_INT (row), 0, NULL, child);
-}
-#endif
-
-static void
-remove_cb (GtkWidget *widget, void *data)
-{
- RightClickData *rcdata = (RightClickData *)data;
-
- e_select_names_model_delete (rcdata->child->source, rcdata->index);
-
- /* Free everything we've created */
- g_free (rcdata);
-}
-
-static void
-section_right_click_cb (EText *text, GdkEventButton *ev, gint pos, ESelectNamesChild *child)
-{
- EPopupMenu right_click_menu[] = {
- E_POPUP_ITEM (N_("Remove"), GTK_SIGNAL_FUNC (remove_cb), 0),
- E_POPUP_TERMINATOR
- };
- gint index;
-
- e_select_names_model_text_pos (child->source, child->text_model->seplen, pos, &index, NULL, NULL);
-
- if (index != -1) {
- RightClickData *rcdata = g_new0 (RightClickData, 1);
- rcdata->index = index;
- rcdata->child = child;
-
- e_popup_menu_run (right_click_menu, (GdkEvent *)ev, 0, 0, rcdata);
- }
-}
-
-void
-e_select_names_add_section(ESelectNames *e_select_names, char *name, char *id, ESelectNamesModel *source)
-{
- ESelectNamesChild *child;
- GtkWidget *button;
- GtkWidget *alignment;
- GtkWidget *label;
- GtkTable *table;
- char *label_text;
- ETable *etable;
-
- GtkWidget *sw;
- GtkWidget *recipient_table;
-
- if (g_hash_table_lookup(e_select_names->children, id)) {
- return;
- }
-
- table = GTK_TABLE(glade_xml_get_widget (e_select_names->gui, "table-recipients"));
-
- child = g_new(ESelectNamesChild, 1);
-
- child->names = e_select_names;
- child->title = e_utf8_from_locale_string(_(name));
-
- child->text_model = (ESelectNamesTextModel *) e_select_names_text_model_new (source);
- e_select_names_text_model_set_separator (child->text_model, "\n");
-
- child->source = source;
- gtk_object_ref(GTK_OBJECT(child->source));
-
- e_select_names->child_count++;
-
- alignment = gtk_alignment_new(0, 0, 1, 0);
-
- button = gtk_button_new ();
-
- label = e_entry_new ();
- gtk_object_set(GTK_OBJECT(label),
- "draw_background", FALSE,
- "draw_borders", FALSE,
- "draw_button", TRUE,
- "editable", FALSE,
- "text", "",
- "use_ellipsis", FALSE,
- "justification", GTK_JUSTIFY_CENTER,
- NULL);
-
- label_text = g_strconcat (child->title, " ->", NULL);
- gtk_object_set (GTK_OBJECT (label),
- "text", label_text,
- "emulate_label_resize", TRUE,
- NULL);
- g_free (label_text);
- gtk_container_add (GTK_CONTAINER (button), label);
- child->label = label;
- child->button = button;
-
- gtk_container_add(GTK_CONTAINER(alignment), button);
- gtk_widget_show_all(alignment);
- gtk_signal_connect(GTK_OBJECT(button), "clicked",
- GTK_SIGNAL_FUNC(button_clicked), child);
- gtk_table_attach(table, alignment,
- 0, 1,
- e_select_names->child_count,
- e_select_names->child_count + 1,
- GTK_FILL, GTK_FILL,
- 0, 0);
-
- etable = e_table_scrolled_get_table (e_select_names->table);
- gtk_widget_set_sensitive (button, e_table_selected_count (etable) > 0);
-
-
- sw = gtk_scrolled_window_new (NULL, NULL);
- recipient_table = e_entry_new ();
- gtk_object_set (GTK_OBJECT (recipient_table),
- "model", child->text_model,
- "allow_newlines", TRUE,
- NULL);
-
- gtk_signal_connect (GTK_OBJECT (recipient_table),
- "popup",
- GTK_SIGNAL_FUNC (section_right_click_cb),
- child);
-
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), recipient_table);
-
-#if 0
- gtk_signal_connect(GTK_OBJECT(e_table_scrolled_get_table(E_TABLE_SCROLLED(etable))), "right_click",
- GTK_SIGNAL_FUNC(section_right_click_cb), child);
- gtk_signal_connect(GTK_OBJECT(e_table_scrolled_get_table(E_TABLE_SCROLLED(etable))), "double_click",
- GTK_SIGNAL_FUNC(remove_address), child);
-#endif
-
-
- gtk_signal_connect (GTK_OBJECT (child->source),
- "changed",
- GTK_SIGNAL_FUNC (sync_table_and_models),
- e_select_names);
-
- gtk_widget_show_all (sw);
-
- gtk_table_attach(table, sw,
- 1, 2,
- e_select_names->child_count,
- e_select_names->child_count + 1,
- GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
- 0, 0);
-
- g_hash_table_insert(e_select_names->children, g_strdup(id), child);
-
- sync_table_and_models (child->source, e_select_names);
-}
-
-static void *
-card_copy(const void *value, void *closure)
-{
- gtk_object_ref(GTK_OBJECT(value));
- return (void *)value;
-}
-
-static void
-card_free(void *value, void *closure)
-{
- gtk_object_unref(GTK_OBJECT(value));
-}
-
-EList *
-e_select_names_get_section(ESelectNames *e_select_names, char *id)
-{
- ESelectNamesChild *child;
- int i;
- int rows;
- EList *list;
-
- child = g_hash_table_lookup(e_select_names->children, id);
- if (!child)
- return NULL;
- rows = e_select_names_model_count (child->source);
-
- list = e_list_new(card_copy, card_free, NULL);
- for (i = 0; i < rows; i++) {
- ECard *card = e_select_names_model_get_card (child->source, i);
- e_list_append(list, card);
- gtk_object_unref(GTK_OBJECT(card));
- }
- return list;
-}
-
-ESelectNamesModel *
-e_select_names_get_source(ESelectNames *e_select_names,
- char *id)
-{
- ESelectNamesChild *child = g_hash_table_lookup(e_select_names->children, id);
- if (child) {
- if (child->source)
- gtk_object_ref(GTK_OBJECT(child->source));
- return child->source;
- } else
- return NULL;
-}
-
-void
-e_select_names_set_default (ESelectNames *e_select_names,
- const char *id)
-{
- ESelectNamesChild *child;
-
- if (e_select_names->def) {
- child = g_hash_table_lookup(e_select_names->children, e_select_names->def);
- if (child)
- gtk_object_set (GTK_OBJECT (E_ENTRY (child->label)->item),
- "bold", FALSE,
- NULL);
- }
-
- g_free(e_select_names->def);
- e_select_names->def = g_strdup(id);
-
- if (e_select_names->def) {
- child = g_hash_table_lookup(e_select_names->children, e_select_names->def);
- if (child)
- gtk_object_set (GTK_OBJECT (E_ENTRY (child->label)->item),
- "bold", TRUE,
- NULL);
- }
-}
diff --git a/addressbook/gui/component/select-names/e-select-names.etspec b/addressbook/gui/component/select-names/e-select-names.etspec
deleted file mode 100644
index 3553ca90bf..0000000000
--- a/addressbook/gui/component/select-names/e-select-names.etspec
+++ /dev/null
@@ -1,7 +0,0 @@
-<ETableSpecification no-headers="true" cursor-mode="line">
- <ETableColumn model_col= "43" _title="Name" expansion="1.0" minimum_width="20" resizable="true" cell="string" compare="string" search="string"/>
- <ETableState>
- <column source="0"/>
- <grouping> <leaf column="0" ascending="true"/> </grouping>
- </ETableState>
-</ETableSpecification>
diff --git a/addressbook/gui/component/select-names/e-select-names.h b/addressbook/gui/component/select-names/e-select-names.h
deleted file mode 100644
index ed9da9e115..0000000000
--- a/addressbook/gui/component/select-names/e-select-names.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-select-names.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_SELECT_NAMES_H__
-#define __E_SELECT_NAMES_H__
-
-#include <glib.h>
-#include <gtk/gtkwidget.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-util.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <glade/glade.h>
-#include <gal/e-table/e-table.h>
-#include <gal/e-table/e-table-scrolled.h>
-
-#include <addressbook/gui/widgets/e-addressbook-model.h>
-
-#include "e-select-names-model.h"
-#include "e-util/e-list.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* ESelectNames - A dialog displaying information about a contact.
- *
- * The following arguments are available:
- *
- * name type read/write description
- * --------------------------------------------------------------------------------
- */
-
-#define E_SELECT_NAMES_TYPE (e_select_names_get_type ())
-#define E_SELECT_NAMES(obj) (GTK_CHECK_CAST ((obj), E_SELECT_NAMES_TYPE, ESelectNames))
-#define E_SELECT_NAMES_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_SELECT_NAMES_TYPE, ESelectNamesClass))
-#define E_IS_SELECT_NAMES(obj) (GTK_CHECK_TYPE ((obj), E_SELECT_NAMES_TYPE))
-#define E_IS_SELECT_NAMES_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_SELECT_NAMES_TYPE))
-
-typedef struct _ESelectNames ESelectNames;
-typedef struct _ESelectNamesClass ESelectNamesClass;
-typedef struct _ESelectNamesFolder ESelectNamesFolder;
-
-struct _ESelectNames
-{
- GnomeDialog parent;
-
- /* item specific fields */
- GladeXML *gui;
-
- GHashTable *children; /* Of type char * to ESelectNamesChild */
- int child_count;
- ETableScrolled *table;
- ETableModel *adapter;
- ETableModel *without;
- EAddressbookModel *model;
- GtkWidget *categories;
- GtkWidget *select_entry;
- GtkWidget *status_message;
- char *def;
- ESelectNamesFolder *current_folder;
-};
-
-struct _ESelectNamesClass
-{
- GnomeDialogClass parent_class;
-};
-
-
-GtkWidget *e_select_names_new (void);
-GtkType e_select_names_get_type (void);
-
-void e_select_names_add_section (ESelectNames *e_select_names,
- char *name,
- char *id,
- ESelectNamesModel *source);
-ESelectNamesModel *e_select_names_get_source (ESelectNames *e_select_names,
- char *id);
-void e_select_names_set_default (ESelectNames *e_select_names,
- const char *id);
-/* Returns a ref counted list of addresses. */
-EList *e_select_names_get_section (ESelectNames *e_select_names,
- char *id);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __E_SELECT_NAMES_H__ */
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 9834eddd83..0000000000
--- a/addressbook/gui/component/select-names/e-simple-card-bonobo.c
+++ /dev/null
@@ -1,269 +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_object_get_type ()
-static BonoboObjectClass *parent_class = NULL;
-
-struct _ESimpleCardBonoboPrivate {
- ECardSimple *card_simple;
-};
-
-
-/* CORBA interface implementation. */
-
-static POA_GNOME_Evolution_Addressbook_SimpleCard__vepv SimpleCard_vepv;
-
-static POA_GNOME_Evolution_Addressbook_SimpleCard *
-create_servant (void)
-{
- POA_GNOME_Evolution_Addressbook_SimpleCard *servant;
- CORBA_Environment ev;
-
- servant = (POA_GNOME_Evolution_Addressbook_SimpleCard *) g_new0 (BonoboObjectServant, 1);
- servant->vepv = &SimpleCard_vepv;
-
- CORBA_exception_init (&ev);
-
- POA_GNOME_Evolution_Addressbook_SimpleCard__init ((PortableServer_Servant) servant, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_free (servant);
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- CORBA_exception_free (&ev);
-
- return servant;
-}
-
-static GNOME_Evolution_Addressbook_SimpleCard_Arbitrary *
-impl_SimpleCard_get_arbitrary (PortableServer_Servant servant,
- const CORBA_char *key,
- CORBA_Environment *ev)
-{
- BonoboObject *bonobo_object;
- ESimpleCardBonobo *simple_card;
- ESimpleCardBonoboPrivate *priv;
- GNOME_Evolution_Addressbook_SimpleCard_Arbitrary *ret_val = GNOME_Evolution_Addressbook_SimpleCard_Arbitrary__alloc ();
-
- bonobo_object = bonobo_object_from_servant (servant);
- simple_card = E_SIMPLE_CARD_BONOBO (bonobo_object);
- 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)
-{
- BonoboObject *bonobo_object;
- ESimpleCardBonobo *simple_card;
- ESimpleCardBonoboPrivate *priv;
-
- bonobo_object = bonobo_object_from_servant (servant);
- simple_card = E_SIMPLE_CARD_BONOBO (bonobo_object);
- 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)
-{
- BonoboObject *bonobo_object;
- ESimpleCardBonobo *simple_card;
- ESimpleCardBonoboPrivate *priv;
-
- bonobo_object = bonobo_object_from_servant (servant);
- simple_card = E_SIMPLE_CARD_BONOBO (bonobo_object);
- 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);
- 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)
-{
- BonoboObject *bonobo_object;
- ESimpleCardBonobo *simple_card;
- ESimpleCardBonoboPrivate *priv;
-
- bonobo_object = bonobo_object_from_servant (servant);
- simple_card = E_SIMPLE_CARD_BONOBO (bonobo_object);
- priv = simple_card->priv;
-
- if (priv->card_simple) {
- e_card_simple_set (priv->card_simple,
- field,
- value);
- }
-}
-
-
-/* GtkObject methods. */
-
-static void
-impl_destroy (GtkObject *object)
-{
- ESimpleCardBonobo *simple_card;
- ESimpleCardBonoboPrivate *priv;
-
- simple_card = E_SIMPLE_CARD_BONOBO (object);
- priv = simple_card->priv;
-
- if (priv->card_simple) {
- gtk_object_unref (GTK_OBJECT (priv->card_simple));
- }
-
- g_free (priv);
-
- simple_card->priv = NULL;
-}
-
-
-static void
-corba_class_init ()
-{
- POA_GNOME_Evolution_Addressbook_SimpleCard__vepv *vepv;
- POA_GNOME_Evolution_Addressbook_SimpleCard__epv *epv;
- PortableServer_ServantBase__epv *base_epv;
-
- base_epv = g_new0 (PortableServer_ServantBase__epv, 1);
- base_epv->_private = NULL;
- base_epv->finalize = NULL;
- base_epv->default_POA = NULL;
-
- epv = g_new0 (POA_GNOME_Evolution_Addressbook_SimpleCard__epv, 1);
- epv->getArbitrary = impl_SimpleCard_get_arbitrary;
- epv->setArbitrary = impl_SimpleCard_set_arbitrary;
- epv->get = impl_SimpleCard_get;
- epv->set = impl_SimpleCard_set;
-
- vepv = &SimpleCard_vepv;
- vepv->Bonobo_Unknown_epv = bonobo_object_get_epv ();
- vepv->GNOME_Evolution_Addressbook_SimpleCard_epv = epv;
-}
-
-static void
-class_init (ESimpleCardBonoboClass *klass)
-{
- GtkObjectClass *object_class;
-
- object_class = GTK_OBJECT_CLASS (klass);
- parent_class = gtk_type_class (bonobo_object_get_type ());
-
- object_class->destroy = impl_destroy;
-
- corba_class_init ();
-}
-
-static void
-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,
- GNOME_Evolution_Addressbook_SimpleCard corba_object,
- ECardSimple *card_simple)
-{
- g_return_if_fail (simple_card != NULL);
- g_return_if_fail (E_IS_SIMPLE_CARD_BONOBO (simple_card));
-
- bonobo_object_construct (BONOBO_OBJECT (simple_card), corba_object);
-
- simple_card->priv->card_simple = card_simple;
- gtk_object_ref (GTK_OBJECT (card_simple));
-}
-
-ESimpleCardBonobo *
-e_simple_card_bonobo_new (ECardSimple *card_simple)
-{
- POA_GNOME_Evolution_Addressbook_SimpleCard *servant;
- GNOME_Evolution_Addressbook_SimpleCard corba_object;
- ESimpleCardBonobo *simple_card;
-
- servant = create_servant ();
- if (servant == NULL)
- return NULL;
-
- simple_card = gtk_type_new (e_simple_card_bonobo_get_type ());
-
- corba_object = bonobo_object_activate_servant (BONOBO_OBJECT (simple_card), servant);
- e_simple_card_bonobo_construct (simple_card, corba_object, card_simple);
-
- return simple_card;
-}
-
-
-E_MAKE_TYPE (e_simple_card_bonobo, "ESimpleCardBonobo", ESimpleCardBonobo, class_init, init, PARENT_TYPE)
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 763c54085b..0000000000
--- a/addressbook/gui/component/select-names/e-simple-card-bonobo.h
+++ /dev/null
@@ -1,70 +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) (GTK_CHECK_CAST ((obj), E_TYPE_SIMPLE_CARD_BONOBO, ESimpleCardBonobo))
-#define E_SIMPLE_CARD_BONOBO_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_SIMPLE_CARD_BONOBO, ESimpleCardBonoboClass))
-#define E_IS_SIMPLE_CARD_BONOBO(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_SIMPLE_CARD_BONOBO))
-#define E_IS_SIMPLE_CARD_BONOBO_CLASS(klass) (GTK_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;
-};
-
-
-GtkType e_simple_card_bonobo_get_type (void);
-void e_simple_card_bonobo_construct (ESimpleCardBonobo *simple_card,
- GNOME_Evolution_Addressbook_SimpleCard corba_object,
- ECardSimple *card_simple);
-ESimpleCardBonobo *e_simple_card_bonobo_new (ECardSimple *card_simple);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __E_SIMPLE_CARD_BONOBO_H__ */
diff --git a/addressbook/gui/component/select-names/recipient.glade b/addressbook/gui/component/select-names/recipient.glade
deleted file mode 100644
index b60972d094..0000000000
--- a/addressbook/gui/component/select-names/recipient.glade
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>Recipient</name>
- <program_name>recipient</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
- <use_widget_names>True</use_widget_names>
- <output_main_file>False</output_main_file>
- <output_support_files>False</output_support_files>
- <output_build_files>False</output_build_files>
- <gnome_help_support>True</gnome_help_support>
-</project>
-
-<widget>
- <class>GtkWindow</class>
- <name>window1</name>
- <visible>False</visible>
- <title>window1</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox-top</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment1</name>
- <xalign>1.08033e-07</xalign>
- <yalign>0</yalign>
- <xscale>1</xscale>
- <yscale>0</yscale>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>text-button</name>
- <can_focus>True</can_focus>
- <label>-&gt;</label>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/addressbook/gui/component/select-names/select-names.glade b/addressbook/gui/component/select-names/select-names.glade
deleted file mode 100644
index e46d745b67..0000000000
--- a/addressbook/gui/component/select-names/select-names.glade
+++ /dev/null
@@ -1,465 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>Select-names</name>
- <program_name>select-names</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>../../../../art/</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
- <output_main_file>False</output_main_file>
- <output_support_files>False</output_support_files>
- <output_build_files>False</output_build_files>
-</project>
-
-<widget>
- <class>GnomeDialog</class>
- <name>dialog-top</name>
- <visible>False</visible>
- <title>Select Names</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <default_width>417</default_width>
- <default_height>332</default_height>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>dialog-vbox1</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>dialog-action_area1</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button4</name>
- <can_default>True</can_default>
- <has_default>True</has_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button5</name>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table-top</name>
- <rows>3</rows>
- <columns>1</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator1</name>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>False</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame1</name>
- <label>Show Contacts</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkTable</class>
- <name>table5</name>
- <border_width>3</border_width>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label30</name>
- <label>_Folder:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label31</name>
- <label>_Category:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment5</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>Custom</class>
- <name>custom-categories</name>
- <creation_function>e_select_names_create_categories</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Tue, 19 Feb 2002 23:06:24 GMT</last_modification_time>
- </widget>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>folder-selector</name>
- <creation_function>e_addressbook_create_folder_selector</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Mon, 15 Jul 2002 02:21:32 GMT</last_modification_time>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox5</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkTable</class>
- <name>table4</name>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label32</name>
- <label>Type a name into the entry, or
-select one from the list below:</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table-recipients</name>
- <rows>5</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>3</row_spacing>
- <column_spacing>3</column_spacing>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label20</name>
- <label>Selected Contacts:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>True</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment4</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>1</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox6</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-select</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment3</name>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xscale>1</xscale>
- <yscale>1</yscale>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>Custom</class>
- <name>table-source</name>
- <creation_function>e_addressbook_create_ebook_table</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Sat, 10 Jun 2000 22:02:57 GMT</last_modification_time>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>status-message</name>
- <label></label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>3</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/addressbook/gui/contact-editor/.cvsignore b/addressbook/gui/contact-editor/.cvsignore
deleted file mode 100644
index 6fd0b5075c..0000000000
--- a/addressbook/gui/contact-editor/.cvsignore
+++ /dev/null
@@ -1,8 +0,0 @@
-.deps
-.libs
-.pure
-Makefile
-Makefile.in
-*.lo
-*.la
-contact-editor-test
diff --git a/addressbook/gui/contact-editor/Makefile.am b/addressbook/gui/contact-editor/Makefile.am
index fe7295bfe6..5307298a0f 100644
--- a/addressbook/gui/contact-editor/Makefile.am
+++ b/addressbook/gui/contact-editor/Makefile.am
@@ -1,48 +1,45 @@
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/addressbook/ \
- -I$(top_srcdir)/addressbook/backend \
- -I$(top_builddir)/addressbook/backend \
- -I$(top_srcdir)/addressbook/gui/merging \
- -I$(top_srcdir)/widgets/e-table \
- -I$(top_builddir)/shell \
- -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
- -DDATADIR=\""$(datadir)"\" \
- -DEVOLUTION_DATADIR=\""$(datadir)"\" \
- -DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \
- -DEVOLUTIONDIR=\""$(evolutiondir)"\" \
- -DG_LOG_DOMAIN=\"contact-editor\" \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
-
-noinst_LIBRARIES = \
- libecontacteditor.a
-
-libecontacteditor_a_SOURCES = \
- e-contact-editor-address.c \
- e-contact-editor-address.h \
+privsolib_LTLIBRARIES = libecontacteditor.la
+
+libecontacteditor_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/addressbook/ \
+ -I$(top_srcdir)/addressbook/gui/merging \
+ -I$(top_builddir)/shell \
+ -DEVOLUTION_UIDIR=\""$(uidir)"\" \
+ -DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \
+ -DG_LOG_DOMAIN=\"contact-editor\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS)
+
+libecontacteditor_la_SOURCES = \
+ eab-editor.c \
+ eab-editor.h \
e-contact-editor-fullname.c \
e-contact-editor-fullname.h \
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
-evolutiondir = $(datadir)/evolution
-
-evolution_DATA = arrow.png
+libecontacteditor_la_LDFLAGS = -avoid-version $(NO_UNDEFINED)
-iconsdir = $(datadir)/images/evolution
+libecontacteditor_la_LIBADD = \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(top_builddir)/addressbook/util/libeabutil.la \
+ $(top_builddir)/addressbook/gui/widgets/libeabwidgets.la \
+ $(top_builddir)/addressbook/gui/merging/libeabbookmerging.la \
+ $(top_builddir)/addressbook/printing/libecontactprint.la \
+ $(EVOLUTION_ADDRESSBOOK_LIBS) \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_LIBS)
-gladedir = $(datadir)/evolution/glade
+ui_DATA = \
+ contact-editor.ui \
+ fullname.ui
-glade_DATA = \
- contact-editor.glade \
- fulladdr.glade \
- fullname.glade \
- file-exists.glade \
- e-contact-editor-confirm-delete.glade
+EXTRA_DIST= $(ui_DATA)
-EXTRA_DIST = $(evolution_DATA) \
- $(glade_DATA)
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/gui/contact-editor/arrow.png b/addressbook/gui/contact-editor/arrow.png
deleted file mode 100644
index b102356c78..0000000000
--- a/addressbook/gui/contact-editor/arrow.png
+++ /dev/null
Binary files differ
diff --git a/addressbook/gui/contact-editor/contact-editor.glade b/addressbook/gui/contact-editor/contact-editor.glade
deleted file mode 100644
index c8c880fa0c..0000000000
--- a/addressbook/gui/contact-editor/contact-editor.glade
+++ /dev/null
@@ -1,2537 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>Contact-editor</name>
- <program_name>contact-editor</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
- <use_widget_names>True</use_widget_names>
- <output_main_file>False</output_main_file>
- <output_support_files>False</output_support_files>
- <output_build_files>False</output_build_files>
- <backup_source_files>False</backup_source_files>
-</project>
-
-<widget>
- <class>GnomeDialog</class>
- <name>dialog2</name>
- <border_width>2</border_width>
- <visible>False</visible>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>False</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>dialog-vbox2</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>dialog-action_area2</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button28</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button29</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_APPLY</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button30</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table2</name>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>0</row_spacing>
- <column_spacing>2</column_spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry2</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>0</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox1</name>
- <homogeneous>False</homogeneous>
- <spacing>2</spacing>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button31</name>
- <border_width>2</border_width>
- <can_focus>True</can_focus>
- <label>_Add</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button32</name>
- <border_width>2</border_width>
- <can_focus>True</can_focus>
- <label>_Delete</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow1</name>
- <height>200</height>
- <hscrollbar_policy>GTK_POLICY_ALWAYS</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>clist1</name>
- <can_focus>True</can_focus>
- <columns>1</columns>
- <column_widths>80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>True</show_titles>
- <shadow_type>GTK_SHADOW_NONE</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label20</name>
- <label>Phone Types</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GnomeDialog</class>
- <name>dialog-add-phone</name>
- <visible>False</visible>
- <title>New phone type</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>False</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>vbox2</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>hbuttonbox1</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button43</name>
- <can_default>True</can_default>
- <has_default>True</has_default>
- <can_focus>True</can_focus>
- <label>_Add</label>
- <stock_pixmap>GNOME_STOCK_PIXMAP_ADD</stock_pixmap>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button44</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame-add-phone</name>
- <border_width>4</border_width>
- <label>New phone type</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment9</name>
- <border_width>9</border_width>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xscale>1</xscale>
- <yscale>1</yscale>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-add-phone</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-<widget>
- <class>GnomeApp</class>
- <name>contact editor</name>
- <visible>False</visible>
- <title>Contact Editor</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <enable_layout_config>True</enable_layout_config>
-
- <widget>
- <class>GnomeDock</class>
- <child_name>GnomeApp:dock</child_name>
- <name>dock1</name>
- <allow_floating>True</allow_floating>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkNotebook</class>
- <child_name>GnomeDock:contents</child_name>
- <name>notebook-contact-editor</name>
- <can_focus>True</can_focus>
- <show_tabs>True</show_tabs>
- <show_border>True</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
-
- <widget>
- <class>GtkTable</class>
- <name>table-contact-editor-general</name>
- <border_width>7</border_width>
- <rows>14</rows>
- <columns>8</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>4</row_spacing>
- <column_spacing>4</column_spacing>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-phone1</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>7</left_attach>
- <right_attach>8</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-phone2</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>7</left_attach>
- <right_attach>8</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-phone3</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>7</left_attach>
- <right_attach>8</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-phone4</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>7</left_attach>
- <right_attach>8</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkText</class>
- <name>text-address</name>
- <width>1</width>
- <height>1</height>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text></text>
- <child>
- <left_attach>7</left_attach>
- <right_attach>8</right_attach>
- <top_attach>5</top_attach>
- <bottom_attach>9</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button-fullname</name>
- <can_focus>True</can_focus>
- <label>Full _Name...</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <left_attach>1</left_attach>
- <right_attach>3</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment3</name>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>5</top_attach>
- <bottom_attach>6</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button-email1</name>
- <relief>GTK_RELIEF_NORMAL</relief>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment5</name>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>6</left_attach>
- <right_attach>7</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button-phone4</name>
- <relief>GTK_RELIEF_NORMAL</relief>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment7</name>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>6</left_attach>
- <right_attach>7</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button-phone2</name>
- <relief>GTK_RELIEF_NORMAL</relief>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment8</name>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>6</left_attach>
- <right_attach>7</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button-phone1</name>
- <relief>GTK_RELIEF_NORMAL</relief>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator4</name>
- <child>
- <left_attach>4</left_attach>
- <right_attach>8</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>2</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment6</name>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>6</left_attach>
- <right_attach>7</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button-phone3</name>
- <relief>GTK_RELIEF_NORMAL</relief>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-fullname</name>
- <can_default>True</can_default>
- <has_default>True</has_default>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-jobtitle</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-company</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-email1</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>5</top_attach>
- <bottom_attach>6</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-web</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>8</top_attach>
- <bottom_attach>9</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator5</name>
- <child>
- <left_attach>0</left_attach>
- <right_attach>4</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>2</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCombo</class>
- <name>combo-file-as</name>
- <value_in_list>False</value_in_list>
- <ok_if_empty>True</ok_if_empty>
- <case_sensitive>True</case_sensitive>
- <use_arrows>True</use_arrows>
- <use_arrows_always>False</use_arrows_always>
- <items></items>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <child_name>GtkCombo:entry</child_name>
- <name>entry-file-as</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator6</name>
- <child>
- <left_attach>0</left_attach>
- <right_attach>4</right_attach>
- <top_attach>7</top_attach>
- <bottom_attach>8</bottom_attach>
- <xpad>0</xpad>
- <ypad>2</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment-htmlmail</name>
- <xalign>0.5</xalign>
- <yalign>0</yalign>
- <xscale>1</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>6</top_attach>
- <bottom_attach>7</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>True</xshrink>
- <yshrink>True</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>checkbutton-htmlmail</name>
- <can_focus>True</can_focus>
- <label>Wants to receive _HTML mail</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment4</name>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>6</left_attach>
- <right_attach>7</right_attach>
- <top_attach>5</top_attach>
- <bottom_attach>6</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button-address</name>
- <relief>GTK_RELIEF_NORMAL</relief>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEventBox</class>
- <name>eventbox1</name>
- <child>
- <left_attach>5</left_attach>
- <right_attach>6</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-phone1</name>
- <label>Business</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-phone1</focus_target>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEventBox</class>
- <name>eventbox2</name>
- <child>
- <left_attach>5</left_attach>
- <right_attach>6</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-phone2</name>
- <label>Home</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-phone2</focus_target>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEventBox</class>
- <name>eventbox3</name>
- <child>
- <left_attach>5</left_attach>
- <right_attach>6</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-phone3</name>
- <label>Business Fax</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-phone3</focus_target>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEventBox</class>
- <name>eventbox4</name>
- <child>
- <left_attach>5</left_attach>
- <right_attach>6</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-phone4</name>
- <label>Mobile</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-phone4</focus_target>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEventBox</class>
- <name>eventbox5</name>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>5</top_attach>
- <bottom_attach>6</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-email1</name>
- <label>Primary Email</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-email1</focus_target>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEventBox</class>
- <name>eventbox-business</name>
- <child>
- <left_attach>5</left_attach>
- <right_attach>6</right_attach>
- <top_attach>5</top_attach>
- <bottom_attach>6</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-address</name>
- <label>Business</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>text-address</focus_target>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment2</name>
- <xalign>0</xalign>
- <yalign>0</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>7</left_attach>
- <right_attach>8</right_attach>
- <top_attach>9</top_attach>
- <bottom_attach>10</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>checkbutton-mailingaddress</name>
- <label>This is the _mailing address</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator9</name>
- <child>
- <left_attach>0</left_attach>
- <right_attach>4</right_attach>
- <top_attach>11</top_attach>
- <bottom_attach>12</bottom_attach>
- <xpad>0</xpad>
- <ypad>2</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator10</name>
- <child>
- <left_attach>4</left_attach>
- <right_attach>8</right_attach>
- <top_attach>11</top_attach>
- <bottom_attach>12</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment-contacts</name>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xscale>1</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>3</right_attach>
- <top_attach>12</top_attach>
- <bottom_attach>13</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button-contacts</name>
- <can_focus>True</can_focus>
- <label>C_ontacts...</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment15</name>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xscale>1</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>7</left_attach>
- <right_attach>8</right_attach>
- <top_attach>12</top_attach>
- <bottom_attach>13</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-categories</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment16</name>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xscale>1</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>5</left_attach>
- <right_attach>7</right_attach>
- <top_attach>12</top_attach>
- <bottom_attach>13</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button-categories</name>
- <can_focus>True</can_focus>
- <label>Ca_tegories...</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEventBox</class>
- <name>eventbox7</name>
- <child>
- <left_attach>1</left_attach>
- <right_attach>3</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-jobtitle</name>
- <label>_Job title:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-jobtitle</focus_target>
- </widget>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>custom1</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>malehead.png</string1>
- <string2></string2>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 18 May 2000 12:19:47 GMT</last_modification_time>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>custom2</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>cellphone.png</string1>
- <string2></string2>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 18 May 2000 12:20:02 GMT</last_modification_time>
- <child>
- <left_attach>4</left_attach>
- <right_attach>5</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>custom3</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>envelope.png</string1>
- <string2></string2>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 18 May 2000 12:19:51 GMT</last_modification_time>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>5</top_attach>
- <bottom_attach>7</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>custom4</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>house.png</string1>
- <string2></string2>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 18 May 2000 12:20:06 GMT</last_modification_time>
- <child>
- <left_attach>4</left_attach>
- <right_attach>5</right_attach>
- <top_attach>5</top_attach>
- <bottom_attach>10</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>custom5</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>evolution-contacts-plain.png</string1>
- <string2></string2>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 18 May 2000 12:19:59 GMT</last_modification_time>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>12</top_attach>
- <bottom_attach>14</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>custom6</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>briefcase.png</string1>
- <string2></string2>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 18 May 2000 12:20:09 GMT</last_modification_time>
- <child>
- <left_attach>4</left_attach>
- <right_attach>5</right_attach>
- <top_attach>12</top_attach>
- <bottom_attach>14</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>custom10</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>globe.png</string1>
- <string2></string2>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 18 May 2000 12:19:56 GMT</last_modification_time>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>8</top_attach>
- <bottom_attach>10</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-company</name>
- <label>Organi_zation:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-company</focus_target>
- <child>
- <left_attach>1</left_attach>
- <right_attach>3</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button-fulladdr</name>
- <can_focus>True</can_focus>
- <label>Add_ress...</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <left_attach>5</left_attach>
- <right_attach>7</right_attach>
- <top_attach>6</top_attach>
- <bottom_attach>7</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment17</name>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xscale>1</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>12</top_attach>
- <bottom_attach>13</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkTable</class>
- <name>table-contacts</name>
- <rows>1</rows>
- <columns>1</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>0</row_spacing>
- <column_spacing>0</column_spacing>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>accellabel-fileas</name>
- <label>File A_s:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-file-as</focus_target>
- <child>
- <left_attach>1</left_attach>
- <right_attach>3</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>accellabel-web</name>
- <label>_Web page address:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-web</focus_target>
- <child>
- <left_attach>1</left_attach>
- <right_attach>3</right_attach>
- <top_attach>8</top_attach>
- <bottom_attach>9</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label15</name>
- <label>General</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table-contact-editor-details</name>
- <border_width>7</border_width>
- <rows>9</rows>
- <columns>6</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>4</row_spacing>
- <column_spacing>4</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-department</name>
- <label>D_epartment:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-department</focus_target>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-office</name>
- <label>_Office:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-office</focus_target>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-profession</name>
- <label>P_rofession:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-profession</focus_target>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-nickname</name>
- <label>_Nickname:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-nickname</focus_target>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-spouse</name>
- <label>S_pouse:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-spouse</focus_target>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>5</top_attach>
- <bottom_attach>6</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-birthday</name>
- <label>Birthda_y:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>dateedit-birthday</focus_target>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-assistant</name>
- <label>A_ssistant's name:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-assistant</focus_target>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-manager</name>
- <label>_Manager's Name:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-manager</focus_target>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-anniversary</name>
- <label>Anni_versary:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>dateedit-anniversary</focus_target>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>5</top_attach>
- <bottom_attach>6</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-spouse</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>5</top_attach>
- <bottom_attach>6</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-department</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-office</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-profession</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-nickname</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-assistant</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>4</left_attach>
- <right_attach>6</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-manager</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>4</left_attach>
- <right_attach>6</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator7</name>
- <child>
- <left_attach>0</left_attach>
- <right_attach>6</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>2</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-comments</name>
- <label>No_tes:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>text-comments</focus_target>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>7</top_attach>
- <bottom_attach>8</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator8</name>
- <child>
- <left_attach>0</left_attach>
- <right_attach>6</right_attach>
- <top_attach>6</top_attach>
- <bottom_attach>7</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>custom7</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>briefcase.png</string1>
- <string2></string2>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 18 May 2000 12:20:13 GMT</last_modification_time>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>custom8</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>malehead.png</string1>
- <string2></string2>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 18 May 2000 12:20:16 GMT</last_modification_time>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>6</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow2</name>
- <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <left_attach>1</left_attach>
- <right_attach>6</right_attach>
- <top_attach>8</top_attach>
- <bottom_attach>9</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkText</class>
- <name>text-comments</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text></text>
- </widget>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>custom9</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>globe.png</string1>
- <string2></string2>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 18 May 2000 12:20:19 GMT</last_modification_time>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>7</top_attach>
- <bottom_attach>9</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>dateedit-birthday</name>
- <can_focus>True</can_focus>
- <creation_function>e_contact_editor_create_date</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Tue, 05 Jun 2001 02:36:27 GMT</last_modification_time>
- <child>
- <left_attach>4</left_attach>
- <right_attach>6</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>dateedit-anniversary</name>
- <can_focus>True</can_focus>
- <creation_function>e_contact_editor_create_date</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Tue, 05 Jun 2001 02:36:32 GMT</last_modification_time>
- <child>
- <left_attach>4</left_attach>
- <right_attach>6</right_attach>
- <top_attach>5</top_attach>
- <bottom_attach>6</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label16</name>
- <label>Details</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox3</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox1</name>
- <border_width>7</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>Custom</class>
- <name>custom12</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>globe.png</string1>
- <string2></string2>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 18 May 2000 12:20:13 GMT</last_modification_time>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label24</name>
- <label>If this person publishes free/busy or other calendar information on the Internet, enter the address
-of that information here.</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment18</name>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xscale>0.75</xscale>
- <yscale>1</yscale>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkTable</class>
- <name>table-contact-editor-collaboration</name>
- <border_width>7</border_width>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>4</row_spacing>
- <column_spacing>4</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-caluri</name>
- <label>_Public Calendar URL:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-caluri</focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-fburl</name>
- <label>F_ree/Busy URL:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-fburl</focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-caluri</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-fburl</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label21</name>
- <label>Collaboration</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GnomeAppBar</class>
- <child_name>GnomeApp:appbar</child_name>
- <name>appbar1</name>
- <has_progress>True</has_progress>
- <has_status>True</has_status>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/addressbook/gui/contact-editor/contact-editor.ui b/addressbook/gui/contact-editor/contact-editor.ui
new file mode 100644
index 0000000000..e4714d1bf4
--- /dev/null
+++ b/addressbook/gui/contact-editor/contact-editor.ui
@@ -0,0 +1,2446 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-requires evolution 0.0 -->
+ <!-- interface-naming-policy toplevel-contextual -->
+ <object class="GtkListStore" id="model1">
+ <columns>
+ <!-- column-name gchararray -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkListStore" id="model2">
+ <columns>
+ <!-- column-name gchararray -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0">Work</col>
+ </row>
+ <row>
+ <col id="0">Personal</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="model3">
+ <columns>
+ <!-- column-name gchararray -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0">Work</col>
+ </row>
+ <row>
+ <col id="0">Personal</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="model4">
+ <columns>
+ <!-- column-name gchararray -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0">Work</col>
+ </row>
+ <row>
+ <col id="0">Personal</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="model5">
+ <columns>
+ <!-- column-name gchararray -->
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0">Work</col>
+ </row>
+ <row>
+ <col id="0">Personal</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkDialog" id="contact editor">
+ <property name="title" translatable="yes">Contact Editor</property>
+ <property name="window_position">center</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkNotebook" id="notebook11">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="border_width">12</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="min-content-width">320</property>
+ <property name="min-content-height">240</property>
+ <child>
+ <object class="GtkViewport" id="viewport1">
+ <property name="visible">True</property>
+ <property name="resize_mode">queue</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkVBox" id="vbox33">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">1</property>
+ <child>
+ <object class="GtkHBox" id="hbox55">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkButton" id="button-image">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="button-image-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes">Image</property>
+ </object>
+ </child>
+ <child>
+ <object class="EImageChooser" type-func="e_image_chooser_get_type" id="image-chooser">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="table83">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">4</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label-nickname">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">Nic_kname:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-nickname</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-fullname">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="name">fullname</property>
+ <accessibility>
+ <relation type="labelled-by" target="button-fullname"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="accellabel-fileas">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_File under:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">combo-file-as</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="where-label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Where:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button-categories">
+ <property name="label" translatable="yes">Ca_tegories...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-categories">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="button-categories"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-nickname">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="name">nickname</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="EClientComboBox" type-func="e_client_combo_box_get_type" id="client-combo-box">
+ <property name="extension-name">Address Book</property>
+ <property name="show-colors">False</property>
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button-fullname">
+ <property name="label" translatable="yes">Full _Name...</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combo-file-as">
+ <property name="visible">True</property>
+ <property name="has-entry">True</property>
+ <property name="entry-text-column">0</property>
+ <property name="model">model1</property>
+ <property name="name">file-as</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHSeparator" id="hseparator10">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">6</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox34">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkFrame" id="frame65">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkTable" id="email-table">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">4</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="entry-email-3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="name">email-3</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-email-1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="name">email-1</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-email-2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="name">email-2</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-email-4">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="name">email-4</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="checkbutton-htmlmail">
+ <property name="label" translatable="yes">_Wants to receive HTML mail</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="right_attach">4</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-email-1">
+ <property name="visible">True</property>
+ <property name="model">model2</property>
+ <child>
+ <object class="GtkCellRendererText" id="renderer2"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-email-3">
+ <property name="visible">True</property>
+ <property name="model">model3</property>
+ <child>
+ <object class="GtkCellRendererText" id="renderer3"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-email-2">
+ <property name="visible">True</property>
+ <property name="model">model4</property>
+ <child>
+ <object class="GtkCellRendererText" id="renderer4"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-email-4">
+ <property name="visible">True</property>
+ <property name="model">model5</property>
+ <child>
+ <object class="GtkCellRendererText" id="renderer5"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkHBox" id="hbox561">
+ <property name="visible">True</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel" id="label400">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Email</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button-mail-expand">
+ <property name="width_request">20</property>
+ <property name="height_request">20</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="relief">none</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="button-mail-expand-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes">Email</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkArrow" id="arrow-mail-expand">
+ <property name="visible">True</property>
+ <property name="shadow_type">none</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox38">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkFrame" id="frame64">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkVBox" id="vbox37">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkTable" id="table84">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">4</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="entry-phone-1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-phone-3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-phone-4">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-phone-2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-phone-1">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-phone-3">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-phone-2">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-phone-4">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="table-phone-extended">
+ <property name="n_rows">2</property>
+ <property name="n_columns">4</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="entry-phone-5">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-phone-7">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-phone-6">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-phone-8">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-phone-5">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-phone-7">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-phone-6">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-phone-8">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkHBox" id="hbox56">
+ <property name="visible">True</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel" id="label399">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Telephone</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button-phone-expand">
+ <property name="width_request">20</property>
+ <property name="height_request">20</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="relief">none</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="button-phone-expand-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes">Telephone</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkArrow" id="arrow-phone-expand">
+ <property name="visible">True</property>
+ <property name="shadow_type">none</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame66">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkTable" id="table86">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">4</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="entry-im-name-1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-im-name-3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-im-name-2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-im-name-4">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-im-service-1">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-im-service-3">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-im-service-2">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combobox-im-service-4">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label404">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Instant Messaging</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label405">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Contact</property>
+ </object>
+ <packing>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow-size-leader">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="min-content-width">320</property>
+ <property name="min-content-height">240</property>
+ <child>
+ <object class="GtkViewport" id="viewport2">
+ <property name="visible">True</property>
+ <property name="shadow-type">none</property>
+ <property name="resize_mode">queue</property>
+ <child>
+ <object class="GtkVBox" id="vbox-size-leader">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkFrame" id="frame67">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkTable" id="table87">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="n_rows">5</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="accellabel-homepage">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Home Page:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-homepage</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-caluri">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Calendar:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-caluri</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-fburl">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Free/Busy:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-fburl</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-videourl">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Video Chat:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-videourl</property>
+ </object>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="EUrlEntry" type-func="e_url_entry_get_type" id="entry-homepage">
+ <property name="visible">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="entry-homepage-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes">Home Page:</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="EUrlEntry" type-func="e_url_entry_get_type" id="entry-caluri">
+ <property name="visible">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="entry-caluri-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes">Calendar:</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="EUrlEntry" type-func="e_url_entry_get_type" id="entry-fburl">
+ <property name="visible">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="entry-fburl-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes">Free/Busy:</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="EUrlEntry" type-func="e_url_entry_get_type" id="entry-videourl">
+ <property name="visible">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="entry-videourl-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes">Video Chat:</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-weblog">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Blog:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-weblog</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="EUrlEntry" type-func="e_url_entry_get_type" id="entry-weblog">
+ <property name="visible">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="entry-weblog-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes" comments="Translators: an accessibility name">Blog:</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkHBox" id="hbox5617">
+ <property name="visible">True</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkLabel" id="label410">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Web Addresses</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button-web-expand">
+ <property name="width_request">20</property>
+ <property name="height_request">20</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="relief">none</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="button-web-expand-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes">Web addresses</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkArrow" id="arrow-web-expand">
+ <property name="visible">True</property>
+ <property name="shadow_type">none</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame68">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkTable" id="table88">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="n_rows">3</property>
+ <property name="n_columns">4</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label-profession">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Profession:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-profession</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-profession">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="label-profession"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-jobtitle">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" context="Job">_Title:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-jobtitle</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-jobtitle">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="label-jobtitle"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-company">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Company:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-company</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-company">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="label-company"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-department">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Department:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-department</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-department">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="label-department"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-manager">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Manager:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-manager</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-manager">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="label-manager"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-assistant">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Assistant:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-assistant</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-assistant">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="label-assistant"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label417">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Job</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkExpander" id="expander-personal-misc">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <child>
+ <object class="GtkTable" id="table89">
+ <property name="visible">True</property>
+ <property name="border_width">12</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">4</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label-office">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Office:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-office</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-spouse">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Spouse:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-spouse</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-office">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="label-office"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-spouse">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <accessibility>
+ <relation type="labelled-by" target="label-spouse"/>
+ </accessibility>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-birthday">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Birthday:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">dateedit-birthday</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-anniversary">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Anniversary:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">dateedit-anniversary</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="EDateEdit" type-func="e_date_edit_get_type" id="dateedit-anniversary">
+ <property name="visible">True</property>
+ <property name="allow_no_date_set">True</property>
+ <property name="show_time">False</property>
+ <property name="twodigit_year_can_future">False</property>
+ <property name="set_none">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="dateedit-anniversary-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes">Anniversary</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="EDateEdit" type-func="e_date_edit_get_type" id="dateedit-birthday">
+ <property name="visible">True</property>
+ <property name="allow_no_date_set">True</property>
+ <property name="show_time">False</property>
+ <property name="twodigit_year_can_future">False</property>
+ <property name="set_none">True</property>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="dateedit-birthday-atkobject">
+ <property name="AtkObject::accessible-name" translatable="yes">Birthday</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label421">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Miscellaneous</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label422">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Personal Information</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow3">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="min-content-width">320</property>
+ <property name="min-content-height">240</property>
+ <child>
+ <object class="GtkViewport" id="viewport3">
+ <property name="visible">True</property>
+ <property name="resize_mode">queue</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkVBox" id="vbox39">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkFrame" id="frame72">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="yalign">0.15000000596046448</property>
+ <property name="yscale">0.69999998807907104</property>
+ <property name="left_padding">19</property>
+ <property name="right_padding">10</property>
+ <child>
+ <object class="GtkHBox" id="hbox59">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkTable" id="table-home-address">
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">4</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow-home-address">
+ <property name="width_request">193</property>
+ <property name="height_request">69</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="textview-home-address">
+ <property name="height_request">25</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="accepts_tab">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-home-city">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-home-city">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_City:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-home-city</property>
+ <property name="single_line_mode">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-home-zip">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-home-zip">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Zip/Postal Code:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-home-zip</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-home-state">
+ <property name="width_request">256</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-home-state">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_State/Province:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-home-state</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-home-country">
+ <property name="width_request">163</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-home-country">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="ypad">4</property>
+ <property name="label" translatable="yes">_Country:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-home-country</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-home-pobox">
+ <property name="width_request">100</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-home-pobox">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_PO Box:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-home-pobox</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-home-address">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Address:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">textview-home-address</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="frame73">
+ <property name="visible">True</property>
+ <property name="xalign">0.41999998688697815</property>
+ <property name="label" translatable="yes">Home</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFrame" id="frame77">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkAlignment" id="alignment6">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="yalign">0.15000000596046448</property>
+ <property name="yscale">0.69999998807907104</property>
+ <property name="left_padding">19</property>
+ <property name="right_padding">10</property>
+ <child>
+ <object class="GtkHBox" id="hbox98">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkTable" id="table-work-address">
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">4</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow-work-address">
+ <property name="width_request">193</property>
+ <property name="height_request">69</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="textview-work-address">
+ <property name="height_request">25</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="accepts_tab">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-work-city">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-work-city">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_City:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-work-city</property>
+ <property name="single_line_mode">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-work-address">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Address:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">textview-work-address</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-work-zip">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-work-zip">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Zip/Postal Code:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-work-zip</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-work-state">
+ <property name="width_request">256</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-work-state">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_State/Province:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-work-state</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-work-country">
+ <property name="width_request">163</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-work-country">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="ypad">4</property>
+ <property name="label" translatable="yes">_Country:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-work-country</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-work-pobox">
+ <property name="width_request">100</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-work-pobox">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_PO Box:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-work-pobox</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label460">
+ <property name="visible">True</property>
+ <property name="xalign">0.41999998688697815</property>
+ <property name="label" translatable="yes">Work</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkExpander" id="expander-address-other">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="border_width">6</property>
+ <child>
+ <object class="GtkAlignment" id="alignment7">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="yalign">0.15000000596046448</property>
+ <property name="yscale">0.69999998807907104</property>
+ <property name="left_padding">19</property>
+ <property name="right_padding">10</property>
+ <child>
+ <object class="GtkHBox" id="hbox103">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkTable" id="table-other-address">
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">4</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="entry-other-city">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-other-city">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_City:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-other-city</property>
+ <property name="single_line_mode">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-other-address">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Address:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">textview-other-address</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-other-zip">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-other-zip">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Zip/Postal Code:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-other-zip</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-other-state">
+ <property name="width_request">256</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-other-state">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_State/Province:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-other-state</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-other-country">
+ <property name="width_request">163</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="right_attach">4</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-other-country">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="ypad">4</property>
+ <property name="label" translatable="yes">_Country:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-other-country</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-other-pobox">
+ <property name="width_request">100</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-other-pobox">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_PO Box:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">entry-other-pobox</property>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow-other-address">
+ <property name="width_request">193</property>
+ <property name="height_request">69</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="textview-other-address">
+ <property name="height_request">25</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="accepts_tab">False</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label467">
+ <property name="visible">True</property>
+ <property name="xalign">0.41999998688697815</property>
+ <property name="label" translatable="yes">Other</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label437">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Mailing Address</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow41">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="border_width">12</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="text-comments">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label468">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Notes</property>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="button-help">
+ <property name="label">gtk-help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button-cancel">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button-ok">
+ <property name="label">gtk-save</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_stock">True</property>
+ <accelerator key="s" modifiers="GDK_CONTROL_MASK" signal="clicked"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-11">button-help</action-widget>
+ <action-widget response="-6">button-cancel</action-widget>
+ <action-widget response="-5">button-ok</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/addressbook/gui/contact-editor/e-contact-editor-address.c b/addressbook/gui/contact-editor/e-contact-editor-address.c
deleted file mode 100644
index dd9405816f..0000000000
--- a/addressbook/gui/contact-editor/e-contact-editor-address.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-contact-editor-address.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 <e-contact-editor-address.h>
-
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-stock.h>
-#include <libgnomeui/gnome-window-icon.h>
-#include <libgnome/gnome-util.h>
-#include <gal/widgets/e-unicode.h>
-#include <gal/widgets/e-gui-utils.h>
-#include <gtk/gtkcombo.h>
-#include <string.h>
-#include <stdlib.h>
-#include <locale.h>
-
-static void e_contact_editor_address_init (EContactEditorAddress *card);
-static void e_contact_editor_address_class_init (EContactEditorAddressClass *klass);
-static void e_contact_editor_address_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_contact_editor_address_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_contact_editor_address_destroy (GtkObject *object);
-
-static void fill_in_info(EContactEditorAddress *editor);
-static void extract_info(EContactEditorAddress *editor);
-
-static GnomeDialogClass *parent_class = NULL;
-
-/* The arguments we take */
-enum {
- ARG_0,
- ARG_ADDRESS,
- ARG_IS_READ_ONLY
-};
-
-GtkType
-e_contact_editor_address_get_type (void)
-{
- static GtkType contact_editor_address_type = 0;
-
- if (!contact_editor_address_type)
- {
- static const GtkTypeInfo contact_editor_address_info =
- {
- "EContactEditorAddress",
- sizeof (EContactEditorAddress),
- sizeof (EContactEditorAddressClass),
- (GtkClassInitFunc) e_contact_editor_address_class_init,
- (GtkObjectInitFunc) e_contact_editor_address_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- contact_editor_address_type = gtk_type_unique (gnome_dialog_get_type (), &contact_editor_address_info);
- }
-
- return contact_editor_address_type;
-}
-
-static void
-e_contact_editor_address_class_init (EContactEditorAddressClass *klass)
-{
- GtkObjectClass *object_class;
- GnomeDialogClass *dialog_class;
-
- object_class = (GtkObjectClass*) klass;
- dialog_class = (GnomeDialogClass *) klass;
-
- parent_class = gtk_type_class (gnome_dialog_get_type ());
-
- gtk_object_add_arg_type ("EContactEditorAddress::address", GTK_TYPE_POINTER,
- GTK_ARG_READWRITE, ARG_ADDRESS);
- gtk_object_add_arg_type ("EContactEditorAddress::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_IS_READ_ONLY);
-
- object_class->set_arg = e_contact_editor_address_set_arg;
- object_class->get_arg = e_contact_editor_address_get_arg;
- object_class->destroy = e_contact_editor_address_destroy;
-}
-
-static GList *
-add_to_tab_order(GList *list, GladeXML *gui, char *name)
-{
- GtkWidget *widget = glade_xml_get_widget(gui, name);
- return g_list_prepend(list, widget);
-}
-
-static void
-setup_tab_order(GladeXML *gui)
-{
- GtkWidget *container;
- GList *list = NULL;
-
- container = glade_xml_get_widget(gui, "table-checkaddress");
-
- if (container) {
- list = add_to_tab_order(list, gui, "entry-city");
- list = add_to_tab_order(list, gui, "entry-region");
- list = add_to_tab_order(list, gui, "entry-code");
- list = add_to_tab_order(list, gui, "combo-country");
- list = g_list_reverse(list);
- e_container_change_tab_order(GTK_CONTAINER(container), list);
- g_list_free(list);
- }
-}
-
-static char * countries [] = {
- N_("United States"),
- N_("Afghanistan"),
- N_("Albania"),
- N_("Algeria"),
- N_("American Samoa"),
- N_("Andorra"),
- N_("Angola"),
- N_("Anguilla"),
- N_("Antarctica"),
- N_("Antigua And Barbuda"),
- N_("Argentina"),
- N_("Armenia"),
- N_("Aruba"),
- N_("Australia"),
- N_("Austria"),
- N_("Azerbaijan"),
- N_("Bahamas"),
- N_("Bahrain"),
- N_("Bangladesh"),
- N_("Barbados"),
- N_("Belarus"),
- N_("Belgium"),
- N_("Belize"),
- N_("Benin"),
- N_("Bermuda"),
- N_("Bhutan"),
- N_("Bolivia"),
- N_("Bosnia And Herzegowina"),
- N_("Botswana"),
- N_("Bouvet Island"),
- N_("Brazil"),
- N_("British Indian Ocean Territory"),
- N_("Brunei Darussalam"),
- N_("Bulgaria"),
- N_("Burkina Faso"),
- N_("Burundi"),
- N_("Cambodia"),
- N_("Cameroon"),
- N_("Canada"),
- N_("Cape Verde"),
- N_("Cayman Islands"),
- N_("Central African Republic"),
- N_("Chad"),
- N_("Chile"),
- N_("China"),
- N_("Christmas Island"),
- N_("Cocos (Keeling) Islands"),
- N_("Colombia"),
- N_("Comoros"),
- N_("Congo"),
- N_("Congo"),
- N_("Cook Islands"),
- N_("Costa Rica"),
- N_("Cote d'Ivoire"),
- N_("Croatia"),
- N_("Cuba"),
- N_("Cyprus"),
- N_("Czech Republic"),
- N_("Denmark"),
- N_("Djibouti"),
- N_("Dominica"),
- N_("Dominican Republic"),
- N_("East Timor"),
- N_("Ecuador"),
- N_("Egypt"),
- N_("El Salvador"),
- N_("Equatorial Guinea"),
- N_("Eritrea"),
- N_("Estonia"),
- N_("Ethiopia"),
- N_("Falkland Islands"),
- N_("Faroe Islands"),
- N_("Fiji"),
- N_("Finland"),
- N_("France"),
- N_("French Guiana"),
- N_("French Polynesia"),
- N_("French Southern Territories"),
- N_("Gabon"),
- N_("Gambia"),
- N_("Georgia"),
- N_("Germany"),
- N_("Ghana"),
- N_("Gibraltar"),
- N_("Greece"),
- N_("Greenland"),
- N_("Grenada"),
- N_("Guadeloupe"),
- N_("Guam"),
- N_("Guatemala"),
- N_("Guinea"),
- N_("Guinea-bissau"),
- N_("Guyana"),
- N_("Haiti"),
- N_("Heard And McDonald Islands"),
- N_("Holy See"),
- N_("Honduras"),
- N_("Hong Kong"),
- N_("Hungary"),
- N_("Iceland"),
- N_("India"),
- N_("Indonesia"),
- N_("Ireland"),
- N_("Israel"),
- N_("Italy"),
- N_("Jamaica"),
- N_("Japan"),
- N_("Jordan"),
- N_("Kazakhstan"),
- N_("Kenya"),
- N_("Kiribati"),
- N_("Korea, Republic Of"),
- N_("Kuwait"),
- N_("Kyrgyzstan"),
- N_("Laos"),
- N_("Latvia"),
- N_("Lebanon"),
- N_("Lesotho"),
- N_("Liberia"),
- N_("Liechtenstein"),
- N_("Lithuania"),
- N_("Luxembourg"),
- N_("Macau"),
- N_("Macedonia"),
- N_("Madagascar"),
- N_("Malawi"),
- N_("Malaysia"),
- N_("Maldives"),
- N_("Mali"),
- N_("Malta"),
- N_("Marshall Islands"),
- N_("Martinique"),
- N_("Mauritania"),
- N_("Mauritius"),
- N_("Mayotte"),
- N_("Mexico"),
- N_("Micronesia"),
- N_("Moldova, Republic Of"),
- N_("Monaco"),
- N_("Mongolia"),
- N_("Montserrat"),
- N_("Morocco"),
- N_("Mozambique"),
- N_("Myanmar"),
- N_("Namibia"),
- N_("Nauru"),
- N_("Nepal"),
- N_("Netherlands"),
- N_("Netherlands Antilles"),
- N_("New Caledonia"),
- N_("New Zealand"),
- N_("Nicaragua"),
- N_("Niger"),
- N_("Nigeria"),
- N_("Niue"),
- N_("Norfolk Island"),
- N_("Northern Mariana Islands"),
- N_("Norway"),
- N_("Oman"),
- N_("Pakistan"),
- N_("Palau"),
- N_("Palestinian Territory"),
- N_("Panama"),
- N_("Papua New Guinea"),
- N_("Paraguay"),
- N_("Peru"),
- N_("Philippines"),
- N_("Pitcairn"),
- N_("Poland"),
- N_("Portugal"),
- N_("Puerto Rico"),
- N_("Qatar"),
- N_("Reunion"),
- N_("Romania"),
- N_("Russian Federation"),
- N_("Rwanda"),
- N_("Saint Kitts And Nevis"),
- N_("Saint Lucia"),
- N_("Saint Vincent And The Grena-dines"),
- N_("Samoa"),
- N_("San Marino"),
- N_("Sao Tome And Principe"),
- N_("Saudi Arabia"),
- N_("Senegal"),
- N_("Seychelles"),
- N_("Sierra Leone"),
- N_("Singapore"),
- N_("Slovakia"),
- N_("Slovenia"),
- N_("Solomon Islands"),
- N_("Somalia"),
- N_("South Africa"),
- N_("South Georgia And The South Sandwich Islands"),
- N_("Spain"),
- N_("Sri Lanka"),
- N_("St. Helena"),
- N_("St. Pierre And Miquelon"),
- N_("Sudan"),
- N_("Suriname"),
- N_("Svalbard And Jan Mayen Islands"),
- N_("Swaziland"),
- N_("Sweden"),
- N_("Switzerland"),
- N_("Taiwan"),
- N_("Tajikistan"),
- N_("Tanzania, United Republic Of"),
- N_("Thailand"),
- N_("Togo"),
- N_("Tokelau"),
- N_("Tonga"),
- N_("Trinidad And Tobago"),
- N_("Tunisia"),
- N_("Turkey"),
- N_("Turkmenistan"),
- N_("Turks And Caicos Islands"),
- N_("Tuvalu"),
- N_("Uganda"),
- N_("Ukraine"),
- N_("United Arab Emirates"),
- N_("United Kingdom"),
- N_("United States Minor Outlying Islands"),
- N_("Uruguay"),
- N_("Uzbekistan"),
- N_("Vanuatu"),
- N_("Venezuela"),
- N_("Viet Nam"),
- N_("Virgin Islands, British"),
- N_("Virgin Islands, U.S."),
- N_("Wallis And Futuna Islands"),
- N_("Western Sahara"),
- N_("Yemen"),
- N_("Yugoslavia"),
- N_("Zambia"),
- N_("Zimbabwe"),
- NULL
-};
-
-static int
-compare_func (const void *voida, const void *voidb)
-{
- char * const *stringa = voida, * const *stringb = voidb;
-
- return strcoll (*stringa, *stringb);
-}
-
-static void
-fill_in_countries (GladeXML *gui)
-{
- GtkCombo *combo;
- combo = (GtkCombo *) glade_xml_get_widget(gui, "combo-country");
- if (combo && GTK_IS_COMBO (combo)) {
- static gboolean sorted = FALSE;
- static GList *country_list;
- if (!sorted) {
- int i;
- char *locale;
-
- for (i = 0; countries[i]; i++) {
- countries[i] = _(countries[i]);
- }
-
- locale = setlocale (LC_COLLATE, NULL);
- qsort (countries + 1, i - 1, sizeof (countries[0]), compare_func);
- country_list = NULL;
- for (i = 0; countries[i]; i++) {
- country_list = g_list_prepend (country_list, countries[i]);
- }
- country_list = g_list_reverse (country_list);
- sorted = TRUE;
- }
- gtk_combo_set_popdown_strings (combo, country_list);
- }
-}
-
-static void
-e_contact_editor_address_init (EContactEditorAddress *e_contact_editor_address)
-{
- GladeXML *gui;
- GtkWidget *widget;
- char *icon_path;
-
- gnome_dialog_append_button ( GNOME_DIALOG(e_contact_editor_address),
- GNOME_STOCK_BUTTON_OK);
-
- gnome_dialog_append_button ( GNOME_DIALOG(e_contact_editor_address),
- GNOME_STOCK_BUTTON_CANCEL);
-
- gtk_window_set_policy(GTK_WINDOW(e_contact_editor_address), FALSE, TRUE, FALSE);
-
- e_contact_editor_address->address = NULL;
-
- gui = glade_xml_new (EVOLUTION_GLADEDIR "/fulladdr.glade", NULL);
- e_contact_editor_address->gui = gui;
-
- setup_tab_order (gui);
- fill_in_countries (gui);
-
- widget = glade_xml_get_widget(gui, "dialog-checkaddress");
- gtk_window_set_title (GTK_WINDOW (e_contact_editor_address),
- GTK_WINDOW (widget)->title);
-
- widget = glade_xml_get_widget(gui, "table-checkaddress");
- gtk_widget_ref(widget);
- gtk_container_remove(GTK_CONTAINER(widget->parent), widget);
- gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (e_contact_editor_address)->vbox), widget, TRUE, TRUE, 0);
- gtk_widget_unref(widget);
-
- icon_path = g_concat_dir_and_file (EVOLUTION_ICONSDIR, "evolution-contacts-mini.png");
- gnome_window_icon_set_from_file (GTK_WINDOW (e_contact_editor_address), icon_path);
- g_free (icon_path);
-}
-
-void
-e_contact_editor_address_destroy (GtkObject *object)
-{
- EContactEditorAddress *e_contact_editor_address = E_CONTACT_EDITOR_ADDRESS(object);
-
- if (e_contact_editor_address->gui)
- gtk_object_unref(GTK_OBJECT(e_contact_editor_address->gui));
- e_card_delivery_address_unref(e_contact_editor_address->address);
-}
-
-GtkWidget*
-e_contact_editor_address_new (const ECardDeliveryAddress *address)
-{
- GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_contact_editor_address_get_type ()));
- gtk_object_set (GTK_OBJECT(widget),
- "address", address,
- NULL);
- return widget;
-}
-
-static void
-e_contact_editor_address_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
-{
- EContactEditorAddress *e_contact_editor_address;
-
- e_contact_editor_address = E_CONTACT_EDITOR_ADDRESS (o);
-
- switch (arg_id){
- case ARG_ADDRESS:
- e_card_delivery_address_unref(e_contact_editor_address->address);
- e_contact_editor_address->address = e_card_delivery_address_copy(GTK_VALUE_POINTER (*arg));
- fill_in_info(e_contact_editor_address);
- break;
- case ARG_IS_READ_ONLY: {
- int i;
- char *entry_names[] = {
- "entry-street",
- "entry-city",
- "entry-ext",
- "entry-po",
- "entry-region",
- "combo-country",
- "entry-code",
- NULL
- };
- e_contact_editor_address->editable = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE;
- for (i = 0; entry_names[i] != NULL; i ++) {
- GtkWidget *w = glade_xml_get_widget(e_contact_editor_address->gui, entry_names[i]);
- if (GTK_IS_ENTRY (w)) {
- gtk_entry_set_editable (GTK_ENTRY (w),
- e_contact_editor_address->editable);
- }
- else if (GTK_IS_COMBO (w)) {
- gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (w)->entry),
- e_contact_editor_address->editable);
- gtk_widget_set_sensitive (GTK_COMBO (w)->button, e_contact_editor_address->editable);
- }
- }
- break;
- }
- }
-}
-
-static void
-e_contact_editor_address_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- EContactEditorAddress *e_contact_editor_address;
-
- e_contact_editor_address = E_CONTACT_EDITOR_ADDRESS (object);
-
- switch (arg_id) {
- case ARG_ADDRESS:
- extract_info(e_contact_editor_address);
- GTK_VALUE_POINTER (*arg) = e_card_delivery_address_ref(e_contact_editor_address->address);
- break;
- case ARG_IS_READ_ONLY:
- GTK_VALUE_BOOL (*arg) = e_contact_editor_address->editable ? TRUE : FALSE;
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
-}
-
-static void
-fill_in_field(EContactEditorAddress *editor, char *field, char *string)
-{
- GtkEditable *editable = GTK_EDITABLE(glade_xml_get_widget(editor->gui, field));
- if (editable) {
- e_utf8_gtk_editable_set_text(editable, string);
- }
-}
-
-static void
-fill_in_info(EContactEditorAddress *editor)
-{
- ECardDeliveryAddress *address = editor->address;
- if (address) {
- fill_in_field(editor, "entry-street" , address->street );
- fill_in_field(editor, "entry-po" , address->po );
- fill_in_field(editor, "entry-ext" , address->ext );
- fill_in_field(editor, "entry-city" , address->city );
- fill_in_field(editor, "entry-region" , address->region );
- fill_in_field(editor, "entry-code" , address->code );
- fill_in_field(editor, "entry-country", address->country);
- }
-}
-
-static char *
-extract_field(EContactEditorAddress *editor, char *field)
-{
- GtkEditable *editable = GTK_EDITABLE(glade_xml_get_widget(editor->gui, field));
- if (editable)
- return e_utf8_gtk_editable_get_text(editable);
- else
- return NULL;
-}
-
-static void
-extract_info(EContactEditorAddress *editor)
-{
- ECardDeliveryAddress *address = editor->address;
- if (!address) {
- address = e_card_delivery_address_new();
- editor->address = address;
- }
- address->street = extract_field(editor, "entry-street" );
- address->po = extract_field(editor, "entry-po" );
- address->ext = extract_field(editor, "entry-ext" );
- address->city = extract_field(editor, "entry-city" );
- address->region = extract_field(editor, "entry-region" );
- address->code = extract_field(editor, "entry-code" );
- address->country = extract_field(editor, "entry-country");
-}
diff --git a/addressbook/gui/contact-editor/e-contact-editor-address.h b/addressbook/gui/contact-editor/e-contact-editor-address.h
deleted file mode 100644
index ff29c5b7ec..0000000000
--- a/addressbook/gui/contact-editor/e-contact-editor-address.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-contact-editor-address.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_EDITOR_ADDRESS_H__
-#define __E_CONTACT_EDITOR_ADDRESS_H__
-
-#include <libgnomeui/gnome-dialog.h>
-#include <glade/glade.h>
-#include <ebook/e-card.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* EContactEditorAddress - A dialog displaying information about a contact.
- *
- * The following arguments are available:
- *
- * name type read/write description
- * --------------------------------------------------------------------------------
- * name ECardName * RW The card currently being edited. Returns a copy.
- */
-
-#define E_CONTACT_EDITOR_ADDRESS_TYPE (e_contact_editor_address_get_type ())
-#define E_CONTACT_EDITOR_ADDRESS(obj) (GTK_CHECK_CAST ((obj), E_CONTACT_EDITOR_ADDRESS_TYPE, EContactEditorAddress))
-#define E_CONTACT_EDITOR_ADDRESS_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_CONTACT_EDITOR_ADDRESS_TYPE, EContactEditorAddressClass))
-#define E_IS_CONTACT_EDITOR_ADDRESS(obj) (GTK_CHECK_TYPE ((obj), E_CONTACT_EDITOR_ADDRESS_TYPE))
-#define E_IS_CONTACT_EDITOR_ADDRESS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_CONTACT_EDITOR_ADDRESS_TYPE))
-
-
-typedef struct _EContactEditorAddress EContactEditorAddress;
-typedef struct _EContactEditorAddressClass EContactEditorAddressClass;
-
-struct _EContactEditorAddress
-{
- GnomeDialog parent;
-
- /* item specific fields */
- ECardDeliveryAddress *address;
-
- guint editable : 1;
-
- GladeXML *gui;
-};
-
-struct _EContactEditorAddressClass
-{
- GnomeDialogClass parent_class;
-};
-
-
-GtkWidget *e_contact_editor_address_new(const ECardDeliveryAddress *name);
-GtkType e_contact_editor_address_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __E_CONTACT_EDITOR_ADDRESS_H__ */
diff --git a/addressbook/gui/contact-editor/e-contact-editor-confirm-delete.glade b/addressbook/gui/contact-editor/e-contact-editor-confirm-delete.glade
deleted file mode 100644
index b91a040d46..0000000000
--- a/addressbook/gui/contact-editor/e-contact-editor-confirm-delete.glade
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>e-contact-editor-confirm-delete</name>
- <program_name>e-contact-editor-confirm-delete</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
- <use_widget_names>True</use_widget_names>
- <output_main_file>False</output_main_file>
- <output_support_files>False</output_support_files>
- <output_build_files>False</output_build_files>
- <gnome_help_support>True</gnome_help_support>
-</project>
-
-<widget>
- <class>GnomeMessageBox</class>
- <name>confirm-dialog</name>
- <message_box_type>GNOME_MESSAGE_BOX_QUESTION</message_box_type>
- <message>Are you sure you want
-to delete this contact?</message>
- <title>Delete Contact?</title>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>False</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>True</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>dialog-vbox1</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>dialog-action_area1</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button1</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button2</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/addressbook/gui/contact-editor/e-contact-editor-fullname.c b/addressbook/gui/contact-editor/e-contact-editor-fullname.c
index 8d602657c0..4777091128 100644
--- a/addressbook/gui/contact-editor/e-contact-editor-fullname.c
+++ b/addressbook/gui/contact-editor/e-contact-editor-fullname.c
@@ -1,260 +1,329 @@
-/* -*- 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>
- *
- * 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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
-#include <libgnomeui/gnome-stock.h>
-#include <gal/widgets/e-unicode.h>
-#include "e-contact-editor-fullname.h"
-#include <libgnomeui/gnome-window-icon.h>
-#include <libgnome/gnome-util.h>
-#include <gtk/gtkcombo.h>
+#endif
-static void e_contact_editor_fullname_init (EContactEditorFullname *card);
-static void e_contact_editor_fullname_class_init (EContactEditorFullnameClass *klass);
-static void e_contact_editor_fullname_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_contact_editor_fullname_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_contact_editor_fullname_destroy (GtkObject *object);
+#include <glib/gi18n.h>
-static void fill_in_info(EContactEditorFullname *editor);
-static void extract_info(EContactEditorFullname *editor);
+#include "e-util/e-util.h"
+#include "e-util/e-util-private.h"
-static GnomeDialogClass *parent_class = NULL;
+#include "e-contact-editor-fullname.h"
+
+static void fill_in_info (EContactEditorFullname *editor);
+static void extract_info (EContactEditorFullname *editor);
-/* The arguments we take */
enum {
- ARG_0,
- ARG_NAME,
- ARG_IS_READ_ONLY
+ PROP_0,
+ PROP_NAME,
+ PROP_EDITABLE
};
-GtkType
-e_contact_editor_fullname_get_type (void)
-{
- static GtkType contact_editor_fullname_type = 0;
-
- if (!contact_editor_fullname_type)
- {
- static const GtkTypeInfo contact_editor_fullname_info =
- {
- "EContactEditorFullname",
- sizeof (EContactEditorFullname),
- sizeof (EContactEditorFullnameClass),
- (GtkClassInitFunc) e_contact_editor_fullname_class_init,
- (GtkObjectInitFunc) e_contact_editor_fullname_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- contact_editor_fullname_type = gtk_type_unique (gnome_dialog_get_type (), &contact_editor_fullname_info);
- }
-
- return contact_editor_fullname_type;
-}
+G_DEFINE_TYPE (
+ EContactEditorFullname,
+ e_contact_editor_fullname,
+ GTK_TYPE_DIALOG)
static void
-e_contact_editor_fullname_class_init (EContactEditorFullnameClass *klass)
+e_contact_editor_fullname_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GtkObjectClass *object_class;
- GnomeDialogClass *dialog_class;
-
- object_class = (GtkObjectClass*) klass;
- dialog_class = (GnomeDialogClass *) klass;
+ EContactEditorFullname *e_contact_editor_fullname;
- parent_class = gtk_type_class (gnome_dialog_get_type ());
+ e_contact_editor_fullname = E_CONTACT_EDITOR_FULLNAME (object);
- gtk_object_add_arg_type ("EContactEditorFullname::name", GTK_TYPE_POINTER,
- GTK_ARG_READWRITE, ARG_NAME);
+ switch (property_id) {
+ case PROP_NAME:
+ e_contact_name_free (e_contact_editor_fullname->name);
- gtk_object_add_arg_type ("EContactEditorFullname::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_IS_READ_ONLY);
-
- object_class->set_arg = e_contact_editor_fullname_set_arg;
- object_class->get_arg = e_contact_editor_fullname_get_arg;
- object_class->destroy = e_contact_editor_fullname_destroy;
-}
+ if (g_value_get_pointer (value) != NULL) {
+ e_contact_editor_fullname->name =
+ e_contact_name_copy (
+ g_value_get_pointer (value));
+ fill_in_info (e_contact_editor_fullname);
+ }
+ else {
+ e_contact_editor_fullname->name = NULL;
+ }
+ break;
+ case PROP_EDITABLE: {
+ gboolean editable;
+ gint i;
-static void
-e_contact_editor_fullname_init (EContactEditorFullname *e_contact_editor_fullname)
-{
- GladeXML *gui;
- GtkWidget *widget;
- char *icon_path;
+ const gchar *widget_names[] = {
+ "comboentry-title",
+ "comboentry-suffix",
+ "entry-first",
+ "entry-middle",
+ "entry-last",
+ "label-title",
+ "label-suffix",
+ "label-first",
+ "label-middle",
+ "label-last",
+ NULL
+ };
- gnome_dialog_append_button ( GNOME_DIALOG(e_contact_editor_fullname),
- GNOME_STOCK_BUTTON_OK);
-
- gnome_dialog_append_button ( GNOME_DIALOG(e_contact_editor_fullname),
- GNOME_STOCK_BUTTON_CANCEL);
+ editable = g_value_get_boolean (value);
+ e_contact_editor_fullname->editable = editable;
- gtk_window_set_policy(GTK_WINDOW(e_contact_editor_fullname), TRUE, TRUE, FALSE);
+ for (i = 0; widget_names[i] != NULL; i++) {
+ GtkWidget *widget;
- e_contact_editor_fullname->name = NULL;
- gui = glade_xml_new (EVOLUTION_GLADEDIR "/fullname.glade", NULL);
- e_contact_editor_fullname->gui = gui;
-
- widget = glade_xml_get_widget(gui, "dialog-checkfullname");
- gtk_window_set_title (GTK_WINDOW (e_contact_editor_fullname),
- GTK_WINDOW (widget)->title);
-
- widget = glade_xml_get_widget(gui, "table-checkfullname");
- gtk_widget_ref(widget);
- gtk_container_remove(GTK_CONTAINER(widget->parent), widget);
- gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (e_contact_editor_fullname)->vbox), widget, TRUE, TRUE, 0);
- gtk_widget_unref(widget);
-
- icon_path = g_concat_dir_and_file (EVOLUTION_ICONSDIR, "evolution-contacts-mini.png");
- gnome_window_icon_set_from_file (GTK_WINDOW (e_contact_editor_fullname), icon_path);
- g_free (icon_path);
-}
+ widget = e_builder_get_widget (
+ e_contact_editor_fullname->builder,
+ widget_names[i]);
-void
-e_contact_editor_fullname_destroy (GtkObject *object)
-{
- EContactEditorFullname *e_contact_editor_fullname = E_CONTACT_EDITOR_FULLNAME(object);
+ if (GTK_IS_ENTRY (widget)) {
+ gtk_editable_set_editable (
+ GTK_EDITABLE (widget), editable);
- if (e_contact_editor_fullname->gui)
- gtk_object_unref(GTK_OBJECT(e_contact_editor_fullname->gui));
- e_card_name_unref(e_contact_editor_fullname->name);
-}
+ } else if (GTK_IS_COMBO_BOX (widget)) {
+ GtkWidget *child;
-GtkWidget*
-e_contact_editor_fullname_new (const ECardName *name)
-{
- GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_contact_editor_fullname_get_type ()));
- gtk_object_set (GTK_OBJECT(widget),
- "name", name,
- NULL);
- return widget;
-}
+ child = gtk_bin_get_child (GTK_BIN (widget));
-static void
-e_contact_editor_fullname_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
-{
- EContactEditorFullname *e_contact_editor_fullname;
+ gtk_editable_set_editable (
+ GTK_EDITABLE (child), editable);
+ gtk_widget_set_sensitive (widget, editable);
- e_contact_editor_fullname = E_CONTACT_EDITOR_FULLNAME (o);
-
- switch (arg_id){
- case ARG_NAME:
- e_card_name_unref(e_contact_editor_fullname->name);
- e_contact_editor_fullname->name = e_card_name_copy(GTK_VALUE_POINTER (*arg));
- fill_in_info(e_contact_editor_fullname);
- break;
- case ARG_IS_READ_ONLY: {
- int i;
- char *entry_names[] = {
- "combo-title",
- "combo-suffix",
- "entry-first",
- "entry-middle",
- "entry-last",
- NULL
- };
- e_contact_editor_fullname->editable = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE;
- for (i = 0; entry_names[i] != NULL; i ++) {
- GtkWidget *w = glade_xml_get_widget(e_contact_editor_fullname->gui, entry_names[i]);
- if (GTK_IS_ENTRY (w)) {
- gtk_entry_set_editable (GTK_ENTRY (w),
- e_contact_editor_fullname->editable);
- }
- else if (GTK_IS_COMBO (w)) {
- gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (w)->entry),
- e_contact_editor_fullname->editable);
- gtk_widget_set_sensitive (GTK_COMBO (w)->button, e_contact_editor_fullname->editable);
+ } else if (GTK_IS_LABEL (widget)) {
+ gtk_widget_set_sensitive (widget, editable);
}
}
break;
}
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
static void
-e_contact_editor_fullname_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+e_contact_editor_fullname_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
EContactEditorFullname *e_contact_editor_fullname;
e_contact_editor_fullname = E_CONTACT_EDITOR_FULLNAME (object);
- switch (arg_id) {
- case ARG_NAME:
- extract_info(e_contact_editor_fullname);
- GTK_VALUE_POINTER (*arg) = e_card_name_ref(e_contact_editor_fullname->name);
+ switch (property_id) {
+ case PROP_NAME:
+ extract_info (e_contact_editor_fullname);
+ g_value_set_pointer (
+ value, e_contact_name_copy (
+ e_contact_editor_fullname->name));
break;
- case ARG_IS_READ_ONLY:
- GTK_VALUE_BOOL (*arg) = e_contact_editor_fullname->editable ? TRUE : FALSE;
+ case PROP_EDITABLE:
+ g_value_set_boolean (
+ value, e_contact_editor_fullname->editable);
break;
default:
- arg->type = GTK_TYPE_INVALID;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
-fill_in_field(EContactEditorFullname *editor, char *field, char *string)
+e_contact_editor_fullname_dispose (GObject *object)
+{
+ EContactEditorFullname *e_contact_editor_fullname;
+
+ e_contact_editor_fullname = E_CONTACT_EDITOR_FULLNAME (object);
+
+ if (e_contact_editor_fullname->builder) {
+ g_object_unref (e_contact_editor_fullname->builder);
+ e_contact_editor_fullname->builder = NULL;
+ }
+
+ if (e_contact_editor_fullname->name) {
+ e_contact_name_free (e_contact_editor_fullname->name);
+ e_contact_editor_fullname->name = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_contact_editor_fullname_parent_class)->dispose (object);
+}
+
+static void
+e_contact_editor_fullname_class_init (EContactEditorFullnameClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = e_contact_editor_fullname_set_property;
+ object_class->get_property = e_contact_editor_fullname_get_property;
+ object_class->dispose = e_contact_editor_fullname_dispose;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_NAME,
+ g_param_spec_pointer (
+ "name",
+ "Name",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ "Editable",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+}
+
+static void
+e_contact_editor_fullname_init (EContactEditorFullname *e_contact_editor_fullname)
+{
+ GtkBuilder *builder;
+ GtkDialog *dialog;
+ GtkWidget *parent;
+ GtkWidget *widget;
+ GtkWidget *action_area;
+ GtkWidget *content_area;
+ const gchar *title;
+
+ dialog = GTK_DIALOG (e_contact_editor_fullname);
+ action_area = gtk_dialog_get_action_area (dialog);
+ content_area = gtk_dialog_get_content_area (dialog);
+
+ gtk_widget_realize (GTK_WIDGET (e_contact_editor_fullname));
+ gtk_container_set_border_width (GTK_CONTAINER (action_area), 12);
+ gtk_container_set_border_width (GTK_CONTAINER (content_area), 0);
+
+ gtk_dialog_add_buttons (
+ dialog,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+
+ gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+
+ e_contact_editor_fullname->name = NULL;
+
+ builder = gtk_builder_new ();
+ e_load_ui_builder_definition (builder, "fullname.ui");
+
+ e_contact_editor_fullname->builder = builder;
+
+ widget = e_builder_get_widget (builder, "dialog-checkfullname");
+ title = gtk_window_get_title (GTK_WINDOW (widget));
+ gtk_window_set_title (GTK_WINDOW (e_contact_editor_fullname), title);
+
+ widget = e_builder_get_widget (builder, "table-checkfullname");
+ parent = gtk_widget_get_parent (widget);
+ g_object_ref (widget);
+ gtk_container_remove (GTK_CONTAINER (parent), widget);
+ gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0);
+ g_object_unref (widget);
+
+ gtk_window_set_icon_name (
+ GTK_WINDOW (e_contact_editor_fullname), "contact-new");
+}
+
+GtkWidget *
+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);
+ return widget;
+}
+
+static void
+fill_in_field (EContactEditorFullname *editor,
+ const gchar *field,
+ const gchar *string)
{
- GtkEntry *entry = GTK_ENTRY(glade_xml_get_widget(editor->gui, field));
+ GtkWidget *widget = e_builder_get_widget (editor->builder, field);
+ GtkEntry *entry = NULL;
+
+ if (GTK_IS_ENTRY (widget))
+ entry = GTK_ENTRY (widget);
+ else if (GTK_IS_COMBO_BOX (widget))
+ entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (widget)));
+
if (entry) {
if (string)
- e_utf8_gtk_entry_set_text(entry, string);
+ gtk_entry_set_text (entry, string);
else
- gtk_entry_set_text(entry, "");
+ gtk_entry_set_text (entry, "");
}
}
static void
-fill_in_info(EContactEditorFullname *editor)
+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-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, "comboentry-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, "comboentry-suffix", name->suffixes);
}
}
-static char *
-extract_field(EContactEditorFullname *editor, char *field)
+static gchar *
+extract_field (EContactEditorFullname *editor,
+ const gchar *field)
{
- GtkEntry *entry = GTK_ENTRY(glade_xml_get_widget(editor->gui, field));
+ GtkWidget *widget = e_builder_get_widget (editor->builder, field);
+ GtkEntry *entry = NULL;
+
+ if (GTK_IS_ENTRY (widget))
+ entry = GTK_ENTRY (widget);
+ else if (GTK_IS_COMBO_BOX (widget))
+ entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (widget)));
+
if (entry)
- return e_utf8_gtk_entry_get_text(entry);
+ return g_strdup (gtk_entry_get_text (entry));
else
return NULL;
}
static void
-extract_info(EContactEditorFullname *editor)
+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->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->prefixes = extract_field (editor, "comboentry-title");
+ name->given = extract_field (editor, "entry-first");
+ name->additional = extract_field (editor, "entry-middle");
+ name->family = extract_field (editor, "entry-last");
+ name->suffixes = extract_field (editor, "comboentry-suffix");
}
diff --git a/addressbook/gui/contact-editor/e-contact-editor-fullname.h b/addressbook/gui/contact-editor/e-contact-editor-fullname.h
index 0d09b13700..51a9e28db9 100644
--- a/addressbook/gui/contact-editor/e-contact-editor-fullname.h
+++ b/addressbook/gui/contact-editor/e-contact-editor-fullname.h
@@ -1,33 +1,32 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-contact-editor-fullname.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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_EDITOR_FULLNAME_H__
#define __E_CONTACT_EDITOR_FULLNAME_H__
-#include <libgnomeui/gnome-dialog.h>
-#include <glade/glade.h>
-#include <ebook/e-card.h>
+#include <gtk/gtk.h>
+#include <libebook/libebook.h>
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
+G_BEGIN_DECLS
/* EContactEditorFullname - A dialog displaying information about a contact.
*
@@ -38,23 +37,22 @@ extern "C" {
* name ECardName * RW The card currently being edited. Returns a copy.
*/
-#define E_CONTACT_EDITOR_FULLNAME_TYPE (e_contact_editor_fullname_get_type ())
-#define E_CONTACT_EDITOR_FULLNAME(obj) (GTK_CHECK_CAST ((obj), E_CONTACT_EDITOR_FULLNAME_TYPE, EContactEditorFullname))
-#define E_CONTACT_EDITOR_FULLNAME_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_CONTACT_EDITOR_FULLNAME_TYPE, EContactEditorFullnameClass))
-#define E_IS_CONTACT_EDITOR_FULLNAME(obj) (GTK_CHECK_TYPE ((obj), E_CONTACT_EDITOR_FULLNAME_TYPE))
-#define E_IS_CONTACT_EDITOR_FULLNAME_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_CONTACT_EDITOR_FULLNAME_TYPE))
-
+#define E_TYPE_CONTACT_EDITOR_FULLNAME (e_contact_editor_fullname_get_type ())
+#define E_CONTACT_EDITOR_FULLNAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CONTACT_EDITOR_FULLNAME, EContactEditorFullname))
+#define E_CONTACT_EDITOR_FULLNAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CONTACT_EDITOR_FULLNAME, EContactEditorFullnameClass))
+#define E_IS_CONTACT_EDITOR_FULLNAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CONTACT_EDITOR_FULLNAME))
+#define E_IS_CONTACT_EDITOR_FULLNAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_CONTACT_EDITOR_FULLNAME))
typedef struct _EContactEditorFullname EContactEditorFullname;
typedef struct _EContactEditorFullnameClass EContactEditorFullnameClass;
struct _EContactEditorFullname
{
- GnomeDialog parent;
-
+ GtkDialog parent;
+
/* item specific fields */
- ECardName *name;
- GladeXML *gui;
+ EContactName *name;
+ GtkBuilder *builder;
/* Whether the dialog will accept modifications */
guint editable : 1;
@@ -62,16 +60,12 @@ struct _EContactEditorFullname
struct _EContactEditorFullnameClass
{
- GnomeDialogClass parent_class;
+ GtkDialogClass parent_class;
};
+GtkWidget *e_contact_editor_fullname_new (const EContactName *name);
+GType e_contact_editor_fullname_get_type (void);
-GtkWidget *e_contact_editor_fullname_new(const ECardName *name);
-GtkType e_contact_editor_fullname_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
+G_END_DECLS
#endif /* __E_CONTACT_EDITOR_FULLNAME_H__ */
diff --git a/addressbook/gui/contact-editor/e-contact-editor.c b/addressbook/gui/contact-editor/e-contact-editor.c
index f22aaa5487..0d3f41e2d5 100644
--- a/addressbook/gui/contact-editor/e-contact-editor.c
+++ b/addressbook/gui/contact-editor/e-contact-editor.c
@@ -1,110 +1,112 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-contact-editor.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
+#include "eab-editor.h"
#include "e-contact-editor.h"
+#include <stdlib.h>
+#include <string.h>
#include <time.h>
-#include <gtk/gtkcheckbutton.h>
-#include <gtk/gtkcheckmenuitem.h>
-#include <gtk/gtkcombo.h>
-#include <gtk/gtktext.h>
-#include <libgnomeui/gnome-popup-menu.h>
-#include <libgnomeui/gnome-dialog-util.h>
-#include <libgnomeui/gnome-window-icon.h>
-#include <libgnomeui/gnome-stock.h>
-#include <libgnome/gnome-i18n.h>
-
-#include <bonobo/bonobo-ui-container.h>
-#include <bonobo/bonobo-ui-util.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gdk-pixbuf/gnome-canvas-pixbuf.h>
-#include <gal/widgets/e-categories.h>
-#include <gal/widgets/e-gui-utils.h>
-#include <gal/widgets/e-unicode.h>
-#include <gal/e-text/e-entry.h>
-#include <e-util/e-categories-master-list-wombat.h>
+#include "shell/e-shell.h"
#include "addressbook/printing/e-contact-print.h"
-#include "addressbook/printing/e-contact-print-envelope.h"
-#include "addressbook/gui/widgets/e-addressbook-util.h"
-#include "e-util/e-gui-utils.h"
-#include "widgets/misc/e-dateedit.h"
-#include "shell/evolution-shell-component-utils.h"
+#include "addressbook/gui/widgets/eab-gui-util.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-save-as.h"
-/* Signal IDs */
+#define EMAIL_SLOTS 4
+#define PHONE_SLOTS 8
+#define IM_SLOTS 4
+#define ADDRESS_SLOTS 3
+
+#define EVOLUTION_UI_SLOT_PARAM "X-EVOLUTION-UI-SLOT"
+
+/* IM columns */
enum {
- CARD_ADDED,
- CARD_MODIFIED,
- CARD_DELETED,
- EDITOR_CLOSED,
- LAST_SIGNAL
+ COLUMN_IM_ICON,
+ COLUMN_IM_SERVICE,
+ COLUMN_IM_SCREENNAME,
+ COLUMN_IM_LOCATION,
+ COLUMN_IM_LOCATION_TYPE,
+ COLUMN_IM_SERVICE_FIELD,
+ NUM_IM_COLUMNS
};
-static void e_contact_editor_init (EContactEditor *card);
-static void e_contact_editor_class_init (EContactEditorClass *klass);
-static void e_contact_editor_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_contact_editor_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_contact_editor_destroy (GtkObject *object);
+typedef struct {
+ EContactEditor *editor;
+ ESource *source;
+} ConnectClosure;
+
+static void e_contact_editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void e_contact_editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void e_contact_editor_dispose (GObject *object);
+static void e_contact_editor_raise (EABEditor *editor);
+static void e_contact_editor_show (EABEditor *editor);
+static void e_contact_editor_save_contact (EABEditor *editor,
+ gboolean should_close);
+static void e_contact_editor_close (EABEditor *editor);
+static gboolean e_contact_editor_is_valid (EABEditor *editor);
+static gboolean e_contact_editor_is_changed (EABEditor *editor);
+static GtkWindow *
+ e_contact_editor_get_window (EABEditor *editor);
+static void save_contact (EContactEditor *ce,
+ gboolean should_close);
+static void entry_activated (EContactEditor *editor);
+
+static void set_entry_text (EContactEditor *editor,
+ GtkEntry *entry,
+ const gchar *string);
+static void sensitize_ok (EContactEditor *ce);
+
+static EABEditorClass *parent_class = NULL;
-#if 0
-static GtkWidget *e_contact_editor_build_dialog(EContactEditor *editor, gchar *entry_id, gchar *label_id, gchar *title, GList **list, GnomeUIInfo **info);
-#endif
-static void _email_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor);
-static void _phone_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor);
-static void _address_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor);
-static void find_address_mailing (EContactEditor *editor);
-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_address_field(EContactEditor *editor, int result);
-static void add_field_callback(GtkWidget *widget, EContactEditor *editor);
-static void command_state_changed (EContactEditor *ce);
-static void widget_changed (GtkWidget *widget, EContactEditor *editor);
-static void close_dialog (EContactEditor *ce);
-static void enable_widget (GtkWidget *widget, gboolean enabled);
-
-static GtkObjectClass *parent_class = NULL;
-
-static guint contact_editor_signals[LAST_SIGNAL];
-
-/* The arguments we take */
enum {
- ARG_0,
- ARG_BOOK,
- ARG_CARD,
- ARG_IS_NEW_CARD,
- ARG_EDITABLE,
- ARG_CHANGED,
- ARG_WRITABLE_FIELDS
+ PROP_0,
+ PROP_SOURCE_CLIENT,
+ PROP_TARGET_CLIENT,
+ PROP_CONTACT,
+ PROP_IS_NEW_CONTACT,
+ PROP_EDITABLE,
+ PROP_CHANGED,
+ PROP_WRITABLE_FIELDS,
+ PROP_REQUIRED_FIELDS
};
enum {
@@ -113,299 +115,319 @@ enum {
DYNAMIC_LIST_ADDRESS
};
-static GSList *all_contact_editors = NULL;
-
-GtkType
-e_contact_editor_get_type (void)
-{
- static GtkType contact_editor_type = 0;
-
- if (!contact_editor_type)
- {
- static const GtkTypeInfo contact_editor_info =
- {
- "EContactEditor",
- sizeof (EContactEditor),
- sizeof (EContactEditorClass),
- (GtkClassInitFunc) e_contact_editor_class_init,
- (GtkObjectInitFunc) e_contact_editor_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- contact_editor_type = gtk_type_unique (GTK_TYPE_OBJECT, &contact_editor_info);
- }
-
- return contact_editor_type;
-}
-
-typedef void (*GtkSignal_NONE__INT_OBJECT) (GtkObject * object,
- gint arg1,
- GtkObject *arg2,
- gpointer user_data);
-
-static void
-e_marshal_NONE__INT_OBJECT (GtkObject * object,
- GtkSignalFunc func,
- gpointer func_data, GtkArg * args)
-{
- GtkSignal_NONE__INT_OBJECT rfunc;
- rfunc = (GtkSignal_NONE__INT_OBJECT) func;
- (*rfunc) (object,
- GTK_VALUE_INT (args[0]),
- GTK_VALUE_OBJECT (args[1]),
- func_data);
+static struct {
+ EContactField field_id;
+ const gchar *type_1;
+ const gchar *type_2;
}
+phones[] = {
+ { E_CONTACT_PHONE_ASSISTANT, EVC_X_ASSISTANT, NULL },
+ { E_CONTACT_PHONE_BUSINESS, "WORK", "VOICE" },
+ { E_CONTACT_PHONE_BUSINESS_FAX, "WORK", "FAX" },
+ { E_CONTACT_PHONE_CALLBACK, EVC_X_CALLBACK, NULL },
+ { E_CONTACT_PHONE_CAR, "CAR", NULL },
+ { E_CONTACT_PHONE_COMPANY, "X-EVOLUTION-COMPANY", NULL },
+ { E_CONTACT_PHONE_HOME, "HOME", "VOICE" },
+ { E_CONTACT_PHONE_HOME_FAX, "HOME", "FAX" },
+ { E_CONTACT_PHONE_ISDN, "ISDN", NULL },
+ { E_CONTACT_PHONE_MOBILE, "CELL", NULL },
+ { E_CONTACT_PHONE_OTHER, "VOICE", NULL },
+ { E_CONTACT_PHONE_OTHER_FAX, "FAX", NULL },
+ { E_CONTACT_PHONE_PAGER, "PAGER", NULL },
+ { E_CONTACT_PHONE_PRIMARY, "PREF", NULL },
+ { E_CONTACT_PHONE_RADIO, EVC_X_RADIO, NULL },
+ { E_CONTACT_PHONE_TELEX, EVC_X_TELEX, NULL },
+ { E_CONTACT_PHONE_TTYTDD, EVC_X_TTYTDD, NULL }
+};
-static void
-e_contact_editor_class_init (EContactEditorClass *klass)
-{
- GtkObjectClass *object_class;
+/* Defaults from the table above */
+static const gint phones_default[] = { 1, 6, 9, 2, 7, 12, 10, 10 };
- object_class = (GtkObjectClass*) klass;
+static EContactField addresses[] = {
+ E_CONTACT_ADDRESS_WORK,
+ E_CONTACT_ADDRESS_HOME,
+ E_CONTACT_ADDRESS_OTHER
+};
- parent_class = gtk_type_class (GTK_TYPE_OBJECT);
+static EContactField address_labels[] = {
+ E_CONTACT_ADDRESS_LABEL_WORK,
+ E_CONTACT_ADDRESS_LABEL_HOME,
+ E_CONTACT_ADDRESS_LABEL_OTHER
+};
- gtk_object_add_arg_type ("EContactEditor::book", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_BOOK);
- gtk_object_add_arg_type ("EContactEditor::card", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_CARD);
- gtk_object_add_arg_type ("EContactEditor::is_new_card", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_IS_NEW_CARD);
- gtk_object_add_arg_type ("EContactEditor::writable_fields", GTK_TYPE_POINTER,
- GTK_ARG_READWRITE, ARG_WRITABLE_FIELDS);
- gtk_object_add_arg_type ("EContactEditor::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
- gtk_object_add_arg_type ("EContactEditor::changed", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_CHANGED);
+static const gchar *address_name[] = {
+ "work",
+ "home",
+ "other"
+};
- contact_editor_signals[CARD_ADDED] =
- gtk_signal_new ("card_added",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EContactEditorClass, card_added),
- e_marshal_NONE__INT_OBJECT,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_INT, GTK_TYPE_OBJECT);
+static struct {
+ EContactField field;
+ const gchar *pretty_name;
+}
+im_service[] =
+{
+ { E_CONTACT_IM_AIM, N_ ("AIM") },
+ { E_CONTACT_IM_JABBER, N_ ("Jabber") },
+ { E_CONTACT_IM_YAHOO, N_ ("Yahoo") },
+ { E_CONTACT_IM_GADUGADU, N_ ("Gadu-Gadu") },
+ { E_CONTACT_IM_MSN, N_ ("MSN") },
+ { E_CONTACT_IM_ICQ, N_ ("ICQ") },
+ { E_CONTACT_IM_GROUPWISE, N_ ("GroupWise") },
+ { E_CONTACT_IM_SKYPE, N_ ("Skype") },
+ { E_CONTACT_IM_TWITTER, N_ ("Twitter") }
+};
- contact_editor_signals[CARD_MODIFIED] =
- gtk_signal_new ("card_modified",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EContactEditorClass, card_modified),
- e_marshal_NONE__INT_OBJECT,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_INT, GTK_TYPE_OBJECT);
+/* Defaults from the table above */
+static const gint im_service_default[] = { 0, 2, 4, 5 };
- contact_editor_signals[CARD_DELETED] =
- gtk_signal_new ("card_deleted",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EContactEditorClass, card_deleted),
- e_marshal_NONE__INT_OBJECT,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_INT, GTK_TYPE_OBJECT);
+static struct {
+ const gchar *name;
+ const gchar *pretty_name;
+}
+common_location[] =
+{
+ { "WORK", N_ ("Work") },
+ { "HOME", N_ ("Home") },
+ { "OTHER", N_ ("Other") }
+};
- contact_editor_signals[EDITOR_CLOSED] =
- gtk_signal_new ("editor_closed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EContactEditorClass, editor_closed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
+/* Default from the table above */
+static const gint email_default[] = { 0, 1, 2, 2 };
- gtk_object_class_add_signals (object_class, contact_editor_signals, LAST_SIGNAL);
-
- object_class->set_arg = e_contact_editor_set_arg;
- object_class->get_arg = e_contact_editor_get_arg;
- object_class->destroy = e_contact_editor_destroy;
-}
-
-static void
-_replace_button(EContactEditor *editor, gchar *button_xml, gchar *image, GtkSignalFunc func)
-{
- GladeXML *gui = editor->gui;
- GtkWidget *button = glade_xml_get_widget(gui, button_xml);
- GtkWidget *pixmap;
- gchar *image_temp;
- if (button && GTK_IS_BUTTON(button)) {
- image_temp = g_strdup_printf("%s/%s", EVOLUTIONDIR, image);
- pixmap = e_create_image_widget(NULL, image_temp, NULL, 0, 0);
- gtk_container_add(GTK_CONTAINER(button),
- pixmap);
- g_free(image_temp);
- gtk_widget_show(pixmap);
- gtk_signal_connect(GTK_OBJECT(button), "button_press_event", func, editor);
- }
-}
+#define STRING_IS_EMPTY(x) (!(x) || !(*(x)))
+#define STRING_MAKE_NON_NULL(x) ((x) ? (x) : "")
-static void
-_replace_buttons(EContactEditor *editor)
+G_DEFINE_TYPE (EContactEditor, e_contact_editor, EAB_TYPE_EDITOR)
+
+static void
+connect_closure_free (ConnectClosure *connect_closure)
{
- _replace_button(editor, "button-phone1", "arrow.png", _phone_arrow_pressed);
- _replace_button(editor, "button-phone2", "arrow.png", _phone_arrow_pressed);
- _replace_button(editor, "button-phone3", "arrow.png", _phone_arrow_pressed);
- _replace_button(editor, "button-phone4", "arrow.png", _phone_arrow_pressed);
- _replace_button(editor, "button-address", "arrow.png", _address_arrow_pressed);
- _replace_button(editor, "button-email1", "arrow.png", _email_arrow_pressed);
+ if (connect_closure->editor != NULL)
+ g_object_unref (connect_closure->editor);
+
+ if (connect_closure->source != NULL)
+ g_object_unref (connect_closure->source);
+
+ g_slice_free (ConnectClosure, connect_closure);
}
-
-static void
-wants_html_changed (GtkWidget *widget, EContactEditor *editor)
+
+static void
+e_contact_editor_contact_added (EABEditor *editor,
+ const GError *error,
+ EContact *contact)
{
- gboolean wants_html;
- gtk_object_get(GTK_OBJECT(widget),
- "active", &wants_html,
- NULL);
- gtk_object_set(GTK_OBJECT(editor->card),
- "wants_html", wants_html,
- NULL);
-
- widget_changed (widget, editor);
-}
-
-static void
-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") ) {
- which = 1;
- } else if ( widget == glade_xml_get_widget(editor->gui, "entry-phone2") ) {
- which = 2;
- } else if ( widget == glade_xml_get_widget(editor->gui, "entry-phone3") ) {
- which = 3;
- } else if ( widget == glade_xml_get_widget(editor->gui, "entry-phone4") ) {
- which = 4;
- } else
+ if (!error)
+ return;
+
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
return;
- phone = e_card_phone_new();
- phone->number = e_utf8_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);
- widget_changed (widget, editor);
+ eab_error_dialog (NULL, eab_editor_get_window (editor), _("Error adding contact"), error);
}
static void
-email_entry_changed (GtkWidget *widget, EContactEditor *editor)
+e_contact_editor_contact_modified (EABEditor *editor,
+ const GError *error,
+ EContact *contact)
{
- gchar *string;
- GtkEntry *entry = GTK_ENTRY(widget);
-
- string = e_utf8_gtk_entry_get_text(entry);
-
- e_card_simple_set_email(editor->simple, editor->email_choice, string);
+ if (!error)
+ return;
- g_free (string);
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
- widget_changed (widget, editor);
+ eab_error_dialog (NULL, eab_editor_get_window (editor), _("Error modifying contact"), error);
}
static void
-address_text_changed (GtkWidget *widget, EContactEditor *editor)
+e_contact_editor_contact_deleted (EABEditor *editor,
+ const GError *error,
+ EContact *contact)
{
- GtkEditable *editable = GTK_EDITABLE(widget);
- ECardAddrLabel *address;
-
- if (editor->address_choice == -1)
+ if (!error)
return;
- address = e_card_address_label_new();
-
- if (editor->address_mailing == editor->address_choice || editor->address_mailing == -1) {
- GtkWidget *check;
-
- address->flags |= E_CARD_ADDR_DEFAULT;
-
- check = glade_xml_get_widget(editor->gui, "checkbutton-mailingaddress");
- if (check && GTK_IS_CHECK_BUTTON (check)) {
- gtk_signal_handler_block_by_data (GTK_OBJECT (check), editor);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (check), editor);
- }
- }
-
- address->data = e_utf8_gtk_editable_get_chars(editable, 0, -1);
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
- e_card_simple_set_address(editor->simple, editor->address_choice, address);
- e_card_address_label_unref(address);
+ eab_error_dialog (NULL, eab_editor_get_window (editor), _("Error removing contact"), error);
+}
- widget_changed (widget, editor);
+static void
+e_contact_editor_closed (EABEditor *editor)
+{
+ g_object_unref (editor);
}
+static void
+e_contact_editor_class_init (EContactEditorClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ EABEditorClass *editor_class = EAB_EDITOR_CLASS (class);
+
+ parent_class = g_type_class_ref (EAB_TYPE_EDITOR);
+
+ object_class->set_property = e_contact_editor_set_property;
+ object_class->get_property = e_contact_editor_get_property;
+ object_class->dispose = e_contact_editor_dispose;
+
+ editor_class->raise = e_contact_editor_raise;
+ editor_class->show = e_contact_editor_show;
+ editor_class->close = e_contact_editor_close;
+ editor_class->is_valid = e_contact_editor_is_valid;
+ editor_class->save_contact = e_contact_editor_save_contact;
+ editor_class->is_changed = e_contact_editor_is_changed;
+ editor_class->get_window = e_contact_editor_get_window;
+ editor_class->contact_added = e_contact_editor_contact_added;
+ editor_class->contact_modified = e_contact_editor_contact_modified;
+ editor_class->contact_deleted = e_contact_editor_contact_deleted;
+ editor_class->editor_closed = e_contact_editor_closed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SOURCE_CLIENT,
+ g_param_spec_object (
+ "source_client",
+ "Source EBookClient",
+ NULL,
+ E_TYPE_BOOK_CLIENT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TARGET_CLIENT,
+ g_param_spec_object (
+ "target_client",
+ "Target EBookClient",
+ NULL,
+ E_TYPE_BOOK_CLIENT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CONTACT,
+ g_param_spec_object (
+ "contact",
+ "Contact",
+ NULL,
+ E_TYPE_CONTACT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_IS_NEW_CONTACT,
+ g_param_spec_boolean (
+ "is_new_contact",
+ "Is New Contact",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WRITABLE_FIELDS,
+ g_param_spec_pointer (
+ "writable_fields",
+ "Writable Fields",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_REQUIRED_FIELDS,
+ g_param_spec_pointer (
+ "required_fields",
+ "Required Fields",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ "Editable",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CHANGED,
+ g_param_spec_boolean (
+ "changed",
+ "Changed",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+}
static void
-address_mailing_changed (GtkWidget *widget, EContactEditor *editor)
+entry_activated (EContactEditor *editor)
{
- ECardAddrLabel *address;
- GtkWidget *text;
- gboolean mailing_address;
+ save_contact (editor, TRUE);
+}
- if (editor->address_choice == -1)
- return;
+/* FIXME: Linear time... */
+static gboolean
+is_field_supported (EContactEditor *editor,
+ EContactField field_id)
+{
+ GSList *fields, *iter;
+ const gchar *field;
- mailing_address = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
-
- /* Mark the current address as the mailing address */
- text = glade_xml_get_widget(editor->gui, "text-address");
- if (text && GTK_IS_TEXT(text)) {
+ fields = editor->writable_fields;
+ if (!fields)
+ return FALSE;
- address = e_card_address_label_new();
-
- if (mailing_address)
- address->flags |= E_CARD_ADDR_DEFAULT;
- else
- address->flags &= ~E_CARD_ADDR_DEFAULT;
- address->data = e_utf8_gtk_editable_get_chars(GTK_EDITABLE (text), 0, -1);
-
- e_card_simple_set_address(editor->simple, editor->address_choice, address);
- e_card_address_label_unref(address);
- }
+ field = e_contact_field_name (field_id);
+ if (!field)
+ return FALSE;
- /* Unset the previous mailing address flag */
- if (mailing_address && editor->address_mailing != -1) {
- const ECardAddrLabel *curr;
+ for (iter = fields; iter; iter = iter->next) {
+ const gchar *this_field = iter->data;
- curr = e_card_simple_get_address(editor->simple,
- editor->address_mailing);
- address = e_card_address_label_copy (curr);
- address->flags &= ~E_CARD_ADDR_DEFAULT;
- e_card_simple_set_address(editor->simple,
- editor->address_mailing,
- address);
- }
+ if (!this_field)
+ continue;
- /* Remember the new mailing address */
- if (mailing_address)
- editor->address_mailing = editor->address_choice;
- else
- editor->address_mailing = -1;
+ if (!strcmp (field, this_field))
+ return TRUE;
+ }
- widget_changed (widget, editor);
+ return FALSE;
}
-
/* 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,
+ const gchar *company,
+ gint style)
{
switch (style) {
case 0: /* Fall Through */
case 1:
return TRUE;
case 2:
+ if (name) {
+ if (name->additional && *name->additional)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ case 3:
if (company && *company)
return TRUE;
else
return FALSE;
- case 3: /* Fall Through */
- case 4:
- if (company && *company && name && ((name->given && *name->given) || (name->family && *name->family)))
+ case 4: /* Fall Through */
+ case 5:
+ if (company && *company && name &&
+ ((name->given && *name->given) ||
+ (name->family && *name->family)))
return TRUE;
else
return FALSE;
@@ -414,12 +436,15 @@ style_makes_sense(const ECardName *name, char *company, int style)
}
}
-static char *
-name_to_style(const ECardName *name, char *company, int style)
+static gchar *
+name_to_style (const EContactName *name,
+ const gchar *company,
+ gint style)
{
- char *string;
- char *strings[4], **stringptr;
- char *substring;
+ gchar *string;
+ gchar *strings[4], **stringptr;
+ gchar *midstring[4], **midstrptr;
+ gchar *substring;
switch (style) {
case 0:
stringptr = strings;
@@ -430,7 +455,7 @@ name_to_style(const ECardName *name, char *company, int style)
*(stringptr++) = name->given;
}
*stringptr = NULL;
- string = g_strjoinv(", ", strings);
+ string = g_strjoinv (", ", strings);
break;
case 1:
stringptr = strings;
@@ -441,13 +466,31 @@ name_to_style(const ECardName *name, char *company, int style)
*(stringptr++) = name->family;
}
*stringptr = NULL;
- string = g_strjoinv(" ", strings);
+ string = g_strjoinv (" ", strings);
break;
case 2:
- string = g_strdup(company);
+ midstrptr = midstring;
+ if (name) {
+ if (name->family && *name->family)
+ *(midstrptr++) = name->family;
+ if (name->given && *name->given)
+ *(midstrptr++) = name->given;
+ }
+ *midstrptr = NULL;
+ stringptr = strings;
+ *(stringptr++) = g_strjoinv(", ", midstring);
+ if (name) {
+ if (name->additional && *name->additional)
+ *(stringptr++) = name->additional;
+ }
+ *stringptr = NULL;
+ string = g_strjoinv (" ", strings);
+ break;
+ case 3:
+ string = g_strdup (company);
break;
- case 3: /* Fall Through */
- case 4:
+ case 4: /* Fall Through */
+ case 5:
stringptr = strings;
if (name) {
if (name->family && *name->family)
@@ -456,2253 +499,4107 @@ name_to_style(const ECardName *name, char *company, int style)
*(stringptr++) = name->given;
}
*stringptr = NULL;
- substring = g_strjoinv(", ", strings);
+ substring = g_strjoinv (", ", strings);
if (!(company && *company))
company = "";
- if (style == 3)
- string = g_strdup_printf("%s (%s)", substring, company);
+ if (style == 4)
+ string = g_strdup_printf ("%s (%s)", substring, company);
else
- string = g_strdup_printf("%s (%s)", company, substring);
- g_free(substring);
+ string = g_strdup_printf ("%s (%s)", company, substring);
+ g_free (substring);
break;
default:
- string = g_strdup("");
+ string = g_strdup ("");
}
return string;
}
-static int
+static gint
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;
- int i;
- int style;
-
- if (!(file_as && GTK_IS_ENTRY(file_as)))
+ GtkEntry *file_as = GTK_ENTRY (
+ gtk_bin_get_child (GTK_BIN (
+ e_builder_get_widget (editor->builder, "combo-file-as"))));
+ GtkEntry *company_w = GTK_ENTRY (
+ e_builder_get_widget (editor->builder, "entry-company"));
+ gchar *filestring;
+ gchar *trystring;
+ EContactName *name = editor->name;
+ const gchar *company;
+ gint i;
+
+ if (!(file_as && GTK_IS_ENTRY (file_as)))
return -1;
- filestring = e_utf8_gtk_entry_get_text(file_as);
+ company = gtk_entry_get_text (GTK_ENTRY (company_w));
+ filestring = g_strdup (gtk_entry_get_text (file_as));
- style = -1;
- for (i = 0; i < 5; i++) {
- trystring = name_to_style(name, editor->company, i);
- if (!strcmp(trystring, filestring)) {
- g_free(trystring);
- g_free(filestring);
+ for (i = 0; i < 6; i++) {
+ trystring = name_to_style (name, company, i);
+ if (!strcmp (trystring, filestring)) {
+ g_free (trystring);
+ g_free (filestring);
return i;
}
- g_free(trystring);
+ g_free (trystring);
}
g_free (filestring);
return -1;
}
static void
-file_as_set_style(EContactEditor *editor, int style)
+file_as_set_style (EContactEditor *editor,
+ gint style)
{
- char *string;
- int i;
+ gchar *string;
+ gint i;
GList *strings = NULL;
- GtkEntry *file_as = GTK_ENTRY(glade_xml_get_widget(editor->gui, "entry-file-as"));
- GtkWidget *widget;
-
+ GtkComboBox *combo_file_as = GTK_COMBO_BOX (
+ e_builder_get_widget (editor->builder, "combo-file-as"));
+ GtkEntry *company_w = GTK_ENTRY (
+ e_builder_get_widget (editor->builder, "entry-company"));
+ const gchar *company;
- if (!(file_as && GTK_IS_ENTRY(file_as)))
+ if (!(combo_file_as && GTK_IS_COMBO_BOX (combo_file_as)))
return;
+ company = gtk_entry_get_text (GTK_ENTRY (company_w));
+
if (style == -1) {
- string = e_utf8_gtk_entry_get_text(file_as);
- strings = g_list_append(strings, string);
- }
+ GtkWidget *entry;
- widget = glade_xml_get_widget(editor->gui, "combo-file-as");
+ entry = gtk_bin_get_child (GTK_BIN (combo_file_as));
+ if (entry) {
+ string = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+ strings = g_list_append (strings, string);
+ }
+ }
- for (i = 0; i < 5; i++) {
- if (style_makes_sense(editor->name, editor->company, i)) {
- char *u;
- u = name_to_style(editor->name, editor->company, i);
- string = e_utf8_to_gtk_string (widget, u);
- g_free (u);
- if (string) strings = g_list_append(strings, string);
+ for (i = 0; i < 6; i++) {
+ if (style_makes_sense (editor->name, company, i)) {
+ gchar *u;
+ u = name_to_style (editor->name, company, i);
+ if (!STRING_IS_EMPTY (u))
+ strings = g_list_append (strings, u);
+ else
+ g_free (u);
}
}
- if (widget && GTK_IS_COMBO(widget)) {
- GtkCombo *combo = GTK_COMBO(widget);
- gtk_combo_set_popdown_strings(combo, strings);
- g_list_foreach(strings, (GFunc) g_free, NULL);
- g_list_free(strings);
+ if (combo_file_as) {
+ GList *l;
+ GtkListStore *list_store;
+ GtkTreeIter iter;
+
+ list_store = GTK_LIST_STORE (
+ gtk_combo_box_get_model (combo_file_as));
+
+ gtk_list_store_clear (list_store);
+
+ for (l = strings; l; l = l->next) {
+ gtk_list_store_append (list_store, &iter);
+ gtk_list_store_set (list_store, &iter, 0, l->data, -1);
+ }
}
+ g_list_foreach (strings, (GFunc) g_free, NULL);
+ g_list_free (strings);
+
if (style != -1) {
- string = name_to_style(editor->name, editor->company, style);
- e_utf8_gtk_entry_set_text(file_as, string);
- g_free(string);
+ string = name_to_style (editor->name, company, style);
+ set_entry_text (
+ editor, GTK_ENTRY (gtk_bin_get_child (
+ GTK_BIN (combo_file_as))), string);
+ g_free (string);
}
}
static void
-name_entry_changed (GtkWidget *widget, EContactEditor *editor)
+name_entry_changed (GtkWidget *widget,
+ EContactEditor *editor)
{
- int style = 0;
- char *string;
+ gint style = 0;
+ const gchar *string;
- style = file_as_get_style(editor);
-
- e_card_name_unref(editor->name);
+ style = file_as_get_style (editor);
+ e_contact_name_free (editor->name);
+ string = gtk_entry_get_text (GTK_ENTRY (widget));
+ editor->name = e_contact_name_from_string (string);
+ file_as_set_style (editor, style);
- string = e_utf8_gtk_entry_get_text (GTK_ENTRY(widget));
- editor->name = e_card_name_from_string(string);
- g_free (string);
-
- file_as_set_style(editor, style);
+ editor->check_merge = TRUE;
- widget_changed (widget, editor);
+ sensitize_ok (editor);
+ if (string && !*string)
+ gtk_window_set_title (
+ GTK_WINDOW (editor->app), _("Contact Editor"));
}
static void
-company_entry_changed (GtkWidget *widget, EContactEditor *editor)
+file_as_combo_changed (GtkWidget *widget,
+ EContactEditor *editor)
{
- int style = 0;
+ GtkWidget *entry;
+ gchar *string = NULL;
+
+ entry = gtk_bin_get_child (GTK_BIN (widget));
+ if (entry)
+ string = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+
+ if (string && *string) {
+ gchar *title;
+ title = g_strdup_printf (_("Contact Editor - %s"), string);
+ gtk_window_set_title (GTK_WINDOW (editor->app), title);
+ g_free (title);
+ }
+ else {
+ gtk_window_set_title (
+ GTK_WINDOW (editor->app), _("Contact Editor"));
+ }
+ sensitize_ok (editor);
- style = file_as_get_style(editor);
-
- g_free(editor->company);
-
- editor->company = e_utf8_gtk_entry_get_text(GTK_ENTRY(widget));
-
- file_as_set_style(editor, style);
+ g_free (string);
+}
+
+static void
+company_entry_changed (GtkWidget *widget,
+ EContactEditor *editor)
+{
+ gint style = 0;
- widget_changed (widget, editor);
+ style = file_as_get_style (editor);
+ file_as_set_style (editor, style);
}
static void
-field_changed (GtkWidget *widget, EContactEditor *editor)
+update_file_as_combo (EContactEditor *editor)
{
- if (!editor->changed) {
- editor->changed = TRUE;
- command_state_changed (editor);
- }
+ file_as_set_style (editor, file_as_get_style (editor));
+}
+
+static void
+fill_in_source_field (EContactEditor *editor)
+{
+ GtkWidget *source_menu;
+
+ if (!editor->target_client)
+ return;
+
+ source_menu = e_builder_get_widget (
+ editor->builder, "client-combo-box");
+
+ e_source_combo_box_set_active (
+ E_SOURCE_COMBO_BOX (source_menu),
+ e_client_get_source (E_CLIENT (editor->target_client)));
}
static void
-set_entry_changed_signal_phone(EContactEditor *editor, char *id)
+sensitize_ok (EContactEditor *ce)
{
- GtkWidget *widget = glade_xml_get_widget(editor->gui, id);
- if (widget && GTK_IS_ENTRY(widget))
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- phone_entry_changed, editor);
+ GtkWidget *widget;
+ gboolean allow_save;
+ GtkWidget *entry_fullname =
+ e_builder_get_widget (ce->builder, "entry-fullname");
+ GtkWidget *entry_file_as =
+ gtk_bin_get_child (GTK_BIN (
+ e_builder_get_widget (ce->builder, "combo-file-as")));
+ GtkWidget *company_name =
+ e_builder_get_widget (ce->builder, "entry-company");
+ const gchar *name_entry_string =
+ gtk_entry_get_text (GTK_ENTRY (entry_fullname));
+ const gchar *file_as_entry_string =
+ gtk_entry_get_text (GTK_ENTRY (entry_file_as));
+ const gchar *company_name_string =
+ gtk_entry_get_text (GTK_ENTRY (company_name));
+
+ allow_save = ce->target_editable && ce->changed;
+
+ if (!strcmp (name_entry_string, "") ||
+ !strcmp (file_as_entry_string, "")) {
+ if (strcmp (company_name_string , "")) {
+ allow_save = TRUE;
+ }
+ else
+ allow_save = FALSE;
+ }
+ widget = e_builder_get_widget (ce->builder, "button-ok");
+ gtk_widget_set_sensitive (widget, allow_save);
}
static void
-widget_changed (GtkWidget *widget, EContactEditor *editor)
+object_changed (GObject *object,
+ EContactEditor *editor)
{
- if (!editor->editable) {
+ if (!editor->target_editable) {
g_warning ("non-editable contact editor has an editable field in it.");
return;
}
+ if (!editor->check_merge && GTK_IS_WIDGET (object)) {
+ const gchar *widget_name;
+
+ widget_name = gtk_widget_get_name (GTK_WIDGET (object));
+
+ if (widget_name &&
+ ((g_str_equal (widget_name, "fullname")) ||
+ (g_str_equal (widget_name, "nickname")) ||
+ (g_str_equal (widget_name, "file-as")) ||
+ (g_str_has_prefix (widget_name, "email-"))))
+ editor->check_merge = TRUE;
+ }
+
if (!editor->changed) {
editor->changed = TRUE;
- command_state_changed (editor);
+ sensitize_ok (editor);
}
}
static void
-set_entry_changed_signal_field(EContactEditor *editor, char *id)
+image_chooser_changed (GtkWidget *widget,
+ EContactEditor *editor)
{
- GtkWidget *widget = glade_xml_get_widget(editor->gui, id);
- if (widget && GTK_IS_ENTRY(widget))
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- field_changed, editor);
+ editor->image_set = TRUE;
+ editor->image_changed = TRUE;
}
static void
-set_entry_changed_signals(EContactEditor *editor)
+set_entry_text (EContactEditor *editor,
+ GtkEntry *entry,
+ const gchar *string)
{
- GtkWidget *widget;
- set_entry_changed_signal_phone(editor, "entry-phone1");
- set_entry_changed_signal_phone(editor, "entry-phone2");
- set_entry_changed_signal_phone(editor, "entry-phone3");
- set_entry_changed_signal_phone(editor, "entry-phone4");
- widget = glade_xml_get_widget(editor->gui, "entry-email1");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- email_entry_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "text-address");
- if (widget && GTK_IS_TEXT(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- address_text_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-fullname");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- name_entry_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-company");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- company_entry_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-web");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-categories");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-jobtitle");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-file-as");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-manager");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-assistant");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-office");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-department");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-profession");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-nickname");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-spouse");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "text-comments");
- if (widget && GTK_IS_TEXT(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "dateedit-birthday");
- if (widget && E_IS_DATE_EDIT(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "dateedit-anniversary");
- if (widget && E_IS_DATE_EDIT(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
- widget = glade_xml_get_widget(editor->gui, "entry-web");
- if (widget && GTK_IS_ENTRY(widget)) {
- gtk_signal_connect(GTK_OBJECT(widget), "changed",
- widget_changed, editor);
- }
-
-}
-
-static void
-full_name_clicked(GtkWidget *button, EContactEditor *editor)
-{
- GnomeDialog *dialog = GNOME_DIALOG(e_contact_editor_fullname_new(editor->name));
- int result;
+ const gchar *oldstring = gtk_entry_get_text (entry);
- gtk_object_set (GTK_OBJECT (dialog),
- "editable", editor->editable,
- NULL);
- gtk_widget_show(GTK_WIDGET(dialog));
- result = gnome_dialog_run (dialog);
+ if (!string)
+ string = "";
- if (result == 0) {
- ECardName *name;
- GtkWidget *fname_widget;
- int style = 0;
+ if (strcmp (string, oldstring)) {
+ g_signal_handlers_block_matched (
+ entry, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor);
+ gtk_entry_set_text (entry, string);
+ g_signal_handlers_unblock_matched (
+ entry, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor);
+ }
+}
- gtk_object_get(GTK_OBJECT(dialog),
- "name", &name,
- NULL);
+static void
+set_combo_box_active (EContactEditor *editor,
+ GtkComboBox *combo_box,
+ gint active)
+{
+ g_signal_handlers_block_matched (
+ combo_box, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor);
+ gtk_combo_box_set_active (combo_box, active);
+ g_signal_handlers_unblock_matched (
+ combo_box, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor);
+}
- style = file_as_get_style(editor);
+static void
+init_email_record_location (EContactEditor *editor,
+ gint record)
+{
+ GtkComboBox *location_combo_box;
+ GtkWidget *email_entry;
+ gchar *widget_name;
+ gint i;
+ GtkTreeIter iter;
+ GtkListStore *store;
+
+ widget_name = g_strdup_printf ("entry-email-%d", record);
+ email_entry = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ widget_name = g_strdup_printf ("combobox-email-%d", record);
+ location_combo_box = GTK_COMBO_BOX (
+ e_builder_get_widget (editor->builder, widget_name));
+ g_free (widget_name);
+
+ store = GTK_LIST_STORE (gtk_combo_box_get_model (location_combo_box));
+ gtk_list_store_clear (store);
+
+ for (i = 0; i < G_N_ELEMENTS (common_location); i++) {
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (
+ store, &iter,
+ 0, _(common_location[i].pretty_name),
+ -1);
+ }
- 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);
- e_utf8_gtk_entry_set_text(GTK_ENTRY(fname_widget), full_name);
- g_free(full_name);
- }
+ g_signal_connect_swapped (
+ location_combo_box, "changed",
+ G_CALLBACK (gtk_widget_grab_focus), email_entry);
+ g_signal_connect (
+ location_combo_box, "changed",
+ G_CALLBACK (object_changed), editor);
+ g_signal_connect (
+ email_entry, "changed",
+ G_CALLBACK (object_changed), editor);
+ g_signal_connect_swapped (
+ email_entry, "activate",
+ G_CALLBACK (entry_activated), editor);
+}
- e_card_name_unref(editor->name);
- editor->name = e_card_name_ref(name);
+static void
+fill_in_email_record (EContactEditor *editor,
+ gint record,
+ const gchar *address,
+ gint location)
+{
+ GtkWidget *location_combo_box;
+ GtkWidget *email_entry;
+ gchar *widget_name;
+
+ widget_name = g_strdup_printf ("combobox-email-%d", record);
+ location_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ widget_name = g_strdup_printf ("entry-email-%d", record);
+ email_entry = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ set_combo_box_active (
+ editor, GTK_COMBO_BOX (location_combo_box),
+ location >= 0 ? location : email_default[2]);
+ set_entry_text (editor, GTK_ENTRY (email_entry), address ? address : "");
+}
- file_as_set_style(editor, style);
- }
- gtk_object_unref(GTK_OBJECT(dialog));
+static void
+extract_email_record (EContactEditor *editor,
+ gint record,
+ gchar **address,
+ gint *location)
+{
+ GtkWidget *location_combo_box;
+ GtkWidget *email_entry;
+ gchar *widget_name;
+ const gchar *text;
+
+ widget_name = g_strdup_printf ("combobox-email-%d", record);
+ location_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ widget_name = g_strdup_printf ("entry-email-%d", record);
+ email_entry = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ text = gtk_entry_get_text (GTK_ENTRY (email_entry));
+ *address = g_strstrip (g_strdup (text));
+ *location = gtk_combo_box_get_active (GTK_COMBO_BOX (location_combo_box));
+}
+
+static const gchar *
+email_index_to_location (gint index)
+{
+ return common_location[index].name;
+}
+
+static const gchar *
+im_index_to_location (gint index)
+{
+ return common_location[index].name;
}
static void
-full_addr_clicked(GtkWidget *button, EContactEditor *editor)
+phone_index_to_type (gint index,
+ const gchar **type_1,
+ const gchar **type_2)
{
- GnomeDialog *dialog;
- int result;
- const ECardDeliveryAddress *address;
+ *type_1 = phones [index].type_1;
+ *type_2 = phones [index].type_2;
+}
- address = e_card_simple_get_delivery_address(editor->simple, editor->address_choice);
+static gint
+get_email_location (EVCardAttribute *attr)
+{
+ gint i;
- dialog = GNOME_DIALOG(e_contact_editor_address_new(address));
- gtk_object_set (GTK_OBJECT (dialog),
- "editable", editor->editable,
- NULL);
- gtk_widget_show(GTK_WIDGET(dialog));
-
- result = gnome_dialog_run (dialog);
- if (result == 0) {
- ECardDeliveryAddress *new_address;
- GtkWidget *address_widget;
-
- gtk_object_get(GTK_OBJECT(dialog),
- "address", &new_address,
- NULL);
-
- address_widget = glade_xml_get_widget(editor->gui, "text-address");
- if (address_widget && GTK_IS_EDITABLE(address_widget)) {
- char *string = e_card_delivery_address_to_string(new_address);
- e_utf8_gtk_editable_set_text(GTK_EDITABLE(address_widget), string);
- g_free(string);
- } else {
- ECardAddrLabel *address = e_card_delivery_address_to_label(new_address);
- e_card_simple_set_address(editor->simple, editor->address_choice, address);
- e_card_address_label_unref(address);
- }
+ for (i = 0; i < G_N_ELEMENTS (common_location); i++) {
+ if (e_vcard_attribute_has_type (attr, common_location[i].name))
+ return i;
+ }
- e_card_simple_set_delivery_address(editor->simple, editor->address_choice, new_address);
+ return -1;
+}
- e_card_delivery_address_unref(new_address);
+static gint
+get_im_location (EVCardAttribute *attr)
+{
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (common_location); i++) {
+ if (e_vcard_attribute_has_type (attr, common_location[i].name))
+ return i;
}
- gtk_object_unref(GTK_OBJECT(dialog));
+
+ return -1;
}
-static void
-categories_clicked(GtkWidget *button, EContactEditor *editor)
+static gint
+get_phone_type (EVCardAttribute *attr)
{
- char *categories = NULL;
- GnomeDialog *dialog;
- int result;
- GtkWidget *entry = glade_xml_get_widget(editor->gui, "entry-categories");
- ECategoriesMasterList *ecml;
- if (entry && GTK_IS_ENTRY(entry))
- categories = e_utf8_gtk_entry_get_text(GTK_ENTRY(entry));
- else if (editor->card)
- gtk_object_get(GTK_OBJECT(editor->card),
- "categories", &categories,
- NULL);
- dialog = GNOME_DIALOG(e_categories_new(categories));
+ gint i;
- if (dialog == NULL) {
- GtkWidget *uh_oh = gnome_error_dialog (_("Category editor not available."));
- gtk_widget_show (uh_oh);
- return;
+ for (i = 0; i < G_N_ELEMENTS (phones); i++) {
+ if (e_vcard_attribute_has_type (attr, phones[i].type_1) &&
+ (phones[i].type_2 == NULL ||
+ e_vcard_attribute_has_type (attr, phones[i].type_2)))
+ return i;
}
- ecml = e_categories_master_list_wombat_new ();
- gtk_object_set(GTK_OBJECT(dialog),
- "header", _("This contact belongs to these categories:"),
- "ecml", ecml,
- NULL);
- gtk_object_unref (GTK_OBJECT (ecml));
- gtk_widget_show(GTK_WIDGET(dialog));
- result = gnome_dialog_run (dialog);
- g_free (categories);
- if (result == 0) {
- gtk_object_get(GTK_OBJECT(dialog),
- "categories", &categories,
- NULL);
- if (entry && GTK_IS_ENTRY(entry))
- e_utf8_gtk_entry_set_text(GTK_ENTRY(entry), categories);
- else
- gtk_object_set(GTK_OBJECT(editor->card),
- "categories", categories,
- NULL);
- g_free(categories);
+ return -1;
+}
+
+static EVCardAttributeParam *
+get_ui_slot_param (EVCardAttribute *attr)
+{
+ EVCardAttributeParam *param = NULL;
+ GList *param_list;
+ GList *l;
+
+ param_list = e_vcard_attribute_get_params (attr);
+
+ for (l = param_list; l; l = g_list_next (l)) {
+ const gchar *str;
+
+ param = l->data;
+
+ str = e_vcard_attribute_param_get_name (param);
+ if (!g_ascii_strcasecmp (str, EVOLUTION_UI_SLOT_PARAM))
+ break;
+
+ param = NULL;
+ }
+
+ return param;
+}
+
+static gint
+get_ui_slot (EVCardAttribute *attr)
+{
+ EVCardAttributeParam *param;
+ gint slot = -1;
+
+ param = get_ui_slot_param (attr);
+
+ if (param) {
+ GList *value_list;
+
+ value_list = e_vcard_attribute_param_get_values (param);
+ slot = atoi (value_list->data);
}
- gtk_object_destroy(GTK_OBJECT(dialog));
+
+ return slot;
}
static void
-ensure_select_names_contact (EContactEditor *editor)
+set_ui_slot (EVCardAttribute *attr,
+ gint slot)
{
- if (editor->select_names_contacts == NULL) {
- editor->select_names_contacts = e_select_names_manager_new ();
- e_select_names_manager_add_section (editor->select_names_contacts,
- "contacts",
- "Related Contacts");
+ EVCardAttributeParam *param;
+ gchar *slot_str;
+
+ param = get_ui_slot_param (attr);
+ if (!param) {
+ param = e_vcard_attribute_param_new (EVOLUTION_UI_SLOT_PARAM);
+ e_vcard_attribute_add_param (attr, param);
}
- set_entry_changed_signal_field(editor, "entry-caluri");
- set_entry_changed_signal_field(editor, "entry-fburl");
+ e_vcard_attribute_param_remove_values (param);
+
+ slot_str = g_strdup_printf ("%d", slot);
+ e_vcard_attribute_param_add_value (param, slot_str);
+ g_free (slot_str);
}
-static void
-contacts_clicked (GtkWidget *button, EContactEditor *editor)
+static gint
+alloc_ui_slot (EContactEditor *editor,
+ const gchar *widget_base,
+ gint preferred_slot,
+ gint num_slots)
{
- ensure_select_names_contact (editor);
- e_select_names_manager_activate_dialog (editor->select_names_contacts,
- "contacts");
+ gchar *widget_name;
+ GtkWidget *widget;
+ const gchar *entry_contents;
+ gint i;
+
+ /* See if we can get the preferred slot */
+
+ if (preferred_slot >= 1) {
+ widget_name = g_strdup_printf ("%s-%d", widget_base, preferred_slot);
+ widget = e_builder_get_widget (editor->builder, widget_name);
+ entry_contents = gtk_entry_get_text (GTK_ENTRY (widget));
+ g_free (widget_name);
+
+ if (STRING_IS_EMPTY (entry_contents))
+ return preferred_slot;
+ }
+
+ /* Find first empty slot */
+
+ for (i = 1; i <= num_slots; i++) {
+ widget_name = g_strdup_printf ("%s-%d", widget_base, i);
+ widget = e_builder_get_widget (editor->builder, widget_name);
+ entry_contents = gtk_entry_get_text (GTK_ENTRY (widget));
+ g_free (widget_name);
+
+ if (STRING_IS_EMPTY (entry_contents))
+ return i;
+ }
+
+ return -1;
}
static void
-add_lists (EContactEditor *editor)
+free_attr_list (GList *attr_list)
{
- GtkWidget *table = glade_xml_get_widget (editor->gui, "table-contacts");
- if (table && GTK_IS_TABLE (table)) {
- GtkWidget *entry;
+ GList *l;
- ensure_select_names_contact (editor);
- entry = e_select_names_manager_create_entry (editor->select_names_contacts,
- "contacts");
- gtk_signal_connect(GTK_OBJECT(entry), "changed",
- widget_changed, editor);
- gtk_table_attach_defaults (GTK_TABLE (table), entry, 0, 1, 0, 1);
- gtk_widget_show (entry);
+ for (l = attr_list; l; l = g_list_next (l)) {
+ EVCardAttribute *attr = l->data;
+ e_vcard_attribute_free (attr);
}
+
+ g_list_free (attr_list);
}
+static void
+fill_in_email (EContactEditor *editor)
+{
+ GList *email_attr_list;
+ GList *l;
+ gint record_n;
-typedef struct {
- EContactEditor *ce;
- gboolean should_close;
-} EditorCloseStruct;
+ /* Clear */
+
+ for (record_n = 1; record_n <= EMAIL_SLOTS; record_n++) {
+ fill_in_email_record (
+ editor, record_n, NULL, email_default[record_n - 1]);
+ }
+
+ /* Fill in */
+
+ email_attr_list = e_contact_get_attributes (
+ editor->contact, E_CONTACT_EMAIL);
+
+ for (record_n = 1, l = email_attr_list;
+ l && record_n <= EMAIL_SLOTS; l = g_list_next (l)) {
+ EVCardAttribute *attr = l->data;
+ gchar *email_address;
+ gint slot;
+
+ email_address = e_vcard_attribute_get_value (attr);
+ slot = alloc_ui_slot (
+ editor, "entry-email",
+ get_ui_slot (attr), EMAIL_SLOTS);
+ if (slot < 1)
+ break;
+
+ fill_in_email_record (
+ editor, slot, email_address,
+ get_email_location (attr));
+
+ record_n++;
+
+ g_free (email_address);
+ }
+
+ g_list_free_full (email_attr_list, (GDestroyNotify) e_vcard_attribute_free);
+}
static void
-card_added_cb (EBook *book, EBookStatus status, const char *id, EditorCloseStruct *ecs)
+extract_email (EContactEditor *editor)
{
- EContactEditor *ce = ecs->ce;
- gboolean should_close = ecs->should_close;
+ GList *attr_list = NULL;
+ GList *old_attr_list;
+ GList *l, *l_next;
+ gint i;
- gtk_widget_set_sensitive (ce->app, TRUE);
- ce->in_async_call = FALSE;
+ for (i = 1; i <= EMAIL_SLOTS; i++) {
+ gchar *address;
+ gint location;
- e_card_set_id (ce->card, id);
+ extract_email_record (editor, i, &address, &location);
- gtk_signal_emit (GTK_OBJECT (ce), contact_editor_signals[CARD_ADDED],
- status, ce->card);
+ if (!STRING_IS_EMPTY (address)) {
+ EVCardAttribute *attr;
+ attr = e_vcard_attribute_new (
+ "", e_contact_vcard_attribute (E_CONTACT_EMAIL));
- if (status == E_BOOK_STATUS_SUCCESS) {
- ce->is_new_card = FALSE;
+ if (location >= 0)
+ e_vcard_attribute_add_param_with_value (
+ attr,
+ e_vcard_attribute_param_new (EVC_TYPE),
+ email_index_to_location (location));
- if (should_close) {
- close_dialog (ce);
- }
- else {
- ce->changed = FALSE;
- command_state_changed (ce);
+ e_vcard_attribute_add_value (attr, address);
+ set_ui_slot (attr, i);
+
+ attr_list = g_list_append (attr_list, attr);
}
+
+ g_free (address);
}
- gtk_object_unref (GTK_OBJECT (ce));
- g_free (ecs);
+ /* Splice in the old attributes, minus the EMAIL_SLOTS first */
+
+ old_attr_list = e_contact_get_attributes (editor->contact, E_CONTACT_EMAIL);
+ for (l = old_attr_list, i = 1; l && i <= EMAIL_SLOTS; l = l_next, i++) {
+ l_next = g_list_next (l);
+
+ e_vcard_attribute_free (l->data);
+ l = g_list_delete_link (l, l);
+ }
+
+ old_attr_list = l;
+ attr_list = g_list_concat (attr_list, old_attr_list);
+
+ e_contact_set_attributes (editor->contact, E_CONTACT_EMAIL, attr_list);
+
+ free_attr_list (attr_list);
}
static void
-card_modified_cb (EBook *book, EBookStatus status, EditorCloseStruct *ecs)
+sensitize_email_record (EContactEditor *editor,
+ gint record,
+ gboolean enabled)
{
- EContactEditor *ce = ecs->ce;
- gboolean should_close = ecs->should_close;
+ GtkWidget *location_combo_box;
+ GtkWidget *email_entry;
+ gchar *widget_name;
- gtk_widget_set_sensitive (ce->app, TRUE);
- ce->in_async_call = FALSE;
+ widget_name = g_strdup_printf ("combobox-email-%d", record);
+ location_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
- gtk_signal_emit (GTK_OBJECT (ce), contact_editor_signals[CARD_MODIFIED],
- status, ce->card);
+ widget_name = g_strdup_printf ("entry-email-%d", record);
+ email_entry = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
- if (status == E_BOOK_STATUS_SUCCESS) {
- if (should_close) {
- close_dialog (ce);
- }
- else {
- ce->changed = FALSE;
- command_state_changed (ce);
+ gtk_widget_set_sensitive (location_combo_box, enabled);
+ gtk_editable_set_editable (GTK_EDITABLE (email_entry), enabled);
+}
+
+static void
+sensitize_email (EContactEditor *editor)
+{
+ gint i;
+
+ for (i = 1; i <= EMAIL_SLOTS; i++) {
+ gboolean enabled = TRUE;
+
+ if (!editor->target_editable)
+ enabled = FALSE;
+
+ if (E_CONTACT_FIRST_EMAIL_ID + i - 1 <= E_CONTACT_LAST_EMAIL_ID &&
+ !is_field_supported (editor, E_CONTACT_FIRST_EMAIL_ID + i - 1))
+ enabled = FALSE;
+
+ sensitize_email_record (editor, i, enabled);
+ }
+}
+
+static void
+init_item_sensitiveable_combo_box (GtkComboBox *combo)
+{
+ GtkCellRenderer *cell;
+ GtkListStore *store;
+
+ g_return_if_fail (combo != NULL);
+ g_return_if_fail (GTK_IS_COMBO_BOX (combo));
+
+ store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
+ gtk_combo_box_set_model (combo, GTK_TREE_MODEL (store));
+ g_object_unref (store);
+
+ gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
+
+ cell = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
+ gtk_cell_layout_set_attributes (
+ GTK_CELL_LAYOUT (combo), cell,
+ "text", 0, "sensitive", 1, NULL);
+}
+
+/* EContact can get attributes by field ID only,
+ * and there is none for TEL, so we need this */
+static GList *
+get_attributes_named (EVCard *vcard,
+ const gchar *attr_name)
+{
+ GList *attr_list_in;
+ GList *attr_list_out = NULL;
+ GList *l;
+
+ attr_list_in = e_vcard_get_attributes (vcard);
+
+ for (l = attr_list_in; l; l = g_list_next (l)) {
+ EVCardAttribute *attr = l->data;
+ const gchar *name;
+
+ name = e_vcard_attribute_get_name (attr);
+
+ if (!g_ascii_strcasecmp (attr_name, name)) {
+ attr_list_out = g_list_append (
+ attr_list_out,
+ e_vcard_attribute_copy (attr));
}
}
- gtk_object_unref (GTK_OBJECT (ce));
- g_free (ecs);
+ return attr_list_out;
}
-/* Emits the signal to request saving a card */
+/* EContact can set attributes by field ID only,
+ * and there is none for TEL, so we need this */
static void
-save_card (EContactEditor *ce, gboolean should_close)
+set_attributes_named (EVCard *vcard,
+ const gchar *attr_name,
+ GList *attr_list)
{
- extract_info (ce);
- e_card_simple_sync_card (ce->simple);
+ GList *l;
+
+ e_vcard_remove_attributes (vcard, NULL, attr_name);
- if (ce->book) {
- EditorCloseStruct *ecs = g_new(EditorCloseStruct, 1);
-
- ecs->ce = ce;
- gtk_object_ref (GTK_OBJECT (ecs->ce));
+ for (l = attr_list; l; l = g_list_next (l)) {
+ EVCardAttribute *attr = l->data;
- ecs->should_close = should_close;
+ e_vcard_add_attribute (vcard, e_vcard_attribute_copy (attr));
+ }
+}
- gtk_widget_set_sensitive (ce->app, FALSE);
- ce->in_async_call = TRUE;
+static void
+set_arrow_image (EContactEditor *editor,
+ const gchar *arrow_widget,
+ gboolean expanded)
+{
+ GtkWidget *arrow;
- if (ce->is_new_card)
- e_card_merging_book_add_card (ce->book, ce->card, GTK_SIGNAL_FUNC(card_added_cb), ecs);
+ arrow = e_builder_get_widget (editor->builder, arrow_widget);
+ if (expanded)
+ gtk_arrow_set (
+ GTK_ARROW (arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE);
+ else
+ gtk_arrow_set (
+ GTK_ARROW (arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE);
+}
+
+static void
+expand_widget_list (EContactEditor *editor,
+ const gchar **widget_names,
+ gboolean expanded)
+{
+ gint i;
+ for (i = 0; widget_names[i]; i++)
+ gtk_widget_set_visible (
+ e_builder_get_widget (editor->builder, widget_names[i]),
+ expanded);
+}
+
+static void
+expand_web (EContactEditor *editor,
+ gboolean expanded)
+{
+ const gchar *names[] = {
+ "label-videourl", "label-fburl",
+ "entry-videourl", "entry-fburl",
+ NULL
+ };
+ set_arrow_image (editor, "arrow-web-expand", expanded);
+ expand_widget_list (editor, names, expanded);
+}
+
+static void
+expand_phone (EContactEditor *editor,
+ gboolean expanded)
+{
+ const gchar *names[] = {
+ "entry-phone-3", "combobox-phone-3",
+ "entry-phone-4", "combobox-phone-4",
+ "table-phone-extended", NULL
+ };
+ set_arrow_image (editor, "arrow-phone-expand", expanded);
+ expand_widget_list (editor, names, expanded);
+}
+
+static void
+expand_mail (EContactEditor *editor,
+ gboolean expanded)
+{
+ GtkTable *table;
+ GtkWidget *check;
+ const gchar *names[] = {
+ "entry-email-2", "combobox-email-2",
+ "entry-email-3", "combobox-email-3",
+ "entry-email-4", "combobox-email-4",
+ NULL
+ };
+ set_arrow_image (editor, "arrow-mail-expand", expanded);
+ expand_widget_list (editor, names, expanded);
+
+ /* move 'use html mail' into position */
+ check = e_builder_get_widget (editor->builder, "checkbutton-htmlmail");
+ table = GTK_TABLE (e_builder_get_widget (editor->builder, "email-table"));
+ if (check != NULL && table != NULL) {
+ GtkWidget *parent;
+
+ g_object_ref (check);
+ parent = gtk_widget_get_parent (check);
+ gtk_container_remove (GTK_CONTAINER (parent), check);
+ if (expanded)
+ gtk_table_attach_defaults (table, check, 0, 4, 2, 3);
else
- e_card_merging_book_commit_card (ce->book, ce->card, GTK_SIGNAL_FUNC(card_modified_cb), ecs);
+ gtk_table_attach_defaults (table, check, 2, 4, 0, 1);
+ g_object_unref (check);
}
}
-/* Closes the dialog box and emits the appropriate signals */
static void
-close_dialog (EContactEditor *ce)
+init_email (EContactEditor *editor)
{
- if (ce->app != NULL) {
- gtk_widget_destroy (ce->app);
- ce->app = NULL;
- gtk_signal_emit (GTK_OBJECT (ce), contact_editor_signals[EDITOR_CLOSED]);
+ gint i;
+
+ for (i = 1; i <= EMAIL_SLOTS; i++)
+ init_email_record_location (editor, i);
+
+ expand_mail (editor, !editor->compress_ui);
+}
+
+static void
+fill_in_phone_record (EContactEditor *editor,
+ gint record,
+ const gchar *phone,
+ gint phone_type)
+{
+ GtkWidget *phone_type_combo_box;
+ GtkWidget *phone_entry;
+ gchar *widget_name;
+
+ widget_name = g_strdup_printf ("combobox-phone-%d", record);
+ phone_type_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ widget_name = g_strdup_printf ("entry-phone-%d", record);
+ phone_entry = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ set_combo_box_active (
+ editor, GTK_COMBO_BOX (phone_type_combo_box),
+ phone_type >= 0 ? phone_type : phones_default[record - 1]);
+ set_entry_text (editor, GTK_ENTRY (phone_entry), phone ? phone : "");
+
+ if (phone && *phone && record >= 3)
+ expand_phone (editor, TRUE);
+}
+
+static void
+extract_phone_record (EContactEditor *editor,
+ gint record,
+ gchar **phone,
+ gint *phone_type)
+{
+ GtkWidget *phone_type_combo_box;
+ GtkWidget *phone_entry;
+ gchar *widget_name;
+
+ widget_name = g_strdup_printf ("combobox-phone-%d", record);
+ phone_type_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ widget_name = g_strdup_printf ("entry-phone-%d", record);
+ phone_entry = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ *phone = g_strdup (gtk_entry_get_text (GTK_ENTRY (phone_entry)));
+ *phone_type = gtk_combo_box_get_active (GTK_COMBO_BOX (phone_type_combo_box));
+}
+
+static void
+fill_in_phone (EContactEditor *editor)
+{
+ GList *phone_attr_list;
+ GList *l;
+ gint record_n;
+
+ /* Clear */
+
+ for (record_n = 1; record_n <= PHONE_SLOTS; record_n++) {
+ fill_in_phone_record (editor, record_n, NULL, -1);
+ }
+
+ /* Fill in */
+
+ phone_attr_list = get_attributes_named (E_VCARD (editor->contact), "TEL");
+
+ for (record_n = 1, l = phone_attr_list;
+ l && record_n <= PHONE_SLOTS; l = g_list_next (l)) {
+ EVCardAttribute *attr = l->data;
+ gchar *phone;
+ gint slot;
+
+ phone = e_vcard_attribute_get_value (attr);
+ slot = alloc_ui_slot (editor, "entry-phone", get_ui_slot (attr), PHONE_SLOTS);
+ if (slot < 1)
+ break;
+
+ fill_in_phone_record (
+ editor, slot, phone, get_phone_type (attr));
+
+ record_n++;
+
+ g_free (phone);
}
}
-static gboolean
-prompt_to_save_changes (EContactEditor *editor)
+static void
+extract_phone (EContactEditor *editor)
{
- if (!editor->changed)
- return TRUE;
+ GList *attr_list = NULL;
+ GList *old_attr_list;
+ GList *l, *l_next;
+ gint i;
- switch (e_addressbook_prompt_save_dialog (GTK_WINDOW(editor->app))) {
- case 0: /* Save */
- save_card (editor, FALSE);
- return TRUE;
- case 1: /* Discard */
- return TRUE;
- case 2: /* Cancel */
- default:
- return FALSE;
+ for (i = 1; i <= PHONE_SLOTS; i++) {
+ gchar *phone;
+ gint phone_type;
+
+ extract_phone_record (editor, i, &phone, &phone_type);
+
+ if (!STRING_IS_EMPTY (phone)) {
+ EVCardAttribute *attr;
+
+ attr = e_vcard_attribute_new ("", "TEL");
+
+ if (phone_type >= 0) {
+ const gchar *type_1;
+ const gchar *type_2;
+
+ phone_index_to_type (phone_type, &type_1, &type_2);
+
+ e_vcard_attribute_add_param_with_value (
+ attr, e_vcard_attribute_param_new (EVC_TYPE), type_1);
+
+ if (type_2)
+ e_vcard_attribute_add_param_with_value (
+ attr, e_vcard_attribute_param_new (EVC_TYPE), type_2);
+
+ }
+
+ e_vcard_attribute_add_value (attr, phone);
+ set_ui_slot (attr, i);
+
+ attr_list = g_list_append (attr_list, attr);
+ }
+
+ g_free (phone);
}
+
+ /* Splice in the old attributes, minus the PHONE_SLOTS first */
+
+ old_attr_list = get_attributes_named (E_VCARD (editor->contact), "TEL");
+ for (l = old_attr_list, i = 1; l && i <= PHONE_SLOTS; l = l_next, i++) {
+ l_next = g_list_next (l);
+
+ e_vcard_attribute_free (l->data);
+ l = g_list_delete_link (l, l);
+ }
+
+ old_attr_list = l;
+ attr_list = g_list_concat (attr_list, old_attr_list);
+
+ set_attributes_named (E_VCARD (editor->contact), "TEL", attr_list);
+
+ free_attr_list (attr_list);
}
-/* Menu callbacks */
+static void
+init_phone_record_type (EContactEditor *editor,
+ gint record)
+{
+ GtkWidget *phone_type_combo_box;
+ GtkWidget *phone_entry;
+ gchar *widget_name;
+ gint i;
+ GtkListStore *store;
+
+ widget_name = g_strdup_printf ("entry-phone-%d", record);
+ phone_entry = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ widget_name = g_strdup_printf ("combobox-phone-%d", record);
+ phone_type_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ init_item_sensitiveable_combo_box (GTK_COMBO_BOX (phone_type_combo_box));
+
+ store = GTK_LIST_STORE (
+ gtk_combo_box_get_model (
+ GTK_COMBO_BOX (phone_type_combo_box)));
+
+ for (i = 0; i < G_N_ELEMENTS (phones); i++) {
+ GtkTreeIter iter;
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (
+ store, &iter,
+ 0, e_contact_pretty_name (phones[i].field_id),
+ 1, TRUE,
+ -1);
+ }
+
+ g_signal_connect_swapped (
+ phone_type_combo_box, "changed",
+ G_CALLBACK (gtk_widget_grab_focus), phone_entry);
+ g_signal_connect (
+ phone_type_combo_box, "changed",
+ G_CALLBACK (object_changed), editor);
+ g_signal_connect (
+ phone_entry, "changed",
+ G_CALLBACK (object_changed), editor);
+ g_signal_connect_swapped (
+ phone_entry, "activate",
+ G_CALLBACK (entry_activated), editor);
+}
-/* File/Save callback */
static void
-file_save_cb (GtkWidget *widget, gpointer data)
+init_phone (EContactEditor *editor)
{
- EContactEditor *ce;
+ gint i;
- ce = E_CONTACT_EDITOR (data);
- save_card (ce, FALSE);
+ expand_phone (editor, FALSE);
+
+ for (i = 1; i <= PHONE_SLOTS; i++)
+ init_phone_record_type (editor, i);
}
-/* File/Close callback */
static void
-file_close_cb (GtkWidget *widget, gpointer data)
+sensitize_phone_types (EContactEditor *editor,
+ GtkWidget *combo_box)
{
- EContactEditor *ce;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gint i;
+ gboolean valid;
- ce = E_CONTACT_EDITOR (data);
- if (!prompt_to_save_changes (ce))
- return;
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
+ valid = gtk_tree_model_get_iter_first (model, &iter);
- close_dialog (ce);
+ for (i = 0; i < G_N_ELEMENTS (phones); i++) {
+ if (!valid) {
+ g_warning (G_STRLOC ": Unexpected end of phone items in combo box");
+ return;
+ }
+
+ gtk_list_store_set (
+ GTK_LIST_STORE (model), &iter,
+ 1, is_field_supported (editor, phones[i].field_id),
+ -1);
+
+ valid = gtk_tree_model_iter_next (model, &iter);
+ }
}
static void
-file_save_as_cb (GtkWidget *widget, gpointer data)
+sensitize_phone_record (EContactEditor *editor,
+ gint record,
+ gboolean enabled)
{
- EContactEditor *ce;
- ECard *card;
+ GtkWidget *phone_type_combo_box;
+ GtkWidget *phone_entry;
+ gchar *widget_name;
- ce = E_CONTACT_EDITOR (data);
+ widget_name = g_strdup_printf ("combobox-phone-%d", record);
+ phone_type_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
- extract_info (ce);
- e_card_simple_sync_card (ce->simple);
+ widget_name = g_strdup_printf ("entry-phone-%d", record);
+ phone_entry = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
- card = ce->card;
- e_contact_save_as(_("Save Contact as VCard"), card, GTK_WINDOW (ce->app));
+ gtk_widget_set_sensitive (phone_type_combo_box, enabled);
+ gtk_editable_set_editable (GTK_EDITABLE (phone_entry), enabled);
+
+ sensitize_phone_types (editor, phone_type_combo_box);
}
static void
-file_send_as_cb (GtkWidget *widget, gpointer data)
+sensitize_phone (EContactEditor *editor)
{
- EContactEditor *ce;
- ECard *card;
+ gint i;
- ce = E_CONTACT_EDITOR (data);
+ for (i = 1; i <= PHONE_SLOTS; i++) {
+ gboolean enabled = TRUE;
- extract_info (ce);
- e_card_simple_sync_card (ce->simple);
+ if (!editor->target_editable)
+ enabled = FALSE;
- card = ce->card;
- e_card_send(card, E_CARD_DISPOSITION_AS_ATTACHMENT);
+ sensitize_phone_record (editor, i, enabled);
+ }
}
static void
-file_send_to_cb (GtkWidget *widget, gpointer data)
+init_im_record_location (EContactEditor *editor,
+ gint record)
{
- EContactEditor *ce;
- ECard *card;
- ce = E_CONTACT_EDITOR (data);
+#ifdef ENABLE_IM_LOCATION
+ GtkWidget *location_combo_box;
+ GtkListStore *store;
+ gint i;
+ gchar *widget_name;
+
+ widget_name = g_strdup_printf ("combobox-im-location-%d", record);
+ location_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ init_item_sensitiveable_combo_box (GTK_COMBO_BOX (location_combo_box));
- extract_info (ce);
- e_card_simple_sync_card (ce->simple);
+ store = GTK_LIST_STORE (
+ gtk_combo_box_get_model (
+ GTK_COMBO_BOX (location_combo_box)));
- card = ce->card;
- e_card_send(card, E_CARD_DISPOSITION_AS_TO);
+ for (i = 0; i < G_N_ELEMENTS (common_location); i++) {
+ GtkTreeIter iter;
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (
+ store, &iter,
+ 0, _(common_location[i].pretty_name),
+ 1, TRUE,
+ -1);
+ }
+
+ g_signal_connect (
+ location_combo_box, "changed",
+ G_CALLBACK (object_changed), editor);
+#endif
}
-gboolean
-e_contact_editor_confirm_delete(GtkWindow *parent)
+static void
+init_im_record_service (EContactEditor *editor,
+ gint record)
{
- GnomeDialog *dialog;
- GladeXML *gui;
- int result;
+ GtkWidget *service_combo_box;
+ GtkListStore *store;
+ GtkWidget *name_entry;
+ gchar *widget_name;
+ gint i;
+
+ widget_name = g_strdup_printf ("entry-im-name-%d", record);
+ name_entry = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ widget_name = g_strdup_printf ("combobox-im-service-%d", record);
+ service_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ if (editor->compress_ui && record > 2) {
+ gtk_widget_hide (name_entry);
+ gtk_widget_hide (service_combo_box);
+ }
- gui = glade_xml_new (EVOLUTION_GLADEDIR "/e-contact-editor-confirm-delete.glade", NULL);
+ init_item_sensitiveable_combo_box (GTK_COMBO_BOX (service_combo_box));
- dialog = GNOME_DIALOG(glade_xml_get_widget(gui, "confirm-dialog"));
+ store = GTK_LIST_STORE (
+ gtk_combo_box_get_model (
+ GTK_COMBO_BOX (service_combo_box)));
- gnome_dialog_set_parent(dialog, parent);
-
- result = gnome_dialog_run_and_close(dialog);
+ for (i = 0; i < G_N_ELEMENTS (im_service); i++) {
+ GtkTreeIter iter;
- gtk_object_unref(GTK_OBJECT(gui));
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (
+ store, &iter,
+ 0, im_service[i].pretty_name,
+ 1, TRUE,
+ -1);
+ }
- return !result;
+ g_signal_connect_swapped (
+ service_combo_box, "changed",
+ G_CALLBACK (gtk_widget_grab_focus), name_entry);
+ g_signal_connect (
+ service_combo_box, "changed",
+ G_CALLBACK (object_changed), editor);
+ g_signal_connect (
+ name_entry, "changed",
+ G_CALLBACK (object_changed), editor);
+ g_signal_connect_swapped (
+ name_entry, "activate",
+ G_CALLBACK (entry_activated), editor);
}
static void
-card_deleted_cb (EBook *book, EBookStatus status, EContactEditor *ce)
+init_im (EContactEditor *editor)
{
- gtk_widget_set_sensitive (ce->app, TRUE);
- ce->in_async_call = FALSE;
+ gint i;
+
+ for (i = 1; i <= IM_SLOTS; i++) {
+ init_im_record_service (editor, i);
+ init_im_record_location (editor, i);
+ }
+}
+
+static void
+fill_in_im_record (EContactEditor *editor,
+ gint record,
+ gint service,
+ const gchar *name,
+ gint location)
+{
+ GtkWidget *service_combo_box;
+#ifdef ENABLE_IM_LOCATION
+ GtkWidget *location_combo_box;
+#endif
+ GtkWidget *name_entry;
+ gchar *widget_name;
- gtk_signal_emit (GTK_OBJECT (ce), contact_editor_signals[CARD_DELETED],
- status, ce->card);
+ widget_name = g_strdup_printf ("combobox-im-service-%d", record);
+ service_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+#ifdef ENABLE_IM_LOCATION
+ widget_name = g_strdup_printf ("combobox-im-location-%d", record);
+ location_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+#endif
- /* always close the dialog after we successfully delete a card */
- if (status == E_BOOK_STATUS_SUCCESS)
- close_dialog (ce);
+ widget_name = g_strdup_printf ("entry-im-name-%d", record);
+ name_entry = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+#ifdef ENABLE_IM_LOCATION
+ set_combo_box_active (
+ editor, GTK_COMBO_BOX (location_combo_box),
+ location >= 0 ? location : 0);
+#endif
+ set_combo_box_active (
+ editor, GTK_COMBO_BOX (service_combo_box),
+ service >= 0 ? service : im_service_default[record - 1]);
+ set_entry_text (editor, GTK_ENTRY (name_entry), name ? name : "");
}
static void
-delete_cb (GtkWidget *widget, gpointer data)
+fill_in_im (EContactEditor *editor)
{
- EContactEditor *ce = E_CONTACT_EDITOR (data);
- ECard *card = ce->card;
- ECardSimple *simple = ce->simple;
+ GList *im_attr_list;
+ GList *l;
+ gint record_n;
+ gint i;
+
+ /* Clear */
+
+ for (record_n = 1; record_n <= IM_SLOTS; record_n++) {
+ fill_in_im_record (editor, record_n, -1, NULL, -1);
+ }
+
+ /* Fill in */
+
+ for (record_n = 1, i = 0; i < G_N_ELEMENTS (im_service); i++) {
+ im_attr_list = e_contact_get_attributes (editor->contact, im_service[i].field);
- gtk_object_ref(GTK_OBJECT(card));
- gtk_object_ref(GTK_OBJECT(simple));
+ for (l = im_attr_list; l && record_n <= IM_SLOTS; l = g_list_next (l)) {
+ EVCardAttribute *attr = l->data;
+ gchar *im_name;
+ gint slot;
- if (e_contact_editor_confirm_delete(GTK_WINDOW(ce->app))) {
+ im_name = e_vcard_attribute_get_value (attr);
+ slot = alloc_ui_slot (
+ editor, "entry-im-name",
+ get_ui_slot (attr), IM_SLOTS);
+ if (slot < 1)
+ break;
- extract_info (ce);
- e_card_simple_sync_card (simple);
-
- if (!ce->is_new_card && ce->book) {
- gtk_widget_set_sensitive (ce->app, FALSE);
- ce->in_async_call = TRUE;
+ fill_in_im_record (
+ editor, slot, i, im_name,
+ get_im_location (attr));
- e_book_remove_card (ce->book, card, GTK_SIGNAL_FUNC(card_deleted_cb), ce);
+ record_n++;
+
+ g_free (im_name);
}
- }
- gtk_object_unref(GTK_OBJECT(card));
- gtk_object_unref(GTK_OBJECT(simple));
+ g_list_free_full (im_attr_list, (GDestroyNotify) e_vcard_attribute_free);
+ }
}
-/* Emits the signal to request printing a card */
static void
-print_cb (BonoboUIComponent *uih, void *data, const char *path)
+extract_im_record (EContactEditor *editor,
+ gint record,
+ gint *service,
+ gchar **name,
+ gint *location)
{
- EContactEditor *ce;
+ GtkWidget *service_combo_box;
+#ifdef ENABLE_IM_LOCATION
+ GtkWidget *location_combo_box;
+#endif
+ GtkWidget *name_entry;
+ gchar *widget_name;
- ce = E_CONTACT_EDITOR (data);
+ widget_name = g_strdup_printf ("combobox-im-service-%d", record);
+ service_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
- extract_info (ce);
- e_card_simple_sync_card (ce->simple);
+#ifdef ENABLE_IM_LOCATION
+ widget_name = g_strdup_printf ("combobox-im-location-%d", record);
+ location_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+#endif
+
+ widget_name = g_strdup_printf ("entry-im-name-%d", record);
+ name_entry = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
- gtk_widget_show(e_contact_print_card_dialog_new(ce->card));
+ *name = g_strdup (gtk_entry_get_text (GTK_ENTRY (name_entry)));
+ *service = gtk_combo_box_get_active (GTK_COMBO_BOX (service_combo_box));
+#ifdef ENABLE_IM_LOCATION
+ *location = gtk_combo_box_get_active (GTK_COMBO_BOX (location_combo_box));
+#else
+ *location = 1; /* set everything to HOME */
+#endif
}
-#if 0 /* Envelope printing is disabled for Evolution 1.0. */
-/* Emits the signal to request printing a card */
static void
-print_envelope_cb (BonoboUIComponent *uih, void *data, const char *path)
+extract_im (EContactEditor *editor)
{
- EContactEditor *ce;
+ GList **service_attr_list;
+ gint remaining_slots = IM_SLOTS;
+ gint i;
- ce = E_CONTACT_EDITOR (data);
+ service_attr_list = g_new0 (GList *, G_N_ELEMENTS (im_service));
+
+ for (i = 1; i <= IM_SLOTS; i++) {
+ EVCardAttribute *attr;
+ gchar *name;
+ gint service;
+ gint location;
+
+ extract_im_record (editor, i, &service, &name, &location);
+
+ if (!STRING_IS_EMPTY (name)) {
+ attr = e_vcard_attribute_new (
+ "", e_contact_vcard_attribute (
+ im_service[service].field));
+
+ if (location >= 0)
+ e_vcard_attribute_add_param_with_value (
+ attr,
+ e_vcard_attribute_param_new (EVC_TYPE),
+ im_index_to_location (location));
- extract_info (ce);
- e_card_simple_sync_card (ce->simple);
+ e_vcard_attribute_add_value (attr, name);
+ set_ui_slot (attr, i);
- gtk_widget_show(e_contact_print_envelope_dialog_new(ce->card));
+ service_attr_list[service] = g_list_append (
+ service_attr_list[service], attr);
+ }
+
+ g_free (name);
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (im_service); i++) {
+ GList *old_service_attr_list;
+ gint filled_in_slots;
+ GList *l, *l_next;
+ gint j;
+
+ /* Splice in the old attributes, minus the filled_in_slots first */
+
+ old_service_attr_list = e_contact_get_attributes (
+ editor->contact, im_service[i].field);
+ filled_in_slots = MIN (
+ remaining_slots,
+ g_list_length (old_service_attr_list));
+ remaining_slots -= filled_in_slots;
+
+ for (l = old_service_attr_list, j = 0;
+ l && j < filled_in_slots; l = l_next, j++) {
+ l_next = g_list_next (l);
+
+ e_vcard_attribute_free (l->data);
+ l = g_list_delete_link (l, l);
+ }
+
+ old_service_attr_list = l;
+ service_attr_list[i] = g_list_concat (
+ service_attr_list[i], old_service_attr_list);
+
+ e_contact_set_attributes (
+ editor->contact,
+ im_service[i].field,
+ service_attr_list[i]);
+
+ free_attr_list (service_attr_list[i]);
+ }
+
+ g_free (service_attr_list);
}
-#endif
-/* Toolbar/Save and Close callback */
static void
-tb_save_and_close_cb (BonoboUIComponent *uih, void *data, const char *path)
+sensitize_im_types (EContactEditor *editor,
+ GtkWidget *combo_box)
{
- EContactEditor *ce;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gint i;
+ gboolean valid;
- ce = E_CONTACT_EDITOR (data);
- save_card (ce, TRUE);
-}
-
-static
-BonoboUIVerb verbs [] = {
- BONOBO_UI_UNSAFE_VERB ("ContactEditorSave", file_save_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactEditorSaveAs", file_save_as_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactEditorSaveClose", tb_save_and_close_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactEditorSendAs", file_send_as_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactEditorSendTo", file_send_to_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactEditorDelete", delete_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactEditorPrint", print_cb),
-#if 0 /* Envelope printing is disabled for Evolution 1.0. */
- BONOBO_UI_UNSAFE_VERB ("ContactEditorPrintEnvelope", print_envelope_cb),
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box));
+ valid = gtk_tree_model_get_iter_first (model, &iter);
+
+ for (i = 0; i < G_N_ELEMENTS (im_service); i++) {
+ if (!valid) {
+ g_warning (G_STRLOC ": Unexpected end of im items in combo box");
+ return;
+ }
+
+ gtk_list_store_set (
+ GTK_LIST_STORE (model), &iter,
+ 1, is_field_supported (editor, im_service[i].field),
+ -1);
+
+ valid = gtk_tree_model_iter_next (model, &iter);
+ }
+}
+
+static void
+sensitize_im_record (EContactEditor *editor,
+ gint record,
+ gboolean enabled)
+{
+ GtkWidget *service_combo_box;
+#ifdef ENABLE_IM_LOCATION
+ GtkWidget *location_combo_box;
#endif
- /* BONOBO_UI_UNSAFE_VERB ("ContactEditorPageSetup", file_page_setup_menu), */
- BONOBO_UI_UNSAFE_VERB ("ContactEditorClose", file_close_cb),
-
- BONOBO_UI_VERB_END
-};
+ GtkWidget *name_entry;
+ gchar *widget_name;
-EPixmap pixmaps[] = {
- E_PIXMAP ("/commands/ContactEditorSave", "save-16.png"),
- E_PIXMAP ("/commands/ContactEditorSaveClose", "save-16.png"),
- E_PIXMAP ("/commands/ContactEditorSaveAs", "save-as-16.png"),
- E_PIXMAP ("/commands/ContactEditorDelete", "evolution-trash-mini.png"),
- E_PIXMAP ("/commands/ContactEditorPrint", "print.xpm"),
-#if 0 /* Envelope printing is disabled for Evolution 1.0. */
- E_PIXMAP ("/commands/ContactEditorPrintEnvelope", "print.xpm"),
+ widget_name = g_strdup_printf ("combobox-im-service-%d", record);
+ service_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+#ifdef ENABLE_IM_LOCATION
+ widget_name = g_strdup_printf ("combobox-im-location-%d", record);
+ location_combo_box = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
#endif
- E_PIXMAP ("/Toolbar/ContactEditorSaveClose", "buttons/save-24.png"),
- E_PIXMAP ("/Toolbar/ContactEditorDelete", "buttons/delete-message.png"),
- E_PIXMAP ("/Toolbar/ContactEditorPrint", "buttons/print.png"),
- E_PIXMAP_END
-};
+ widget_name = g_strdup_printf ("entry-im-name-%d", record);
+ name_entry = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ gtk_widget_set_sensitive (service_combo_box, enabled);
+#ifdef ENABLE_IM_LOCATION
+ gtk_widget_set_sensitive (location_combo_box, enabled);
+#endif
+ gtk_editable_set_editable (GTK_EDITABLE (name_entry), enabled);
+ sensitize_im_types (editor, service_combo_box);
+}
static void
-create_ui (EContactEditor *ce)
+sensitize_im (EContactEditor *editor)
{
- bonobo_ui_component_add_verb_list_with_data (ce->uic, verbs, ce);
+ gint i;
+ gboolean enabled;
+ gboolean no_ims_supported;
+
+ enabled = editor->target_editable;
+ no_ims_supported = TRUE;
+
+ for (i = 0; i < G_N_ELEMENTS (im_service); i++)
+ if (is_field_supported (editor, im_service[i].field)) {
+ no_ims_supported = FALSE;
+ break;
+ }
- bonobo_ui_util_set_ui (ce->uic, EVOLUTION_DATADIR,
- "evolution-contact-editor.xml",
- "evolution-contact-editor");
+ if (no_ims_supported)
+ enabled = FALSE;
- e_pixmaps_update (ce->uic, pixmaps);
+ for (i = 1; i <= IM_SLOTS; i++) {
+ sensitize_im_record (editor, i, enabled);
+ }
}
-/* Callback used when the dialog box is destroyed */
-static gint
-app_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+static void
+init_personal (EContactEditor *editor)
{
- EContactEditor *ce;
+ gtk_expander_set_expanded (
+ GTK_EXPANDER (e_builder_get_widget (
+ editor->builder, "expander-personal-misc")),
+ !editor->compress_ui);
- ce = E_CONTACT_EDITOR (data);
+ expand_web (editor, !editor->compress_ui);
+}
- /* if we're saving, don't allow the dialog to close */
- if (ce->in_async_call)
- return TRUE;
+static void
+init_address_textview (EContactEditor *editor,
+ gint record)
+{
+ gchar *textview_name;
+ GtkWidget *textview;
+ GtkTextBuffer *text_buffer;
- if (!prompt_to_save_changes (ce))
- return TRUE;
+ textview_name = g_strdup_printf (
+ "textview-%s-address", address_name[record]);
+ textview = e_builder_get_widget (editor->builder, textview_name);
+ g_free (textview_name);
- close_dialog (ce);
- return TRUE;
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
+
+ g_signal_connect (
+ text_buffer, "changed",
+ G_CALLBACK (object_changed), editor);
}
-static GList *
-add_to_tab_order(GList *list, GladeXML *gui, char *name)
+static void
+init_address_field (EContactEditor *editor,
+ gint record,
+ const gchar *widget_field_name)
{
- GtkWidget *widget = glade_xml_get_widget(gui, name);
- return g_list_prepend(list, widget);
+ gchar *entry_name;
+ GtkWidget *entry;
+
+ entry_name = g_strdup_printf (
+ "entry-%s-%s", address_name[record], widget_field_name);
+ entry = e_builder_get_widget (editor->builder, entry_name);
+ g_free (entry_name);
+
+ g_signal_connect (
+ entry, "changed",
+ G_CALLBACK (object_changed), editor);
+ g_signal_connect_swapped (
+ entry, "activate",
+ G_CALLBACK (entry_activated), editor);
}
static void
-setup_tab_order(GladeXML *gui)
+init_address_record (EContactEditor *editor,
+ gint record)
{
- GtkWidget *container;
- GList *list = NULL;
+ init_address_textview (editor, record);
+ init_address_field (editor, record, "city");
+ init_address_field (editor, record, "state");
+ init_address_field (editor, record, "zip");
+ init_address_field (editor, record, "country");
+ init_address_field (editor, record, "pobox");
+}
- container = glade_xml_get_widget(gui, "table-contact-editor-general");
+static void
+init_address (EContactEditor *editor)
+{
+ gint i;
- if (container) {
- list = add_to_tab_order(list, gui, "entry-fullname");
- list = add_to_tab_order(list, gui, "entry-jobtitle");
- list = add_to_tab_order(list, gui, "entry-company");
- list = add_to_tab_order(list, gui, "combo-file-as");
- list = add_to_tab_order(list, gui, "entry-phone1");
- list = add_to_tab_order(list, gui, "entry-phone2");
- list = add_to_tab_order(list, gui, "entry-phone3");
- list = add_to_tab_order(list, gui, "entry-phone4");
+ for (i = 0; i < ADDRESS_SLOTS; i++)
+ init_address_record (editor, i);
+
+ gtk_expander_set_expanded (
+ GTK_EXPANDER (e_builder_get_widget (
+ editor->builder, "expander-address-other")),
+ !editor->compress_ui);
+}
- 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, "button-fulladdr");
- list = add_to_tab_order(list, gui, "text-address");
- list = add_to_tab_order(list, gui, "alignment-contacts");
- list = g_list_reverse(list);
- e_container_change_tab_order(GTK_CONTAINER(container), list);
- g_list_free(list);
+static void
+fill_in_address_textview (EContactEditor *editor,
+ gint record,
+ EContactAddress *address)
+{
+ gchar *textview_name;
+ GtkWidget *textview;
+ GtkTextBuffer *text_buffer;
+ GtkTextIter iter_end, iter_start;
+
+ textview_name = g_strdup_printf ("textview-%s-address", address_name[record]);
+ textview = e_builder_get_widget (editor->builder, textview_name);
+ g_free (textview_name);
+
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
+ gtk_text_buffer_set_text (text_buffer, address->street ? address->street : "", -1);
+
+ gtk_text_buffer_get_end_iter (text_buffer, &iter_end);
+ if (address->ext && *address->ext) {
+ gtk_text_buffer_insert (text_buffer, &iter_end, "\n", -1);
+ gtk_text_buffer_insert (text_buffer, &iter_end, address->ext, -1);
+ } else {
+ gtk_text_buffer_insert (text_buffer, &iter_end, "", -1);
}
+ gtk_text_buffer_get_iter_at_line (text_buffer, &iter_start, 0);
+ gtk_text_buffer_place_cursor (text_buffer, &iter_start);
}
static void
-e_contact_editor_init (EContactEditor *e_contact_editor)
+fill_in_address_label_textview (EContactEditor *editor,
+ gint record,
+ const gchar *label)
{
- GladeXML *gui;
- GtkWidget *widget;
- GtkWidget *bonobo_win;
- GtkWidget *wants_html;
- BonoboUIContainer *container;
- char *icon_path;
-
- e_contact_editor->email_info = NULL;
- e_contact_editor->phone_info = NULL;
- e_contact_editor->address_info = NULL;
- e_contact_editor->email_popup = NULL;
- e_contact_editor->phone_popup = NULL;
- e_contact_editor->address_popup = NULL;
- 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->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->address_choice = 0;
- e_contact_editor->address_mailing = -1;
-
- e_contact_editor->arbitrary_fields = NULL;
-
- e_contact_editor->simple = e_card_simple_new(NULL);
-
- e_contact_editor->card = NULL;
- e_contact_editor->changed = FALSE;
- e_contact_editor->in_async_call = FALSE;
- e_contact_editor->editable = TRUE;
+ gchar *textview_name;
+ GtkWidget *textview;
+ GtkTextBuffer *text_buffer;
- gui = glade_xml_new (EVOLUTION_GLADEDIR "/contact-editor.glade", NULL);
- e_contact_editor->gui = gui;
+ textview_name = g_strdup_printf (
+ "textview-%s-address", address_name[record]);
+ textview = e_builder_get_widget (editor->builder, textview_name);
+ g_free (textview_name);
- setup_tab_order(gui);
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
+ gtk_text_buffer_set_text (text_buffer, label ? label : "", -1);
+}
- e_contact_editor->app = glade_xml_get_widget (gui, "contact editor");
+static void
+fill_in_address_field (EContactEditor *editor,
+ gint record,
+ const gchar *widget_field_name,
+ const gchar *string)
+{
+ gchar *entry_name;
+ GtkWidget *entry;
- e_container_foreach_leaf (GTK_CONTAINER (e_contact_editor->app),
- (GtkCallback) add_field_callback,
- e_contact_editor);
+ entry_name = g_strdup_printf (
+ "entry-%s-%s", address_name[record], widget_field_name);
+ entry = e_builder_get_widget (editor->builder, entry_name);
+ g_free (entry_name);
- _replace_buttons(e_contact_editor);
- add_lists (e_contact_editor);
- set_entry_changed_signals(e_contact_editor);
+ set_entry_text (editor, GTK_ENTRY (entry), string);
+}
- wants_html = glade_xml_get_widget(e_contact_editor->gui, "checkbutton-htmlmail");
- if (wants_html && GTK_IS_TOGGLE_BUTTON(wants_html))
- gtk_signal_connect(GTK_OBJECT(wants_html), "toggled",
- wants_html_changed, e_contact_editor);
+static void
+fill_in_address_record (EContactEditor *editor,
+ gint record)
+{
+ EContactAddress *address;
+ gchar *address_label;
+
+ address = e_contact_get (editor->contact, addresses[record]);
+ address_label = e_contact_get (editor->contact, address_labels[record]);
+
+ if (address &&
+ (!STRING_IS_EMPTY (address->street) ||
+ !STRING_IS_EMPTY (address->ext) ||
+ !STRING_IS_EMPTY (address->locality) ||
+ !STRING_IS_EMPTY (address->region) ||
+ !STRING_IS_EMPTY (address->code) ||
+ !STRING_IS_EMPTY (address->po) ||
+ !STRING_IS_EMPTY (address->country))) {
+ fill_in_address_textview (editor, record, address);
+ fill_in_address_field (editor, record, "city", address->locality);
+ fill_in_address_field (editor, record, "state", address->region);
+ fill_in_address_field (editor, record, "zip", address->code);
+ fill_in_address_field (editor, record, "country", address->country);
+ fill_in_address_field (editor, record, "pobox", address->po);
+ } else if (!STRING_IS_EMPTY (address_label)) {
+ fill_in_address_label_textview (editor, record, address_label);
+ }
- widget = glade_xml_get_widget(e_contact_editor->gui, "checkbutton-mailingaddress");
- if (widget && GTK_IS_TOGGLE_BUTTON(widget))
- gtk_signal_connect(GTK_OBJECT(widget), "toggled",
- address_mailing_changed, e_contact_editor);
-
- widget = glade_xml_get_widget(e_contact_editor->gui, "button-fullname");
- if (widget && GTK_IS_BUTTON(widget))
- gtk_signal_connect(GTK_OBJECT(widget), "clicked",
- full_name_clicked, e_contact_editor);
+ g_free (address_label);
+ if (address)
+ g_boxed_free (e_contact_address_get_type (), address);
+}
- widget = glade_xml_get_widget(e_contact_editor->gui, "button-fulladdr");
- if (widget && GTK_IS_BUTTON(widget))
- gtk_signal_connect(GTK_OBJECT(widget), "clicked",
- full_addr_clicked, e_contact_editor);
+static void
+fill_in_address (EContactEditor *editor)
+{
+ gint i;
- widget = glade_xml_get_widget(e_contact_editor->gui, "button-categories");
- if (widget && GTK_IS_BUTTON(widget))
- gtk_signal_connect(GTK_OBJECT(widget), "clicked",
- categories_clicked, e_contact_editor);
+ for (i = 0; i < ADDRESS_SLOTS; i++)
+ fill_in_address_record (editor, i);
+}
- widget = glade_xml_get_widget(e_contact_editor->gui, "button-contacts");
- if (widget && GTK_IS_BUTTON(widget))
- gtk_signal_connect(GTK_OBJECT(widget), "clicked",
- contacts_clicked, e_contact_editor);
+static void
+extract_address_textview (EContactEditor *editor,
+ gint record,
+ EContactAddress *address)
+{
+ gchar *textview_name;
+ GtkWidget *textview;
+ GtkTextBuffer *text_buffer;
+ GtkTextIter iter_1, iter_2;
+ textview_name = g_strdup_printf ("textview-%s-address", address_name[record]);
+ textview = e_builder_get_widget (editor->builder, textview_name);
+ g_free (textview_name);
- /* Construct the app */
- bonobo_win = bonobo_window_new ("contact-editor-dialog", _("Contact Editor"));
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
+ gtk_text_buffer_get_start_iter (text_buffer, &iter_1);
- /* FIXME: The sucking bit */
- {
- GtkWidget *contents;
+ /* Skip blank lines */
+ while (gtk_text_iter_get_chars_in_line (&iter_1) < 1 &&
+ !gtk_text_iter_is_end (&iter_1))
+ gtk_text_iter_forward_line (&iter_1);
- contents = gnome_dock_get_client_area (
- GNOME_DOCK (GNOME_APP (e_contact_editor->app)->dock));
- if (!contents) {
- g_message ("contact_editor_construct(): Could not get contents");
- return;
- }
- gtk_widget_ref (contents);
- gtk_container_remove (GTK_CONTAINER (contents->parent), contents);
- bonobo_window_set_contents (BONOBO_WINDOW (bonobo_win), contents);
- gtk_widget_destroy (e_contact_editor->app);
- e_contact_editor->app = bonobo_win;
- }
+ if (gtk_text_iter_is_end (&iter_1))
+ return;
+
+ iter_2 = iter_1;
+ gtk_text_iter_forward_to_line_end (&iter_2);
- /* Build the menu and toolbar */
+ /* Extract street (first line of text) */
+ address->street = gtk_text_iter_get_text (&iter_1, &iter_2);
- container = bonobo_ui_container_new ();
- bonobo_ui_container_set_win (container, BONOBO_WINDOW (e_contact_editor->app));
+ iter_1 = iter_2;
+ gtk_text_iter_forward_line (&iter_1);
- e_contact_editor->uic = bonobo_ui_component_new_default ();
- if (!e_contact_editor->uic) {
- g_message ("e_contact_editor_init(): eeeeek, could not create the UI handler!");
+ if (gtk_text_iter_is_end (&iter_1))
return;
- }
- bonobo_ui_component_set_container (e_contact_editor->uic,
- bonobo_object_corba_objref (
- BONOBO_OBJECT (container)));
- create_ui (e_contact_editor);
+ gtk_text_iter_forward_to_end (&iter_2);
- widget = glade_xml_get_widget(e_contact_editor->gui, "entry-fullname");
- if (widget)
- gtk_widget_grab_focus (widget);
+ /* Extract extended address (remaining lines of text) */
+ address->ext = gtk_text_iter_get_text (&iter_1, &iter_2);
+}
- /* Connect to the deletion of the dialog */
+static gchar *
+extract_address_field (EContactEditor *editor,
+ gint record,
+ const gchar *widget_field_name)
+{
+ gchar *entry_name;
+ GtkWidget *entry;
- gtk_signal_connect (GTK_OBJECT (e_contact_editor->app), "delete_event",
- GTK_SIGNAL_FUNC (app_delete_event_cb), e_contact_editor);
+ entry_name = g_strdup_printf (
+ "entry-%s-%s", address_name[record], widget_field_name);
+ entry = e_builder_get_widget (editor->builder, entry_name);
+ g_free (entry_name);
- /* set the icon */
- icon_path = g_concat_dir_and_file (EVOLUTION_ICONSDIR, "evolution-contacts-mini.png");
- gnome_window_icon_set_from_file (GTK_WINDOW (e_contact_editor->app), icon_path);
- g_free (icon_path);
+ return g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
}
-void
-e_contact_editor_destroy (GtkObject *object) {
- EContactEditor *e_contact_editor = E_CONTACT_EDITOR(object);
+static gchar *
+append_to_address_label (gchar *address_label,
+ const gchar *part,
+ gboolean newline)
+{
+ gchar *new_address_label;
- if (e_contact_editor->writable_fields) {
- gtk_object_unref(GTK_OBJECT(e_contact_editor->writable_fields));
- }
- if (e_contact_editor->email_list) {
- g_list_foreach(e_contact_editor->email_list, (GFunc) g_free, NULL);
- g_list_free(e_contact_editor->email_list);
- }
- if (e_contact_editor->email_info) {
- g_free(e_contact_editor->email_info);
- }
- if (e_contact_editor->email_popup) {
- gtk_widget_unref(e_contact_editor->email_popup);
- }
-
- if (e_contact_editor->phone_list) {
- g_list_foreach(e_contact_editor->phone_list, (GFunc) g_free, NULL);
- g_list_free(e_contact_editor->phone_list);
- }
- if (e_contact_editor->phone_info) {
- g_free(e_contact_editor->phone_info);
+ if (STRING_IS_EMPTY (part))
+ return address_label;
+
+ if (address_label)
+ new_address_label = g_strjoin (
+ newline ? "\n" : ", ",
+ address_label, part, NULL);
+ else
+ new_address_label = g_strdup (part);
+
+ g_free (address_label);
+ return new_address_label;
+}
+
+static void
+set_address_label (EContact *contact,
+ EContactField field,
+ EContactAddress *address)
+{
+ gchar *address_label = NULL;
+ gboolean format_address;
+ GSettings *settings;
+
+ if (!address) {
+ e_contact_set (contact, field, NULL);
+ return;
}
- if (e_contact_editor->phone_popup) {
- gtk_widget_unref(e_contact_editor->phone_popup);
+
+ settings = g_settings_new ("org.gnome.evolution.addressbook");
+ format_address = g_settings_get_boolean (settings, "address-formatting");
+ g_object_unref (settings);
+
+ if (format_address) {
+ address_label = eab_format_address (
+ contact,
+ (field == E_CONTACT_ADDRESS_LABEL_WORK) ?
+ E_CONTACT_ADDRESS_WORK :
+ E_CONTACT_ADDRESS_HOME);
}
-
- if (e_contact_editor->address_list) {
- g_list_foreach(e_contact_editor->address_list, (GFunc) g_free, NULL);
- g_list_free(e_contact_editor->address_list);
+
+ if (!format_address || !address_label) {
+ address_label = append_to_address_label (
+ address_label, address->street, TRUE);
+ address_label = append_to_address_label (
+ address_label, address->ext, TRUE);
+ address_label = append_to_address_label (
+ address_label, address->locality, TRUE);
+ address_label = append_to_address_label (
+ address_label, address->region, FALSE);
+ address_label = append_to_address_label (
+ address_label, address->code, TRUE);
+ address_label = append_to_address_label (
+ address_label, address->po, TRUE);
+ address_label = append_to_address_label (
+ address_label, address->country, TRUE);
}
- if (e_contact_editor->address_info) {
- g_free(e_contact_editor->address_info);
+
+ e_contact_set (contact, field, address_label);
+ g_free (address_label);
+}
+
+static void
+extract_address_record (EContactEditor *editor,
+ gint record)
+{
+ EContactAddress *address;
+
+ address = g_new0 (EContactAddress, 1);
+
+ extract_address_textview (editor, record, address);
+ address->locality = extract_address_field (editor, record, "city");
+ address->region = extract_address_field (editor, record, "state");
+ address->code = extract_address_field (editor, record, "zip");
+ address->country = extract_address_field (editor, record, "country");
+ address->po = extract_address_field (editor, record, "pobox");
+
+ if (!STRING_IS_EMPTY (address->street) ||
+ !STRING_IS_EMPTY (address->ext) ||
+ !STRING_IS_EMPTY (address->locality) ||
+ !STRING_IS_EMPTY (address->region) ||
+ !STRING_IS_EMPTY (address->code) ||
+ !STRING_IS_EMPTY (address->po) ||
+ !STRING_IS_EMPTY (address->country)) {
+ e_contact_set (editor->contact, addresses[record], address);
+ set_address_label (editor->contact, address_labels[record], address);
}
- if (e_contact_editor->address_popup) {
- gtk_widget_unref(e_contact_editor->address_popup);
+ else {
+ e_contact_set (editor->contact, addresses[record], NULL);
+ set_address_label (editor->contact, address_labels[record], NULL);
}
-
- if (e_contact_editor->simple)
- gtk_object_unref(GTK_OBJECT(e_contact_editor->simple));
- if (e_contact_editor->book)
- gtk_object_unref(GTK_OBJECT(e_contact_editor->book));
+ g_boxed_free (e_contact_address_get_type (), address);
+}
- e_card_name_unref(e_contact_editor->name);
- g_free (e_contact_editor->company);
+static void
+extract_address (EContactEditor *editor)
+{
+ gint i;
- gtk_object_unref(GTK_OBJECT(e_contact_editor->gui));
+ for (i = 0; i < ADDRESS_SLOTS; i++)
+ extract_address_record (editor, i);
}
static void
-command_state_changed (EContactEditor *ce)
+sensitize_address_textview (EContactEditor *editor,
+ gint record,
+ gboolean enabled)
{
- bonobo_ui_component_set_prop (ce->uic,
- "/commands/ContactEditorSaveClose",
- "sensitive",
- ce->changed ? "1" : "0", NULL);
- bonobo_ui_component_set_prop (ce->uic,
- "/commands/ContactEditorSave",
- "sensitive",
- ce->changed ? "1" : "0", NULL);
- bonobo_ui_component_set_prop (ce->uic,
- "/commands/ContactEditorDelete",
- "sensitive",
- (ce->editable && !ce->is_new_card) ? "1" : "0", NULL);
+ gchar *widget_name;
+ GtkWidget *textview;
+ GtkWidget *label;
+
+ widget_name = g_strdup_printf ("textview-%s-address", address_name[record]);
+ textview = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ widget_name = g_strdup_printf ("label-%s-address", address_name[record]);
+ label = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
+
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (textview), enabled);
+ gtk_widget_set_sensitive (label, enabled);
}
static void
-supported_fields_cb (EBook *book, EBookStatus status,
- EList *fields, EContactEditor *ce)
+sensitize_address_field (EContactEditor *editor,
+ gint record,
+ const gchar *widget_field_name,
+ gboolean enabled)
{
- gtk_object_set (GTK_OBJECT (ce),
- "writable_fields", fields,
- NULL);
+ gchar *widget_name;
+ GtkWidget *entry;
+ GtkWidget *label;
+
+ widget_name = g_strdup_printf (
+ "entry-%s-%s", address_name[record], widget_field_name);
+ entry = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
- e_contact_editor_show (ce);
+ widget_name = g_strdup_printf (
+ "label-%s-%s", address_name[record], widget_field_name);
+ label = e_builder_get_widget (editor->builder, widget_name);
+ g_free (widget_name);
- command_state_changed (ce);
+ gtk_editable_set_editable (GTK_EDITABLE (entry), enabled);
+ gtk_widget_set_sensitive (label, enabled);
}
static void
-contact_editor_destroy_notify (void *data)
+sensitize_address_record (EContactEditor *editor,
+ gint record,
+ gboolean enabled)
{
- EContactEditor *ce = E_CONTACT_EDITOR (data);
-
- all_contact_editors = g_slist_remove (all_contact_editors, ce);
+ sensitize_address_textview (editor, record, enabled);
+ sensitize_address_field (editor, record, "city", enabled);
+ sensitize_address_field (editor, record, "state", enabled);
+ sensitize_address_field (editor, record, "zip", enabled);
+ sensitize_address_field (editor, record, "country", enabled);
+ sensitize_address_field (editor, record, "pobox", enabled);
}
-EContactEditor *
-e_contact_editor_new (EBook *book,
- ECard *card,
- gboolean is_new_card,
- gboolean editable)
+static void
+sensitize_address (EContactEditor *editor)
{
- EContactEditor *ce;
+ gint i;
- g_return_val_if_fail (E_IS_BOOK (book), NULL);
- g_return_val_if_fail (E_IS_CARD (card), NULL);
+ for (i = 0; i < ADDRESS_SLOTS; i++) {
+ gboolean enabled = TRUE;
- ce = E_CONTACT_EDITOR (gtk_type_new (E_CONTACT_EDITOR_TYPE));
+ if (!editor->target_editable ||
+ !(is_field_supported (editor, addresses[i]) ||
+ is_field_supported (editor, address_labels[i])))
+ enabled = FALSE;
- all_contact_editors = g_slist_prepend (all_contact_editors, ce);
- gtk_object_weakref (GTK_OBJECT (ce), contact_editor_destroy_notify, ce);
+ sensitize_address_record (editor, i, enabled);
+ }
+}
- gtk_object_set (GTK_OBJECT (ce),
- "book", book,
- "card", card,
- "is_new_card", is_new_card,
- "editable", editable,
- NULL);
+typedef struct {
+ const gchar *widget_name;
+ gint field_id; /* EContactField or -1 */
+ gboolean process_data; /* If we should extract/fill in contents */
+ gboolean desensitize_for_read_only;
+}
+FieldMapping;
+
+/* Table of widgets that interact with simple fields. This table is used to:
+ *
+ * - Fill in data.
+ * - Extract data.
+ * - Set sensitivity based on backend capabilities.
+ * - Set sensitivity based on book writeability. */
+
+static FieldMapping simple_field_map[] = {
+ { "entry-homepage", E_CONTACT_HOMEPAGE_URL, TRUE, TRUE },
+ { "accellabel-homepage", E_CONTACT_HOMEPAGE_URL, FALSE, TRUE },
+
+ { "entry-jobtitle", E_CONTACT_TITLE, TRUE, TRUE },
+ { "label-jobtitle", E_CONTACT_TITLE, FALSE, TRUE },
+
+ { "entry-company", E_CONTACT_ORG, TRUE, TRUE },
+ { "label-company", E_CONTACT_ORG, FALSE, TRUE },
+
+ { "entry-department", E_CONTACT_ORG_UNIT, TRUE, TRUE },
+ { "label-department", E_CONTACT_ORG_UNIT, FALSE, TRUE },
+
+ { "entry-profession", E_CONTACT_ROLE, TRUE, TRUE },
+ { "label-profession", E_CONTACT_ROLE, FALSE, TRUE },
+
+ { "entry-manager", E_CONTACT_MANAGER, TRUE, TRUE },
+ { "label-manager", E_CONTACT_MANAGER, FALSE, TRUE },
+
+ { "entry-assistant", E_CONTACT_ASSISTANT, TRUE, TRUE },
+ { "label-assistant", E_CONTACT_ASSISTANT, FALSE, TRUE },
- if (book)
- e_book_get_supported_fields (book, (EBookFieldsCallback)supported_fields_cb, ce);
+ { "entry-nickname", E_CONTACT_NICKNAME, TRUE, TRUE },
+ { "label-nickname", E_CONTACT_NICKNAME, FALSE, TRUE },
- return ce;
+ { "dateedit-birthday", E_CONTACT_BIRTH_DATE, TRUE, TRUE },
+ { "label-birthday", E_CONTACT_BIRTH_DATE, FALSE, TRUE },
+
+ { "dateedit-anniversary", E_CONTACT_ANNIVERSARY, TRUE, TRUE },
+ { "label-anniversary", E_CONTACT_ANNIVERSARY, FALSE, TRUE },
+
+ { "entry-spouse", E_CONTACT_SPOUSE, TRUE, TRUE },
+ { "label-spouse", E_CONTACT_SPOUSE, FALSE, TRUE },
+
+ { "entry-office", E_CONTACT_OFFICE, TRUE, TRUE },
+ { "label-office", E_CONTACT_OFFICE, FALSE, TRUE },
+
+ { "text-comments", E_CONTACT_NOTE, TRUE, TRUE },
+
+ { "entry-fullname", E_CONTACT_FULL_NAME, TRUE, TRUE },
+ { "button-fullname", E_CONTACT_FULL_NAME, FALSE, TRUE },
+
+ { "entry-categories", E_CONTACT_CATEGORIES, TRUE, TRUE },
+ { "button-categories", E_CONTACT_CATEGORIES, FALSE, TRUE },
+
+ { "entry-weblog", E_CONTACT_BLOG_URL, TRUE, TRUE },
+ { "label-weblog", E_CONTACT_BLOG_URL, FALSE, TRUE },
+
+ { "entry-caluri", E_CONTACT_CALENDAR_URI, TRUE, TRUE },
+ { "label-caluri", E_CONTACT_CALENDAR_URI, FALSE, TRUE },
+
+ { "entry-fburl", E_CONTACT_FREEBUSY_URL, TRUE, TRUE },
+ { "label-fburl", E_CONTACT_FREEBUSY_URL, FALSE, TRUE },
+
+ { "entry-videourl", E_CONTACT_VIDEO_URL, TRUE, TRUE },
+ { "label-videourl", E_CONTACT_VIDEO_URL, FALSE, TRUE },
+
+ { "checkbutton-htmlmail", E_CONTACT_WANTS_HTML, TRUE, TRUE },
+
+ { "image-chooser", E_CONTACT_PHOTO, TRUE, TRUE },
+ { "button-image", E_CONTACT_PHOTO, FALSE, TRUE },
+
+ { "combo-file-as", E_CONTACT_FILE_AS, TRUE, TRUE },
+ { "accellabel-fileas", E_CONTACT_FILE_AS, FALSE, TRUE },
+};
+
+static void
+init_simple_field (EContactEditor *editor,
+ GtkWidget *widget)
+{
+ GObject *changed_object = NULL;
+
+ if (GTK_IS_ENTRY (widget)) {
+ changed_object = G_OBJECT (widget);
+ g_signal_connect_swapped (
+ widget, "activate",
+ G_CALLBACK (entry_activated), editor);
+
+ } else if (GTK_IS_COMBO_BOX (widget)) {
+ changed_object = G_OBJECT (widget);
+ g_signal_connect_swapped (
+ gtk_bin_get_child (GTK_BIN (widget)), "activate",
+ G_CALLBACK (entry_activated), editor);
+
+ } else if (GTK_IS_TEXT_VIEW (widget)) {
+ changed_object = G_OBJECT (
+ gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget)));
+
+ } else if (E_IS_URL_ENTRY (widget)) {
+ changed_object = G_OBJECT (widget);
+ g_signal_connect_swapped (
+ changed_object, "activate",
+ G_CALLBACK (entry_activated), editor);
+
+ } else if (E_IS_DATE_EDIT (widget)) {
+ changed_object = G_OBJECT (widget);
+
+ } else if (E_IS_IMAGE_CHOOSER (widget)) {
+ changed_object = G_OBJECT (widget);
+ g_signal_connect (
+ widget, "changed",
+ G_CALLBACK (image_chooser_changed), editor);
+
+ } else if (GTK_IS_TOGGLE_BUTTON (widget)) {
+ g_signal_connect (
+ widget, "toggled",
+ G_CALLBACK (object_changed), editor);
+ }
+
+ if (changed_object)
+ g_signal_connect (
+ changed_object, "changed",
+ G_CALLBACK (object_changed), editor);
}
static void
-e_contact_editor_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+fill_in_simple_field (EContactEditor *editor,
+ GtkWidget *widget,
+ gint field_id)
{
- EContactEditor *editor;
+ EContact *contact;
- editor = E_CONTACT_EDITOR (o);
-
- switch (arg_id){
- case ARG_BOOK:
- if (editor->book)
- gtk_object_unref(GTK_OBJECT(editor->book));
- editor->book = E_BOOK(GTK_VALUE_OBJECT (*arg));
- gtk_object_ref (GTK_OBJECT (editor->book));
- /* XXX more here about editable/etc. */
- break;
- case ARG_CARD:
- if (editor->card)
- gtk_object_unref(GTK_OBJECT(editor->card));
- editor->card = e_card_duplicate(E_CARD(GTK_VALUE_OBJECT (*arg)));
- gtk_object_set(GTK_OBJECT(editor->simple),
- "card", editor->card,
- NULL);
- fill_in_info(editor);
- editor->changed = FALSE;
- break;
+ contact = editor->contact;
- case ARG_IS_NEW_CARD:
- editor->is_new_card = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE;
- break;
+ g_signal_handlers_block_matched (
+ widget, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor);
- case ARG_EDITABLE: {
- gboolean new_value = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE;
- gboolean changed = (editor->editable != new_value);
+ if (GTK_IS_ENTRY (widget)) {
+ gchar *text = e_contact_get (contact, field_id);
+ gtk_entry_set_text (GTK_ENTRY (widget), STRING_MAKE_NON_NULL (text));
+ g_free (text);
+
+ } else if (GTK_IS_COMBO_BOX (widget)) {
+ gchar *text = e_contact_get (contact, field_id);
+ gtk_entry_set_text (
+ GTK_ENTRY (gtk_bin_get_child (GTK_BIN (widget))),
+ STRING_MAKE_NON_NULL (text));
+ g_free (text);
+
+ } else if (GTK_IS_TEXT_VIEW (widget)) {
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
+ gchar *text = e_contact_get (contact, field_id);
+ gtk_text_buffer_set_text (buffer, STRING_MAKE_NON_NULL (text), -1);
+ g_free (text);
+
+ } else if (E_IS_URL_ENTRY (widget)) {
+ gchar *text = e_contact_get (contact, field_id);
+ gtk_entry_set_text (
+ GTK_ENTRY (widget), STRING_MAKE_NON_NULL (text));
+ g_free (text);
+
+ } else if (E_IS_DATE_EDIT (widget)) {
+ EContactDate *date = e_contact_get (contact, field_id);
+ if (date)
+ e_date_edit_set_date (
+ E_DATE_EDIT (widget),
+ date->year, date->month, date->day);
+ else
+ e_date_edit_set_time (E_DATE_EDIT (widget), -1);
+
+ e_contact_date_free (date);
+
+ } else if (E_IS_IMAGE_CHOOSER (widget)) {
+ EContactPhoto *photo = e_contact_get (contact, field_id);
+ editor->image_set = FALSE;
+ if (photo && photo->type == E_CONTACT_PHOTO_TYPE_INLINED) {
+ e_image_chooser_set_image_data (
+ E_IMAGE_CHOOSER (widget),
+ (gchar *) photo->data.inlined.data,
+ photo->data.inlined.length);
+ editor->image_set = TRUE;
+ } else if (photo && photo->type == E_CONTACT_PHOTO_TYPE_URI) {
+ gchar *file_name = g_filename_from_uri (photo->data.uri, NULL, NULL);
+ if (file_name) {
+ e_image_chooser_set_from_file (
+ E_IMAGE_CHOOSER (widget),
+ file_name);
+ editor->image_set = TRUE;
+ g_free (file_name);
+ }
+ }
- editor->editable = new_value;
+ if (!editor->image_set) {
+ gchar *file_name;
- if (changed) {
- set_editable (editor);
- command_state_changed (editor);
+ file_name = e_icon_factory_get_icon_filename (
+ "avatar-default", GTK_ICON_SIZE_DIALOG);
+ e_image_chooser_set_from_file (
+ E_IMAGE_CHOOSER (widget), file_name);
+ editor->image_set = FALSE;
+ g_free (file_name);
}
- break;
- }
- case ARG_CHANGED: {
- gboolean new_value = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE;
- gboolean changed = (editor->changed != new_value);
+ editor->image_changed = FALSE;
+ e_contact_photo_free (photo);
- editor->changed = new_value;
+ } else if (GTK_IS_TOGGLE_BUTTON (widget)) {
+ gboolean val = e_contact_get (contact, field_id) != NULL;
- if (changed)
- command_state_changed (editor);
- break;
- }
- case ARG_WRITABLE_FIELDS:
- if (editor->writable_fields)
- gtk_object_unref(GTK_OBJECT(editor->writable_fields));
- editor->writable_fields = GTK_VALUE_POINTER (*arg);
- if (editor->writable_fields)
- gtk_object_ref (GTK_OBJECT (editor->writable_fields));
- else
- editor->writable_fields = e_list_new(NULL, NULL, NULL);
- enable_writable_fields (editor);
- break;
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), val);
+
+ } else {
+ g_warning (G_STRLOC ": Unhandled widget class in mappings!");
}
+
+ g_signal_handlers_unblock_matched (
+ widget, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor);
}
static void
-e_contact_editor_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+extract_simple_field (EContactEditor *editor,
+ GtkWidget *widget,
+ gint field_id)
{
- EContactEditor *e_contact_editor;
+ EContact *contact;
- e_contact_editor = E_CONTACT_EDITOR (object);
+ contact = editor->contact;
- switch (arg_id) {
- case ARG_BOOK:
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(e_contact_editor->book);
- break;
+ if (GTK_IS_ENTRY (widget)) {
+ const gchar *text = gtk_entry_get_text (GTK_ENTRY (widget));
+ e_contact_set (contact, field_id, (gchar *) text);
- case ARG_CARD:
- e_card_simple_sync_card(e_contact_editor->simple);
- extract_info(e_contact_editor);
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(e_contact_editor->card);
- break;
+ } else if (GTK_IS_COMBO_BOX_TEXT (widget)) {
+ gchar *text = NULL;
- case ARG_IS_NEW_CARD:
- GTK_VALUE_BOOL (*arg) = e_contact_editor->is_new_card ? TRUE : FALSE;
- break;
+ if (gtk_combo_box_get_has_entry (GTK_COMBO_BOX (widget))) {
+ GtkWidget *entry = gtk_bin_get_child (GTK_BIN (widget));
- case ARG_EDITABLE:
- GTK_VALUE_BOOL (*arg) = e_contact_editor->editable ? TRUE : FALSE;
- break;
+ text = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+ }
- case ARG_CHANGED:
- GTK_VALUE_BOOL (*arg) = e_contact_editor->changed ? TRUE : FALSE;
- break;
+ if (!text)
+ text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (widget));
+
+ e_contact_set (contact, field_id, text);
+
+ g_free (text);
+ } else if (GTK_IS_COMBO_BOX (widget)) {
+ GtkTreeIter iter;
+ gchar *text = NULL;
+
+ if (gtk_combo_box_get_has_entry (GTK_COMBO_BOX (widget))) {
+ GtkWidget *entry = gtk_bin_get_child (GTK_BIN (widget));
+
+ text = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+ }
+
+ if (!text && gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter)) {
+ GtkListStore *store;
- case ARG_WRITABLE_FIELDS:
- if (e_contact_editor->writable_fields)
- GTK_VALUE_POINTER (*arg) = e_list_duplicate (e_contact_editor->writable_fields);
+ store = GTK_LIST_STORE (
+ gtk_combo_box_get_model (
+ GTK_COMBO_BOX (widget)));
+
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (store), &iter,
+ 0, &text,
+ -1);
+ }
+
+ e_contact_set (contact, field_id, text);
+
+ g_free (text);
+
+ } else if (GTK_IS_TEXT_VIEW (widget)) {
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
+ GtkTextIter start, end;
+ gchar *text;
+
+ gtk_text_buffer_get_start_iter (buffer, &start);
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+ e_contact_set (contact, field_id, text);
+ g_free (text);
+
+ } else if (E_IS_URL_ENTRY (widget)) {
+ const gchar *text = gtk_entry_get_text (GTK_ENTRY (widget));
+ e_contact_set (contact, field_id, (gchar *) text);
+
+ } else if (E_IS_DATE_EDIT (widget)) {
+ EContactDate date;
+ if (e_date_edit_get_date (
+ E_DATE_EDIT (widget),
+ (gint *) &date.year,
+ (gint *) &date.month,
+ (gint *) &date.day))
+ e_contact_set (contact, field_id, &date);
else
- GTK_VALUE_POINTER (*arg) = NULL;
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
+ e_contact_set (contact, field_id, NULL);
+
+ } else if (E_IS_IMAGE_CHOOSER (widget)) {
+ EContactPhoto photo;
+ photo.type = E_CONTACT_PHOTO_TYPE_INLINED;
+ photo.data.inlined.mime_type = NULL;
+ if (editor->image_changed) {
+ gchar *img_buff = NULL;
+ if (editor->image_set &&
+ e_image_chooser_get_image_data (
+ E_IMAGE_CHOOSER (widget),
+ &img_buff, &photo.data.inlined.length)) {
+ GdkPixbuf *pixbuf, *new;
+ GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
+
+ photo.data.inlined.data = (guchar *) img_buff;
+ img_buff = NULL;
+ gdk_pixbuf_loader_write (
+ loader,
+ photo.data.inlined.data,
+ photo.data.inlined.length, NULL);
+ gdk_pixbuf_loader_close (loader, NULL);
+
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+ if (pixbuf) {
+ gint width, height, prompt_response;
+
+ g_object_ref (pixbuf);
+
+ height = gdk_pixbuf_get_height (pixbuf);
+ width = gdk_pixbuf_get_width (pixbuf);
+ if ((height > 96 || width > 96)) {
+
+ prompt_response =
+ e_alert_run_dialog_for_args
+ (GTK_WINDOW (editor->app),
+ "addressbook:prompt-resize",
+ NULL);
+
+ if (prompt_response == GTK_RESPONSE_YES) {
+ if (width > height) {
+ height = height * 96 / width;
+ width = 96;
+ } else {
+ width = width *96 / height;
+ height = 96;
+ }
+
+ new = e_icon_factory_pixbuf_scale (pixbuf, width, height);
+ if (new) {
+ GdkPixbufFormat *format =
+ gdk_pixbuf_loader_get_format (loader);
+ gchar *format_name =
+ gdk_pixbuf_format_get_name (format);
+ g_free (photo.data.inlined.data);
+ gdk_pixbuf_save_to_buffer (
+ new, &img_buff,
+ &photo.data.inlined.length,
+ format_name, NULL, NULL);
+ photo.data.inlined.data = (guchar *) img_buff;
+ img_buff = NULL;
+ g_free (format_name);
+ g_object_unref (new);
+ }
+ } else if (prompt_response == GTK_RESPONSE_CANCEL) {
+ g_object_unref (pixbuf);
+ g_object_unref (loader);
+ return;
+ }
+ }
+ g_object_unref (pixbuf);
+ }
+ editor->image_changed = FALSE;
+ g_object_unref (loader);
+
+ e_contact_set (contact, field_id, &photo);
+
+ g_free (photo.data.inlined.data);
+
+ } else {
+ editor->image_changed = FALSE;
+ e_contact_set (contact, E_CONTACT_PHOTO, NULL);
+ }
+ }
+
+ } else if (GTK_IS_TOGGLE_BUTTON (widget)) {
+ gboolean val;
+
+ val = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
+ e_contact_set (contact, field_id, val ? (gpointer) 1 : NULL);
+
+ } else {
+ g_warning (G_STRLOC ": Unhandled widget class in mappings!");
}
}
static void
-_popup_position(GtkMenu *menu,
- gint *x,
- gint *y,
- gpointer data)
+sensitize_simple_field (GtkWidget *widget,
+ gboolean enabled)
+{
+ if (GTK_IS_ENTRY (widget))
+ gtk_editable_set_editable (GTK_EDITABLE (widget), enabled);
+ else if (GTK_IS_TEXT_VIEW (widget))
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (widget), enabled);
+ else if (E_IS_DATE_EDIT (widget))
+ e_date_edit_set_editable (E_DATE_EDIT (widget), enabled);
+ else
+ gtk_widget_set_sensitive (widget, enabled);
+}
+
+static void
+init_simple (EContactEditor *editor)
{
- GtkWidget *button = GTK_WIDGET(data);
- GtkRequisition request;
- int mh, mw;
- gdk_window_get_origin (button->window, x, y);
- *x += button->allocation.width;
- *y += button->allocation.height;
+ GtkWidget *widget;
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (simple_field_map); i++) {
+ widget = e_builder_get_widget (
+ editor->builder, simple_field_map[i].widget_name);
+ if (!widget)
+ continue;
- gtk_widget_size_request(GTK_WIDGET(menu), &request);
+ init_simple_field (editor, widget);
+ }
+
+ /* --- Special cases --- */
+
+ /* Update file_as */
- mh = request.height;
- mw = request.width;
+ widget = e_builder_get_widget (editor->builder, "entry-fullname");
+ g_signal_connect (
+ widget, "changed",
+ G_CALLBACK (name_entry_changed), editor);
- *x -= mw;
- if (*x < 0)
- *x = 0;
-
- if (*y < 0)
- *y = 0;
-
- if ((*x + mw) > gdk_screen_width ())
- *x = gdk_screen_width () - mw;
-
- if ((*y + mh) > gdk_screen_height ())
- *y = gdk_screen_height () - mh;
+ widget = e_builder_get_widget (editor->builder, "combo-file-as");
+ gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (widget), 0);
+ g_signal_connect (
+ widget, "changed",
+ G_CALLBACK (file_as_combo_changed), editor);
+
+ widget = e_builder_get_widget (editor->builder, "entry-company");
+ g_signal_connect (
+ widget, "changed",
+ G_CALLBACK (company_entry_changed), editor);
}
-static gint
-_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor, GtkWidget *popup, GList **list, GnomeUIInfo **info, gchar *label, gchar *entry, gchar *dialog_title)
-{
- gint menu_item;
- gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "button_press_event");
- gtk_widget_realize(popup);
- menu_item = gnome_popup_menu_do_popup_modal(popup, _popup_position, widget, button, editor);
- if ( menu_item != -1 ) {
-#if 0
- if (menu_item == g_list_length (*list)) {
- e_contact_editor_build_dialog(editor, entry, label, dialog_title, list, info);
- } else {
-#endif
- GtkWidget *label_widget = glade_xml_get_widget(editor->gui, label);
- if (label_widget && GTK_IS_LABEL(label_widget)) {
- gtk_object_set(GTK_OBJECT(label_widget),
- "label", _(g_list_nth_data(*list, menu_item)),
- NULL);
- }
-#if 0
- }
-#endif
+static void
+fill_in_simple (EContactEditor *editor)
+{
+ EContactName *name;
+ gchar *filename;
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (simple_field_map); i++) {
+ GtkWidget *widget;
+
+ if (simple_field_map[i].field_id < 0 ||
+ !simple_field_map[i].process_data)
+ continue;
+
+ widget = e_builder_get_widget (
+ editor->builder, simple_field_map[i].widget_name);
+ if (!widget)
+ continue;
+
+ fill_in_simple_field (
+ editor, widget, simple_field_map[i].field_id);
}
- return menu_item;
+
+ /* --- Special cases --- */
+
+ /* Update broken-up name */
+
+ g_object_get (editor->contact, "name", &name, NULL);
+
+ if (editor->name)
+ e_contact_name_free (editor->name);
+
+ editor->name = name;
+
+ /* Update the contact editor title */
+
+ filename = (gchar *) e_contact_get (editor->contact, E_CONTACT_FILE_AS);
+
+ if (filename) {
+ gchar *title;
+ title = g_strdup_printf (_("Contact Editor - %s"), filename);
+ gtk_window_set_title (GTK_WINDOW (editor->app), title);
+ g_free (title);
+ g_free (filename);
+ } else
+ gtk_window_set_title (
+ GTK_WINDOW (editor->app), _("Contact Editor"));
+
+ /* Update file_as combo options */
+
+ update_file_as_combo (editor);
}
static void
-e_contact_editor_build_ui_info(GList *list, GnomeUIInfo **infop)
+extract_simple (EContactEditor *editor)
{
- GnomeUIInfo *info;
- GnomeUIInfo singleton = { GNOME_APP_UI_TOGGLEITEM, NULL, NULL, NULL, NULL, NULL, GNOME_APP_PIXMAP_NONE, 0, 0, 0, NULL };
- GnomeUIInfo end = GNOMEUIINFO_END;
- int length;
- int i;
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (simple_field_map); i++) {
+ GtkWidget *widget;
- info = *infop;
+ if (simple_field_map[i].field_id < 0 ||
+ !simple_field_map[i].process_data)
+ continue;
+
+ widget = e_builder_get_widget (
+ editor->builder, simple_field_map[i].widget_name);
+ if (!widget)
+ continue;
- if ( info )
- g_free(info);
- length = g_list_length( list );
- info = g_new(GnomeUIInfo, length + 2);
- for (i = 0; i < length; i++) {
- info[i] = singleton;
- info[i].label = _(list->data);
- list = list->next;
+ extract_simple_field (
+ editor, widget, simple_field_map[i].field_id);
}
- info[i] = end;
- *infop = info;
+ /* Special cases */
+
+ e_contact_set (editor->contact, E_CONTACT_NAME, editor->name);
}
static void
-e_contact_editor_build_phone_ui (EContactEditor *editor)
+sensitize_simple (EContactEditor *editor)
{
- int i;
+ gint 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]));
- }
- }
- if (editor->phone_info == NULL) {
- e_contact_editor_build_ui_info(editor->phone_list, &editor->phone_info);
-
- if ( editor->phone_popup )
- gtk_widget_unref(editor->phone_popup);
-
- editor->phone_popup = gnome_popup_menu_new(editor->phone_info);
+ for (i = 0; i < G_N_ELEMENTS (simple_field_map); i++) {
+ GtkWidget *widget;
+ gboolean enabled = TRUE;
+
+ widget = e_builder_get_widget (
+ editor->builder, simple_field_map[i].widget_name);
+ if (!widget)
+ continue;
+
+ if (simple_field_map[i].field_id >= 0 &&
+ !is_field_supported (editor, simple_field_map[i].field_id))
+ enabled = FALSE;
+
+ if (simple_field_map[i].desensitize_for_read_only &&
+ !editor->target_editable)
+ enabled = FALSE;
+
+ sensitize_simple_field (widget, enabled);
}
}
static void
-e_contact_editor_build_email_ui (EContactEditor *editor)
+fill_in_all (EContactEditor *editor)
{
- int i;
+ fill_in_source_field (editor);
+ fill_in_simple (editor);
+ fill_in_email (editor);
+ fill_in_phone (editor);
+ fill_in_im (editor);
+ fill_in_address (editor);
+}
- 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]));
- }
+static void
+extract_all (EContactEditor *editor)
+{
+ extract_simple (editor);
+ extract_email (editor);
+ extract_phone (editor);
+ extract_im (editor);
+ extract_address (editor);
+}
+
+static void
+sensitize_all (EContactEditor *editor)
+{
+ sensitize_ok (editor);
+ sensitize_simple (editor);
+ sensitize_email (editor);
+ sensitize_phone (editor);
+ sensitize_im (editor);
+ sensitize_address (editor);
+}
+
+static void
+init_all (EContactEditor *editor)
+{
+ const gchar *contents[] = { "viewport1", "viewport2", "viewport3", "text-comments" };
+ gint ii;
+ GtkRequisition tab_req, requisition;
+ GtkWidget *widget;
+
+ init_simple (editor);
+ init_email (editor);
+ init_phone (editor);
+ init_im (editor);
+ init_personal (editor);
+ init_address (editor);
+
+ /* with so many scrolled windows, we need to
+ * do some manual sizing */
+ requisition.width = -1;
+ requisition.height = -1;
+
+ for (ii = 0; ii < G_N_ELEMENTS (contents); ii++) {
+ widget = e_builder_get_widget (editor->builder, contents[ii]);
+
+ gtk_widget_get_preferred_size (widget, NULL, &tab_req);
+
+ if (tab_req.width > requisition.width)
+ requisition.width = tab_req.width;
+ if (tab_req.height > requisition.height)
+ requisition.height = tab_req.height;
}
- if (editor->email_info == NULL) {
- e_contact_editor_build_ui_info(editor->email_list, &editor->email_info);
- if ( editor->email_popup )
- gtk_widget_unref(editor->email_popup);
-
- editor->email_popup = gnome_popup_menu_new(editor->email_info);
+ if (requisition.width > 0 && requisition.height > 0) {
+ GtkWindow *window;
+ GdkScreen *screen;
+ GdkRectangle monitor_area;
+ gint x = 0, y = 0, monitor, width, height;
+
+ window = GTK_WINDOW (e_builder_get_widget (editor->builder, "contact editor"));
+
+ gtk_widget_get_preferred_size (GTK_WIDGET (window), &tab_req, NULL);
+ width = tab_req.width - 320 + 24;
+ height = tab_req.height - 240 + 24;
+
+ screen = gtk_window_get_screen (window);
+ gtk_window_get_position (window, &x, &y);
+
+ monitor = gdk_screen_get_monitor_at_point (screen, x, y);
+ if (monitor < 0 || monitor >= gdk_screen_get_n_monitors (screen))
+ monitor = 0;
+
+ gdk_screen_get_monitor_workarea (screen, monitor, &monitor_area);
+
+ if (requisition.width > monitor_area.width - width)
+ requisition.width = monitor_area.width - width;
+
+ if (requisition.height > monitor_area.height - height)
+ requisition.height = monitor_area.height - height;
+
+ if (requisition.width > 0 && requisition.height > 0)
+ gtk_window_set_default_size (window, width + requisition.width, height + requisition.height);
}
}
static void
-e_contact_editor_build_address_ui (EContactEditor *editor)
+contact_editor_get_client_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- int i;
+ EClientComboBox *combo_box;
+ ConnectClosure *closure = user_data;
+ EClient *client;
+ GError *error = NULL;
- if (editor->address_list == NULL) {
- static char *info[] = {
- N_("Business"),
- N_("Home"),
- N_("Other")
- };
-
- for (i = 0; i < sizeof(info) / sizeof(info[0]); i++) {
- editor->address_list = g_list_append(editor->address_list, g_strdup(info[i]));
- }
+ combo_box = E_CLIENT_COMBO_BOX (source_object);
+
+ client = e_client_combo_box_get_client_finish (
+ combo_box, result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_warn_if_fail (client == NULL);
+ g_error_free (error);
+ goto exit;
+
+ } else if (error != NULL) {
+ GtkWindow *parent;
+
+ parent = eab_editor_get_window (EAB_EDITOR (closure->editor));
+
+ eab_load_error_dialog (
+ GTK_WIDGET (parent), NULL,
+ closure->source, error);
+
+ e_source_combo_box_set_active (
+ E_SOURCE_COMBO_BOX (combo_box),
+ closure->source);
+
+ g_error_free (error);
+ goto exit;
}
- if (editor->address_info == NULL) {
- e_contact_editor_build_ui_info(editor->address_list, &editor->address_info);
- if ( editor->address_popup )
- gtk_widget_unref(editor->address_popup);
-
- editor->address_popup = gnome_popup_menu_new(editor->address_info);
+ /* FIXME Write a private contact_editor_set_target_client(). */
+ g_object_set (closure->editor, "target_client", client, NULL);
+
+ g_object_unref (client);
+
+exit:
+ connect_closure_free (closure);
+}
+
+static void
+source_changed (EClientComboBox *combo_box,
+ EContactEditor *editor)
+{
+ ConnectClosure *closure;
+ ESource *target_source;
+ ESource *source_source;
+ ESource *source;
+
+ source = e_source_combo_box_ref_active (
+ E_SOURCE_COMBO_BOX (combo_box));
+ g_return_if_fail (source != NULL);
+
+ if (editor->cancellable != NULL) {
+ g_cancellable_cancel (editor->cancellable);
+ g_object_unref (editor->cancellable);
+ editor->cancellable = NULL;
}
+
+ target_source = e_client_get_source (E_CLIENT (editor->target_client));
+ source_source = e_client_get_source (E_CLIENT (editor->source_client));
+
+ if (e_source_equal (target_source, source))
+ goto exit;
+
+ if (e_source_equal (source_source, source)) {
+ g_object_set (
+ editor, "target_client",
+ editor->source_client, NULL);
+ goto exit;
+ }
+
+ editor->cancellable = g_cancellable_new ();
+
+ closure = g_slice_new0 (ConnectClosure);
+ closure->editor = g_object_ref (editor);
+ closure->source = g_object_ref (source);
+
+ e_client_combo_box_get_client (
+ combo_box, source,
+ editor->cancellable,
+ contact_editor_get_client_cb,
+ closure);
+
+exit:
+ g_object_unref (source);
}
-#if 0
+
static void
-_dialog_clicked(GtkWidget *dialog, gint button, EContactEditor *editor)
+full_name_response (GtkDialog *dialog,
+ gint response,
+ EContactEditor *editor)
{
- GtkWidget *label = gtk_object_get_data(GTK_OBJECT(dialog),
- "e_contact_editor_label");
+ EContactName *name;
+ GtkWidget *fname_widget;
+ gint style = 0;
+ gboolean editable = FALSE;
- GtkWidget *dialog_entry = gtk_object_get_data(GTK_OBJECT(dialog),
- "e_contact_editor_dialog_entry");
-
- GList **list = gtk_object_get_data(GTK_OBJECT(dialog),
- "e_contact_editor_list");
- GList **info = gtk_object_get_data(GTK_OBJECT(dialog),
- "e_contact_editor_info");
- switch (button) {
- case 0:
- if (label && GTK_IS_LABEL(label)) {
- gtk_object_set(GTK_OBJECT(label),
- "label", gtk_entry_get_text(GTK_ENTRY(dialog_entry)),
- NULL);
- *list = g_list_append(*list, e_utf8_gtk_entry_get_text(GTK_ENTRY(dialog_entry)));
- g_free(*info);
- *info = NULL;
+ g_object_get (dialog, "editable", &editable, NULL);
+
+ if (editable && response == GTK_RESPONSE_OK) {
+ g_object_get (dialog, "name", &name, NULL);
+
+ style = file_as_get_style (editor);
+
+ fname_widget = e_builder_get_widget (
+ editor->builder, "entry-fullname");
+
+ if (GTK_IS_ENTRY (fname_widget)) {
+ GtkEntry *entry;
+ gchar *full_name = e_contact_name_to_string (name);
+ const gchar *old_full_name;
+
+ entry = GTK_ENTRY (fname_widget);
+ old_full_name = gtk_entry_get_text (entry);
+
+ if (strcmp (full_name, old_full_name))
+ gtk_entry_set_text (entry, full_name);
+ g_free (full_name);
}
- break;
+
+ e_contact_name_free (editor->name);
+ editor->name = name;
+
+ file_as_set_style (editor, style);
}
- gnome_dialog_close(GNOME_DIALOG(dialog));
-}
-
-static void
-_dialog_destroy(EContactEditor *editor, GtkWidget *dialog)
-{
- gnome_dialog_close(GNOME_DIALOG(dialog));
-}
-
-static GtkWidget *
-e_contact_editor_build_dialog(EContactEditor *editor, gchar *entry_id, gchar *label_id, gchar *title, GList **list, GnomeUIInfo **info)
-{
- GtkWidget *dialog_entry = gtk_entry_new();
- GtkWidget *entry = glade_xml_get_widget(editor->gui, entry_id);
- GtkWidget *label = glade_xml_get_widget(editor->gui, label_id);
-
- GtkWidget *dialog = gnome_dialog_new(title,
- NULL);
-
- gtk_container_add(GTK_CONTAINER(GNOME_DIALOG(dialog)->vbox),
- gtk_widget_new (gtk_frame_get_type(),
- "border_width", 4,
- "label", title,
- "child", gtk_widget_new(gtk_alignment_get_type(),
- "child", dialog_entry,
- "xalign", .5,
- "yalign", .5,
- "xscale", 1.0,
- "yscale", 1.0,
- "border_width", 9,
- NULL),
- NULL));
-
- gnome_dialog_append_button_with_pixmap(GNOME_DIALOG(dialog),
- "Add",
- GNOME_STOCK_PIXMAP_ADD);
- gnome_dialog_append_button(GNOME_DIALOG(dialog), GNOME_STOCK_BUTTON_CANCEL);
- gnome_dialog_set_default(GNOME_DIALOG(dialog), 0);
-
- gtk_signal_connect(GTK_OBJECT(dialog), "clicked",
- _dialog_clicked, editor);
- gtk_signal_connect_while_alive(GTK_OBJECT(editor), "destroy",
- _dialog_destroy, GTK_OBJECT(dialog), GTK_OBJECT(dialog));
-
- gtk_object_set_data(GTK_OBJECT(dialog),
- "e_contact_editor_entry", entry);
- gtk_object_set_data(GTK_OBJECT(dialog),
- "e_contact_editor_label", label);
- gtk_object_set_data(GTK_OBJECT(dialog),
- "e_contact_editor_dialog_entry", dialog_entry);
- gtk_object_set_data(GTK_OBJECT(dialog),
- "e_contact_editor_list", list);
- gtk_object_set_data(GTK_OBJECT(dialog),
- "e_contact_editor_info", info);
-
- gtk_widget_show_all(dialog);
- return dialog;
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ editor->fullname_dialog = NULL;
+}
+
+static gint
+full_name_editor_delete_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data)
+{
+ if (GTK_IS_WIDGET (widget))
+ gtk_widget_destroy (widget);
+
+ return TRUE;
}
-#endif
static void
-_phone_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor)
-{
- int which;
- int i;
- gchar *label;
- gchar *entry;
- int result;
- if ( widget == glade_xml_get_widget(editor->gui, "button-phone1") ) {
- which = 1;
- } else if ( widget == glade_xml_get_widget(editor->gui, "button-phone2") ) {
- which = 2;
- } else if ( widget == glade_xml_get_widget(editor->gui, "button-phone3") ) {
- which = 3;
- } else if ( widget == glade_xml_get_widget(editor->gui, "button-phone4") ) {
- which = 4;
- } else
- return;
-
- label = g_strdup_printf("label-phone%d", which);
- entry = g_strdup_printf("entry-phone%d", which);
+full_name_clicked (GtkWidget *button,
+ EContactEditor *editor)
+{
+ GtkDialog *dialog;
+ gboolean fullname_supported;
- 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;
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(editor->phone_info[i].widget),
- checked);
- gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(editor->phone_info[i].widget),
- TRUE);
- }
-
- result = _arrow_pressed (widget, button, editor, editor->phone_popup, &editor->phone_list, &editor->phone_info, label, entry, "Add new phone number type");
-
- if (result != -1) {
- editor->phone_choice[which - 1] = 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);
+ if (editor->fullname_dialog) {
+ gtk_window_present (GTK_WINDOW (editor->fullname_dialog));
+ return;
}
- g_free(label);
- g_free(entry);
+ dialog = GTK_DIALOG (e_contact_editor_fullname_new (editor->name));
+ fullname_supported = is_field_supported (editor, E_CONTACT_FULL_NAME);
+
+ g_object_set (
+ dialog, "editable",
+ fullname_supported & editor->target_editable, NULL);
+
+ g_signal_connect (
+ dialog, "response",
+ G_CALLBACK (full_name_response), editor);
+
+ /* Close the fullname dialog if the editor is closed */
+ g_signal_connect_swapped (
+ editor, "editor_closed",
+ G_CALLBACK (full_name_editor_delete_event_cb), dialog);
+
+ gtk_widget_show (GTK_WIDGET (dialog));
+ editor->fullname_dialog = GTK_WIDGET (dialog);
}
static void
-_email_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor)
+categories_response (GtkDialog *dialog,
+ gint response,
+ EContactEditor *editor)
{
- int i;
- int result;
+ gchar *categories;
+ GtkWidget *entry;
- e_contact_editor_build_email_ui (editor);
+ entry = e_builder_get_widget (editor->builder, "entry-categories");
- for(i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i++) {
- const char *string = e_card_simple_get_email(editor->simple, i);
- gboolean checked;
- checked = string && *string;
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(editor->email_info[i].widget),
- checked);
- gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(editor->email_info[i].widget),
- TRUE);
+ if (response == GTK_RESPONSE_OK) {
+ categories = e_categories_dialog_get_categories (
+ E_CATEGORIES_DIALOG (dialog));
+ if (GTK_IS_ENTRY (entry))
+ gtk_entry_set_text (
+ GTK_ENTRY (entry), categories);
+ else
+ e_contact_set (
+ editor->contact,
+ E_CONTACT_CATEGORIES,
+ categories);
+ g_free (categories);
}
-
- result = _arrow_pressed (widget, button, editor, editor->email_popup, &editor->email_list, &editor->email_info, "label-email1", "entry-email1", "Add new Email type");
-
- if (result != -1) {
- editor->email_choice = result;
- 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 (glade_xml_get_widget (editor->gui, "checkbutton-htmlmail"), editor->editable);
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ editor->categories_dialog = NULL;
+}
+
+static gint
+categories_editor_delete_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data)
+{
+ if (GTK_IS_WIDGET (widget))
+ gtk_widget_destroy (widget);
+
+ return TRUE;
+}
+
+static void
+categories_clicked (GtkWidget *button,
+ EContactEditor *editor)
+{
+ gchar *categories = NULL;
+ GtkDialog *dialog;
+ GtkWidget *entry = e_builder_get_widget (editor->builder, "entry-categories");
+
+ if (entry && GTK_IS_ENTRY (entry))
+ categories = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
+ else if (editor->contact)
+ categories = e_contact_get (editor->contact, E_CONTACT_CATEGORIES);
+
+ if (editor->categories_dialog != NULL) {
+ gtk_window_present (GTK_WINDOW (editor->categories_dialog));
+ g_free (categories);
+ return;
+ }else if (!(dialog = GTK_DIALOG (e_categories_dialog_new (categories)))) {
+ e_alert_run_dialog_for_args (
+ GTK_WINDOW (editor->app),
+ "addressbook:edit-categories", NULL);
+ g_free (categories);
+ return;
}
+
+ g_signal_connect (
+ dialog, "response",
+ G_CALLBACK (categories_response), editor);
+
+ /* Close the category dialog if the editor is closed*/
+ g_signal_connect_swapped (
+ editor, "editor_closed",
+ G_CALLBACK (categories_editor_delete_event_cb), dialog);
+
+ gtk_widget_show (GTK_WIDGET (dialog));
+ g_free (categories);
+
+ editor->categories_dialog = GTK_WIDGET (dialog);
}
static void
-_address_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor)
+image_selected (EContactEditor *editor)
{
- int i;
- int result;
+ gchar *file_name;
+ GtkWidget *image_chooser;
- e_contact_editor_build_address_ui (editor);
+ file_name = gtk_file_chooser_get_filename (
+ GTK_FILE_CHOOSER (editor->file_selector));
- for(i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) {
- const ECardAddrLabel *address = e_card_simple_get_address(editor->simple, i);
- gboolean checked;
- checked = address && address->data && *address->data;
- gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(editor->address_info[i].widget),
- checked);
- gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(editor->address_info[i].widget),
- TRUE);
- }
+ if (!file_name)
+ return;
- result = _arrow_pressed (widget, button, editor, editor->address_popup, &editor->address_list, &editor->address_info, "label-address", "text-address", "Add new Address type");
+ image_chooser = e_builder_get_widget (editor->builder, "image-chooser");
- if (result != -1) {
- set_address_field(editor, result);
+ g_signal_handlers_block_by_func (
+ image_chooser, image_chooser_changed, editor);
+ e_image_chooser_set_from_file (
+ E_IMAGE_CHOOSER (image_chooser), file_name);
+ g_signal_handlers_unblock_by_func (
+ image_chooser, image_chooser_changed, editor);
- /* make sure the buttons/entry is/are sensitive */
- enable_widget (glade_xml_get_widget (editor->gui, "label-address"), TRUE);
- enable_widget (glade_xml_get_widget (editor->gui, "text-address"), editor->editable);
- }
+ editor->image_set = TRUE;
+ editor->image_changed = TRUE;
+ object_changed (G_OBJECT (image_chooser), editor);
}
static void
-find_address_mailing (EContactEditor *editor)
+image_cleared (EContactEditor *editor)
{
- const ECardAddrLabel *address;
- int i;
-
- editor->address_mailing = -1;
- for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) {
- address = e_card_simple_get_address(editor->simple, i);
- if (address && (address->flags & E_CARD_ADDR_DEFAULT)) {
- if (editor->address_mailing == -1) {
- editor->address_mailing = i;
- } else {
- ECardAddrLabel *new;
-
- new = e_card_address_label_copy (address);
- new->flags &= ~E_CARD_ADDR_DEFAULT;
- e_card_simple_set_address(editor->simple, i, new);
- e_card_address_label_unref (new);
- }
- }
- }
+ GtkWidget *image_chooser;
+ gchar *file_name;
+
+ image_chooser = e_builder_get_widget (
+ editor->builder, "image-chooser");
+
+ file_name = e_icon_factory_get_icon_filename (
+ "avatar-default", GTK_ICON_SIZE_DIALOG);
+
+ g_signal_handlers_block_by_func (
+ image_chooser, image_chooser_changed, editor);
+ e_image_chooser_set_from_file (
+ E_IMAGE_CHOOSER (image_chooser), file_name);
+ g_signal_handlers_unblock_by_func (
+ image_chooser, image_chooser_changed, editor);
+
+ g_free (file_name);
+
+ editor->image_set = FALSE;
+ editor->image_changed = TRUE;
+ object_changed (G_OBJECT (image_chooser), editor);
}
static void
-set_field(GtkEntry *entry, const char *string)
+file_chooser_response (GtkWidget *widget,
+ gint response,
+ EContactEditor *editor)
{
- char *oldstring = e_utf8_gtk_entry_get_text(entry);
- if (!string)
- string = "";
- if (strcmp(string, oldstring))
- e_utf8_gtk_entry_set_text(entry, string);
- g_free (oldstring);
+ if (response == GTK_RESPONSE_ACCEPT)
+ image_selected (editor);
+ else if (response == GTK_RESPONSE_NO)
+ image_cleared (editor);
+
+ gtk_widget_hide (editor->file_selector);
+}
+
+static gboolean
+file_selector_deleted (GtkWidget *widget)
+{
+ gtk_widget_hide (widget);
+ return TRUE;
}
static void
-set_phone_field(GtkWidget *entry, const ECardPhone *phone)
+update_preview_cb (GtkFileChooser *file_chooser,
+ gpointer data)
{
- set_field(GTK_ENTRY(entry), phone ? phone->number : "");
+ GtkWidget *preview;
+ gchar *filename = NULL;
+ GdkPixbuf *pixbuf;
+
+ gtk_file_chooser_set_preview_widget_active (file_chooser, TRUE);
+ preview = GTK_WIDGET (data);
+ filename = gtk_file_chooser_get_preview_filename (file_chooser);
+ if (filename == NULL)
+ return;
+
+ pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, NULL);
+ if (!pixbuf) {
+ gchar *alternate_file;
+ alternate_file = e_icon_factory_get_icon_filename (
+ "avatar-default", GTK_ICON_SIZE_DIALOG);
+ if (alternate_file) {
+ pixbuf = gdk_pixbuf_new_from_file_at_size (
+ alternate_file, 128, 128, NULL);
+ g_free (alternate_file);
+ }
+ }
+ g_free (filename);
+
+ gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
+ if (pixbuf)
+ g_object_unref (pixbuf);
}
static void
-set_fields(EContactEditor *editor)
+image_clicked (GtkWidget *button,
+ EContactEditor *editor)
{
- GtkWidget *entry;
- GtkWidget *label_widget;
- int i;
+ if (!editor->file_selector) {
+ const gchar *title = _("Please select an image for this contact");
+ const gchar *no_image = _("_No image");
+ GtkImage *preview;
+ GtkFileFilter *filter;
+
+ editor->file_selector = gtk_file_chooser_dialog_new (
+ title, GTK_WINDOW (editor->app),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ no_image, GTK_RESPONSE_NO,
+ NULL);
- entry = glade_xml_get_widget(editor->gui, "entry-phone1");
- if (entry && GTK_IS_ENTRY(entry))
- set_phone_field(entry, e_card_simple_get_phone(editor->simple, editor->phone_choice[0]));
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_add_mime_type (filter, "image/*");
+ gtk_file_chooser_set_filter (
+ GTK_FILE_CHOOSER (editor->file_selector),
+ filter);
+
+ preview = GTK_IMAGE (gtk_image_new ());
+ gtk_file_chooser_set_preview_widget (
+ GTK_FILE_CHOOSER (editor->file_selector),
+ GTK_WIDGET (preview));
+ g_signal_connect (
+ editor->file_selector, "update-preview",
+ G_CALLBACK (update_preview_cb), preview);
+
+ gtk_dialog_set_default_response (
+ GTK_DIALOG (editor->file_selector),
+ GTK_RESPONSE_ACCEPT);
+
+ g_signal_connect (
+ editor->file_selector, "response",
+ G_CALLBACK (file_chooser_response), editor);
+
+ g_signal_connect_after (
+ editor->file_selector, "delete-event",
+ G_CALLBACK (file_selector_deleted),
+ editor->file_selector);
+ }
- entry = glade_xml_get_widget(editor->gui, "entry-phone2");
- if (entry && GTK_IS_ENTRY(entry))
- set_phone_field(entry, e_card_simple_get_phone(editor->simple, editor->phone_choice[1]));
+ /* Display the dialog */
- entry = glade_xml_get_widget(editor->gui, "entry-phone3");
- if (entry && GTK_IS_ENTRY(entry))
- set_phone_field(entry, e_card_simple_get_phone(editor->simple, editor->phone_choice[2]));
+ gtk_window_set_modal (GTK_WINDOW (editor->file_selector), TRUE);
+ gtk_window_present (GTK_WINDOW (editor->file_selector));
+}
- entry = glade_xml_get_widget(editor->gui, "entry-phone4");
- if (entry && GTK_IS_ENTRY(entry))
- set_phone_field(entry, e_card_simple_get_phone(editor->simple, editor->phone_choice[3]));
-
- entry = glade_xml_get_widget(editor->gui, "entry-email1");
- if (entry && GTK_IS_ENTRY(entry))
- set_field(GTK_ENTRY(entry), e_card_simple_get_email(editor->simple, editor->email_choice));
+typedef struct {
+ EContactEditor *ce;
+ gboolean should_close;
+ gchar *new_id;
+} EditorCloseStruct;
+static void
+contact_removed_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ EditorCloseStruct *ecs = user_data;
+ EContactEditor *ce = ecs->ce;
+ gboolean should_close = ecs->should_close;
+ GError *error = NULL;
+ e_book_client_remove_contact_finish (book_client, result, &error);
- e_contact_editor_build_address_ui (editor);
+ gtk_widget_set_sensitive (ce->app, TRUE);
+ ce->in_async_call = FALSE;
- for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) {
- const ECardAddrLabel *address = e_card_simple_get_address(editor->simple, i);
+ e_contact_set (ce->contact, E_CONTACT_UID, ecs->new_id);
- if (address && address->data && *address->data)
- break;
- }
- if (i == E_CARD_SIMPLE_ADDRESS_ID_LAST)
- i = 0;
+ eab_editor_contact_deleted (EAB_EDITOR (ce), error, ce->contact);
+
+ ce->is_new_contact = FALSE;
+
+ if (should_close) {
+ eab_editor_close (EAB_EDITOR (ce));
+ } else {
+ ce->changed = FALSE;
- label_widget = glade_xml_get_widget(editor->gui, "label-address");
- if (label_widget && GTK_IS_LABEL(label_widget)) {
- gtk_object_set(GTK_OBJECT(label_widget),
- "label", _(g_list_nth_data(editor->address_list, i)),
- NULL);
+ g_object_ref (ce->target_client);
+ g_object_unref (ce->source_client);
+ ce->source_client = ce->target_client;
+
+ sensitize_all (ce);
}
- set_address_field(editor, i);
+ if (error)
+ g_error_free (error);
+
+ g_object_unref (ce);
+ g_free (ecs->new_id);
+ g_free (ecs);
}
static void
-set_address_field(EContactEditor *editor, int result)
+contact_added_cb (EBookClient *book_client,
+ const GError *error,
+ const gchar *id,
+ gpointer closure)
{
- GtkWidget *text, *check;
-
- text = glade_xml_get_widget(editor->gui, "text-address");
+ EditorCloseStruct *ecs = closure;
+ EContactEditor *ce = ecs->ce;
+ gboolean should_close = ecs->should_close;
- if (text && GTK_IS_TEXT(text)) {
- int position;
- GtkEditable *editable;
- const ECardAddrLabel *address;
+ if (ce->source_client != ce->target_client && !e_client_is_readonly (E_CLIENT (ce->source_client)) &&
+ !error && ce->is_new_contact == FALSE) {
+ ecs->new_id = g_strdup (id);
+ e_book_client_remove_contact (
+ ce->source_client, ce->contact, NULL, contact_removed_cb, ecs);
+ return;
+ }
- if (result == -1)
- result = editor->address_choice;
- editor->address_choice = -1;
+ gtk_widget_set_sensitive (ce->app, TRUE);
+ ce->in_async_call = FALSE;
- position = 0;
- editable = GTK_EDITABLE(text);
+ e_contact_set (ce->contact, E_CONTACT_UID, id);
- gtk_editable_delete_text(editable, 0, -1);
- address = e_card_simple_get_address(editor->simple, result);
- if (address && address->data) {
- gchar *u = e_utf8_to_gtk_string ((GtkWidget *) editable, address->data);
- gtk_editable_insert_text(editable, u, strlen(u), &position);
- g_free (u);
- }
+ eab_editor_contact_added (EAB_EDITOR (ce), error, ce->contact);
- check = glade_xml_get_widget(editor->gui, "checkbutton-mailingaddress");
- if (check && GTK_IS_CHECK_BUTTON (check)) {
- if (address && address->data)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
- address->flags & E_CARD_ADDR_DEFAULT);
- else
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), FALSE);
+ if (!error) {
+ ce->is_new_contact = FALSE;
+
+ if (should_close) {
+ eab_editor_close (EAB_EDITOR (ce));
+ } else {
+ ce->changed = FALSE;
+ sensitize_all (ce);
}
-
- 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-contacts",
- "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;
+ }
+
+ g_object_unref (ce);
+ g_free (ecs);
+}
+
+static void
+contact_modified_cb (EBookClient *book_client,
+ const GError *error,
+ gpointer closure)
+{
+ EditorCloseStruct *ecs = closure;
+ EContactEditor *ce = ecs->ce;
+ gboolean should_close = ecs->should_close;
+
+ gtk_widget_set_sensitive (ce->app, TRUE);
+ ce->in_async_call = FALSE;
+
+ eab_editor_contact_modified (EAB_EDITOR (ce), error, ce->contact);
+
+ if (!error) {
+ if (should_close) {
+ eab_editor_close (EAB_EDITOR (ce));
}
- if (GTK_IS_ENTRY(widget) || GTK_IS_TEXT(widget)) {
- editor->arbitrary_fields = g_list_prepend(editor->arbitrary_fields, g_strdup(name));
+ else {
+ ce->changed = FALSE;
+ sensitize_all (ce);
}
}
+
+ g_object_unref (ce);
+ g_free (ecs);
}
-static struct {
- char *id;
- char *key;
-} 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" },
-};
+static void
+contact_modified_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ GError *error = NULL;
+
+ e_book_client_modify_contact_finish (book_client, result, &error);
+
+ contact_modified_cb (book_client, error, user_data);
+
+ if (error)
+ g_error_free (error);
+}
+
+/* Emits the signal to request saving a contact */
+static void
+real_save_contact (EContactEditor *ce,
+ gboolean should_close)
+{
+ EShell *shell;
+ EditorCloseStruct *ecs;
+ ESourceRegistry *registry;
+
+ shell = eab_editor_get_shell (EAB_EDITOR (ce));
+ registry = e_shell_get_registry (shell);
+
+ ecs = g_new0 (EditorCloseStruct, 1);
+ ecs->ce = ce;
+ g_object_ref (ecs->ce);
+
+ ecs->should_close = should_close;
+
+ gtk_widget_set_sensitive (ce->app, FALSE);
+ ce->in_async_call = TRUE;
+
+ if (ce->source_client != ce->target_client) {
+ /* Two-step move; add to target, then remove from source */
+ eab_merging_book_add_contact (
+ registry, ce->target_client,
+ ce->contact, contact_added_cb, ecs);
+ } else {
+ if (ce->is_new_contact)
+ eab_merging_book_add_contact (
+ registry, ce->target_client,
+ ce->contact, contact_added_cb, ecs);
+ else if (ce->check_merge)
+ eab_merging_book_modify_contact (
+ registry, ce->target_client,
+ ce->contact, contact_modified_cb, ecs);
+ else
+ e_book_client_modify_contact (
+ ce->target_client, ce->contact, NULL,
+ contact_modified_ready_cb, ecs);
+ }
+}
static void
-fill_in_field(EContactEditor *editor, char *id, char *value)
+save_contact (EContactEditor *ce,
+ gboolean should_close)
{
- GtkWidget *widget = glade_xml_get_widget(editor->gui, id);
- if (widget && GTK_IS_EDITABLE(widget)) {
- int position = 0;
- GtkEditable *editable = GTK_EDITABLE(widget);
- gtk_editable_delete_text(editable, 0, -1);
- if (value) {
- gchar *u = e_utf8_to_gtk_string ((GtkWidget *) editable, value);
- gtk_editable_insert_text(editable, u, strlen(u), &position);
- g_free (u);
+ gchar *uid;
+ const gchar *name_entry_string;
+ const gchar *file_as_entry_string;
+ const gchar *company_name_string;
+ GtkWidget *entry_fullname, *entry_file_as, *company_name;
+
+ if (!ce->target_client)
+ return;
+
+ if (ce->target_editable && e_client_is_readonly (E_CLIENT (ce->source_client))) {
+ if (e_alert_run_dialog_for_args (
+ GTK_WINDOW (ce->app),
+ "addressbook:prompt-move",
+ NULL) == GTK_RESPONSE_NO)
+ return;
+ }
+
+ entry_fullname = e_builder_get_widget (ce->builder, "entry-fullname");
+ entry_file_as = gtk_bin_get_child (
+ GTK_BIN (e_builder_get_widget (ce->builder, "combo-file-as")));
+ company_name = e_builder_get_widget (ce->builder, "entry-company");
+ name_entry_string = gtk_entry_get_text (GTK_ENTRY (entry_fullname));
+ file_as_entry_string = gtk_entry_get_text (GTK_ENTRY (entry_file_as));
+ company_name_string = gtk_entry_get_text (GTK_ENTRY (company_name));
+
+ if (strcmp (company_name_string , "")) {
+ if (!strcmp (name_entry_string, ""))
+ gtk_entry_set_text (
+ GTK_ENTRY (entry_fullname),
+ company_name_string);
+ if (!strcmp (file_as_entry_string, ""))
+ gtk_entry_set_text (
+ GTK_ENTRY (entry_file_as),
+ company_name_string);
+ }
+
+ extract_all (ce);
+
+ if (!e_contact_editor_is_valid (EAB_EDITOR (ce))) {
+ uid = e_contact_get (ce->contact, E_CONTACT_UID);
+ g_object_unref (ce->contact);
+ ce->contact = e_contact_new ();
+ if (uid) {
+ e_contact_set (ce->contact, E_CONTACT_UID, uid);
+ g_free (uid);
}
+ return;
}
+
+ real_save_contact (ce, should_close);
}
static void
-fill_in_card_field(EContactEditor *editor, ECard *card, char *id, char *key)
+e_contact_editor_save_contact (EABEditor *editor,
+ gboolean should_close)
{
- char *string;
- gtk_object_get(GTK_OBJECT(card),
- key, &string,
- NULL);
- fill_in_field(editor, id, string);
+ save_contact (E_CONTACT_EDITOR (editor), should_close);
}
+/* Closes the dialog box and emits the appropriate signals */
static void
-fill_in_single_field(EContactEditor *editor, char *name)
+e_contact_editor_close (EABEditor *editor)
{
- 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;
+ EContactEditor *ce = E_CONTACT_EDITOR (editor);
- gtk_editable_delete_text(editable, 0, -1);
- arbitrary = e_card_simple_get_arbitrary(simple,
- name);
- if (arbitrary && arbitrary->value) {
- gchar *u = e_utf8_to_gtk_string ((GtkWidget *) editable, arbitrary->value);
- gtk_editable_insert_text(editable, u, strlen(u), &position);
- g_free (u);
- }
+ if (ce->app != NULL) {
+ gtk_widget_destroy (ce->app);
+ ce->app = NULL;
+ eab_editor_closed (editor);
}
}
-static void
-disable_widget_foreach (char *key, GtkWidget *widget, gpointer closure)
+static const EContactField non_string_fields[] = {
+ E_CONTACT_FULL_NAME,
+ E_CONTACT_ADDRESS,
+ E_CONTACT_ADDRESS_HOME,
+ E_CONTACT_ADDRESS_WORK,
+ E_CONTACT_ADDRESS_OTHER,
+ E_CONTACT_EMAIL,
+ E_CONTACT_IM_AIM,
+ E_CONTACT_IM_GROUPWISE,
+ E_CONTACT_IM_JABBER,
+ E_CONTACT_IM_YAHOO,
+ E_CONTACT_IM_GADUGADU,
+ E_CONTACT_IM_MSN,
+ E_CONTACT_IM_ICQ,
+ E_CONTACT_IM_SKYPE,
+ E_CONTACT_IM_TWITTER,
+ E_CONTACT_PHOTO,
+ E_CONTACT_LOGO,
+ E_CONTACT_X509_CERT,
+ E_CONTACT_CATEGORY_LIST,
+ E_CONTACT_BIRTH_DATE,
+ E_CONTACT_ANNIVERSARY
+
+};
+
+static gboolean
+is_non_string_field (EContactField id)
{
- enable_widget (widget, FALSE);
+ gint count = sizeof (non_string_fields) / sizeof (EContactField);
+ gint i;
+ for (i = 0; i < count; i++)
+ if (id == non_string_fields[i])
+ return TRUE;
+ return FALSE;
+
}
-static struct {
- char *widget_name;
- ECardSimpleField 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 },
+/* insert checks here (date format, for instance, etc.) */
+static gboolean
+e_contact_editor_is_valid (EABEditor *editor)
+{
+ EContactEditor *ce = E_CONTACT_EDITOR (editor);
+ GtkWidget *widget;
+ gboolean validation_error = FALSE;
+ GSList *iter;
+ GString *errmsg = g_string_new (_("The contact data is invalid:\n\n"));
+ time_t bday, now = time (NULL);
+
+ widget = e_builder_get_widget (ce->builder, "dateedit-birthday");
+ if (!(e_date_edit_date_is_valid (E_DATE_EDIT (widget)))) {
+ g_string_append_printf (
+ errmsg, _("'%s' has an invalid format"),
+ e_contact_pretty_name (E_CONTACT_BIRTH_DATE));
+ validation_error = TRUE;
+ }
+ /* If valid, see if the birthday is a future date */
+ bday = e_date_edit_get_time (E_DATE_EDIT (widget));
+ if (bday > now) {
+ g_string_append_printf (
+ errmsg, _("'%s' cannot be a future date"),
+ e_contact_pretty_name (E_CONTACT_BIRTH_DATE));
+ validation_error = TRUE;
+ }
- { "entry-jobtitle", E_CARD_SIMPLE_FIELD_TITLE, TRUE },
- { "label-jobtitle", E_CARD_SIMPLE_FIELD_TITLE },
+ widget = e_builder_get_widget (ce->builder, "dateedit-anniversary");
+ if (!(e_date_edit_date_is_valid (E_DATE_EDIT (widget)))) {
+ g_string_append_printf (
+ errmsg, _("%s'%s' has an invalid format"),
+ validation_error ? ",\n" : "",
+ e_contact_pretty_name (E_CONTACT_ANNIVERSARY));
+ validation_error = TRUE;
+ }
- { "entry-company", E_CARD_SIMPLE_FIELD_ORG, TRUE },
- { "label-company", E_CARD_SIMPLE_FIELD_ORG },
+ for (iter = ce->required_fields; iter; iter = iter->next) {
+ const gchar *field_name = iter->data;
+ EContactField field_id = e_contact_field_id (field_name);
+
+ if (is_non_string_field (field_id)) {
+ if (e_contact_get_const (ce->contact, field_id) == NULL) {
+ g_string_append_printf (
+ errmsg, _("%s'%s' is empty"),
+ validation_error ? ",\n" : "",
+ e_contact_pretty_name (field_id));
+ validation_error = TRUE;
+ break;
+ }
- { "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 },
+ } else {
+ const gchar *text;
- { "label-department", E_CARD_SIMPLE_FIELD_ORG_UNIT },
- { "entry-department", E_CARD_SIMPLE_FIELD_ORG_UNIT, TRUE },
+ text = e_contact_get_const (ce->contact, field_id);
- { "label-office", E_CARD_SIMPLE_FIELD_OFFICE },
- { "entry-office", E_CARD_SIMPLE_FIELD_OFFICE, TRUE },
+ if (STRING_IS_EMPTY (text)) {
+ g_string_append_printf (
+ errmsg, _("%s'%s' is empty"),
+ validation_error ? ",\n" : "",
+ e_contact_pretty_name (field_id));
+ validation_error = TRUE;
+ break;
+ }
- { "label-profession", E_CARD_SIMPLE_FIELD_ROLE },
- { "entry-profession", E_CARD_SIMPLE_FIELD_ROLE, TRUE },
+ }
+ }
- { "label-manager", E_CARD_SIMPLE_FIELD_MANAGER },
- { "entry-manager", E_CARD_SIMPLE_FIELD_MANAGER, TRUE },
+ if (validation_error) {
+ g_string_append (errmsg, ".");
+ e_alert_run_dialog_for_args (
+ GTK_WINDOW (ce->app),
+ "addressbook:generic-error",
+ _("Invalid contact."), errmsg->str, NULL);
+ g_string_free (errmsg, TRUE);
+ return FALSE;
+ }
+ else {
+ g_string_free (errmsg, TRUE);
+ return TRUE;
+ }
+}
- { "label-assistant", E_CARD_SIMPLE_FIELD_ASSISTANT },
- { "entry-assistant", E_CARD_SIMPLE_FIELD_ASSISTANT, TRUE },
+static gboolean
+e_contact_editor_is_changed (EABEditor *editor)
+{
+ return E_CONTACT_EDITOR (editor)->changed;
+}
- { "label-nickname", E_CARD_SIMPLE_FIELD_NICKNAME },
- { "entry-nickname", E_CARD_SIMPLE_FIELD_NICKNAME, TRUE },
+static GtkWindow *
+e_contact_editor_get_window (EABEditor *editor)
+{
+ return GTK_WINDOW (E_CONTACT_EDITOR (editor)->app);
+}
- { "label-spouse", E_CARD_SIMPLE_FIELD_SPOUSE },
- { "entry-spouse", E_CARD_SIMPLE_FIELD_SPOUSE, TRUE },
+static void
+file_save_and_close_cb (GtkWidget *widget,
+ EContactEditor *ce)
+{
+ save_contact (ce, TRUE);
+}
- { "label-birthday", E_CARD_SIMPLE_FIELD_BIRTH_DATE },
- { "dateedit-birthday", E_CARD_SIMPLE_FIELD_BIRTH_DATE, TRUE },
+static void
+file_cancel_cb (GtkWidget *widget,
+ EContactEditor *ce)
+{
+ eab_editor_close (EAB_EDITOR (ce));
+}
- { "label-anniversary", E_CARD_SIMPLE_FIELD_ANNIVERSARY },
- { "dateedit-anniversary", E_CARD_SIMPLE_FIELD_ANNIVERSARY, TRUE },
+/* Callback used when the dialog box is destroyed */
+static gint
+app_delete_event_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer data)
+{
+ EContactEditor *ce;
- { "label-comments", E_CARD_SIMPLE_FIELD_NOTE },
- { "text-comments", E_CARD_SIMPLE_FIELD_NOTE, TRUE },
+ ce = E_CONTACT_EDITOR (data);
- { "entry-fullname", E_CARD_SIMPLE_FIELD_FULL_NAME, TRUE },
+ /* if we're saving, don't allow the dialog to close */
+ if (ce->in_async_call)
+ return TRUE;
- { "button-categories", E_CARD_SIMPLE_FIELD_CATEGORIES, TRUE },
- { "entry-categories", E_CARD_SIMPLE_FIELD_CATEGORIES, TRUE },
+ if (ce->changed) {
+ switch (eab_prompt_save_dialog (GTK_WINDOW (ce->app))) {
+ case GTK_RESPONSE_YES:
+ eab_editor_save_contact (EAB_EDITOR (ce), TRUE);
+ return TRUE;
- { "label-caluri", E_CARD_SIMPLE_FIELD_CALURI },
- { "entry-caluri", E_CARD_SIMPLE_FIELD_CALURI, TRUE },
+ case GTK_RESPONSE_NO:
+ break;
- { "label-fburl", E_CARD_SIMPLE_FIELD_FBURL },
- { "entry-fburl", E_CARD_SIMPLE_FIELD_FBURL, TRUE }
-};
-static int num_widget_field_mappings = sizeof(widget_field_mappings) / sizeof (widget_field_mappings[0]);
+ case GTK_RESPONSE_CANCEL:
+ default:
+ return TRUE;
+
+ }
+ }
+
+ eab_editor_close (EAB_EDITOR (ce));
+ return TRUE;
+}
static void
-enable_writable_fields(EContactEditor *editor)
+show_help_cb (GtkWidget *widget,
+ gpointer data)
{
- EList *fields = editor->writable_fields;
- EIterator *iter;
- GHashTable *dropdown_hash, *supported_hash;
- int i;
- ECardSimple *simple;
- ECard *card;
- char *widget_name;
+ /* FIXME Pass a proper parent window. */
+ e_display_help (NULL, "contacts-usage-add-contact");
+}
- if (!fields)
- return;
+static GList *
+add_to_tab_order (GList *list,
+ GtkBuilder *builder,
+ const gchar *name)
+{
+ GtkWidget *widget = e_builder_get_widget (builder, name);
+ return g_list_prepend (list, widget);
+}
- 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 ++)
- g_hash_table_insert (dropdown_hash,
- (char*)e_card_simple_get_ecard_field(simple, e_card_simple_map_phone_to_field (i)),
- editor->phone_info[i].widget);
- e_contact_editor_build_email_ui (editor);
- for (i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i ++)
- g_hash_table_insert (dropdown_hash,
- (char*)e_card_simple_get_ecard_field(simple, e_card_simple_map_email_to_field (i)),
- editor->email_info[i].widget);
- 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);
-
- /* then disable them all */
- g_hash_table_foreach (dropdown_hash, (GHFunc)disable_widget_foreach, NULL);
-
- /* disable the label widgets for the dropdowns (4 phone, 1
- email and the toggle button, and 1 address and one for
- the full address button */
- for (i = 0; i < 4; i ++) {
- widget_name = g_strdup_printf ("label-phone%d", i+1);
- enable_widget (glade_xml_get_widget (editor->gui, widget_name), FALSE);
- g_free (widget_name);
- widget_name = g_strdup_printf ("entry-phone%d", i+1);
- enable_widget (glade_xml_get_widget (editor->gui, widget_name), FALSE);
- g_free (widget_name);
+static void
+setup_tab_order (GtkBuilder *builder)
+{
+ GtkWidget *container;
+ GList *list = NULL;
+/*
+ container = e_builder_get_widget (builder, "table-contact-editor-general");
+ *
+ if (container) {
+ list = add_to_tab_order (list, builder, "entry-fullname");
+ list = add_to_tab_order (list, builder, "entry-jobtitle");
+ list = add_to_tab_order (list, builder, "entry-company");
+ list = add_to_tab_order (list, builder, "combo-file-as");
+ list = add_to_tab_order (list, builder, "entry-phone-1");
+ list = add_to_tab_order (list, builder, "entry-phone-2");
+ list = add_to_tab_order (list, builder, "entry-phone-3");
+ list = add_to_tab_order (list, builder, "entry-phone-4");
+ *
+ list = add_to_tab_order (list, builder, "entry-email1");
+ list = add_to_tab_order (list, builder, "alignment-htmlmail");
+ list = add_to_tab_order (list, builder, "entry-web");
+ list = add_to_tab_order (list, builder, "entry-homepage");
+ list = add_to_tab_order (list, builder, "button-fulladdr");
+ list = add_to_tab_order (list, builder, "text-address");
+ list = g_list_reverse (list);
+ e_container_change_tab_order (GTK_CONTAINER (container), list);
+ g_list_free (list);
}
- enable_widget (glade_xml_get_widget (editor->gui, "label-email1"), FALSE);
- enable_widget (glade_xml_get_widget (editor->gui, "entry-email1"), FALSE);
- enable_widget (glade_xml_get_widget (editor->gui, "checkbutton-htmlmail"), FALSE);
- enable_widget (glade_xml_get_widget (editor->gui, "label-address"), FALSE);
- enable_widget (glade_xml_get_widget (editor->gui, "text-address"), FALSE);
+*/
+
+ container = e_builder_get_widget (builder, "table-home-address");
+ gtk_container_get_focus_chain (GTK_CONTAINER (container), &list);
+
+ list = add_to_tab_order (list, builder, "scrolledwindow-home-address");
+ list = add_to_tab_order (list, builder, "entry-home-city");
+ list = add_to_tab_order (list, builder, "entry-home-zip");
+ list = add_to_tab_order (list, builder, "entry-home-state");
+ list = add_to_tab_order (list, builder, "entry-home-pobox");
+ list = add_to_tab_order (list, builder, "entry-home-country");
+ list = g_list_reverse (list);
+
+ gtk_container_set_focus_chain (GTK_CONTAINER (container), list);
+ g_list_free (list);
+
+ container = e_builder_get_widget (builder, "table-work-address");
+ gtk_container_get_focus_chain (GTK_CONTAINER (container), &list);
+
+ list = add_to_tab_order (list, builder, "scrolledwindow-work-address");
+ list = add_to_tab_order (list, builder, "entry-work-city");
+ list = add_to_tab_order (list, builder, "entry-work-zip");
+ list = add_to_tab_order (list, builder, "entry-work-state");
+ list = add_to_tab_order (list, builder, "entry-work-pobox");
+ list = add_to_tab_order (list, builder, "entry-work-country");
+ list = g_list_reverse (list);
+
+ gtk_container_set_focus_chain (GTK_CONTAINER (container), list);
+ g_list_free (list);
+
+ container = e_builder_get_widget (builder, "table-other-address");
+ gtk_container_get_focus_chain (GTK_CONTAINER (container), &list);
+
+ list = add_to_tab_order (list, builder, "scrolledwindow-other-address");
+ list = add_to_tab_order (list, builder, "entry-other-city");
+ list = add_to_tab_order (list, builder, "entry-other-zip");
+ list = add_to_tab_order (list, builder, "entry-other-state");
+ list = add_to_tab_order (list, builder, "entry-other-pobox");
+ list = add_to_tab_order (list, builder, "entry-other-country");
+ list = g_list_reverse (list);
+
+ gtk_container_set_focus_chain (GTK_CONTAINER (container), list);
+ g_list_free (list);
+}
- /* enable widgets that map directly from a field to a widget (the drop down items) */
- iter = e_list_get_iterator (fields);
- for (; e_iterator_is_valid (iter); e_iterator_next (iter)) {
- char *field = (char*)e_iterator_get (iter);
- GtkWidget *widget = g_hash_table_lookup (dropdown_hash, field);
+static void
+expand_web_toggle (EContactEditor *ce)
+{
+ GtkWidget *widget;
- if (widget) {
- enable_widget (widget, TRUE);
- }
- else {
- /* if it's not a field that's handled by the
- dropdown items, add it to the has to be
- used in the second step */
- g_hash_table_insert (supported_hash, field, field);
- }
+ widget = e_builder_get_widget (ce->builder, "label-videourl");
+ expand_web (ce, !gtk_widget_get_visible (widget));
+}
- /* 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)))) {
- 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)))) {
- enable_widget (glade_xml_get_widget (editor->gui, "label-address"), TRUE);
- 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])))) {
- 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);
- widget_name = g_strdup_printf ("entry-phone%d", i+1);
- enable_widget (glade_xml_get_widget (editor->gui, widget_name), editor->editable);
- g_free (widget_name);
- }
- }
- }
+static void
+expand_phone_toggle (EContactEditor *ce)
+{
+ GtkWidget *phone_ext_table;
- /* handle the label next to the dropdown widgets */
+ phone_ext_table = e_builder_get_widget (
+ ce->builder, "table-phone-extended");
+ expand_phone (ce, !gtk_widget_get_visible (phone_ext_table));
+}
- for (i = 0; i < num_widget_field_mappings; i ++) {
- gboolean enabled;
- GtkWidget *w;
- const char *field;
+static void
+expand_mail_toggle (EContactEditor *ce)
+{
+ GtkWidget *mail;
- w = glade_xml_get_widget(editor->gui, widget_field_mappings[i].widget_name);
- if (!w) {
- g_warning (_("Could not find widget for a field: `%s'"),
- widget_field_mappings[i].widget_name);
- continue;
- }
- field = e_card_simple_get_ecard_field (simple,
- widget_field_mappings[i].field_id);
+ mail = e_builder_get_widget (ce->builder, "entry-email-4");
+ expand_mail (ce, !gtk_widget_get_visible (mail));
+}
- enabled = (g_hash_table_lookup (supported_hash, field) != NULL);
+static void
+e_contact_editor_init (EContactEditor *e_contact_editor)
+{
+ GtkBuilder *builder;
+ EShell *shell;
+ EClientCache *client_cache;
+ GtkWidget *container;
+ GtkWidget *widget, *label;
+ GtkEntryCompletion *completion;
- if (widget_field_mappings[i].desensitize_for_read_only && !editor->editable) {
- enabled = FALSE;
- }
+ /* FIXME The shell should be obtained
+ * through a constructor property. */
+ shell = e_shell_get_default ();
+ client_cache = e_shell_get_client_cache (shell);
- enable_widget (w, enabled);
- }
+ e_contact_editor->name = e_contact_name_new ();
+
+ e_contact_editor->contact = NULL;
+ e_contact_editor->changed = FALSE;
+ e_contact_editor->check_merge = FALSE;
+ e_contact_editor->image_set = FALSE;
+ e_contact_editor->image_changed = FALSE;
+ e_contact_editor->in_async_call = FALSE;
+ e_contact_editor->target_editable = TRUE;
+ e_contact_editor->fullname_dialog = NULL;
+ e_contact_editor->categories_dialog = NULL;
+ e_contact_editor->compress_ui = e_shell_get_express_mode (shell);
+
+ builder = gtk_builder_new ();
+ e_load_ui_builder_definition (builder, "contact-editor.ui");
+
+ e_contact_editor->builder = builder;
+
+ setup_tab_order (builder);
+
+ e_contact_editor->app =
+ e_builder_get_widget (builder, "contact editor");
+ widget = e_contact_editor->app;
+
+ gtk_widget_ensure_style (widget);
+ gtk_window_set_type_hint (
+ GTK_WINDOW (widget), GDK_WINDOW_TYPE_HINT_NORMAL);
+ container = gtk_dialog_get_action_area (GTK_DIALOG (widget));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 12);
+ container = gtk_dialog_get_content_area (GTK_DIALOG (widget));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 0);
+
+ init_all (e_contact_editor);
+
+ widget = e_builder_get_widget (
+ e_contact_editor->builder, "button-image");
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (image_clicked), e_contact_editor);
+ widget = e_builder_get_widget (
+ e_contact_editor->builder, "button-fullname");
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (full_name_clicked), e_contact_editor);
+ widget = e_builder_get_widget (
+ e_contact_editor->builder, "button-categories");
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (categories_clicked), e_contact_editor);
+ widget = e_builder_get_widget (
+ e_contact_editor->builder, "client-combo-box");
+ e_client_combo_box_set_client_cache (
+ E_CLIENT_COMBO_BOX (widget), client_cache);
+ g_signal_connect (
+ widget, "changed",
+ G_CALLBACK (source_changed), e_contact_editor);
+ label = e_builder_get_widget (
+ e_contact_editor->builder, "where-label");
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
+ widget = e_builder_get_widget (
+ e_contact_editor->builder, "button-ok");
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (file_save_and_close_cb), e_contact_editor);
+ widget = e_builder_get_widget (
+ e_contact_editor->builder, "button-cancel");
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (file_cancel_cb), e_contact_editor);
+ widget = e_builder_get_widget (
+ e_contact_editor->builder, "button-help");
+ g_signal_connect (
+ widget, "clicked",
+ G_CALLBACK (show_help_cb), e_contact_editor);
+ widget = e_builder_get_widget (
+ e_contact_editor->builder, "button-web-expand");
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (expand_web_toggle), e_contact_editor);
+ widget = e_builder_get_widget (
+ e_contact_editor->builder, "button-phone-expand");
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (expand_phone_toggle), e_contact_editor);
+ widget = e_builder_get_widget (
+ e_contact_editor->builder, "button-mail-expand");
+ g_signal_connect_swapped (
+ widget, "clicked",
+ G_CALLBACK (expand_mail_toggle), e_contact_editor);
+
+ widget = e_builder_get_widget (
+ e_contact_editor->builder, "entry-fullname");
+ if (widget)
+ gtk_widget_grab_focus (widget);
+
+ widget = e_builder_get_widget (
+ e_contact_editor->builder, "entry-categories");
+ completion = e_category_completion_new ();
+ gtk_entry_set_completion (GTK_ENTRY (widget), completion);
+ g_object_unref (completion);
+
+ /* Connect to the deletion of the dialog */
+
+ g_signal_connect (
+ e_contact_editor->app, "delete_event",
+ G_CALLBACK (app_delete_event_cb), e_contact_editor);
+
+ /* set the icon */
+ gtk_window_set_icon_name (
+ GTK_WINDOW (e_contact_editor->app), "contact-editor");
+
+ /* show window */
+ gtk_widget_show (e_contact_editor->app);
- g_hash_table_destroy (dropdown_hash);
- g_hash_table_destroy (supported_hash);
- gtk_object_unref (GTK_OBJECT(simple));
- gtk_object_unref (GTK_OBJECT(card));
+ gtk_application_add_window (
+ GTK_APPLICATION (shell),
+ GTK_WINDOW (e_contact_editor->app));
}
static void
-set_editable (EContactEditor *editor)
+e_contact_editor_dispose (GObject *object)
{
- int i;
- char *entry;
- /* set the sensitivity of all the non-dropdown entry/texts/dateedits */
- for (i = 0; i < num_widget_field_mappings; i ++) {
- if (widget_field_mappings[i].desensitize_for_read_only) {
- GtkWidget *widget = glade_xml_get_widget(editor->gui, widget_field_mappings[i].widget_name);
- enable_widget (widget, editor->editable);
- }
+ EContactEditor *e_contact_editor = E_CONTACT_EDITOR (object);
+
+ if (e_contact_editor->file_selector != NULL) {
+ gtk_widget_destroy (e_contact_editor->file_selector);
+ e_contact_editor->file_selector = NULL;
+ }
+
+ g_slist_free_full (
+ e_contact_editor->writable_fields,
+ (GDestroyNotify) g_free);
+ e_contact_editor->writable_fields = NULL;
+
+ g_slist_free_full (
+ e_contact_editor->required_fields,
+ (GDestroyNotify) g_free);
+ e_contact_editor->required_fields = NULL;
+
+ if (e_contact_editor->contact) {
+ g_object_unref (e_contact_editor->contact);
+ e_contact_editor->contact = NULL;
+ }
+
+ if (e_contact_editor->source_client) {
+ g_object_unref (e_contact_editor->source_client);
+ e_contact_editor->source_client = NULL;
}
- /* handle the phone dropdown entries */
- for (i = 0; i < 4; i ++) {
- entry = g_strdup_printf ("entry-phone%d", i+1);
+ if (e_contact_editor->target_client) {
+ g_signal_handler_disconnect (
+ e_contact_editor->target_client,
+ e_contact_editor->target_editable_id);
+ g_object_unref (e_contact_editor->target_client);
+ e_contact_editor->target_client = NULL;
+ }
- enable_widget (glade_xml_get_widget(editor->gui, entry),
- editor->editable);
+ if (e_contact_editor->name) {
+ e_contact_name_free (e_contact_editor->name);
+ e_contact_editor->name = NULL;
+ }
- g_free (entry);
+ if (e_contact_editor->builder) {
+ g_object_unref (e_contact_editor->builder);
+ e_contact_editor->builder = NULL;
}
- /* handle the email dropdown entry */
- entry = "entry-email1";
- enable_widget (glade_xml_get_widget(editor->gui, entry),
- editor->editable);
- enable_widget (glade_xml_get_widget(editor->gui, "checkbutton-htmlmail"),
- editor->editable);
+ if (e_contact_editor->cancellable != NULL) {
+ g_object_unref (e_contact_editor->cancellable);
+ e_contact_editor->cancellable = NULL;
+ }
- /* handle the address dropdown entry */
- entry = "text-address";
- enable_widget (glade_xml_get_widget(editor->gui, entry),
- editor->editable);
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
-fill_in_info(EContactEditor *editor)
+supported_fields_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- ECard *card = editor->card;
- if (card) {
- char *file_as;
- char *related_contacts;
- ECardName *name;
- const ECardDate *anniversary;
- const ECardDate *bday;
- int i;
- GtkWidget *widget;
- GList *list;
- gboolean wants_html, wants_html_set;
-
- gtk_object_get(GTK_OBJECT(card),
- "file_as", &file_as,
- "related_contacts", &related_contacts,
- "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);
- }
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ EContactEditor *ce = user_data;
+ gchar *prop_value = NULL;
+ GSList *fields;
+ gboolean success;
+ GError *error = NULL;
+
+ success = e_client_get_backend_property_finish (
+ E_CLIENT (book_client), result, &prop_value, &error);
+
+ if (!success)
+ prop_value = NULL;
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to get supported fields: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
- for (list = editor->arbitrary_fields; list; list = list->next) {
- fill_in_single_field(editor, list->data);
- }
+ if (!g_slist_find (eab_editor_get_all_editors (), ce)) {
+ g_warning (
+ "supported_fields_cb called for book that's still "
+ "around, but contact editor that's been destroyed.");
+ g_free (prop_value);
+ return;
+ }
- 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)) {
- gtk_object_set(GTK_OBJECT(widget),
- "active", wants_html,
- NULL);
- }
- }
+ fields = e_client_util_parse_comma_strings (prop_value);
- /* 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);
-
- e_card_name_unref(editor->name);
- editor->name = e_card_name_ref(name);
-
- widget = glade_xml_get_widget(editor->gui, "dateedit-anniversary");
- if (widget && E_IS_DATE_EDIT(widget)) {
- EDateEdit *dateedit;
- dateedit = E_DATE_EDIT(widget);
- if (anniversary)
- e_date_edit_set_date (dateedit,
- anniversary->year,
- anniversary->month,
- anniversary->day);
- else
- e_date_edit_set_time (dateedit, -1);
- }
+ g_object_set (ce, "writable_fields", fields, NULL);
- widget = glade_xml_get_widget(editor->gui, "dateedit-birthday");
- if (widget && E_IS_DATE_EDIT(widget)) {
- EDateEdit *dateedit;
- dateedit = E_DATE_EDIT(widget);
- if (bday)
- e_date_edit_set_date (dateedit,
- bday->year,
- bday->month,
- bday->day);
- else
- e_date_edit_set_time (dateedit, -1);
- }
+ g_slist_free_full (fields, (GDestroyNotify) g_free);
+ g_free (prop_value);
- if (editor->select_names_contacts && related_contacts && *related_contacts) {
- ESelectNamesModel *model = e_select_names_manager_get_source (editor->select_names_contacts,
- "contacts");
- e_select_names_model_import_destinationv (model, related_contacts);
- }
+ eab_editor_show (EAB_EDITOR (ce));
- set_fields(editor);
- }
+ sensitize_all (ce);
}
static void
-extract_field(EContactEditor *editor, ECard *card, char *editable_id, char *key)
+required_fields_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- GtkWidget *widget = glade_xml_get_widget(editor->gui, editable_id);
- if (widget && GTK_IS_EDITABLE(widget)) {
- GtkEditable *editable = GTK_EDITABLE(widget);
- char *string = e_utf8_gtk_editable_get_chars(editable, 0, -1);
-
- if (string && *string)
- gtk_object_set(GTK_OBJECT(card),
- key, string,
- NULL);
- else
- gtk_object_set(GTK_OBJECT(card),
- key, NULL,
- NULL);
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ EContactEditor *ce = user_data;
+ gchar *prop_value = NULL;
+ GSList *fields;
+ gboolean success;
+ GError *error = NULL;
+
+ success = e_client_get_backend_property_finish (
+ E_CLIENT (book_client), result, &prop_value, &error);
+
+ if (!success)
+ prop_value = NULL;
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to get supported fields: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
- if (string) g_free(string);
+ if (!g_slist_find (eab_editor_get_all_editors (), ce)) {
+ g_warning (
+ "supported_fields_cb called for book that's still "
+ "around, but contact editor that's been destroyed.");
+ g_free (prop_value);
+ return;
}
+
+ fields = e_client_util_parse_comma_strings (prop_value);
+
+ g_object_set (ce, "required_fields", fields, NULL);
+
+ g_slist_free_full (fields, (GDestroyNotify) g_free);
+ g_free (prop_value);
+}
+
+EABEditor *
+e_contact_editor_new (EShell *shell,
+ EBookClient *book_client,
+ EContact *contact,
+ gboolean is_new_contact,
+ gboolean editable)
+{
+ EABEditor *editor;
+
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+ g_return_val_if_fail (E_IS_BOOK_CLIENT (book_client), NULL);
+ g_return_val_if_fail (E_IS_CONTACT (contact), NULL);
+
+ editor = g_object_new (E_TYPE_CONTACT_EDITOR, "shell", shell, NULL);
+
+ g_object_set (
+ editor,
+ "source_client", book_client,
+ "contact", contact,
+ "is_new_contact", is_new_contact,
+ "editable", editable,
+ NULL);
+
+ return editor;
}
static void
-extract_single_field(EContactEditor *editor, char *name)
+notify_readonly_cb (EBookClient *book_client,
+ GParamSpec *pspec,
+ EContactEditor *ce)
{
- 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 = e_utf8_gtk_editable_get_chars(editable, 0, -1);
+ EClient *client;
+ gint new_target_editable;
+ gboolean changed = FALSE;
- 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);
- }
+ client = E_CLIENT (ce->target_client);
+ new_target_editable = !e_client_is_readonly (client);
+
+ if (ce->target_editable != new_target_editable)
+ changed = TRUE;
+
+ ce->target_editable = new_target_editable;
+
+ if (changed)
+ sensitize_all (ce);
}
static void
-extract_info(EContactEditor *editor)
+e_contact_editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- ECard *card = editor->card;
- if (card) {
- ECardDate anniversary;
- ECardDate bday;
- int i;
- GtkWidget *widget;
- GList *list;
+ EContactEditor *editor;
- widget = glade_xml_get_widget(editor->gui, "entry-file-as");
- if (widget && GTK_IS_EDITABLE(widget)) {
- GtkEditable *editable = GTK_EDITABLE(widget);
- char *string = e_utf8_gtk_editable_get_chars(editable, 0, -1);
+ editor = E_CONTACT_EDITOR (object);
- if (string && *string)
- gtk_object_set(GTK_OBJECT(card),
- "file_as", string,
- NULL);
+ switch (property_id) {
+ case PROP_SOURCE_CLIENT: {
+ gboolean writable;
+ gboolean changed = FALSE;
+ EBookClient *source_client;
- if (string) g_free(string);
- }
+ source_client = E_BOOK_CLIENT (g_value_get_object (value));
- for (i = 0; i < sizeof(field_mapping) / sizeof(field_mapping[0]); i++) {
- extract_field(editor, card, field_mapping[i].id, field_mapping[i].key);
- }
+ if (source_client == editor->source_client)
+ break;
+
+ if (editor->source_client)
+ g_object_unref (editor->source_client);
+
+ editor->source_client = source_client;
+ g_object_ref (editor->source_client);
+
+ if (!editor->target_client) {
+ editor->target_client = editor->source_client;
+ g_object_ref (editor->target_client);
+
+ editor->target_editable_id = g_signal_connect (
+ editor->target_client, "notify::readonly",
+ G_CALLBACK (notify_readonly_cb), editor);
+
+ e_client_get_backend_property (
+ E_CLIENT (editor->target_client),
+ BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS,
+ NULL, supported_fields_cb, editor);
- for (list = editor->arbitrary_fields; list; list = list->next) {
- extract_single_field(editor, list->data);
+ e_client_get_backend_property (
+ E_CLIENT (editor->target_client),
+ BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS,
+ NULL, required_fields_cb, editor);
}
- if (editor->select_names_contacts) {
- ESelectNamesModel *model = e_select_names_manager_get_source (editor->select_names_contacts,
- "contacts");
- char *string = e_select_names_model_export_destinationv (model);
- if (string && *string)
- gtk_object_set (GTK_OBJECT (card),
- "related_contacts", string,
- NULL);
- else
- gtk_object_set (GTK_OBJECT (card),
- "related_contacts", NULL,
- NULL);
- g_free (string);
+ writable = !e_client_is_readonly (E_CLIENT (editor->target_client));
+ if (writable != editor->target_editable) {
+ editor->target_editable = writable;
+ changed = TRUE;
}
- if (editor->name)
- gtk_object_set(GTK_OBJECT(card),
- "name", editor->name,
- NULL);
-
- widget = glade_xml_get_widget(editor->gui, "dateedit-anniversary");
- if (widget && E_IS_DATE_EDIT(widget)) {
- if (e_date_edit_get_date (E_DATE_EDIT (widget),
- &anniversary.year,
- &anniversary.month,
- &anniversary.day)) {
- /* g_print ("%d %d %d\n", anniversary.year, anniversary.month, anniversary.day); */
- gtk_object_set(GTK_OBJECT(card),
- "anniversary", &anniversary,
- NULL);
- } else
- gtk_object_set(GTK_OBJECT(card),
- "anniversary", NULL,
- NULL);
+ if (changed)
+ sensitize_all (editor);
+
+ break;
+ }
+
+ case PROP_TARGET_CLIENT: {
+ gboolean writable;
+ gboolean changed = FALSE;
+ EBookClient *target_client;
+
+ target_client = E_BOOK_CLIENT (g_value_get_object (value));
+
+ if (target_client == editor->target_client)
+ break;
+
+ if (editor->target_client) {
+ g_signal_handler_disconnect (
+ editor->target_client,
+ editor->target_editable_id);
+ g_object_unref (editor->target_client);
}
- widget = glade_xml_get_widget(editor->gui, "dateedit-birthday");
- if (widget && E_IS_DATE_EDIT(widget)) {
- if (e_date_edit_get_date (E_DATE_EDIT (widget),
- &bday.year,
- &bday.month,
- &bday.day)) {
- /* g_print ("%d %d %d\n", bday.year, bday.month, bday.day); */
- gtk_object_set(GTK_OBJECT(card),
- "birth_date", &bday,
- NULL);
- } else
- gtk_object_set(GTK_OBJECT(card),
- "birth_date", NULL,
- NULL);
+ editor->target_client = target_client;
+ g_object_ref (editor->target_client);
+
+ editor->target_editable_id = g_signal_connect (
+ editor->target_client, "notify::readonly",
+ G_CALLBACK (notify_readonly_cb), editor);
+
+ e_client_get_backend_property (
+ E_CLIENT (editor->target_client),
+ BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS,
+ NULL, supported_fields_cb, editor);
+
+ e_client_get_backend_property (
+ E_CLIENT (editor->target_client),
+ BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS,
+ NULL, required_fields_cb, editor);
+
+ if (!editor->is_new_contact)
+ editor->changed = TRUE;
+
+ writable = !e_client_is_readonly (E_CLIENT (editor->target_client));
+
+ if (writable != editor->target_editable) {
+ editor->target_editable = writable;
+ changed = TRUE;
}
+
+ if (changed)
+ sensitize_all (editor);
+
+ break;
+ }
+
+ 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_all (editor);
+ editor->changed = FALSE;
+ break;
+
+ case PROP_IS_NEW_CONTACT:
+ editor->is_new_contact = g_value_get_boolean (value);
+ break;
+
+ case PROP_EDITABLE: {
+ gboolean new_value = g_value_get_boolean (value);
+ gboolean changed = (editor->target_editable != new_value);
+
+ editor->target_editable = new_value;
+
+ if (changed)
+ sensitize_all (editor);
+ break;
+ }
+
+ case PROP_CHANGED: {
+ gboolean new_value = g_value_get_boolean (value);
+ gboolean changed = (editor->changed != new_value);
+
+ editor->changed = new_value;
+
+ if (changed)
+ sensitize_ok (editor);
+ break;
+ }
+ case PROP_WRITABLE_FIELDS:
+ g_slist_free_full (
+ editor->writable_fields,
+ (GDestroyNotify) g_free);
+ editor->writable_fields = g_slist_copy_deep (
+ g_value_get_pointer (value),
+ (GCopyFunc) g_strdup, NULL);
+
+ sensitize_all (editor);
+ break;
+ case PROP_REQUIRED_FIELDS:
+ g_slist_free_full (
+ editor->required_fields,
+ (GDestroyNotify) g_free);
+ editor->required_fields = g_slist_copy_deep (
+ g_value_get_pointer (value),
+ (GCopyFunc) g_strdup, NULL);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+static void
+e_contact_editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EContactEditor *e_contact_editor;
+
+ e_contact_editor = E_CONTACT_EDITOR (object);
+
+ switch (property_id) {
+ case PROP_SOURCE_CLIENT:
+ g_value_set_object (value, e_contact_editor->source_client);
+ break;
+
+ case PROP_TARGET_CLIENT:
+ g_value_set_object (value, e_contact_editor->target_client);
+ break;
+
+ case PROP_CONTACT:
+ extract_all (e_contact_editor);
+ g_value_set_object (value, e_contact_editor->contact);
+ break;
+
+ case PROP_IS_NEW_CONTACT:
+ g_value_set_boolean (
+ value, e_contact_editor->is_new_contact);
+ break;
+
+ case PROP_EDITABLE:
+ g_value_set_boolean (
+ value, e_contact_editor->target_editable);
+ break;
+
+ case PROP_CHANGED:
+ g_value_set_boolean (
+ value, e_contact_editor->changed);
+ break;
+
+ case PROP_WRITABLE_FIELDS:
+ g_value_set_pointer (value, e_contact_editor->writable_fields);
+ break;
+ case PROP_REQUIRED_FIELDS:
+ g_value_set_pointer (value, e_contact_editor->required_fields);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
@@ -2712,12 +4609,16 @@ extract_info(EContactEditor *editor)
*
* Raises the dialog associated with this %EContactEditor object.
*/
-void
-e_contact_editor_raise (EContactEditor *editor)
+static void
+e_contact_editor_raise (EABEditor *editor)
{
- /* FIXME: perhaps we should raise at realize time */
- if (GTK_WIDGET (editor->app)->window)
- gdk_window_raise (GTK_WIDGET (editor->app)->window);
+ EContactEditor *ce = E_CONTACT_EDITOR (editor);
+ GdkWindow *window;
+
+ window = gtk_widget_get_window (ce->app);
+
+ if (window != NULL)
+ gdk_window_raise (window);
}
/**
@@ -2726,71 +4627,9 @@ e_contact_editor_raise (EContactEditor *editor)
*
* Shows the dialog associated with this %EContactEditor object.
*/
-void
-e_contact_editor_show (EContactEditor *ce)
-{
- gtk_widget_show (ce->app);
-}
-
-GtkWidget *
-e_contact_editor_create_date(gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2);
-
-GtkWidget *
-e_contact_editor_create_date(gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2)
-{
- GtkWidget *widget = e_date_edit_new ();
- e_date_edit_set_allow_no_date_set (E_DATE_EDIT (widget),
- TRUE);
- e_date_edit_set_show_time (E_DATE_EDIT (widget), FALSE);
- e_date_edit_set_time (E_DATE_EDIT (widget), -1);
- return widget;
-}
-
static void
-enable_widget (GtkWidget *widget, gboolean enabled)
-{
- if (GTK_IS_ENTRY (widget)) {
- gtk_entry_set_editable (GTK_ENTRY (widget), enabled);
- }
- else if (GTK_IS_TEXT (widget)) {
- gtk_text_set_editable (GTK_TEXT (widget), enabled);
- }
- else if (GTK_IS_COMBO (widget)) {
- gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (widget)->entry),
- enabled);
- gtk_widget_set_sensitive (GTK_COMBO (widget)->button, enabled);
- }
- else if (E_IS_DATE_EDIT (widget)) {
- e_date_edit_set_editable (E_DATE_EDIT (widget), enabled);
- }
- else
- gtk_widget_set_sensitive (widget, enabled);
-}
-
-
-gboolean
-e_contact_editor_request_close_all (void)
+e_contact_editor_show (EABEditor *editor)
{
- GSList *p;
- GSList *pnext;
- gboolean retval;
-
- retval = TRUE;
- for (p = all_contact_editors; p != NULL; p = pnext) {
- pnext = p->next;
-
- e_contact_editor_raise (E_CONTACT_EDITOR (p->data));
- if (! prompt_to_save_changes (E_CONTACT_EDITOR (p->data))) {
- retval = FALSE;
- break;
- }
-
- close_dialog (E_CONTACT_EDITOR (p->data));
- }
-
- return retval;
+ EContactEditor *ce = E_CONTACT_EDITOR (editor);
+ gtk_widget_show (ce->app);
}
diff --git a/addressbook/gui/contact-editor/e-contact-editor.h b/addressbook/gui/contact-editor/e-contact-editor.h
index 0010182b99..49446f7350 100644
--- a/addressbook/gui/contact-editor/e-contact-editor.h
+++ b/addressbook/gui/contact-editor/e-contact-editor.h
@@ -1,39 +1,33 @@
-/* -*- 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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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_EDITOR_H__
#define __E_CONTACT_EDITOR_H__
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-app-helper.h>
-#include <bonobo/bonobo-ui-component.h>
-#include <glade/glade.h>
+#include "addressbook/gui/contact-editor/eab-editor.h"
-#include "addressbook/gui/component/select-names/e-select-names-manager.h"
-#include "addressbook/backend/ebook/e-book.h"
-#include "addressbook/backend/ebook/e-card.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
+#include <gtk/gtk.h>
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
+G_BEGIN_DECLS
/* EContactEditor - A dialog displaying information about a contact.
*
@@ -44,96 +38,80 @@ extern "C" {
* card ECard * RW The card currently being edited
*/
-#define E_CONTACT_EDITOR_TYPE (e_contact_editor_get_type ())
-#define E_CONTACT_EDITOR(obj) (GTK_CHECK_CAST ((obj), E_CONTACT_EDITOR_TYPE, EContactEditor))
-#define E_CONTACT_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_CONTACT_EDITOR_TYPE, EContactEditorClass))
-#define E_IS_CONTACT_EDITOR(obj) (GTK_CHECK_TYPE ((obj), E_CONTACT_EDITOR_TYPE))
-#define E_IS_CONTACT_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_CONTACT_EDITOR_TYPE))
-
+#define E_TYPE_CONTACT_EDITOR (e_contact_editor_get_type ())
+#define E_CONTACT_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CONTACT_EDITOR, EContactEditor))
+#define E_CONTACT_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CONTACT_EDITOR, EContactEditorClass))
+#define E_IS_CONTACT_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CONTACT_EDITOR))
+#define E_IS_CONTACT_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_CONTACT_EDITOR))
typedef struct _EContactEditor EContactEditor;
typedef struct _EContactEditorClass EContactEditorClass;
struct _EContactEditor
{
- GtkObject object;
-
+ EABEditor object;
+
/* item specific fields */
- EBook *book;
- ECard *card;
- ECardSimple *simple;
-
- /* UI handler */
- BonoboUIComponent *uic;
-
- GladeXML *gui;
+ EBookClient *source_client;
+ EBookClient *target_client;
+ EContact *contact;
+
+ GtkBuilder *builder;
GtkWidget *app;
- GnomeUIInfo *email_info;
- GnomeUIInfo *phone_info;
- GnomeUIInfo *address_info;
- GtkWidget *email_popup;
- GtkWidget *phone_popup;
- GtkWidget *address_popup;
- GList *email_list;
- GList *phone_list;
- GList *address_list;
-
- ESelectNamesManager *select_names_contacts;
-
- ECardName *name;
- char *company;
-
- ECardSimpleEmailId email_choice;
- ECardSimplePhoneId phone_choice[4];
- ECardSimpleAddressId address_choice;
- ECardSimpleAddressId address_mailing;
-
- GList *arbitrary_fields;
-
- /* 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 */
+
+ GtkWidget *file_selector;
+
+ EContactName *name;
+
+ /* Whether we are editing a new contact or an existing one */
+ guint is_new_contact : 1;
+
+ /* Whether an image is associated with a contact. */
+ guint image_set : 1;
+
+ /* Whether the contact has been changed since bringing up the contact editor */
guint changed : 1;
- /* Whether the contact editor will accept modifications */
- guint editable : 1;
+ /* Wheter should check for contact to merge. Only when name or email are changed */
+ guint check_merge : 1;
+
+ /* Whether the contact editor will accept modifications, save */
+ guint target_editable : 1;
/* Whether an async wombat call is in progress */
guint in_async_call : 1;
- EList *writable_fields;
-};
+ /* Whether an image is changed */
+ guint image_changed : 1;
-struct _EContactEditorClass
-{
- GtkObjectClass parent_class;
+ /* Whether to try to reduce space used */
+ guint compress_ui : 1;
- /* Notification signals */
+ GSList *writable_fields;
- 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);
-};
+ GSList *required_fields;
-EContactEditor *e_contact_editor_new (EBook *book,
- ECard *card,
- gboolean is_new_card,
- gboolean editable);
-GtkType e_contact_editor_get_type (void);
+ GCancellable *cancellable;
-void e_contact_editor_show (EContactEditor *editor);
-void e_contact_editor_close (EContactEditor *editor);
-void e_contact_editor_raise (EContactEditor *editor);
+ /* signal ids for "writable_status" */
+ gint target_editable_id;
-gboolean e_contact_editor_confirm_delete (GtkWindow *parent);
+ GtkWidget *fullname_dialog;
+ GtkWidget *categories_dialog;
+};
-gboolean e_contact_editor_request_close_all (void);
+struct _EContactEditorClass
+{
+ EABEditorClass parent_class;
+};
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+GType e_contact_editor_get_type (void);
+EABEditor *e_contact_editor_new (EShell *shell,
+ EBookClient *book_client,
+ EContact *contact,
+ gboolean is_new_contact,
+ gboolean editable);
+G_END_DECLS
#endif /* __E_CONTACT_EDITOR_H__ */
diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.c b/addressbook/gui/contact-editor/e-contact-quick-add.c
index e8d623afb0..5814205c4d 100644
--- a/addressbook/gui/contact-editor/e-contact-quick-add.c
+++ b/addressbook/gui/contact-editor/e-contact-quick-add.c
@@ -1,286 +1,395 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-contact-quick-add.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.
- *
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Jon Trowbridge <trow@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
+
#include <ctype.h>
-#include <glib.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtktable.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <libgnomeui/gnome-stock.h>
-#include <gal/widgets/e-unicode.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 <string.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include <addressbook/util/eab-book-util.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;
+ gchar *vcard;
+ EContact *contact;
+ GCancellable *cancellable;
+ EClientCache *client_cache;
+ ESource *source;
EContactQuickAddCallback cb;
gpointer closure;
+ GtkWidget *dialog;
GtkWidget *name_entry;
GtkWidget *email_entry;
+ GtkWidget *combo_box;
gint refs;
};
static QuickAdd *
-quick_add_new (void)
+quick_add_new (EClientCache *client_cache)
{
QuickAdd *qa = g_new0 (QuickAdd, 1);
- qa->card = e_card_new ("");
+ qa->contact = e_contact_new ();
+ qa->client_cache = g_object_ref (client_cache);
qa->refs = 1;
return qa;
}
static void
-quick_add_ref (QuickAdd *qa)
-{
- if (qa) {
- ++qa->refs;
- }
-}
-
-static void
quick_add_unref (QuickAdd *qa)
{
if (qa) {
--qa->refs;
if (qa->refs == 0) {
+ if (qa->cancellable != NULL) {
+ g_cancellable_cancel (qa->cancellable);
+ g_object_unref (qa->cancellable);
+ }
g_free (qa->name);
g_free (qa->email);
- gtk_object_unref (GTK_OBJECT (qa->card));
+ g_free (qa->vcard);
+ g_object_unref (qa->contact);
+ g_object_unref (qa->client_cache);
g_free (qa);
}
}
}
static void
-quick_add_set_name (QuickAdd *qa, const gchar *name)
+quick_add_set_name (QuickAdd *qa,
+ const gchar *name)
{
- ECardName *card_name;
-
if (name == qa->name)
return;
g_free (qa->name);
-
- card_name = e_card_name_from_string (name);
- qa->name = e_card_name_to_string (card_name);
-
- gtk_object_set (GTK_OBJECT (qa->card),
- "full_name", qa->name,
- NULL);
-
- e_card_name_unref (card_name);
+ qa->name = g_strdup (name);
}
static void
-quick_add_set_email (QuickAdd *qa, const gchar *email)
+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);
+}
+
+static void
+quick_add_set_vcard (QuickAdd *qa,
+ const gchar *vcard)
+{
+ if (vcard == qa->vcard)
+ return;
- simple = e_card_simple_new (qa->card);
- e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_EMAIL, email);
- e_card_simple_sync_card (simple);
- gtk_object_unref (GTK_OBJECT (simple));
+ g_free (qa->vcard);
+ qa->vcard = g_strdup (vcard);
}
static void
-merge_cb (EBook *book, EBookStatus status, gpointer closure)
+merge_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- QuickAdd *qa = (QuickAdd *) closure;
+ QuickAdd *qa = user_data;
+ EClient *client;
+ GError *error = NULL;
+
+ client = e_client_cache_get_client_finish (
+ E_CLIENT_CACHE (source_object), result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ /* Ignore cancellations. */
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_warn_if_fail (client == NULL);
+ g_error_free (error);
+ return;
+ }
- if (book != NULL) {
- e_card_merging_book_add_card (book, qa->card, NULL, NULL);
- if (qa->cb)
- qa->cb (qa->card, qa->closure);
- gtk_object_unref (GTK_OBJECT (book));
- } else {
- /* Something went wrong. */
+ if (error != NULL) {
if (qa->cb)
qa->cb (NULL, qa->closure);
+ g_error_free (error);
+ quick_add_unref (qa);
+ return;
+ }
+
+ if (!e_client_is_readonly (client)) {
+ ESourceRegistry *registry;
+
+ registry = e_client_cache_ref_registry (qa->client_cache);
+
+ eab_merging_book_add_contact (
+ registry, E_BOOK_CLIENT (client),
+ qa->contact, NULL, NULL);
+
+ g_object_unref (registry);
+ } else {
+ ESource *source = e_client_get_source (client);
+
+ e_alert_run_dialog_for_args (
+ e_shell_get_active_window (NULL),
+ "addressbook:error-read-only",
+ e_source_get_display_name (source),
+ NULL);
}
-
+
+ if (qa->cb)
+ qa->cb (qa->contact, qa->closure);
+
+ g_object_unref (client);
+
quick_add_unref (qa);
}
static void
-quick_add_merge_card (QuickAdd *qa)
+quick_add_merge_contact (QuickAdd *qa)
{
- EBook *book;
+ if (qa->cancellable != NULL) {
+ g_cancellable_cancel (qa->cancellable);
+ g_object_unref (qa->cancellable);
+ }
- quick_add_ref (qa);
+ qa->cancellable = g_cancellable_new ();
- book = e_book_new ();
- if (!addressbook_load_default_book (book, merge_cb, qa)) {
- gtk_object_unref (GTK_OBJECT (book));
- merge_cb (book, E_BOOK_STATUS_OTHER_ERROR, qa);
- }
+ e_client_cache_get_client (
+ qa->client_cache, qa->source,
+ E_SOURCE_EXTENSION_ADDRESS_BOOK,
+ qa->cancellable, merge_cb, qa);
}
-
-/*
- * Raise a contact editor with all fields editable, and hook up all signals accordingly.
- */
+/* Raise a contact editor with all fields editable,
+ * and hook up all signals accordingly. */
static void
-card_added_cb (EContactEditor *ce, EBookStatus status, ECard *card, gpointer closure)
+contact_added_cb (EContactEditor *ce,
+ const GError *error,
+ EContact *contact,
+ gpointer closure)
{
- QuickAdd *qa = (QuickAdd *) gtk_object_get_data (GTK_OBJECT (ce), "quick_add");
+ QuickAdd *qa;
- if (qa) {
+ qa = 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 */
- gtk_object_set_data (GTK_OBJECT (ce), "quick_add", NULL);
+ g_object_set_data (G_OBJECT (ce), "quick_add", NULL);
}
}
static void
-editor_closed_cb (GtkWidget *w, gpointer closure)
+editor_closed_cb (GtkWidget *w,
+ gpointer closure)
{
- QuickAdd *qa = (QuickAdd *) gtk_object_get_data (GTK_OBJECT (w), "quick_add");
+ QuickAdd *qa;
+
+ qa = g_object_get_data (G_OBJECT (w), "quick_add");
if (qa)
/* We don't need to unref qa because we set_data_full below */
- gtk_object_set_data (GTK_OBJECT (w), "quick_add", NULL);
-
- gtk_object_unref (GTK_OBJECT (w));
+ g_object_set_data (G_OBJECT (w), "quick_add", NULL);
}
static void
-ce_have_book (EBook *book, EBookStatus status, gpointer closure)
+ce_have_contact (EBookClient *book_client,
+ const GError *error,
+ EContact *contact,
+ gpointer closure)
{
QuickAdd *qa = (QuickAdd *) closure;
- if (book == NULL) {
- g_warning ("Couldn't open local address book.");
+ if (error) {
+ if (book_client)
+ g_object_unref (book_client);
+ g_warning (
+ "Failed to find contact, status %d (%s).",
+ error->code, error->message);
quick_add_unref (qa);
} else {
- EContactEditor *contact_editor = e_contact_editor_new (book, qa->card, TRUE, TRUE /* XXX */);
-
- /* mark it as changed so the Save buttons are enabled when we bring up the dialog. */
- gtk_object_set (GTK_OBJECT(contact_editor),
- "changed", TRUE,
- 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,
- I think can happen and cause a crash. */
- gtk_object_set_data_full (GTK_OBJECT (contact_editor), "quick_add", qa,
- (GtkDestroyNotify) quick_add_unref);
-
- gtk_signal_connect (GTK_OBJECT (contact_editor),
- "card_added",
- GTK_SIGNAL_FUNC (card_added_cb),
- NULL);
- gtk_signal_connect (GTK_OBJECT (contact_editor),
- "editor_closed",
- GTK_SIGNAL_FUNC (editor_closed_cb),
- NULL);
-
- gtk_object_unref (GTK_OBJECT (book));
+ EShell *shell;
+ EABEditor *contact_editor;
+
+ if (contact) {
+ /* use found contact */
+ if (qa->contact)
+ g_object_unref (qa->contact);
+ qa->contact = g_object_ref (contact);
+ }
+
+ shell = e_shell_get_default ();
+ contact_editor = e_contact_editor_new (
+ shell, book_client, 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, "changed", contact != NULL, NULL);
+
+ /* We pass this via object data, so that we don't get a
+ * dangling pointer referenced if both 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, "contact_added",
+ G_CALLBACK (contact_added_cb), NULL);
+ g_signal_connect (
+ contact_editor, "editor_closed",
+ G_CALLBACK (editor_closed_cb), NULL);
+
+ g_object_unref (book_client);
+ }
+}
+
+static void
+ce_have_book (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ QuickAdd *qa = user_data;
+ EClient *client;
+ ESourceRegistry *registry;
+ GError *error = NULL;
+
+ client = e_client_cache_get_client_finish (
+ E_CLIENT_CACHE (source_object), result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ /* Ignore cancellations. */
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_warn_if_fail (client == NULL);
+ g_error_free (error);
+ return;
}
+
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ quick_add_unref (qa);
+ g_error_free (error);
+ return;
+ }
+
+ registry = e_client_cache_ref_registry (qa->client_cache);
+
+ eab_merging_book_find_contact (
+ registry, E_BOOK_CLIENT (client),
+ qa->contact, ce_have_contact, qa);
+
+ g_object_unref (registry);
}
static void
-edit_card (QuickAdd *qa)
+edit_contact (QuickAdd *qa)
{
- EBook *book;
- book = e_book_new ();
- if (!addressbook_load_default_book (book, ce_have_book, qa)) {
- gtk_object_unref (GTK_OBJECT (book));
- ce_have_book (book, E_BOOK_STATUS_OTHER_ERROR, qa);
+ if (qa->cancellable != NULL) {
+ g_cancellable_cancel (qa->cancellable);
+ g_object_unref (qa->cancellable);
}
+
+ qa->cancellable = g_cancellable_new ();
+
+ e_client_cache_get_client (
+ qa->client_cache, qa->source,
+ E_SOURCE_EXTENSION_ADDRESS_BOOK,
+ qa->cancellable, ce_have_book, qa);
}
+#define QUICK_ADD_RESPONSE_EDIT_FULL 2
+
static void
-clicked_cb (GtkWidget *w, gint button, gpointer closure)
+clicked_cb (GtkWidget *w,
+ gint button,
+ gpointer closure)
{
QuickAdd *qa = (QuickAdd *) closure;
/* Get data out of entries. */
- if (button == 0 || button == 1) {
+ if (!qa->vcard && (button == GTK_RESPONSE_OK ||
+ button == QUICK_ADD_RESPONSE_EDIT_FULL)) {
gchar *name = NULL;
gchar *email = NULL;
- if (qa->name_entry) {
- gchar *tmp;
- tmp = gtk_editable_get_chars (GTK_EDITABLE (qa->name_entry), 0, -1);
- name = e_utf8_from_gtk_string (qa->name_entry, tmp);
- g_free (tmp);
- }
+ if (qa->name_entry)
+ name = gtk_editable_get_chars (
+ GTK_EDITABLE (qa->name_entry), 0, -1);
- if (qa->email_entry) {
- gchar *tmp;
- tmp = gtk_editable_get_chars (GTK_EDITABLE (qa->email_entry), 0, -1);
- email = e_utf8_from_gtk_string (qa->email_entry, tmp);
- g_free (tmp);
- }
+ if (qa->email_entry)
+ email = gtk_editable_get_chars (
+ GTK_EDITABLE (qa->email_entry), 0, -1);
+
+ e_contact_set (
+ qa->contact, E_CONTACT_FULL_NAME,
+ (name != NULL) ? name : "");
+
+ e_contact_set (
+ qa->contact, E_CONTACT_EMAIL_1,
+ (email != NULL) ? email : "");
- quick_add_set_name (qa, name);
- quick_add_set_email (qa, email);
-
g_free (name);
g_free (email);
}
gtk_widget_destroy (w);
- if (button == 0) {
+ if (button == GTK_RESPONSE_OK) {
/* OK */
- quick_add_merge_card (qa);
+ quick_add_merge_contact (qa);
+
+ } else if (button == QUICK_ADD_RESPONSE_EDIT_FULL) {
- } else if (button == 1) {
-
/* EDIT FULL */
- edit_card (qa);
+ edit_contact (qa);
} else {
/* CANCEL */
@@ -289,74 +398,177 @@ clicked_cb (GtkWidget *w, gint button, gpointer closure)
}
+static void
+sanitize_widgets (QuickAdd *qa)
+{
+ GtkComboBox *combo_box;
+ const gchar *active_id;
+ gboolean enabled = TRUE;
+
+ g_return_if_fail (qa != NULL);
+ g_return_if_fail (qa->dialog != NULL);
+
+ combo_box = GTK_COMBO_BOX (qa->combo_box);
+ active_id = gtk_combo_box_get_active_id (combo_box);
+ enabled = (active_id != NULL);
+
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (qa->dialog),
+ QUICK_ADD_RESPONSE_EDIT_FULL, enabled);
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (qa->dialog), GTK_RESPONSE_OK, enabled);
+}
+
+static void
+source_changed (ESourceComboBox *source_combo_box,
+ QuickAdd *qa)
+{
+ ESource *source;
+
+ source = e_source_combo_box_ref_active (source_combo_box);
+
+ if (source != NULL) {
+ if (qa->source != NULL)
+ g_object_unref (qa->source);
+ qa->source = source; /* takes reference */
+ }
+
+ sanitize_widgets (qa);
+}
+
static GtkWidget *
build_quick_add_dialog (QuickAdd *qa)
{
+ GtkWidget *container;
GtkWidget *dialog;
+ GtkWidget *label;
GtkTable *table;
- const gint xpad=1, ypad=1;
+ ESource *source;
+ ESourceRegistry *registry;
+ const gchar *extension_name;
+ const gint xpad = 0, ypad = 0;
g_return_val_if_fail (qa != NULL, NULL);
- dialog = gnome_dialog_new (_("Contact Quick-Add"),
- GNOME_STOCK_BUTTON_OK,
- _("Edit Full"),
- GNOME_STOCK_BUTTON_CANCEL,
- NULL);
+ dialog = gtk_dialog_new_with_buttons (
+ _("Contact Quick-Add"),
+ e_shell_get_active_window (NULL),
+ 0,
+ _("_Edit Full"), QUICK_ADD_RESPONSE_EDIT_FULL,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
- gtk_signal_connect (GTK_OBJECT (dialog),
- "clicked",
- clicked_cb,
- qa);
+ gtk_widget_ensure_style (dialog);
- qa->name_entry = gtk_entry_new ();
- if (qa->name) {
- gchar *str = e_utf8_to_gtk_string (qa->name_entry, qa->name);
- gtk_entry_set_text (GTK_ENTRY (qa->name_entry), str);
- g_free (str);
- }
+ container = gtk_dialog_get_action_area (GTK_DIALOG (dialog));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 12);
+ container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 0);
+
+ g_signal_connect (
+ dialog, "response",
+ G_CALLBACK (clicked_cb), qa);
+ qa->dialog = dialog;
+
+ qa->name_entry = gtk_entry_new ();
+ if (qa->name)
+ gtk_entry_set_text (GTK_ENTRY (qa->name_entry), qa->name);
qa->email_entry = gtk_entry_new ();
- if (qa->email) {
- gchar *str = e_utf8_to_gtk_string (qa->email_entry, qa->email);
- gtk_entry_set_text (GTK_ENTRY (qa->email_entry), str);
- g_free (str);
+ if (qa->email)
+ gtk_entry_set_text (GTK_ENTRY (qa->email_entry), qa->email);
+
+ if (qa->vcard) {
+ /* when adding vCard, then do not allow change name or email */
+ gtk_widget_set_sensitive (qa->name_entry, FALSE);
+ gtk_widget_set_sensitive (qa->email_entry, FALSE);
}
- table = GTK_TABLE (gtk_table_new (2, 2, FALSE));
-
- gtk_table_attach (table, gtk_label_new (_("Full Name")),
- 0, 1, 0, 1,
- 0, 0, xpad, ypad);
- gtk_table_attach (table, qa->name_entry,
- 1, 2, 0, 1,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND, xpad, ypad);
- gtk_table_attach (table, gtk_label_new (_("E-mail")),
- 0, 1, 1, 2,
- 0, 0, xpad, ypad);
- gtk_table_attach (table, qa->email_entry,
- 1, 2, 1, 2,
- GTK_EXPAND | GTK_FILL, GTK_EXPAND, xpad, ypad);
-
- gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox),
- GTK_WIDGET (table),
- TRUE, TRUE, 0);
+ extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+ registry = e_client_cache_ref_registry (qa->client_cache);
+ source = e_source_registry_ref_default_address_book (registry);
+ g_object_unref (registry);
+
+ qa->combo_box = e_client_combo_box_new (
+ qa->client_cache, extension_name);
+ e_source_combo_box_set_active (
+ E_SOURCE_COMBO_BOX (qa->combo_box), source);
+
+ g_object_unref (source);
+
+ source_changed (E_SOURCE_COMBO_BOX (qa->combo_box), qa);
+ g_signal_connect (
+ qa->combo_box, "changed",
+ G_CALLBACK (source_changed), qa);
+
+ table = GTK_TABLE (gtk_table_new (3, 2, FALSE));
+ gtk_table_set_row_spacings (table, 6);
+ gtk_table_set_col_spacings (table, 12);
+
+ label = gtk_label_new_with_mnemonic (_("_Full name"));
+ gtk_label_set_mnemonic_widget ((GtkLabel *) label, qa->name_entry);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+ gtk_table_attach (
+ table, label,
+ 0, 1, 0, 1,
+ GTK_FILL, 0, xpad, ypad);
+ gtk_table_attach (
+ table, qa->name_entry,
+ 1, 2, 0, 1,
+ GTK_EXPAND | GTK_FILL, 0, xpad, ypad);
+
+ label = gtk_label_new_with_mnemonic (_("E_mail"));
+ gtk_label_set_mnemonic_widget ((GtkLabel *) label, qa->email_entry);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+ gtk_table_attach (
+ table, label,
+ 0, 1, 1, 2,
+ GTK_FILL, 0, xpad, ypad);
+ gtk_table_attach (
+ table, qa->email_entry,
+ 1, 2, 1, 2,
+ GTK_EXPAND | GTK_FILL, 0, xpad, ypad);
+
+ label = gtk_label_new_with_mnemonic (_("_Select Address Book"));
+ gtk_label_set_mnemonic_widget ((GtkLabel *) label, qa->combo_box);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+ gtk_table_attach (
+ table, label,
+ 0, 1, 2, 3,
+ GTK_FILL, 0, xpad, ypad);
+ gtk_table_attach (
+ table, qa->combo_box,
+ 1, 2, 2, 3,
+ GTK_EXPAND | GTK_FILL, 0, xpad, ypad);
+
+ gtk_container_set_border_width (GTK_CONTAINER (table), 12);
+ container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ gtk_box_pack_start (
+ GTK_BOX (container), GTK_WIDGET (table), FALSE, FALSE, 0);
gtk_widget_show_all (GTK_WIDGET (table));
-
-
+
return dialog;
}
void
-e_contact_quick_add (const gchar *in_name, const gchar *email,
- EContactQuickAddCallback cb, gpointer closure)
+e_contact_quick_add (EClientCache *client_cache,
+ const gchar *in_name,
+ const gchar *email,
+ EContactQuickAddCallback cb,
+ gpointer closure)
{
QuickAdd *qa;
GtkWidget *dialog;
gchar *name = NULL;
gint len;
+ g_return_if_fail (E_IS_CLIENT_CACHE (client_cache));
+
/* We need to have *something* to work with. */
if (in_name == NULL && email == NULL) {
if (cb)
@@ -370,14 +582,15 @@ e_contact_quick_add (const gchar *in_name, const gchar *email,
/* Remove extra whitespace and the quotes some mailers put around names. */
g_strstrip (name);
len = strlen (name);
- if ((name[0] == '\'' && name[len-1] == '\'') || (name[0] == '"' && name[len-1] == '"')) {
+ if ((name[0] == '\'' && name[len - 1] == '\'') ||
+ (name[0] == '"' && name[len - 1] == '"')) {
name[0] = ' ';
- name[len-1] = ' ';
+ name[len - 1] = ' ';
}
g_strstrip (name);
}
- qa = quick_add_new ();
+ qa = quick_add_new (client_cache);
qa->cb = cb;
qa->closure = closure;
if (name)
@@ -392,14 +605,19 @@ e_contact_quick_add (const gchar *in_name, const gchar *email,
}
void
-e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, gpointer closure)
+e_contact_quick_add_free_form (EClientCache *client_cache,
+ const gchar *text,
+ EContactQuickAddCallback cb,
+ gpointer closure)
{
- gchar *name=NULL, *email=NULL;
+ gchar *name = NULL, *email = NULL;
const gchar *last_at, *s;
gboolean in_quote;
+ g_return_if_fail (E_IS_CLIENT_CACHE (client_cache));
+
if (text == NULL) {
- e_contact_quick_add (NULL, NULL, cb, closure);
+ e_contact_quick_add (client_cache, NULL, NULL, cb, closure);
return;
}
@@ -413,16 +631,17 @@ e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, g
in_quote = !in_quote;
}
-
if (last_at == NULL) {
/* No at sign, so we treat it all as the name */
name = g_strdup (text);
} else {
gboolean bad_char = FALSE;
-
+
/* walk backwards to whitespace or a < or a quote... */
while (last_at >= text && !bad_char
- && !(isspace ((gint) *last_at) || *last_at == '<' || *last_at == '"')) {
+ && !(isspace ((gint) *last_at) ||
+ *last_at == '<' ||
+ *last_at == '"')) {
/* Check for some stuff that can't appear in a legal e-mail address. */
if (*last_at == '['
|| *last_at == ']'
@@ -437,16 +656,14 @@ e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, g
/* ...and then split the text there */
if (!bad_char) {
if (text < last_at)
- name = g_strndup (text, last_at-text);
+ name = g_strndup (text, last_at - text);
email = g_strdup (last_at);
}
}
/* If all else has failed, make it the name. */
- if (name == NULL && email == NULL)
+ if (name == NULL && email == NULL)
name = g_strdup (text);
-
-
/* Clean up email, remove bracketing <>s */
if (email && *email) {
@@ -456,16 +673,106 @@ e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, g
*email = ' ';
changed = TRUE;
}
- if (email[strlen (email)-1] == '>') {
- email[strlen (email)-1] = ' ';
+ if (email[strlen (email) - 1] == '>') {
+ email[strlen (email) - 1] = ' ';
changed = TRUE;
}
if (changed)
g_strstrip (email);
}
-
- e_contact_quick_add (name, email, cb, closure);
+ e_contact_quick_add (client_cache, name, email, cb, closure);
+
g_free (name);
g_free (email);
}
+
+void
+e_contact_quick_add_email (EClientCache *client_cache,
+ const gchar *email,
+ EContactQuickAddCallback cb,
+ gpointer closure)
+{
+ gchar *name = NULL;
+ gchar *addr = NULL;
+ gchar *lt, *gt;
+
+ /* Handle something of the form "Foo <foo@bar.com>". This is more
+ * more forgiving than the free-form parser, allowing for unquoted
+ * whitespace since we know the whole string is an email address. */
+
+ lt = (email != NULL) ? strchr (email, '<') : NULL;
+ gt = (lt != NULL) ? strchr (email, '>') : NULL;
+
+ if (lt != NULL && gt != NULL && (gt - lt) > 0) {
+ name = g_strndup (email, lt - email);
+ addr = g_strndup (lt + 1, gt - lt - 1);
+ } else {
+ addr = g_strdup (email);
+ }
+
+ e_contact_quick_add (client_cache, name, addr, cb, closure);
+
+ g_free (name);
+ g_free (addr);
+}
+
+void
+e_contact_quick_add_vcard (EClientCache *client_cache,
+ const gchar *vcard,
+ EContactQuickAddCallback cb,
+ gpointer closure)
+{
+ QuickAdd *qa;
+ GtkWidget *dialog;
+ EContact *contact;
+
+ g_return_if_fail (E_IS_CLIENT_CACHE (client_cache));
+
+ /* We need to have *something* to work with. */
+ if (vcard == NULL) {
+ if (cb)
+ cb (NULL, closure);
+ return;
+ }
+
+ qa = quick_add_new (client_cache);
+ qa->cb = cb;
+ qa->closure = closure;
+ quick_add_set_vcard (qa, vcard);
+
+ contact = e_contact_new_from_vcard (qa->vcard);
+
+ if (contact) {
+ GList *emails;
+ gchar *name;
+ EContactName *contact_name;
+
+ g_object_unref (qa->contact);
+ qa->contact = contact;
+
+ contact_name = e_contact_get (qa->contact, E_CONTACT_NAME);
+ name = e_contact_name_to_string (contact_name);
+ quick_add_set_name (qa, name);
+ g_free (name);
+ e_contact_name_free (contact_name);
+
+ emails = e_contact_get (qa->contact, E_CONTACT_EMAIL);
+ if (emails) {
+ quick_add_set_email (qa, emails->data);
+
+ g_list_foreach (emails, (GFunc) g_free, NULL);
+ g_list_free (emails);
+ }
+ } else {
+ if (cb)
+ cb (NULL, closure);
+
+ quick_add_unref (qa);
+ g_warning ("Contact's vCard parsing failed!");
+ return;
+ }
+
+ dialog = build_quick_add_dialog (qa);
+ gtk_widget_show_all (dialog);
+}
diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.h b/addressbook/gui/contact-editor/e-contact-quick-add.h
index 1bf69ee114..abc94fddb7 100644
--- a/addressbook/gui/contact-editor/e-contact-quick-add.h
+++ b/addressbook/gui/contact-editor/e-contact-quick-add.h
@@ -1,40 +1,52 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * e-contact-quick-add.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.
- *
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Jon Trowbridge <trow@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
*/
#ifndef __E_CONTACT_QUICK_ADD_H__
#define __E_CONTACT_QUICK_ADD_H__
-#include <addressbook/backend/ebook/e-card.h>
-
-typedef void (*EContactQuickAddCallback) (ECard *new_card, gpointer closure);
-
-void e_contact_quick_add (const gchar *name, const gchar *email,
- EContactQuickAddCallback cb, gpointer closure);
-
-void e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, gpointer closure);
+#include <libebook/libebook.h>
+
+#include <e-util/e-util.h>
+
+typedef void (*EContactQuickAddCallback) (EContact *new_contact,
+ gpointer closure);
+
+void e_contact_quick_add (EClientCache *client_cache,
+ const gchar *name,
+ const gchar *email,
+ EContactQuickAddCallback cb,
+ gpointer closure);
+void e_contact_quick_add_free_form (EClientCache *client_cache,
+ const gchar *text,
+ EContactQuickAddCallback cb,
+ gpointer closure);
+void e_contact_quick_add_email (EClientCache *client_cache,
+ const gchar *email,
+ EContactQuickAddCallback cb,
+ gpointer closure);
+void e_contact_quick_add_vcard (EClientCache *client_cache,
+ const gchar *vcard,
+ EContactQuickAddCallback cb,
+ gpointer closure);
#endif /* __E_CONTACT_QUICK_ADD_H__ */
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 f2251ee233..0000000000
--- a/addressbook/gui/contact-editor/e-contact-save-as.c
+++ /dev/null
@@ -1,228 +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/gtk.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <gal/util/e-util.h>
-#include <libgnome/gnome-i18n.h>
-#include <errno.h>
-#include <string.h>
-#include <libgnomeui/gnome-messagebox.h>
-#include <libgnomeui/gnome-stock.h>
-
-static int 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 0 : /* Overwrite */
- e_write_file(filename, info->vcard, O_WRONLY | O_CREAT | O_TRUNC);
- break;
- case 1 : /* cancel */
- return;
- }
- } else if (error != 0) {
- GtkWidget *dialog;
- char *str;
-
- str = g_strdup_printf ("Error saving %s: %s", filename, strerror(errno));
- dialog = gnome_message_box_new (str, GNOME_MESSAGE_BOX_ERROR, GNOME_STOCK_BUTTON_OK, NULL);
- g_free (str);
-
- gnome_dialog_set_parent (GNOME_DIALOG (dialog), GTK_WINDOW (info->filesel));
-
- gtk_widget_show (dialog);
-
- return;
- }
-
- g_free (info->vcard);
- gtk_widget_destroy(GTK_WIDGET(info->filesel));
- g_free(info);
-}
-
-static void
-close_it(GtkWidget *widget, SaveAsInfo *info)
-{
- g_free (info->vcard);
- gtk_widget_destroy (GTK_WIDGET (info->filesel));
- g_free (info);
-}
-
-static void
-delete_it(GtkWidget *widget, SaveAsInfo *info)
-{
- 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));
-
- gtk_object_get (GTK_OBJECT (card),
- "file_as", &name,
- NULL);
- 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_card_get_vcard(card);
-
- gtk_signal_connect(GTK_OBJECT(filesel->ok_button), "clicked",
- save_it, info);
- gtk_signal_connect(GTK_OBJECT(filesel->cancel_button), "clicked",
- close_it, info);
- gtk_signal_connect(GTK_OBJECT(filesel), "delete_event",
- delete_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;
- gtk_object_get (GTK_OBJECT (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);
- } 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);
-
- gtk_signal_connect(GTK_OBJECT(filesel->ok_button), "clicked",
- save_it, info);
- gtk_signal_connect(GTK_OBJECT(filesel->cancel_button), "clicked",
- close_it, info);
- gtk_signal_connect(GTK_OBJECT(filesel), "delete_event",
- delete_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 int
-file_exists(GtkFileSelection *filesel, const char *filename)
-{
- GnomeDialog *dialog = NULL;
- GtkWidget *label;
- GladeXML *gui = NULL;
- int result = 0;
- char *string;
-
- gui = glade_xml_new (EVOLUTION_GLADEDIR "/file-exists.glade", NULL);
- dialog = GNOME_DIALOG(glade_xml_get_widget(gui, "dialog-exists"));
-
- label = glade_xml_get_widget (gui, "label-exists");
- if (GTK_IS_LABEL (label)) {
- string = g_strdup_printf (_("%s already exists\nDo you want to overwrite it?"), filename);
- gtk_label_set_text (GTK_LABEL (label), string);
- g_free (string);
- }
-
- gnome_dialog_set_parent(dialog, GTK_WINDOW(filesel));
-
- gtk_widget_show (GTK_WIDGET (dialog));
- result = gnome_dialog_run_and_close(dialog);
-
- g_free(gui);
-
- return result;
-}
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 66d1e8bad9..0000000000
--- a/addressbook/gui/contact-editor/e-contact-save-as.h
+++ /dev/null
@@ -1,40 +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 <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-editor/eab-editor.c b/addressbook/gui/contact-editor/eab-editor.c
new file mode 100644
index 0000000000..fcbdfb1049
--- /dev/null
+++ b/addressbook/gui/contact-editor/eab-editor.c
@@ -0,0 +1,403 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include "eab-editor.h"
+#include "e-util/e-util.h"
+#include "addressbook/gui/widgets/eab-gui-util.h"
+
+#define EAB_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EAB_TYPE_EDITOR, EABEditorPrivate))
+
+struct _EABEditorPrivate {
+ EShell *shell;
+};
+
+enum {
+ PROP_0,
+ PROP_SHELL
+};
+
+enum {
+ CONTACT_ADDED,
+ CONTACT_MODIFIED,
+ CONTACT_DELETED,
+ EDITOR_CLOSED,
+ LAST_SIGNAL
+};
+
+static GSList *all_editors;
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_ABSTRACT_TYPE (EABEditor, eab_editor, G_TYPE_OBJECT)
+
+static void
+eab_editor_quit_requested_cb (EShell *shell,
+ EShellQuitReason reason,
+ EABEditor *editor)
+{
+ GtkWindow *window;
+
+ /* Quit immediately if another Evolution process asked us to. */
+ if (reason == E_SHELL_QUIT_REMOTE_REQUEST)
+ return;
+
+ window = eab_editor_get_window (editor);
+
+ eab_editor_raise (editor);
+ if (!eab_editor_prompt_to_save_changes (editor, window))
+ e_shell_cancel_quit (shell);
+}
+
+static void
+eab_editor_set_shell (EABEditor *editor,
+ EShell *shell)
+{
+ g_return_if_fail (editor->priv->shell == NULL);
+ g_return_if_fail (E_IS_SHELL (shell));
+
+ editor->priv->shell = g_object_ref (shell);
+
+ g_signal_connect (
+ shell, "quit-requested",
+ G_CALLBACK (eab_editor_quit_requested_cb), editor);
+}
+
+static void
+eab_editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL:
+ eab_editor_set_shell (
+ EAB_EDITOR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+eab_editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL:
+ g_value_set_object (
+ value, eab_editor_get_shell (
+ EAB_EDITOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+eab_editor_dispose (GObject *object)
+{
+ EABEditorPrivate *priv;
+
+ priv = EAB_EDITOR_GET_PRIVATE (object);
+
+ if (priv->shell != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->shell, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->shell);
+ priv->shell = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (eab_editor_parent_class)->dispose (object);
+}
+
+static void
+eab_editor_finalize (GObject *object)
+{
+ all_editors = g_slist_remove (all_editors, object);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (eab_editor_parent_class)->finalize (object);
+}
+
+static void
+eab_editor_class_init (EABEditorClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EABEditorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = eab_editor_set_property;
+ object_class->get_property = eab_editor_get_property;
+ object_class->dispose = eab_editor_dispose;
+ object_class->finalize = eab_editor_finalize;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL,
+ g_param_spec_object (
+ "shell",
+ "Shell",
+ "The EShell singleton",
+ E_TYPE_SHELL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ signals[CONTACT_ADDED] = g_signal_new (
+ "contact_added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EABEditorClass, contact_added),
+ NULL, NULL,
+ e_marshal_NONE__POINTER_OBJECT,
+ G_TYPE_NONE, 2,
+ G_TYPE_POINTER,
+ G_TYPE_OBJECT);
+
+ signals[CONTACT_MODIFIED] = g_signal_new (
+ "contact_modified",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EABEditorClass, contact_modified),
+ NULL, NULL,
+ e_marshal_NONE__POINTER_OBJECT,
+ G_TYPE_NONE, 2,
+ G_TYPE_POINTER,
+ G_TYPE_OBJECT);
+
+ signals[CONTACT_DELETED] = g_signal_new (
+ "contact_deleted",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EABEditorClass, contact_deleted),
+ NULL, NULL,
+ e_marshal_NONE__POINTER_OBJECT,
+ G_TYPE_NONE, 2,
+ G_TYPE_POINTER,
+ G_TYPE_OBJECT);
+
+ signals[EDITOR_CLOSED] = g_signal_new (
+ "editor_closed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EABEditorClass, editor_closed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+eab_editor_init (EABEditor *editor)
+{
+ editor->priv = EAB_EDITOR_GET_PRIVATE (editor);
+
+ all_editors = g_slist_prepend (all_editors, editor);
+}
+
+EShell *
+eab_editor_get_shell (EABEditor *editor)
+{
+ g_return_val_if_fail (EAB_IS_EDITOR (editor), NULL);
+
+ return E_SHELL (editor->priv->shell);
+}
+
+GSList *
+eab_editor_get_all_editors (void)
+{
+ return all_editors;
+}
+
+void
+eab_editor_show (EABEditor *editor)
+{
+ EABEditorClass *class;
+
+ g_return_if_fail (EAB_IS_EDITOR (editor));
+
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_if_fail (class->show != NULL);
+
+ class->show (editor);
+}
+
+void
+eab_editor_close (EABEditor *editor)
+{
+ EABEditorClass *class;
+
+ g_return_if_fail (EAB_IS_EDITOR (editor));
+
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_if_fail (class->close != NULL);
+
+ class->close (editor);
+}
+
+void
+eab_editor_raise (EABEditor *editor)
+{
+ EABEditorClass *class;
+
+ g_return_if_fail (EAB_IS_EDITOR (editor));
+
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_if_fail (class->raise != NULL);
+
+ class->raise (editor);
+}
+
+void
+eab_editor_save_contact (EABEditor *editor,
+ gboolean should_close)
+{
+ EABEditorClass *class;
+
+ g_return_if_fail (EAB_IS_EDITOR (editor));
+
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_if_fail (class->save_contact != NULL);
+
+ class->save_contact (editor, should_close);
+}
+
+gboolean
+eab_editor_is_changed (EABEditor *editor)
+{
+ EABEditorClass *class;
+
+ g_return_val_if_fail (EAB_IS_EDITOR (editor), FALSE);
+
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_val_if_fail (class->is_changed != NULL, FALSE);
+
+ return class->is_changed (editor);
+}
+
+gboolean
+eab_editor_is_valid (EABEditor *editor)
+{
+ EABEditorClass *class;
+
+ g_return_val_if_fail (EAB_IS_EDITOR (editor), FALSE);
+
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_val_if_fail (class->is_valid != NULL, FALSE);
+
+ return class->is_valid (editor);
+}
+
+GtkWindow *
+eab_editor_get_window (EABEditor *editor)
+{
+ EABEditorClass *class;
+
+ g_return_val_if_fail (EAB_IS_EDITOR (editor), NULL);
+
+ class = EAB_EDITOR_GET_CLASS (editor);
+ g_return_val_if_fail (class->get_window != NULL, NULL);
+
+ return class->get_window (editor);
+}
+
+/* This function prompts for saving if editor conents are in changed state and
+ * save or discards or cancels (just returns with out doing anything) according
+ * to user input. Editor gets destroyed in case of save and discard case. */
+
+gboolean
+eab_editor_prompt_to_save_changes (EABEditor *editor,
+ GtkWindow *window)
+{
+ if (!eab_editor_is_changed (editor)) {
+ eab_editor_close (EAB_EDITOR (editor));
+ return TRUE;
+ }
+
+ switch (eab_prompt_save_dialog (window)) {
+ case GTK_RESPONSE_YES:
+ if (!eab_editor_is_valid (editor)) {
+ return FALSE;
+ }
+ eab_editor_save_contact (editor, TRUE);
+ return TRUE;
+ case GTK_RESPONSE_NO:
+ eab_editor_close (EAB_EDITOR (editor));
+ return TRUE;
+ case GTK_RESPONSE_CANCEL:
+ default:
+ return FALSE;
+ }
+}
+
+void
+eab_editor_contact_added (EABEditor *editor,
+ const GError *error,
+ EContact *contact)
+{
+ g_return_if_fail (EAB_IS_EDITOR (editor));
+ g_return_if_fail (E_IS_CONTACT (contact));
+
+ g_signal_emit (editor, signals[CONTACT_ADDED], 0, error, contact);
+}
+
+void
+eab_editor_contact_modified (EABEditor *editor,
+ const GError *error,
+ EContact *contact)
+{
+ g_return_if_fail (EAB_IS_EDITOR (editor));
+ g_return_if_fail (E_IS_CONTACT (contact));
+
+ g_signal_emit (editor, signals[CONTACT_MODIFIED], 0, error, contact);
+}
+
+void
+eab_editor_contact_deleted (EABEditor *editor,
+ const GError *error,
+ EContact *contact)
+{
+ g_return_if_fail (EAB_IS_EDITOR (editor));
+ g_return_if_fail (E_IS_CONTACT (contact));
+
+ g_signal_emit (editor, signals[CONTACT_DELETED], 0, error, contact);
+}
+
+void
+eab_editor_closed (EABEditor *editor)
+{
+ g_return_if_fail (EAB_IS_EDITOR (editor));
+
+ g_signal_emit (editor, signals[EDITOR_CLOSED], 0);
+}
diff --git a/addressbook/gui/contact-editor/eab-editor.h b/addressbook/gui/contact-editor/eab-editor.h
new file mode 100644
index 0000000000..88ede1522f
--- /dev/null
+++ b/addressbook/gui/contact-editor/eab-editor.h
@@ -0,0 +1,112 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EAB_EDITOR_H__
+#define __EAB_EDITOR_H__
+
+#include <gtk/gtk.h>
+#include <libebook/libebook.h>
+#include <shell/e-shell.h>
+
+/* Standard GObject macros */
+#define EAB_TYPE_EDITOR \
+ (eab_editor_get_type ())
+#define EAB_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EAB_TYPE_EDITOR, EABEditor))
+#define EAB_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EAB_TYPE_EDITOR, EABEditorClass))
+#define EAB_IS_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EAB_TYPE_EDITOR))
+#define EAB_IS_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EAB_TYPE_EDITOR))
+#define EAB_EDITOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), EAB_EDITOR_TYPE, EABEditorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EABEditor EABEditor;
+typedef struct _EABEditorClass EABEditorClass;
+typedef struct _EABEditorPrivate EABEditorPrivate;
+
+struct _EABEditor {
+ GObject parent;
+ EABEditorPrivate *priv;
+};
+
+struct _EABEditorClass {
+ GObjectClass parent_class;
+
+ /* virtual functions */
+ void (* show) (EABEditor *editor);
+ void (* close) (EABEditor *editor);
+ void (* raise) (EABEditor *editor);
+ void (* save_contact) (EABEditor *editor, gboolean should_close);
+ gboolean (* is_valid) (EABEditor *editor);
+ gboolean (* is_changed) (EABEditor *editor);
+ GtkWindow * (* get_window) (EABEditor *editor);
+
+ /* signals */
+ void (* contact_added) (EABEditor *editor, const GError *error, EContact *contact);
+ void (* contact_modified) (EABEditor *editor, const GError *error, EContact *contact);
+ void (* contact_deleted) (EABEditor *editor, const GError *error, EContact *contact);
+ void (* editor_closed) (EABEditor *editor);
+};
+
+GType eab_editor_get_type (void);
+EShell * eab_editor_get_shell (EABEditor *editor);
+GSList * eab_editor_get_all_editors (void);
+
+/* virtual functions */
+void eab_editor_show (EABEditor *editor);
+void eab_editor_close (EABEditor *editor);
+void eab_editor_raise (EABEditor *editor);
+void eab_editor_save_contact (EABEditor *editor,
+ gboolean should_close);
+gboolean eab_editor_is_valid (EABEditor *editor);
+gboolean eab_editor_is_changed (EABEditor *editor);
+GtkWindow * eab_editor_get_window (EABEditor *editor);
+
+gboolean eab_editor_prompt_to_save_changes
+ (EABEditor *editor,
+ GtkWindow *window);
+
+/* these four generate EABEditor signals */
+void eab_editor_contact_added (EABEditor *editor,
+ const GError *error,
+ EContact *contact);
+void eab_editor_contact_modified (EABEditor *editor,
+ const GError *error,
+ EContact *contact);
+void eab_editor_contact_deleted (EABEditor *editor,
+ const GError *error,
+ EContact *contact);
+void eab_editor_closed (EABEditor *editor);
+
+G_END_DECLS
+
+#endif /* __E_CONTACT_EDITOR_H__ */
diff --git a/addressbook/gui/contact-editor/file-exists.glade b/addressbook/gui/contact-editor/file-exists.glade
deleted file mode 100644
index 7c457cb892..0000000000
--- a/addressbook/gui/contact-editor/file-exists.glade
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>File_exists.glade</name>
- <program_name>file_exists.glade</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
-</project>
-
-<widget>
- <class>GnomeDialog</class>
- <name>dialog-exists</name>
- <visible>False</visible>
- <title>Confirm Overwrite</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>False</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>dialog-vbox1</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>dialog-action_area1</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button1</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>Overwrite</label>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button3</name>
- <can_default>True</can_default>
- <has_default>True</has_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label-exists</name>
- <label>Don't bother translating this string. It's not used.</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/addressbook/gui/contact-editor/fulladdr.glade b/addressbook/gui/contact-editor/fulladdr.glade
deleted file mode 100644
index d66b9163e8..0000000000
--- a/addressbook/gui/contact-editor/fulladdr.glade
+++ /dev/null
@@ -1,473 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>fulladdr</name>
- <program_name>fulladdr</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
- <use_widget_names>True</use_widget_names>
- <output_main_file>False</output_main_file>
- <output_support_files>False</output_support_files>
- <output_build_files>False</output_build_files>
-</project>
-
-<widget>
- <class>GnomeDialog</class>
- <name>dialog-checkaddress</name>
- <visible>False</visible>
- <title>Check Address</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>True</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>vbox-container</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>hbuttonbox1</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button1</name>
- <can_default>True</can_default>
- <has_default>True</has_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button2</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table-checkaddress</name>
- <border_width>8</border_width>
- <rows>4</rows>
- <columns>4</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>6</row_spacing>
- <column_spacing>6</column_spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label2</name>
- <label>_Address:</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-street</focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label4</name>
- <label>_City:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-city</focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-city</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-ext</name>
- <width>100</width>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label8</name>
- <label>_PO Box:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-po</focus_target>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label3</name>
- <label>Address _2:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-ext</focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-po</name>
- <width>100</width>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-street</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>4</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label5</name>
- <label>_State/Province:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-region</focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-region</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCombo</class>
- <name>combo-country</name>
- <width>100</width>
- <can_focus>True</can_focus>
- <value_in_list>False</value_in_list>
- <ok_if_empty>True</ok_if_empty>
- <case_sensitive>False</case_sensitive>
- <use_arrows>True</use_arrows>
- <use_arrows_always>False</use_arrows_always>
- <items></items>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <child_name>GtkCombo:entry</child_name>
- <name>entry-country</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-code</name>
- <width>100</width>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label6</name>
- <label>_ZIP Code:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-code</focus_target>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label7</name>
- <label>Countr_y:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-country</focus_target>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/addressbook/gui/contact-editor/fullname.glade b/addressbook/gui/contact-editor/fullname.glade
deleted file mode 100644
index 17be70647c..0000000000
--- a/addressbook/gui/contact-editor/fullname.glade
+++ /dev/null
@@ -1,389 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>fullname</name>
- <program_name>fullname</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
- <use_widget_names>True</use_widget_names>
- <output_main_file>False</output_main_file>
- <output_support_files>False</output_support_files>
- <output_build_files>False</output_build_files>
-</project>
-
-<widget>
- <class>GnomeDialog</class>
- <name>dialog-checkfullname</name>
- <visible>False</visible>
- <title>Check Full Name</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>True</modal>
- <allow_shrink>True</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>vbox-container</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>hbuttonbox1</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button1</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button2</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table-checkfullname</name>
- <border_width>8</border_width>
- <rows>5</rows>
- <columns>3</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>6</row_spacing>
- <column_spacing>21</column_spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCombo</class>
- <name>combo-title</name>
- <value_in_list>False</value_in_list>
- <ok_if_empty>True</ok_if_empty>
- <case_sensitive>False</case_sensitive>
- <use_arrows>True</use_arrows>
- <use_arrows_always>False</use_arrows_always>
- <items>
-Mr.
-Mrs.
-Ms.
-Miss
-Dr.
-</items>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <child_name>GtkCombo:entry</child_name>
- <name>entry-title</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
-
- <widget>
- <class>GtkCombo</class>
- <name>combo-suffix</name>
- <value_in_list>False</value_in_list>
- <ok_if_empty>True</ok_if_empty>
- <case_sensitive>False</case_sensitive>
- <use_arrows>True</use_arrows>
- <use_arrows_always>False</use_arrows_always>
- <items>
-Sr.
-Jr.
-I
-II
-III
-Esq.
-</items>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <child_name>GtkCombo:entry</child_name>
- <name>entry-suffix</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-first</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>3</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-middle</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>3</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry-last</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>3</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label2</name>
- <label>_First:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-first</focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label1</name>
- <label>_Title:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-title</focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label3</name>
- <label>_Middle:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-middle</focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label5</name>
- <label>_Last:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-last</focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label4</name>
- <label>_Suffix:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>entry-suffix</focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/addressbook/gui/contact-editor/fullname.ui b/addressbook/gui/contact-editor/fullname.ui
new file mode 100644
index 0000000000..90a1f04a9b
--- /dev/null
+++ b/addressbook/gui/contact-editor/fullname.ui
@@ -0,0 +1,363 @@
+<?xml version="1.0"?>
+<!--*- mode: xml -*-->
+<interface>
+ <object class="GtkListStore" id="model1">
+ <columns>
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes"></col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">Mr.</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">Mrs.</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">Ms.</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">Miss</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">Dr.</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="model2">
+ <columns>
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes"></col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">Sr.</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">Jr.</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">I</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">II</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">III</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">Esq.</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkDialog" id="dialog-checkfullname">
+ <property name="title" translatable="yes">Full Name</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="vbox-container">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="hbuttonbox1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <object class="GtkButton" id="button1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="button2">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="table-checkfullname">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="n_rows">5</property>
+ <property name="n_columns">3</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="entry-first">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"/>
+ <property name="has_frame">True</property>
+ <property name="activates_default">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-middle">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"/>
+ <property name="has_frame">True</property>
+ <property name="activates_default">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="entry-last">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"/>
+ <property name="has_frame">True</property>
+ <property name="activates_default">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">3</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-first">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_First:</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-first</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-title">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes" context="FullName">_Title:</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="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ <property name="mnemonic_widget">comboentry-title</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-middle">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Middle:</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-middle</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-last">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Last:</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-last</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label-suffix">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Suffix:</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="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ <property name="mnemonic_widget">comboentry-suffix</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="comboentry-title">
+ <property name="visible">True</property>
+ <property name="has-entry">True</property>
+ <property name="entry-text-column">0</property>
+ <property name="add_tearoffs">False</property>
+ <property name="has_frame">True</property>
+ <property name="focus_on_click">True</property>
+ <property name="model">model1</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="comboentry-suffix">
+ <property name="visible">True</property>
+ <property name="has-entry">True</property>
+ <property name="entry-text-column">0</property>
+ <property name="add_tearoffs">False</property>
+ <property name="has_frame">True</property>
+ <property name="focus_on_click">True</property>
+ <property name="model">model2</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="0">button1</action-widget>
+ <action-widget response="0">button2</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/addressbook/gui/contact-editor/test-editor.c b/addressbook/gui/contact-editor/test-editor.c
index e6b46adb83..1d9c24aed7 100644
--- a/addressbook/gui/contact-editor/test-editor.c
+++ b/addressbook/gui/contact-editor/test-editor.c
@@ -1,65 +1,53 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * test-editor.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <stdlib.h>
-#include <gtk/gtkmain.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-init.h>
-#include <glade/glade.h>
+#include <gtk/gtk.h>
#include "e-contact-editor.h"
-
-#define TEST_VCARD \
-"BEGIN:VCARD
-" \
-"FN:Nat
-" \
-"N:Friedman;Nat;D;Mr.
-" \
-"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
-" \
-"
-"
-
-static char *
-read_file (char *name)
+#include "ebook/e-card.h"
+
+#define TEST_VCARD \
+"BEGIN:VCARD\n" \
+"FN:Nat\n" \
+"N:Friedman;Nat;D;Mr.\n" \
+"BDAY:1977-08-06\n" \
+"TEL;WORK:617 679 1984\n" \
+"TEL;CELL:123 456 7890\n" \
+"EMAIL;INTERNET:nat@nat.org\n" \
+"EMAIL;INTERNET:nat@ximian.com\n" \
+"ADR;WORK;POSTAL:P.O. Box 101;;;Any Town;CA;91921-1234;\n" \
+"ADR;HOME;POSTAL;INTL:P.O. Box 202;;;Any Town 2;MI;12344-4321;USA\n" \
+"END:VCARD\n"
+
+static gchar *
+read_file (gchar *name)
{
- int len;
- char buff[65536];
- char line[1024];
+ gint len;
+ gchar buff[65536];
+ gchar line[1024];
FILE *f;
f = fopen (name, "r");
@@ -79,65 +67,49 @@ read_file (char *name)
/* Callback used when a contact editor is closed */
static void
-editor_closed_cb (EContactEditor *ce, gpointer data)
+editor_closed_cb (EContactEditor *ce,
+ gpointer data)
{
- static int count = 2;
+ static gint count = 2;
count--;
- gtk_object_unref (GTK_OBJECT (ce));
+ g_object_unref (ce);
if (count == 0)
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 ( _( "Contact Editor Test" ), VERSION,
- _( "Copyright (C) 2000, Ximian, Inc." ),
- authors,
- _( "This should test the contact editor canvas item" ),
- NULL);
- gtk_widget_show (about);
-}
-#endif
-
-int main( int argc, char *argv[] )
+gint
+main (gint argc,
+ gchar *argv[])
{
- char *cardstr;
+ gchar *cardstr;
EContactEditor *ce;
- /* bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);*/
-
- gnome_init( "Contact Editor Test", VERSION, argc, argv);
-
- glade_gnome_init ();
+ gtk_init (&argc, &argv);
cardstr = NULL;
if (argc == 2)
- cardstr = read_file (argv [1]);
+ cardstr = read_file (argv[1]);
if (cardstr == NULL)
cardstr = TEST_VCARD;
- ce = e_contact_editor_new (e_card_new_with_default_charset (cardstr, "ISO-8859-1"), TRUE, NULL, FALSE);
- gtk_signal_connect (GTK_OBJECT (ce), "editor_closed",
- GTK_SIGNAL_FUNC (editor_closed_cb), NULL);
-
- ce = e_contact_editor_new (e_card_new_with_default_charset (cardstr, "ISO-8859-1"), TRUE, NULL, FALSE);
- gtk_signal_connect (GTK_OBJECT (ce), "editor_closed",
- GTK_SIGNAL_FUNC (editor_closed_cb), NULL);
-
- gtk_main();
+ ce = e_contact_editor_new (
+ NULL, e_card_new_with_default_charset (
+ cardstr, "ISO-8859-1"), TRUE, FALSE);
+ g_signal_connect (
+ ce, "editor_closed",
+ G_CALLBACK (editor_closed_cb), NULL);
+
+ ce = e_contact_editor_new (
+ NULL, e_card_new_with_default_charset (
+ cardstr, "ISO-8859-1"), TRUE, FALSE);
+ g_signal_connect (
+ ce, "editor_closed",
+ G_CALLBACK (editor_closed_cb), NULL);
+
+ gtk_main ();
/* Not reached. */
return 0;
diff --git a/addressbook/gui/contact-list-editor/.cvsignore b/addressbook/gui/contact-list-editor/.cvsignore
deleted file mode 100644
index 5eaae75530..0000000000
--- a/addressbook/gui/contact-list-editor/.cvsignore
+++ /dev/null
@@ -1,4 +0,0 @@
-Makefile.in
-Makefile
-.deps
-.pure
diff --git a/addressbook/gui/contact-list-editor/Makefile.am b/addressbook/gui/contact-list-editor/Makefile.am
index c87f352879..6f38f09160 100644
--- a/addressbook/gui/contact-list-editor/Makefile.am
+++ b/addressbook/gui/contact-list-editor/Makefile.am
@@ -1,38 +1,37 @@
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/addressbook/ \
- -I$(top_srcdir)/addressbook/backend \
- -I$(top_builddir)/addressbook/backend \
- -I$(top_srcdir)/addressbook/gui/merging \
- -I$(top_srcdir)/addressbook/gui/contact-editor \
- -I$(top_builddir)/shell \
- -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
- -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\"\
- -DDATADIR=\""$(datadir)"\" \
- -DEVOLUTION_DATADIR=\""$(datadir)"\" \
- -DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \
- -DEVOLUTIONDIR=\""$(evolutiondir)"\" \
- -DG_LOG_DOMAIN=\"contact-list-editor\" \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
+privsolib_LTLIBRARIES = libecontactlisteditor.la
-noinst_LIBRARIES = \
- libecontactlisteditor.a
+libecontactlisteditor_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/addressbook/ \
+ -I$(top_srcdir)/addressbook/gui/merging \
+ -I$(top_srcdir)/addressbook/gui/contact-editor \
+ -I$(top_builddir)/shell \
+ -DEVOLUTION_UIDIR=\""$(uidir)"\" \
+ -DG_LOG_DOMAIN=\"contact-list-editor\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS)
-libecontactlisteditor_a_SOURCES = \
+libecontactlisteditor_la_SOURCES = \
e-contact-list-editor.c \
e-contact-list-editor.h \
e-contact-list-model.c \
e-contact-list-model.h
-iconsdir = $(datadir)/images/evolution
+libecontactlisteditor_la_LDFLAGS = -avoid-version $(NO_UNDEFINED)
-gladedir = $(datadir)/evolution/glade
+libecontactlisteditor_la_LIBADD = \
+ $(top_builddir)/addressbook/util/libeabutil.la \
+ $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(top_builddir)/shell/libevolution-shell.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_LIBS)
-glade_DATA = \
- contact-list-editor.glade
+ui_DATA = contact-list-editor.ui
-etspecdir = $(datadir)/evolution/etspec
-etspec_DATA = e-contact-list-editor.etspec
+EXTRA_DIST = $(ui_DATA)
-EXTRA_DIST = $(glade_DATA) \
- $(etspec_DATA)
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/gui/contact-list-editor/contact-list-editor.glade b/addressbook/gui/contact-list-editor/contact-list-editor.glade
deleted file mode 100644
index 92c6aa013f..0000000000
--- a/addressbook/gui/contact-list-editor/contact-list-editor.glade
+++ /dev/null
@@ -1,272 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>contact-list-editor</name>
- <program_name>contact-list-editor</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
-</project>
-
-<widget>
- <class>GnomeApp</class>
- <name>contact list editor</name>
- <title>contact-list-editor</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <default_width>426</default_width>
- <default_height>304</default_height>
- <allow_shrink>True</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <enable_layout_config>True</enable_layout_config>
-
- <widget>
- <class>GnomeDock</class>
- <child_name>GnomeApp:dock</child_name>
- <name>dock1</name>
- <allow_floating>True</allow_floating>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDock:contents</child_name>
- <name>vbox8</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox6</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label10</name>
- <label>List _name:</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>list-name-entry</default_focus_target>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>list-name-entry</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>custom7</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>evolution-contacts-plain.png</string1>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Sat, 23 Jun 2001 05:59:21 GMT</last_modification_time>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame3</name>
- <border_width>3</border_width>
- <label>Members</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox7</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox9</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label11</name>
- <label>Type an email address or drag a contact into the list below:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>email-entry</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>contact-list-table</name>
- <creation_function>e_contact_list_editor_create_table</creation_function>
- <string1></string1>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Sat, 23 Jun 2001 06:00:16 GMT</last_modification_time>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>visible-addrs-checkbutton</name>
- <can_focus>True</can_focus>
- <label>_Hide addresses when sending mail to this list</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox10</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label12</name>
- <label>
-</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkVButtonBox</class>
- <name>vbuttonbox4</name>
- <layout_style>GTK_BUTTONBOX_START</layout_style>
- <spacing>0</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>add-email-button</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_Add</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>remove-button</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_Remove</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/addressbook/gui/contact-list-editor/contact-list-editor.ui b/addressbook/gui/contact-list-editor/contact-list-editor.ui
new file mode 100644
index 0000000000..d6a197877c
--- /dev/null
+++ b/addressbook/gui/contact-list-editor/contact-list-editor.ui
@@ -0,0 +1,412 @@
+<?xml version="1.0"?>
+<!--*- mode: xml -*-->
+<interface>
+ <object class="GtkDialog" id="dialog">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="title" translatable="yes">Contact List Editor</property>
+ <property name="window_position">GTK_WIN_POS_CENTER</property>
+ <property name="icon_name">stock_contact-list</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+ <signal handler="contact_list_editor_delete_event_cb" name="delete_event"/>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkTable" id="table">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="border_width">6</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">12</property>
+ <child>
+ <object class="GtkImage" id="image">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="icon_size">6</property>
+ <property name="icon_name">x-office-address-book</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="x_options"/>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="source-table">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="list-name-label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_List name:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">list-name-entry</property>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="source-label">
+ <property name="visible">True</property>
+ <property name="xalign">1</property>
+ <property name="label" translatable="yes">_Where:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">client-combo-box</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="list-name-entry">
+ <property name="visible">True</property>
+ <signal handler="contact_list_editor_list_name_entry_changed_cb" name="changed"/>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="EClientComboBox" type-func="e_client_combo_box_get_type" id="client-combo-box">
+ <property name="extension-name">Address Book</property>
+ <property name="show-colors">False</property>
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="members-vbox">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="members-label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Members</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="members-alignment">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <object class="GtkTable" id="members-table">
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">6</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <object class="GtkLabel" id="members-instructions">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Type an email address or drag a contact into the list below:</property>
+ <property name="use_underline">True</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ </object>
+ <packing>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="email-entry">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolled-window">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+ <child>
+ <object class="GtkTreeView" id="tree-view">
+ <property name="visible">True</property>
+ <property name="headers_visible">False</property>
+ <property name="search_column">0</property>
+ <signal handler="contact_list_editor_tree_view_key_press_event_cb" name="key_press_event"/>
+ <signal handler="contact_list_editor_drag_data_received_cb" name="drag_data_received"/>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="check-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="label" translatable="yes">_Hide addresses when sending mail to this list</property>
+ <property name="use_underline">True</property>
+ <signal handler="contact_list_editor_check_button_toggled_cb" name="toggled"/>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="members-buttons">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkButton" id="add-button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="is_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_text" translatable="yes">Add an email to the List</property>
+ <property name="label">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="xalign">0</property>
+ <signal handler="contact_list_editor_add_button_clicked_cb" name="clicked"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="remove-button">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="is_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_text" translatable="yes">Remove an email address from the List</property>
+ <property name="label">gtk-remove</property>
+ <property name="use_stock">True</property>
+ <property name="xalign">0</property>
+ <signal handler="contact_list_editor_remove_button_clicked_cb" name="clicked"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="select-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="has_tooltip">True</property>
+ <property name="tooltip_text" translatable="yes">Insert email addresses from Address Book</property>
+ <property name="label" translatable="yes">_Select...</property>
+ <signal name="clicked" handler="contact_list_editor_select_button_clicked_cb"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="top-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="label">gtk-goto-top</property>
+ <property name="use-stock">True</property>
+ <property name="sensitive">False</property>
+ <signal name="clicked" handler="contact_list_editor_top_button_clicked_cb"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="up-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="use_underline">True</property>
+ <property name="label">gtk-go-up</property>
+ <property name="use-stock">True</property>
+ <property name="sensitive">False</property>
+ <signal name="clicked" handler="contact_list_editor_up_button_clicked_cb"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="down-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="use_underline">True</property>
+ <property name="label">gtk-go-down</property>
+ <property name="use-stock">True</property>
+ <property name="sensitive">False</property>
+ <signal name="clicked" handler="contact_list_editor_down_button_clicked_cb"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="bottom-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="use_underline">True</property>
+ <property name="label">gtk-goto-bottom</property>
+ <property name="use-stock">True</property>
+ <property name="sensitive">False</property>
+ <signal name="clicked" handler="contact_list_editor_bottom_button_clicked_cb"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="members-buttons-alignment">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options"/>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action-area">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <object class="GtkButton" id="cancel-button">
+ <property name="visible">True</property>
+ <property name="is_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <signal handler="contact_list_editor_cancel_button_clicked_cb" name="clicked"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok-button">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="label">gtk-save</property>
+ <property name="use_stock">True</property>
+ <accelerator key="s" modifiers="GDK_CONTROL_MASK" signal="clicked"/>
+ <signal handler="contact_list_editor_ok_button_clicked_cb" name="clicked"/>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="0">check-button</action-widget>
+ <action-widget response="0">add-button</action-widget>
+ <action-widget response="0">remove-button</action-widget>
+ <action-widget response="0">select-button</action-widget>
+ <action-widget response="0">cancel-button</action-widget>
+ <action-widget response="0">ok-button</action-widget>
+ </action-widgets>
+ </object>
+</interface>
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 cf185d4957..2eac787950 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.c
+++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.c
@@ -1,1029 +1,1989 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-contact-list-editor.c
- * 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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
#include "e-contact-list-editor.h"
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-window-icon.h>
-#include <bonobo/bonobo-ui-container.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <gal/e-table/e-table-scrolled.h>
-#include <gal/widgets/e-unicode.h>
-#include "shell/evolution-shell-component-utils.h"
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <camel/camel.h>
-#include "addressbook/gui/widgets/e-addressbook-util.h"
+#include "shell/e-shell.h"
+#include "addressbook/gui/widgets/eab-gui-util.h"
+#include "addressbook/util/eab-book-util.h"
+
+#include "eab-editor.h"
#include "e-contact-editor.h"
-#include "e-contact-save-as.h"
#include "e-contact-list-model.h"
+#include "eab-contact-merging.h"
+
+#define E_CONTACT_LIST_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CONTACT_LIST_EDITOR, EContactListEditorPrivate))
+
+#define E_CONTACT_LIST_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CONTACT_LIST_EDITOR, EContactListEditorPrivate))
+
+#define CONTACT_LIST_EDITOR_WIDGET(editor, name) \
+ (e_builder_get_widget \
+ (E_CONTACT_LIST_EDITOR_GET_PRIVATE (editor)->builder, name))
+
+/* More macros, less typos. */
+#define CONTACT_LIST_EDITOR_WIDGET_ADD_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "add-button")
+#define CONTACT_LIST_EDITOR_WIDGET_CHECK_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "check-button")
+#define CONTACT_LIST_EDITOR_WIDGET_CLIENT_COMBO_BOX(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "client-combo-box")
+#define CONTACT_LIST_EDITOR_WIDGET_DIALOG(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "dialog")
+#define CONTACT_LIST_EDITOR_WIDGET_EMAIL_ENTRY(editor) \
+ E_CONTACT_LIST_EDITOR_GET_PRIVATE (editor)->email_entry
+#define CONTACT_LIST_EDITOR_WIDGET_LIST_NAME_ENTRY(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "list-name-entry")
+#define CONTACT_LIST_EDITOR_WIDGET_MEMBERS_VBOX(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "members-vbox")
+#define CONTACT_LIST_EDITOR_WIDGET_OK_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "ok-button")
+#define CONTACT_LIST_EDITOR_WIDGET_REMOVE_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "remove-button")
+#define CONTACT_LIST_EDITOR_WIDGET_TREE_VIEW(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "tree-view")
+#define CONTACT_LIST_EDITOR_WIDGET_TOP_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "top-button")
+#define CONTACT_LIST_EDITOR_WIDGET_UP_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "up-button")
+#define CONTACT_LIST_EDITOR_WIDGET_DOWN_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "down-button")
+#define CONTACT_LIST_EDITOR_WIDGET_BOTTOM_BUTTON(editor) \
+ CONTACT_LIST_EDITOR_WIDGET ((editor), "bottom-button")
+
+/* Shorthand, requires a variable named "editor". */
+#define WIDGET(name) (CONTACT_LIST_EDITOR_WIDGET_##name (editor))
+
+#define TOPLEVEL_KEY (g_type_name (E_TYPE_CONTACT_LIST_EDITOR))
-/* Signal IDs */
enum {
- LIST_ADDED,
- LIST_MODIFIED,
- LIST_DELETED,
- EDITOR_CLOSED,
- LAST_SIGNAL
+ PROP_0,
+ PROP_CLIENT,
+ PROP_CONTACT,
+ PROP_IS_NEW_LIST,
+ PROP_EDITABLE
};
-static void e_contact_list_editor_init (EContactListEditor *editor);
-static void e_contact_list_editor_class_init (EContactListEditorClass *klass);
-static void e_contact_list_editor_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_contact_list_editor_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_contact_list_editor_destroy (GtkObject *object);
-
-static void create_ui (EContactListEditor *ce);
-static void set_editable (EContactListEditor *editor);
-static void command_state_changed (EContactListEditor *editor);
-static void close_dialog (EContactListEditor *cle);
-static void extract_info(EContactListEditor *editor);
-static void fill_in_info(EContactListEditor *editor);
-
-static void add_email_cb (GtkWidget *w, EContactListEditor *editor);
-static void remove_entry_cb (GtkWidget *w, EContactListEditor *editor);
-static void list_name_changed_cb (GtkWidget *w, EContactListEditor *editor);
-static void visible_addrs_toggled_cb (GtkWidget *w, EContactListEditor *editor);
-
-static gint app_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data);
-static gboolean table_drag_drop_cb (ETable *table, int row, int col, GdkDragContext *context,
- gint x, gint y, guint time, EContactListEditor *editor);
-static gboolean table_drag_motion_cb (ETable *table, int row, int col, GdkDragContext *context,
- gint x, gint y, guint time, EContactListEditor *editor);
-static void table_drag_data_received_cb (ETable *table, int row, int col,
- GdkDragContext *context,
- gint x, gint y,
- GtkSelectionData *selection_data, guint info, guint time,
- EContactListEditor *editor);
-
-static GtkObjectClass *parent_class = NULL;
-
-static guint contact_list_editor_signals[LAST_SIGNAL];
-
-enum DndTargetType {
- DND_TARGET_TYPE_VCARD,
-};
-#define VCARD_TYPE "text/x-vcard"
-static GtkTargetEntry drag_types[] = {
- { VCARD_TYPE, 0, DND_TARGET_TYPE_VCARD },
-};
-static const int num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]);
+typedef struct {
+ EContactListEditor *editor;
+ gboolean should_close;
+} EditorCloseStruct;
-/* The arguments we take */
-enum {
- ARG_0,
- ARG_BOOK,
- ARG_CARD,
- ARG_IS_NEW_LIST,
- ARG_EDITABLE
+struct _EContactListEditorPrivate {
+
+ EBookClient *book_client;
+ EContact *contact;
+
+ GtkBuilder *builder;
+ GtkTreeModel *model;
+ ENameSelector *name_selector;
+
+ /* This is kept here because the builder has an old widget
+ * which was changed with this one. */
+ ENameSelectorEntry *email_entry;
+
+ /* Whether we are editing a new contact or an existing one. */
+ guint is_new_list : 1;
+
+ /* Whether the contact has been changed since bringing up the
+ * contact editor. */
+ guint changed : 1;
+
+ /* Whether the contact editor will accept modifications. */
+ guint editable : 1;
+
+ /* Whether the target book accepts storing of contact lists. */
+ guint allows_contact_lists : 1;
+
+ /* Whether an async wombat call is in progress. */
+ guint in_async_call : 1;
};
-static GSList *all_contact_list_editors = NULL;
+typedef struct {
+ EContactListEditor *editor;
+ ESource *source;
+} ConnectClosure;
+
+G_DEFINE_TYPE (EContactListEditor, e_contact_list_editor, EAB_TYPE_EDITOR)
-GtkType
-e_contact_list_editor_get_type (void)
+static void
+connect_closure_free (ConnectClosure *connect_closure)
{
- static GtkType contact_list_editor_type = 0;
-
- if (!contact_list_editor_type)
- {
- static const GtkTypeInfo contact_list_editor_info =
- {
- "EContactListEditor",
- sizeof (EContactListEditor),
- sizeof (EContactListEditorClass),
- (GtkClassInitFunc) e_contact_list_editor_class_init,
- (GtkObjectInitFunc) e_contact_list_editor_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- contact_list_editor_type = gtk_type_unique (GTK_TYPE_OBJECT, &contact_list_editor_info);
- }
-
- return contact_list_editor_type;
-}
+ if (connect_closure->editor != NULL)
+ g_object_unref (connect_closure->editor);
+ if (connect_closure->source != NULL)
+ g_object_unref (connect_closure->source);
-typedef void (*GtkSignal_NONE__INT_OBJECT) (GtkObject * object,
- gint arg1,
- GtkObject *arg2,
- gpointer user_data);
+ g_slice_free (ConnectClosure, connect_closure);
+}
-static void
-e_marshal_NONE__INT_OBJECT (GtkObject * object,
- GtkSignalFunc func,
- gpointer func_data, GtkArg * args)
+static EContactListEditor *
+contact_list_editor_extract (GtkWidget *widget)
{
- GtkSignal_NONE__INT_OBJECT rfunc;
- rfunc = (GtkSignal_NONE__INT_OBJECT) func;
- (*rfunc) (object,
- GTK_VALUE_INT (args[0]),
- GTK_VALUE_OBJECT (args[1]),
- func_data);
+ GtkWidget *toplevel;
+
+ toplevel = gtk_widget_get_toplevel (widget);
+ return g_object_get_data (G_OBJECT (toplevel), TOPLEVEL_KEY);
}
static void
-e_contact_list_editor_class_init (EContactListEditorClass *klass)
+contact_list_editor_scroll_to_end (EContactListEditor *editor)
{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass*) klass;
-
- parent_class = gtk_type_class (GTK_TYPE_OBJECT);
-
- gtk_object_add_arg_type ("EContactListEditor::book", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_BOOK);
- gtk_object_add_arg_type ("EContactListEditor::card", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_CARD);
- gtk_object_add_arg_type ("EContactListEditor::is_new_list", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_IS_NEW_LIST);
- gtk_object_add_arg_type ("EContactListEditor::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
-
- contact_list_editor_signals[LIST_ADDED] =
- gtk_signal_new ("list_added",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EContactListEditorClass, list_added),
- e_marshal_NONE__INT_OBJECT,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_INT, GTK_TYPE_OBJECT);
-
- contact_list_editor_signals[LIST_MODIFIED] =
- gtk_signal_new ("list_modified",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EContactListEditorClass, list_modified),
- e_marshal_NONE__INT_OBJECT,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_INT, GTK_TYPE_OBJECT);
-
- contact_list_editor_signals[LIST_DELETED] =
- gtk_signal_new ("list_deleted",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EContactListEditorClass, list_deleted),
- e_marshal_NONE__INT_OBJECT,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_INT, GTK_TYPE_OBJECT);
-
- contact_list_editor_signals[EDITOR_CLOSED] =
- gtk_signal_new ("editor_closed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EContactListEditorClass, editor_closed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, contact_list_editor_signals, LAST_SIGNAL);
-
- object_class->set_arg = e_contact_list_editor_set_arg;
- object_class->get_arg = e_contact_list_editor_get_arg;
- object_class->destroy = e_contact_list_editor_destroy;
+ GtkTreeView *view;
+ GtkTreePath *path;
+ gint n_rows;
+
+ view = GTK_TREE_VIEW (WIDGET (TREE_VIEW));
+ n_rows = gtk_tree_model_iter_n_children (editor->priv->model, NULL);
+
+ path = gtk_tree_path_new_from_indices (n_rows - 1, -1);
+ gtk_tree_view_scroll_to_cell (view, path, NULL, FALSE, 0., 0.);
+ gtk_tree_view_set_cursor (view, path, NULL, FALSE);
+ gtk_tree_path_free (path);
}
static void
-e_contact_list_editor_init (EContactListEditor *editor)
+contact_list_editor_update (EContactListEditor *editor)
{
- GladeXML *gui;
- GtkWidget *bonobo_win;
- BonoboUIContainer *container;
- char *icon_path;
+ EContactListEditorPrivate *priv = editor->priv;
- editor->card = NULL;
- editor->changed = FALSE;
- editor->editable = TRUE;
- editor->in_async_call = FALSE;
- editor->is_new_list = FALSE;
+ gtk_widget_set_sensitive (
+ WIDGET (OK_BUTTON),
+ eab_editor_is_valid (EAB_EDITOR (editor)) &&
+ priv->allows_contact_lists);
- gui = glade_xml_new (EVOLUTION_GLADEDIR "/contact-list-editor.glade", NULL);
- editor->gui = gui;
+ gtk_widget_set_sensitive (
+ WIDGET (CLIENT_COMBO_BOX), priv->is_new_list);
+}
- editor->app = glade_xml_get_widget (gui, "contact list editor");
+static void
+contact_list_editor_notify_cb (EContactListEditor *editor,
+ GParamSpec *pspec)
+{
+ EContactListEditorPrivate *priv = editor->priv;
+ gboolean sensitive;
- editor->table = glade_xml_get_widget (gui, "contact-list-table");
- editor->model = gtk_object_get_data (GTK_OBJECT(editor->table), "model");
+ sensitive = priv->editable && priv->allows_contact_lists;
- editor->add_button = glade_xml_get_widget (editor->gui, "add-email-button");
- editor->remove_button = glade_xml_get_widget (editor->gui, "remove-button");
+ gtk_widget_set_sensitive (WIDGET (LIST_NAME_ENTRY), sensitive);
+ gtk_widget_set_sensitive (WIDGET (MEMBERS_VBOX), sensitive);
+}
- editor->email_entry = glade_xml_get_widget (gui, "email-entry");
- editor->list_name_entry = glade_xml_get_widget (gui, "list-name-entry");
+static gboolean
+contact_list_editor_add_destination (GtkWidget *widget,
+ EDestination *dest)
+{
+ EContactListEditor *editor = contact_list_editor_extract (widget);
+ EContactListModel *model = E_CONTACT_LIST_MODEL (editor->priv->model);
+ GtkTreeView *treeview = GTK_TREE_VIEW (WIDGET (TREE_VIEW));
+ GtkTreePath *path;
+ gboolean ignore_conflicts = TRUE;
+
+ if (e_destination_is_evolution_list (dest)) {
+ const gchar *id = e_destination_get_contact_uid (dest);
+ const gchar *name = e_destination_get_name (dest);
+
+ if (e_contact_list_model_has_uid (model, id)) {
+ gint response;
+
+ response = e_alert_run_dialog_for_args (
+ GTK_WINDOW (WIDGET (DIALOG)),
+ "addressbook:ask-list-add-list-exists",
+ name, NULL);
+ if (response != GTK_RESPONSE_YES)
+ return FALSE;
+ } else {
+ const GList *l_dests, *l_dest;
+ gint reply;
+
+ /* Check the new list mail-by-mail for conflicts and
+ * eventually ask user what to do with all conflicts. */
+ l_dests = e_destination_list_get_dests (dest);
+ for (l_dest = l_dests; l_dest; l_dest = l_dest->next) {
+ if (e_contact_list_model_has_email (model, e_destination_get_email (l_dest->data))) {
+ reply = e_alert_run_dialog_for_args (
+ GTK_WINDOW (WIDGET (DIALOG)),
+ "addressbook:ask-list-add-some-mails-exist", NULL);
+ if (reply == GTK_RESPONSE_YES) {
+ ignore_conflicts = TRUE;
+ break;
+ } else if (reply == GTK_RESPONSE_NO) {
+ ignore_conflicts = FALSE;
+ break;
+ } else {
+ return FALSE;
+ }
+ }
+ }
+ }
- editor->visible_addrs_checkbutton = glade_xml_get_widget (gui, "visible-addrs-checkbutton");
+ } else {
+ const gchar *email = e_destination_get_email (dest);
+ const gchar *tag = "addressbook:ask-list-add-exists";
- /* Construct the app */
- bonobo_win = bonobo_window_new ("contact-list-editor", _("Contact List Editor"));
+ if (e_contact_list_model_has_email (model, email) &&
+ (e_alert_run_dialog_for_args (GTK_WINDOW (WIDGET (DIALOG)), tag, email, NULL) != GTK_RESPONSE_YES))
+ return FALSE;
+ }
- /* FIXME: The sucking bit */
- {
- GtkWidget *contents;
+ /* always add to the root level */
+ path = e_contact_list_model_add_destination (
+ model, dest, NULL, ignore_conflicts);
+ if (path) {
+ contact_list_editor_scroll_to_end (editor);
+ gtk_tree_view_expand_to_path (treeview, path);
+ gtk_tree_path_free (path);
- contents = gnome_dock_get_client_area (
- GNOME_DOCK (GNOME_APP (editor->app)->dock));
- if (!contents) {
- g_message ("contact_list_editor_construct(): Could not get contents");
- return;
- }
- gtk_widget_ref (contents);
- gtk_container_remove (GTK_CONTAINER (contents->parent), contents);
- bonobo_window_set_contents (BONOBO_WINDOW (bonobo_win), contents);
- gtk_widget_destroy (editor->app);
- editor->app = bonobo_win;
+ return TRUE;
}
- /* Build the menu and toolbar */
+ return FALSE;
+}
- container = bonobo_ui_container_new ();
- bonobo_ui_container_set_win (container, BONOBO_WINDOW (editor->app));
+static void
+contact_list_editor_add_email (EContactListEditor *editor,
+ const gchar *email)
+{
+ CamelInternetAddress *addr;
+ EContactListEditorPrivate *priv = editor->priv;
+ EDestination *dest = NULL;
+ gint addr_length;
+
+ addr = camel_internet_address_new ();
+ addr_length = camel_address_unformat (CAMEL_ADDRESS (addr), email);
+ if (addr_length >= 1) {
+ const gchar *name, *mail;
+ gint ii;
+
+ for (ii = 0; ii < addr_length; ii++) {
+ camel_internet_address_get (addr, ii, &name, &mail);
+
+ if (name || mail) {
+ dest = e_destination_new ();
+ if (mail)
+ e_destination_set_email (dest, mail);
+ if (name)
+ e_destination_set_name (dest, name);
+
+ priv->changed = contact_list_editor_add_destination (WIDGET (DIALOG), dest)
+ || priv->changed;
+ }
+ }
+ } else {
+ dest = e_destination_new ();
+ e_destination_set_email (dest, email);
- editor->uic = bonobo_ui_component_new_default ();
- if (!editor->uic) {
- g_message ("e_contact_list_editor_init(): eeeeek, could not create the UI handler!");
- return;
+ priv->changed = contact_list_editor_add_destination (WIDGET (DIALOG), dest)
+ || priv->changed;
}
- bonobo_ui_component_set_container (editor->uic,
- bonobo_object_corba_objref (
- BONOBO_OBJECT (container)));
-
- create_ui (editor);
-
- /* connect signals */
- gtk_signal_connect (GTK_OBJECT(editor->add_button),
- "clicked", GTK_SIGNAL_FUNC(add_email_cb), editor);
- gtk_signal_connect (GTK_OBJECT(editor->email_entry),
- "activate", GTK_SIGNAL_FUNC(add_email_cb), editor);
- gtk_signal_connect (GTK_OBJECT(editor->remove_button),
- "clicked", GTK_SIGNAL_FUNC(remove_entry_cb), editor);
- gtk_signal_connect (GTK_OBJECT(editor->list_name_entry),
- "changed", GTK_SIGNAL_FUNC(list_name_changed_cb), editor);
- gtk_signal_connect (GTK_OBJECT(editor->visible_addrs_checkbutton),
- "toggled", GTK_SIGNAL_FUNC(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);
-
- gtk_signal_connect (GTK_OBJECT(e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table))),
- "table_drag_motion", GTK_SIGNAL_FUNC(table_drag_motion_cb), editor);
- gtk_signal_connect (GTK_OBJECT(e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table))),
- "table_drag_drop", GTK_SIGNAL_FUNC(table_drag_drop_cb), editor);
- gtk_signal_connect (GTK_OBJECT(e_table_scrolled_get_table (E_TABLE_SCROLLED (editor->table))),
- "table_drag_data_received", GTK_SIGNAL_FUNC(table_drag_data_received_cb), editor);
-
- command_state_changed (editor);
-
- /* Connect to the deletion of the dialog */
-
- gtk_signal_connect (GTK_OBJECT (editor->app), "delete_event",
- GTK_SIGNAL_FUNC (app_delete_event_cb), editor);
-
- /* set the icon */
- icon_path = g_concat_dir_and_file (EVOLUTION_ICONSDIR, "contact-list-16.png");
- gnome_window_icon_set_from_file (GTK_WINDOW (editor->app), icon_path);
- g_free (icon_path);
+ g_object_unref (addr);
+
+ contact_list_editor_update (editor);
}
static void
-e_contact_list_editor_destroy (GtkObject *object)
+contact_list_editor_get_client_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
-}
+ ConnectClosure *closure = user_data;
+ EContactListEditor *editor = closure->editor;
+ EClientComboBox *combo_box;
+ EContactStore *contact_store;
+ ENameSelectorEntry *entry;
+ EClient *client;
+ EBookClient *book_client;
+ GError *error = NULL;
-typedef struct {
- EContactListEditor *cle;
- gboolean should_close;
-} EditorCloseStruct;
+ combo_box = E_CLIENT_COMBO_BOX (source_object);
+
+ client = e_client_combo_box_get_client_finish (
+ combo_box, result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ if (error != NULL) {
+ GtkWindow *parent;
+
+ parent = eab_editor_get_window (EAB_EDITOR (editor));
+
+ eab_load_error_dialog (
+ GTK_WIDGET (parent), NULL,
+ closure->source, error);
+
+ e_source_combo_box_set_active (
+ E_SOURCE_COMBO_BOX (combo_box),
+ closure->source);
+
+ g_error_free (error);
+ goto exit;
+ }
+
+ book_client = E_BOOK_CLIENT (client);
+
+ entry = E_NAME_SELECTOR_ENTRY (WIDGET (EMAIL_ENTRY));
+ contact_store = e_name_selector_entry_peek_contact_store (entry);
+ e_contact_store_add_client (contact_store, book_client);
+ e_contact_list_editor_set_client (editor, book_client);
+
+ g_object_unref (client);
+
+exit:
+ connect_closure_free (closure);
+}
static void
-list_added_cb (EBook *book, EBookStatus status, const char *id, EditorCloseStruct *ecs)
+contact_list_editor_list_added_cb (EBookClient *book_client,
+ const GError *error,
+ const gchar *id,
+ gpointer closure)
{
- EContactListEditor *cle = ecs->cle;
+ EditorCloseStruct *ecs = closure;
+ EContactListEditor *editor = ecs->editor;
+ EContactListEditorPrivate *priv = editor->priv;
gboolean should_close = ecs->should_close;
- if (cle->app)
- gtk_widget_set_sensitive (cle->app, TRUE);
- cle->in_async_call = FALSE;
+ gtk_widget_set_sensitive (WIDGET (DIALOG), TRUE);
+ priv->in_async_call = FALSE;
- e_card_set_id (cle->card, id);
+ e_contact_set (priv->contact, E_CONTACT_UID, (gchar *) id);
- gtk_signal_emit (GTK_OBJECT (cle), contact_list_editor_signals[LIST_ADDED],
- status, cle->card);
+ eab_editor_contact_added (
+ EAB_EDITOR (editor), error, priv->contact);
- if (status == E_BOOK_STATUS_SUCCESS) {
- cle->is_new_list = FALSE;
+ if (!error) {
+ priv->is_new_list = FALSE;
if (should_close)
- close_dialog (cle);
+ eab_editor_close (EAB_EDITOR (editor));
else
- command_state_changed (cle);
+ contact_list_editor_update (editor);
}
- gtk_object_unref (GTK_OBJECT (cle));
+ g_object_unref (editor);
g_free (ecs);
}
static void
-list_modified_cb (EBook *book, EBookStatus status, EditorCloseStruct *ecs)
+contact_list_editor_list_modified_cb (EBookClient *book_client,
+ const GError *error,
+ gpointer closure)
{
- EContactListEditor *cle = ecs->cle;
+ EditorCloseStruct *ecs = closure;
+ EContactListEditor *editor = ecs->editor;
+ EContactListEditorPrivate *priv = editor->priv;
gboolean should_close = ecs->should_close;
- if (cle->app)
- gtk_widget_set_sensitive (cle->app, TRUE);
- cle->in_async_call = FALSE;
+ gtk_widget_set_sensitive (WIDGET (DIALOG), TRUE);
+ priv->in_async_call = FALSE;
- gtk_signal_emit (GTK_OBJECT (cle), contact_list_editor_signals[LIST_MODIFIED],
- status, cle->card);
+ eab_editor_contact_modified (
+ EAB_EDITOR (editor), error, priv->contact);
- if (status == E_BOOK_STATUS_SUCCESS) {
+ if (!error) {
if (should_close)
- close_dialog (cle);
+ eab_editor_close (EAB_EDITOR (editor));
}
- gtk_object_unref (GTK_OBJECT (cle)); /* release ref held for ebook callback */
+ g_object_unref (editor);
g_free (ecs);
}
static void
-save_card (EContactListEditor *cle, gboolean should_close)
+contact_list_editor_render_destination (GtkTreeViewColumn *column,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter)
{
- extract_info (cle);
+ /* XXX Would be nice if EDestination had a text property
+ * that we could just bind the GtkCellRenderer to. */
+
+ EDestination *destination = NULL;
+ gchar *name = NULL, *email = NULL;
+ const gchar *textrep;
+ gchar *out;
+
+ g_return_if_fail (GTK_IS_TREE_MODEL (model));
+
+ gtk_tree_model_get (model, iter, 0, &destination, -1);
+ g_return_if_fail (destination && E_IS_DESTINATION (destination));
+
+ textrep = e_destination_get_textrep (destination, TRUE);
+ if (eab_parse_qp_email (textrep, &name, &email)) {
+ if (e_destination_is_evolution_list (destination)) {
+ g_object_set (renderer, "text", name, NULL);
+ } else {
+ out = g_strdup_printf ("%s <%s>", name, email);
+ g_object_set (renderer, "text", out, NULL);
+ g_free (out);
+ }
+ g_free (email);
+ g_free (name);
+ } else {
+ g_object_set (renderer, "text", textrep, NULL);
+ }
- if (cle->book) {
- EditorCloseStruct *ecs = g_new(EditorCloseStruct, 1);
-
- ecs->cle = cle;
- gtk_object_ref (GTK_OBJECT (cle));
- ecs->should_close = should_close;
+ g_object_unref (destination);
+}
- if (cle->app)
- gtk_widget_set_sensitive (cle->app, FALSE);
- cle->in_async_call = TRUE;
+static void
+contact_list_editor_selection_changed_cb (GtkTreeSelection *selection,
+ gpointer user_data)
+{
+ EContactListEditor *editor = user_data;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreePath *first_item;
+ GList *selected;
+
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (WIDGET (TREE_VIEW)));
+
+ /* Is selected anything at all? */
+ if (gtk_tree_selection_count_selected_rows (selection) == 0) {
+ gtk_widget_set_sensitive (WIDGET (TOP_BUTTON), FALSE);
+ gtk_widget_set_sensitive (WIDGET (UP_BUTTON), FALSE);
+ gtk_widget_set_sensitive (WIDGET (DOWN_BUTTON), FALSE);
+ gtk_widget_set_sensitive (WIDGET (BOTTOM_BUTTON), FALSE);
+ gtk_widget_set_sensitive (WIDGET (REMOVE_BUTTON), FALSE);
+ return;
+ }
- if (cle->is_new_list)
- e_book_add_card (cle->book, cle->card, GTK_SIGNAL_FUNC(list_added_cb), ecs);
- else
- e_book_commit_card (cle->book, cle->card, GTK_SIGNAL_FUNC(list_modified_cb), ecs);
+ gtk_widget_set_sensitive (WIDGET (REMOVE_BUTTON), TRUE);
+
+ /* Item before selected item exists => enable Top/Up buttons */
+ selected = gtk_tree_selection_get_selected_rows (selection, &model);
- cle->changed = FALSE;
+ /* Don't update path in the list! */
+ first_item = gtk_tree_path_copy (selected->data);
+ if (gtk_tree_path_prev (first_item)) {
+ gtk_widget_set_sensitive (WIDGET (TOP_BUTTON), TRUE);
+ gtk_widget_set_sensitive (WIDGET (UP_BUTTON), TRUE);
+ } else {
+ gtk_widget_set_sensitive (WIDGET (TOP_BUTTON), FALSE);
+ gtk_widget_set_sensitive (WIDGET (UP_BUTTON), FALSE);
}
+
+ gtk_tree_model_get_iter (model, &iter, g_list_last (selected)->data);
+ /* Item below last selected exists => enable Down/Bottom buttons */
+ if (gtk_tree_model_iter_next (model, &iter)) {
+ gtk_widget_set_sensitive (WIDGET (DOWN_BUTTON), TRUE);
+ gtk_widget_set_sensitive (WIDGET (BOTTOM_BUTTON), TRUE);
+ } else {
+ gtk_widget_set_sensitive (WIDGET (DOWN_BUTTON), FALSE);
+ gtk_widget_set_sensitive (WIDGET (BOTTOM_BUTTON), FALSE);
+ }
+
+ g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (selected);
+ gtk_tree_path_free (first_item);
}
-static gboolean
-is_named (EContactListEditor *editor)
+static void
+contact_list_editor_add_from_email_entry (EContactListEditor *editor,
+ ENameSelectorEntry *entry)
{
- char *string = e_utf8_gtk_editable_get_chars(GTK_EDITABLE (editor->list_name_entry), 0, -1);
- gboolean named = FALSE;
+ EDestinationStore *store;
+ GList *dests, *diter;
+ gboolean added = FALSE;
+
+ g_return_if_fail (E_IS_CONTACT_LIST_EDITOR (editor));
+ g_return_if_fail (E_IS_NAME_SELECTOR_ENTRY (entry));
+
+ store = e_name_selector_entry_peek_destination_store (entry);
+ dests = e_destination_store_list_destinations (store);
- if (string && *string) {
- named = TRUE;
+ for (diter = dests; diter; diter = g_list_next (diter)) {
+ EDestination *dest = diter->data;
+
+ if (dest && e_destination_get_address (dest)) {
+ editor->priv->changed = contact_list_editor_add_destination (WIDGET (DIALOG), dest)
+ || editor->priv->changed;
+ added = TRUE;
+ }
}
- g_free (string);
+ g_list_free (dests);
- return named;
+ if (!added)
+ contact_list_editor_add_email (editor, gtk_entry_get_text (GTK_ENTRY (entry)));
}
-static gboolean
-prompt_to_save_changes (EContactListEditor *editor)
+/*********************** Autoconnected Signal Handlers ***********************/
+
+void
+contact_list_editor_add_button_clicked_cb (GtkWidget *widget);
+
+void
+contact_list_editor_add_button_clicked_cb (GtkWidget *widget)
{
- if (!editor->changed || !is_named (editor))
- return TRUE;
+ EContactListEditor *editor;
- switch (e_addressbook_prompt_save_dialog (GTK_WINDOW(editor->app))) {
- case 0: /* Save */
- save_card (editor, FALSE);
- return TRUE;
- case 1: /* Discard */
- return TRUE;
- case 2: /* Cancel */
- default:
- return FALSE;
- }
+ editor = contact_list_editor_extract (widget);
+
+ contact_list_editor_add_from_email_entry (
+ editor,
+ E_NAME_SELECTOR_ENTRY (WIDGET (EMAIL_ENTRY)));
+ gtk_entry_set_text (GTK_ENTRY (WIDGET (EMAIL_ENTRY)), "");
}
-static void
-file_close_cb (GtkWidget *widget, gpointer data)
+void
+contact_list_editor_cancel_button_clicked_cb (GtkWidget *widget);
+
+void
+contact_list_editor_cancel_button_clicked_cb (GtkWidget *widget)
{
- EContactListEditor *cle = E_CONTACT_LIST_EDITOR (data);
+ EContactListEditor *editor;
+ GtkWindow *window;
- if (!prompt_to_save_changes (cle))
- return;
+ editor = contact_list_editor_extract (widget);
+ window = GTK_WINDOW (WIDGET (DIALOG));
- close_dialog (cle);
+ eab_editor_prompt_to_save_changes (EAB_EDITOR (editor), window);
}
-static void
-file_save_cb (GtkWidget *widget, gpointer data)
+void
+contact_list_editor_check_button_toggled_cb (GtkWidget *widget);
+
+void
+contact_list_editor_check_button_toggled_cb (GtkWidget *widget)
{
- EContactListEditor *cle = E_CONTACT_LIST_EDITOR (data);
+ EContactListEditor *editor;
- save_card (cle, FALSE);
+ editor = contact_list_editor_extract (widget);
+
+ editor->priv->changed = TRUE;
+ contact_list_editor_update (editor);
}
-static void
-file_save_as_cb (GtkWidget *widget, gpointer data)
+gboolean
+contact_list_editor_delete_event_cb (GtkWidget *widget,
+ GdkEvent *event);
+
+gboolean
+contact_list_editor_delete_event_cb (GtkWidget *widget,
+ GdkEvent *event)
{
- EContactListEditor *cle = E_CONTACT_LIST_EDITOR (data);
+ EContactListEditor *editor;
+ GtkWindow *window;
+
+ editor = contact_list_editor_extract (widget);
+ window = GTK_WINDOW (WIDGET (DIALOG));
- extract_info (cle);
+ /* If we're in an async call, don't allow the dialog to close. */
+ if (!editor->priv->in_async_call)
+ eab_editor_prompt_to_save_changes (
+ EAB_EDITOR (editor), window);
- e_contact_save_as(_("Save List as VCard"), cle->card, GTK_WINDOW (cle->app));
+ return TRUE;
}
-static void
-file_send_as_cb (GtkWidget *widget, gpointer data)
+void
+contact_list_editor_drag_data_received_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time);
+
+void
+contact_list_editor_drag_data_received_cb (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
{
- EContactListEditor *cle = E_CONTACT_LIST_EDITOR (data);
+ CamelInternetAddress *address;
+ EContactListEditor *editor;
+ gboolean changed = FALSE;
+ gboolean handled = FALSE;
+ const guchar *data;
+ GSList *list, *iter;
+ GdkAtom target;
+ gint n_addresses = 0;
+ gchar *text;
+
+ editor = contact_list_editor_extract (widget);
+
+ target = gtk_selection_data_get_target (selection_data);
+
+ /* Sanity check the selection target. */
+
+ if (gtk_targets_include_text (&target, 1))
+ goto handle_text;
+
+ if (!e_targets_include_directory (&target, 1))
+ goto exit;
+
+ data = gtk_selection_data_get_data (selection_data);
+ list = eab_contact_list_from_string ((gchar *) data);
+
+ if (list != NULL)
+ handled = TRUE;
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ EContact *contact = iter->data;
+ EDestination *dest;
+
+ dest = e_destination_new ();
+ e_destination_set_contact (dest, contact, 0);
+
+ changed = contact_list_editor_add_destination (widget, dest) || changed;
+
+ g_object_unref (dest);
+ }
+
+ g_slist_free_full (list, (GDestroyNotify) g_object_unref);
+
+ contact_list_editor_scroll_to_end (editor);
+
+ if (changed) {
+ editor->priv->changed = TRUE;
+ contact_list_editor_update (editor);
+ }
+
+ goto exit;
+
+handle_text:
+
+ address = camel_internet_address_new ();
+ text = (gchar *) gtk_selection_data_get_text (selection_data);
- extract_info (cle);
+ /* See if Camel can parse a valid email address from the text. */
+ if (text != NULL && *text != '\0') {
+ camel_url_decode (text);
+ if (g_ascii_strncasecmp (text, "mailto:", 7) == 0)
+ n_addresses = camel_address_decode (
+ CAMEL_ADDRESS (address), text + 7);
+ else
+ n_addresses = camel_address_decode (
+ CAMEL_ADDRESS (address), text);
+ }
+
+ if (n_addresses == 1) {
+ g_free (text);
+
+ text = camel_address_format (CAMEL_ADDRESS (address));
+ contact_list_editor_add_email (editor, text);
+
+ contact_list_editor_scroll_to_end (editor);
+ editor->priv->changed = TRUE;
+
+ contact_list_editor_update (editor);
+ handled = TRUE;
+ }
+
+ g_free (text);
- e_card_send(cle->card, E_CARD_DISPOSITION_AS_ATTACHMENT);
+exit:
+ gtk_drag_finish (context, handled, FALSE, time);
}
-static void
-file_send_to_cb (GtkWidget *widget, gpointer data)
+void
+contact_list_editor_email_entry_activate_cb (GtkWidget *widget);
+
+void
+contact_list_editor_email_entry_activate_cb (GtkWidget *widget)
{
- EContactListEditor *cle = E_CONTACT_LIST_EDITOR (data);
+ EContactListEditor *editor;
+ GtkEntry *entry;
- extract_info (cle);
+ editor = contact_list_editor_extract (widget);
+ entry = GTK_ENTRY (WIDGET (EMAIL_ENTRY));
- e_card_send(cle->card, E_CARD_DISPOSITION_AS_TO);
+ contact_list_editor_add_from_email_entry (
+ editor,
+ E_NAME_SELECTOR_ENTRY (entry));
+ gtk_entry_set_text (entry, "");
}
-static void
-tb_save_and_close_cb (GtkWidget *widget, gpointer data)
+void
+contact_list_editor_email_entry_changed_cb (GtkWidget *widget);
+
+void
+contact_list_editor_email_entry_changed_cb (GtkWidget *widget)
{
- EContactListEditor *cle = E_CONTACT_LIST_EDITOR (data);
- save_card (cle, TRUE);
+ EContactListEditor *editor;
+ const gchar *text;
+ gboolean sensitive;
+
+ editor = contact_list_editor_extract (widget);
+ text = gtk_entry_get_text (GTK_ENTRY (widget));
+
+ sensitive = (text != NULL && *text != '\0');
+ gtk_widget_set_sensitive (WIDGET (ADD_BUTTON), sensitive);
}
-static void
-list_deleted_cb (EBook *book, EBookStatus status, EContactListEditor *cle)
+gboolean
+contact_list_editor_email_entry_key_press_event_cb (GtkWidget *widget,
+ GdkEventKey *event);
+
+gboolean
+contact_list_editor_email_entry_key_press_event_cb (GtkWidget *widget,
+ GdkEventKey *event)
{
- if (cle->app)
- gtk_widget_set_sensitive (cle->app, TRUE);
- cle->in_async_call = FALSE;
+ EContactListEditor *editor;
+ gboolean can_comma = FALSE;
- gtk_signal_emit (GTK_OBJECT (cle), contact_list_editor_signals[LIST_DELETED],
- status, cle->card);
+ editor = contact_list_editor_extract (widget);
- /* always close the dialog after we successfully delete a list */
- if (status == E_BOOK_STATUS_SUCCESS)
- close_dialog (cle);
+ if (event->keyval == GDK_KEY_comma) {
+ GtkEntry *entry;
+ gint cpos = -1;
- gtk_object_unref (GTK_OBJECT (cle)); /* release reference held for callback */
-}
+ entry = GTK_ENTRY (WIDGET (EMAIL_ENTRY));
+ g_object_get (entry, "cursor-position", &cpos, NULL);
-static void
-delete_cb (GtkWidget *widget, gpointer data)
-{
- EContactListEditor *cle = E_CONTACT_LIST_EDITOR (data);
- ECard *card = cle->card;
+ /* not the first letter */
+ if (cpos > 0) {
+ const gchar *text;
+ gint quotes = 0, i;
- gtk_object_ref(GTK_OBJECT(card));
+ text = gtk_entry_get_text (entry);
- if (e_contact_editor_confirm_delete(GTK_WINDOW(cle->app))) {
+ for (i = 0; text && text[i] && i < cpos; i++) {
+ if (text[i] == '\"')
+ quotes++;
+ }
- extract_info (cle);
-
- if (!cle->is_new_list) {
- gtk_widget_set_sensitive (cle->app, FALSE);
- cle->in_async_call = TRUE;
-
- gtk_object_ref (GTK_OBJECT (cle)); /* hold reference for callback */
- e_book_remove_card (cle->book, card, GTK_SIGNAL_FUNC(list_deleted_cb), cle);
+ /* even count of quotes */
+ can_comma = (quotes & 1) == 0;
}
}
- gtk_object_unref(GTK_OBJECT(card));
+ if (can_comma || event->keyval == GDK_KEY_Return) {
+ g_signal_emit_by_name (WIDGET (EMAIL_ENTRY), "activate", 0);
+
+ return TRUE;
+ }
+
+ return FALSE;
}
-static
-BonoboUIVerb verbs [] = {
- BONOBO_UI_UNSAFE_VERB ("ContactListEditorSave", file_save_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactListEditorSaveClose", tb_save_and_close_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactListEditorDelete", delete_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactListEditorSaveAs", file_save_as_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactListEditorSendAs", file_send_as_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactListEditorSendTo", file_send_to_cb),
- BONOBO_UI_UNSAFE_VERB ("ContactListEditorClose", file_close_cb),
- BONOBO_UI_VERB_END
-};
+void
+contact_list_editor_list_name_entry_changed_cb (GtkWidget *widget);
-static EPixmap pixmaps[] = {
- E_PIXMAP ("/commands/ContactListEditorSave", "save-16.png"),
- E_PIXMAP ("/commands/ContactListEditorSaveClose", "save-16.png"),
- E_PIXMAP ("/commands/ContactListEditorSaveAs", "save-as-16.png"),
+void
+contact_list_editor_list_name_entry_changed_cb (GtkWidget *widget)
+{
+ EContactListEditor *editor;
+ const gchar *title;
- E_PIXMAP ("/commands/ContactListEditorDelete", "evolution-trash-mini.png"),
-#if 0 /* Envelope printing is disabled for Evolution 1.0. */
- E_PIXMAP ("/commands/ContactListEditorPrint", "print.xpm"),
- E_PIXMAP ("/commands/ContactListEditorPrintEnvelope", "print.xpm"),
-#endif
- E_PIXMAP ("/Toolbar/ContactListEditorSaveClose", "buttons/save-24.png"),
- E_PIXMAP ("/Toolbar/ContactListEditorDelete", "buttons/delete-message.png"),
- E_PIXMAP ("/Toolbar/ContactListEditorPrint", "buttons/print.png"),
+ editor = contact_list_editor_extract (widget);
- E_PIXMAP_END
-};
+ title = gtk_entry_get_text (GTK_ENTRY (widget));
-static void
-create_ui (EContactListEditor *ce)
+ if (title == NULL || *title == '\0')
+ title = _("Contact List Editor");
+
+ gtk_window_set_title (GTK_WINDOW (WIDGET (DIALOG)), title);
+
+ editor->priv->changed = TRUE;
+ contact_list_editor_update (editor);
+}
+
+void
+contact_list_editor_ok_button_clicked_cb (GtkWidget *widget);
+
+void
+contact_list_editor_ok_button_clicked_cb (GtkWidget *widget)
{
- bonobo_ui_component_add_verb_list_with_data (
- ce->uic, verbs, ce);
+ EContactListEditor *editor;
+ gboolean save_contact;
+
+ editor = contact_list_editor_extract (widget);
- bonobo_ui_util_set_ui (ce->uic, EVOLUTION_DATADIR,
- "evolution-contact-list-editor.xml",
- "evolution-contact-list-editor");
+ save_contact =
+ editor->priv->editable &&
+ editor->priv->allows_contact_lists;
- e_pixmaps_update (ce->uic, pixmaps);
+ if (save_contact)
+ eab_editor_save_contact (EAB_EDITOR (editor), TRUE);
+ else
+ eab_editor_close (EAB_EDITOR (editor));
}
-static void
-contact_list_editor_destroy_notify (void *data)
+void
+contact_list_editor_remove_button_clicked_cb (GtkWidget *widget);
+
+void
+contact_list_editor_remove_button_clicked_cb (GtkWidget *widget)
{
- EContactListEditor *ce = E_CONTACT_LIST_EDITOR (data);
+ EContactListEditor *editor;
+ GtkTreeSelection *selection;
+ GtkTreeRowReference *new_selection = NULL;
+ GtkTreeModel *model;
+ GtkTreeView *view;
+ GtkTreePath *path;
+ GList *list, *liter;
+
+ editor = contact_list_editor_extract (widget);
+
+ view = GTK_TREE_VIEW (WIDGET (TREE_VIEW));
+ selection = gtk_tree_view_get_selection (view);
+ list = gtk_tree_selection_get_selected_rows (selection, &model);
- all_contact_list_editors = g_slist_remove (all_contact_list_editors, ce);
+ /* Convert the GtkTreePaths to GtkTreeRowReferences. */
+ for (liter = list; liter != NULL; liter = liter->next) {
+ path = liter->data;
+
+ liter->data = gtk_tree_row_reference_new (model, path);
+
+ /* Store reference to next item below current selection */
+ if (!liter->next) {
+ gtk_tree_path_next (path);
+ new_selection = gtk_tree_row_reference_new (model, path);
+ }
+
+ gtk_tree_path_free (path);
+ }
+
+ /* Delete each row in the list. */
+ for (liter = list; liter != NULL; liter = liter->next) {
+ GtkTreeRowReference *reference = liter->data;
+ GtkTreeIter iter;
+ gboolean valid;
+
+ path = gtk_tree_row_reference_get_path (reference);
+ valid = gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_path_free (path);
+ g_assert (valid);
+
+ e_contact_list_model_remove_row (E_CONTACT_LIST_MODEL (model), &iter);
+ gtk_tree_row_reference_free (reference);
+ }
+
+ /* new_selection != NULL when there is at least one item below the
+ * removed selection */
+ if (new_selection) {
+ path = gtk_tree_row_reference_get_path (new_selection);
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_path_free (path);
+ gtk_tree_row_reference_free (new_selection);
+ } else {
+ /* If selection was including the last item in the list, then
+ * find and select the new last item */
+ GtkTreeIter iter, iter2;
+
+ /* When FALSE is returned, there are no items in the list to be selected */
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ iter2 = iter;
+
+ while (gtk_tree_model_iter_next (model, &iter))
+ iter2 = iter;
+
+ gtk_tree_selection_select_iter (selection, &iter2);
+ }
+ }
+
+ g_list_free (list);
+
+ editor->priv->changed = TRUE;
+ contact_list_editor_update (editor);
}
-EContactListEditor *
-e_contact_list_editor_new (EBook *book,
- ECard *list_card,
- gboolean is_new_list,
- gboolean editable)
+void
+contact_list_editor_select_button_clicked_cb (GtkWidget *widget);
+
+void
+contact_list_editor_select_button_clicked_cb (GtkWidget *widget)
{
- EContactListEditor *ce;
+ EContactListEditor *editor;
+ ENameSelectorDialog *dialog;
+ EDestinationStore *store;
+ GList *list, *iter;
+ GtkWindow *window;
+
+ editor = contact_list_editor_extract (widget);
+
+ dialog = e_name_selector_peek_dialog (editor->priv->name_selector);
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Contact List Members"));
+
+ /* We need to empty out the destination store, since we copy its
+ * contents every time. This sucks, we should really be wired
+ * directly to the EDestinationStore that the name selector uses
+ * in true MVC fashion. */
+
+ e_name_selector_model_peek_section (
+ e_name_selector_peek_model (editor->priv->name_selector),
+ "Members", NULL, &store);
- ce = E_CONTACT_LIST_EDITOR (gtk_type_new (E_CONTACT_LIST_EDITOR_TYPE));
+ list = e_destination_store_list_destinations (store);
+
+ for (iter = list; iter != NULL; iter = iter->next)
+ e_destination_store_remove_destination (store, iter->data);
+
+ g_list_free (list);
+
+ window = eab_editor_get_window (EAB_EDITOR (editor));
+ e_name_selector_show_dialog (
+ editor->priv->name_selector, GTK_WIDGET (window));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_hide (GTK_WIDGET (dialog));
+
+ list = e_destination_store_list_destinations (store);
+
+ for (iter = list; iter != NULL; iter = iter->next) {
+ EDestination *destination = iter->data;
+
+ contact_list_editor_add_destination (widget, destination);
+ e_destination_store_remove_destination (store, destination);
+ }
- all_contact_list_editors = g_slist_prepend (all_contact_list_editors, ce);
- gtk_object_weakref (GTK_OBJECT (ce), contact_list_editor_destroy_notify, ce);
+ g_list_free (list);
- gtk_object_set (GTK_OBJECT (ce),
- "book", book,
- "card", list_card,
- "is_new_list", is_new_list,
- "editable", editable,
- NULL);
+ gtk_entry_set_text (GTK_ENTRY (WIDGET (EMAIL_ENTRY)), "");
- return ce;
+ editor->priv->changed = TRUE;
+ contact_list_editor_update (editor);
}
-static void
-e_contact_list_editor_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+void
+contact_list_editor_combo_box_changed_cb (GtkWidget *widget);
+
+void
+contact_list_editor_combo_box_changed_cb (GtkWidget *widget)
{
+ ESourceComboBox *combo_box;
EContactListEditor *editor;
+ ESource *active_source;
+ ESource *client_source;
+ EClient *client;
+
+ editor = contact_list_editor_extract (widget);
+
+ combo_box = E_SOURCE_COMBO_BOX (widget);
+ active_source = e_source_combo_box_ref_active (combo_box);
+ g_return_if_fail (active_source != NULL);
+
+ client = E_CLIENT (editor->priv->book_client);
+ client_source = e_client_get_source (client);
+
+ if (!e_source_equal (client_source, active_source)) {
+ ConnectClosure *connect_closure;
- editor = E_CONTACT_LIST_EDITOR (o);
-
- switch (arg_id){
- case ARG_BOOK:
- if (editor->book)
- gtk_object_unref(GTK_OBJECT(editor->book));
- editor->book = E_BOOK(GTK_VALUE_OBJECT (*arg));
- gtk_object_ref (GTK_OBJECT (editor->book));
- /* XXX more here about editable/etc. */
- break;
- case ARG_CARD:
- if (editor->card)
- gtk_object_unref(GTK_OBJECT(editor->card));
- editor->card = e_card_duplicate(E_CARD(GTK_VALUE_OBJECT (*arg)));
- fill_in_info(editor);
- editor->changed = FALSE;
- command_state_changed (editor);
- break;
-
- case ARG_IS_NEW_LIST: {
- gboolean new_value = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE;
- gboolean changed = (editor->is_new_list != new_value);
-
- editor->is_new_list = new_value;
-
- if (changed)
- command_state_changed (editor);
- break;
+ connect_closure = g_slice_new0 (ConnectClosure);
+ connect_closure->editor = g_object_ref (editor);
+ connect_closure->source = g_object_ref (active_source);
+
+ e_client_combo_box_get_client (
+ E_CLIENT_COMBO_BOX (widget),
+ active_source, NULL,
+ contact_list_editor_get_client_cb,
+ connect_closure);
}
- case ARG_EDITABLE: {
- gboolean new_value = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE;
- gboolean changed = (editor->editable != new_value);
+ g_object_unref (active_source);
+}
- editor->editable = new_value;
+gboolean
+contact_list_editor_tree_view_key_press_event_cb (GtkWidget *widget,
+ GdkEventKey *event);
+gboolean
+contact_list_editor_tree_view_key_press_event_cb (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ EContactListEditor *editor;
- if (changed) {
- set_editable (editor);
- command_state_changed (editor);
- }
- break;
+ editor = contact_list_editor_extract (widget);
+
+ if (event->keyval == GDK_KEY_Delete) {
+ g_signal_emit_by_name (WIDGET (REMOVE_BUTTON), "clicked");
+ return TRUE;
}
+ return FALSE;
+}
+
+void
+contact_list_editor_top_button_clicked_cb (GtkButton *button);
+
+void
+contact_list_editor_top_button_clicked_cb (GtkButton *button)
+{
+ EContactListEditor *editor;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GList *references = NULL;
+ GList *l, *selected;
+
+ editor = contact_list_editor_extract (GTK_WIDGET (button));
+
+ tree_view = GTK_TREE_VIEW (WIDGET (TREE_VIEW));
+ model = gtk_tree_view_get_model (tree_view);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ selected = gtk_tree_selection_get_selected_rows (selection, &model);
+
+ for (l = selected; l; l = l->next)
+ references = g_list_prepend (
+ references,
+ gtk_tree_row_reference_new (model, l->data));
+
+ for (l = references; l; l = l->next) {
+ path = gtk_tree_row_reference_get_path (l->data);
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_store_move_after (
+ GTK_TREE_STORE (model), &iter, NULL);
+ gtk_tree_path_free (path);
}
+
+ g_list_foreach (references, (GFunc) gtk_tree_row_reference_free, NULL);
+ g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (references);
+ g_list_free (selected);
+
+ contact_list_editor_selection_changed_cb (selection, editor);
}
-static void
-e_contact_list_editor_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+void
+contact_list_editor_up_button_clicked_cb (GtkButton *button);
+
+void
+contact_list_editor_up_button_clicked_cb (GtkButton *button)
{
EContactListEditor *editor;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter, iter2;
+ GtkTreePath *path;
+ GList *selected;
- editor = E_CONTACT_LIST_EDITOR (object);
+ editor = contact_list_editor_extract (GTK_WIDGET (button));
- switch (arg_id) {
- case ARG_BOOK:
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(editor->book);
- break;
-
- case ARG_CARD:
- extract_info(editor);
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(editor->card);
- break;
-
- case ARG_IS_NEW_LIST:
- GTK_VALUE_BOOL (*arg) = editor->is_new_list ? TRUE : FALSE;
- break;
-
- case ARG_EDITABLE:
- GTK_VALUE_BOOL (*arg) = editor->editable ? TRUE : FALSE;
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
+ tree_view = GTK_TREE_VIEW (WIDGET (TREE_VIEW));
+ model = gtk_tree_view_get_model (tree_view);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ selected = gtk_tree_selection_get_selected_rows (selection, &model);
+
+ /* Get iter of item above the first selected item */
+ path = gtk_tree_path_copy (selected->data);
+ gtk_tree_path_prev (path);
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_path_free (path);
+
+ /* Get iter of the last selected item */
+ gtk_tree_model_get_iter (model, &iter2, g_list_last (selected)->data);
+
+ gtk_tree_store_move_after (GTK_TREE_STORE (model), &iter, &iter2);
+
+ g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (selected);
+
+ contact_list_editor_selection_changed_cb (selection, editor);
}
void
-e_contact_list_editor_show (EContactListEditor *editor)
+contact_list_editor_down_button_clicked_cb (GtkButton *button);
+
+void
+contact_list_editor_down_button_clicked_cb (GtkButton *button)
{
- gtk_widget_show (editor->app);
+ EContactListEditor *editor;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter, iter2;
+ GList *selected;
+
+ editor = contact_list_editor_extract (GTK_WIDGET (button));
+
+ tree_view = GTK_TREE_VIEW (WIDGET (TREE_VIEW));
+ model = gtk_tree_view_get_model (tree_view);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ selected = gtk_tree_selection_get_selected_rows (selection, &model);
+
+ /* Iter of the first selected item */
+ gtk_tree_model_get_iter (model, &iter, selected->data);
+
+ /* Iter of item below the last selected item */
+ gtk_tree_model_get_iter (model, &iter2, g_list_last (selected)->data);
+ gtk_tree_model_iter_next (model, &iter2);
+
+ gtk_tree_store_move_before (GTK_TREE_STORE (model), &iter2, &iter);
+
+ g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (selected);
+
+ contact_list_editor_selection_changed_cb (selection, editor);
}
void
-e_contact_list_editor_raise (EContactListEditor *editor)
+contact_list_editor_bottom_button_clicked_cb (GtkButton *button);
+
+void
+contact_list_editor_bottom_button_clicked_cb (GtkButton *button)
{
- gdk_window_raise (GTK_WIDGET (editor->app)->window);
+ EContactListEditor *editor;
+ GtkTreeView *tree_view;
+ GtkTreeModel *model;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ GList *references = NULL;
+
+ GList *l, *selected;
+
+ editor = contact_list_editor_extract (GTK_WIDGET (button));
+
+ tree_view = GTK_TREE_VIEW (WIDGET (TREE_VIEW));
+ model = gtk_tree_view_get_model (tree_view);
+ selection = gtk_tree_view_get_selection (tree_view);
+
+ selected = gtk_tree_selection_get_selected_rows (selection, &model);
+ for (l = selected; l; l = l->next)
+ references = g_list_prepend (
+ references,
+ gtk_tree_row_reference_new (model, l->data));
+ references = g_list_reverse (references);
+
+ for (l = references; l; l = l->next) {
+ path = gtk_tree_row_reference_get_path (l->data);
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_store_move_before (
+ GTK_TREE_STORE (model), &iter, NULL);
+ gtk_tree_path_free (path);
+ }
+
+ g_list_foreach (references, (GFunc) gtk_tree_row_reference_free, NULL);
+ g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
+ g_list_free (references);
+ g_list_free (selected);
+
+ contact_list_editor_selection_changed_cb (selection, editor);
}
-GtkWidget *
-e_contact_list_editor_create_table(gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2);
+/******************** GtkBuilder Custom Widgets Functions ********************/
-GtkWidget *
-e_contact_list_editor_create_table(gchar *name,
- gchar *string1, gchar *string2,
- gint int1, gint int2)
+static gpointer
+contact_editor_fudge_new (EBookClient *book_client,
+ EContact *contact,
+ gboolean is_new,
+ gboolean editable)
{
-
- ETableModel *model;
- GtkWidget *table;
+ EShell *shell = e_shell_get_default ();
- model = e_contact_list_model_new ();
+ /* XXX Putting this function signature in libedataserverui
+ * was a terrible idea. Now we're stuck with it. */
- table = e_table_scrolled_new_from_spec_file (model,
- NULL,
- EVOLUTION_ETSPECDIR "/e-contact-list-editor.etspec",
- NULL);
+ return e_contact_editor_new (
+ shell, book_client, contact, is_new, editable);
+}
+
+static gpointer
+contact_list_editor_fudge_new (EBookClient *book_client,
+ EContact *contact,
+ gboolean is_new,
+ gboolean editable)
+{
+ EShell *shell = e_shell_get_default ();
- gtk_object_set_data(GTK_OBJECT(table), "model", model);
+ /* XXX Putting this function signature in libedataserverui
+ * was a terrible idea. Now we're stuck with it. */
- return table;
+ return e_contact_list_editor_new (
+ shell, book_client, contact, is_new, editable);
}
static void
-add_email_cb (GtkWidget *w, EContactListEditor *editor)
+setup_custom_widgets (EContactListEditor *editor)
{
- GtkAdjustment *adj = e_scroll_frame_get_vadjustment (E_SCROLL_FRAME (editor->table));
- char *text = gtk_entry_get_text (GTK_ENTRY(editor->email_entry));
+ EShell *shell;
+ EClientCache *client_cache;
+ GtkWidget *combo_box;
+ ENameSelectorEntry *name_selector_entry;
+ GtkWidget *old, *parent;
+ EContactListEditorPrivate *priv;
+ guint ba = 0, la = 0, ra = 0, ta = 0, xo = 0, xp = 0, yo = 0, yp = 0;
+
+ g_return_if_fail (editor != NULL);
+
+ priv = E_CONTACT_LIST_EDITOR_GET_PRIVATE (editor);
+
+ shell = eab_editor_get_shell (EAB_EDITOR (editor));
+ client_cache = e_shell_get_client_cache (shell);
+
+ combo_box = WIDGET (CLIENT_COMBO_BOX);
+
+ e_client_combo_box_set_client_cache (
+ E_CLIENT_COMBO_BOX (combo_box), client_cache);
+
+ g_signal_connect (
+ combo_box, "changed", G_CALLBACK (
+ contact_list_editor_combo_box_changed_cb), NULL);
+
+ old = CONTACT_LIST_EDITOR_WIDGET (editor, "email-entry");
+ g_return_if_fail (old != NULL);
+
+ name_selector_entry = e_name_selector_peek_section_entry (
+ priv->name_selector, "Members");
+
+ gtk_widget_set_name (
+ GTK_WIDGET (name_selector_entry),
+ gtk_widget_get_name (old));
+ parent = gtk_widget_get_parent (old);
+
+ gtk_container_child_get (
+ GTK_CONTAINER (parent), old,
+ "bottom-attach", &ba,
+ "left-attach", &la,
+ "right-attach", &ra,
+ "top-attach", &ta,
+ "x-options", &xo,
+ "x-padding", &xp,
+ "y-options", &yo,
+ "y-padding", &yp,
+ NULL);
+
+ /* only hide it... */
+ gtk_widget_hide (old);
+
+ /* ... and place the new name selector to the
+ * exact place as is the old one in UI file */
+ gtk_widget_show (GTK_WIDGET (name_selector_entry));
+ gtk_table_attach (
+ GTK_TABLE (parent), GTK_WIDGET (name_selector_entry),
+ la, ra, ta, ba, xo, yo, xp, yp);
+ priv->email_entry = name_selector_entry;
+
+ e_name_selector_entry_set_contact_editor_func (
+ name_selector_entry, contact_editor_fudge_new);
+ e_name_selector_entry_set_contact_list_editor_func (
+ name_selector_entry, contact_list_editor_fudge_new);
+
+ g_signal_connect (
+ name_selector_entry, "activate", G_CALLBACK (
+ contact_list_editor_email_entry_activate_cb), NULL);
+ g_signal_connect (
+ name_selector_entry, "changed", G_CALLBACK (
+ contact_list_editor_email_entry_changed_cb), NULL);
+ g_signal_connect (
+ name_selector_entry, "key-press-event", G_CALLBACK (
+ contact_list_editor_email_entry_key_press_event_cb), NULL);
+}
+
+/***************************** GObject Callbacks *****************************/
+
+static void
+contact_list_editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CLIENT:
+ e_contact_list_editor_set_client (
+ E_CONTACT_LIST_EDITOR (object),
+ g_value_get_object (value));
+ return;
- if (text && *text) {
- e_contact_list_model_add_email (E_CONTACT_LIST_MODEL(editor->model), text);
+ case PROP_CONTACT:
+ e_contact_list_editor_set_contact (
+ E_CONTACT_LIST_EDITOR (object),
+ g_value_get_object (value));
+ return;
- /* Skip to the end of the list */
- if (adj->upper - adj->lower > adj->page_size)
- gtk_adjustment_set_value (adj, adj->upper);
+ case PROP_IS_NEW_LIST:
+ e_contact_list_editor_set_is_new_list (
+ E_CONTACT_LIST_EDITOR (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_EDITABLE:
+ e_contact_list_editor_set_editable (
+ E_CONTACT_LIST_EDITOR (object),
+ g_value_get_boolean (value));
+ return;
}
- gtk_entry_set_text (GTK_ENTRY(editor->email_entry), "");
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
- editor->changed = TRUE;
+static void
+contact_list_editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CLIENT:
+ g_value_set_object (
+ value,
+ e_contact_list_editor_get_client (
+ E_CONTACT_LIST_EDITOR (object)));
+ return;
- command_state_changed (editor);
+ case PROP_CONTACT:
+ g_value_set_object (
+ value,
+ e_contact_list_editor_get_contact (
+ E_CONTACT_LIST_EDITOR (object)));
+ return;
+
+ case PROP_IS_NEW_LIST:
+ g_value_set_boolean (
+ value,
+ e_contact_list_editor_get_is_new_list (
+ E_CONTACT_LIST_EDITOR (object)));
+ return;
+
+ case PROP_EDITABLE:
+ g_value_set_boolean (
+ value,
+ e_contact_list_editor_get_editable (
+ E_CONTACT_LIST_EDITOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-remove_row (int model_row, EContactListEditor *editor)
+contact_list_editor_dispose (GObject *object)
{
- e_contact_list_model_remove_row (E_CONTACT_LIST_MODEL (editor->model), model_row);
+ EContactListEditor *editor = E_CONTACT_LIST_EDITOR (object);
+ EContactListEditorPrivate *priv = editor->priv;
+
+ if (priv->name_selector) {
+ e_name_selector_cancel_loading (priv->name_selector);
+ g_object_unref (priv->name_selector);
+ priv->name_selector = NULL;
+ }
+
+ if (priv->contact) {
+ g_object_unref (priv->contact);
+ priv->contact = NULL;
+ }
+
+ if (priv->builder) {
+ g_object_unref (priv->builder);
+ priv->builder = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_contact_list_editor_parent_class)->dispose (object);
}
static void
-remove_entry_cb (GtkWidget *w, EContactListEditor *editor)
+contact_list_editor_constructed (GObject *object)
{
- e_table_selected_row_foreach (e_table_scrolled_get_table(E_TABLE_SCROLLED(editor->table)),
- (EForeachFunc)remove_row, editor);
- editor->changed = TRUE;
- command_state_changed (editor);
+ EContactListEditor *editor;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ GtkTreeView *view;
+ GtkTreeSelection *selection;
+ EClientCache *client_cache;
+ EShell *shell;
+
+ editor = E_CONTACT_LIST_EDITOR (object);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_contact_list_editor_parent_class)->
+ constructed (object);
+
+ shell = eab_editor_get_shell (EAB_EDITOR (editor));
+ client_cache = e_shell_get_client_cache (shell);
+
+ editor->priv->editable = TRUE;
+ editor->priv->allows_contact_lists = TRUE;
+
+ editor->priv->builder = gtk_builder_new ();
+ e_load_ui_builder_definition (
+ editor->priv->builder, "contact-list-editor.ui");
+ gtk_builder_connect_signals (editor->priv->builder, NULL);
+
+ /* Embed a pointer to the EContactListEditor in the top-level
+ * widget. Signal handlers can then access the pointer from any
+ * child widget by calling contact_list_editor_extract(widget). */
+ g_object_set_data (G_OBJECT (WIDGET (DIALOG)), TOPLEVEL_KEY, editor);
+
+ view = GTK_TREE_VIEW (WIDGET (TREE_VIEW));
+ editor->priv->model = e_contact_list_model_new ();
+ gtk_tree_view_set_model (view, editor->priv->model);
+
+ selection = gtk_tree_view_get_selection (view);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+ g_signal_connect (
+ selection, "changed",
+ G_CALLBACK (contact_list_editor_selection_changed_cb), editor);
+
+ gtk_tree_view_enable_model_drag_dest (view, NULL, 0, GDK_ACTION_LINK);
+ e_drag_dest_add_directory_targets (WIDGET (TREE_VIEW));
+ gtk_drag_dest_add_text_targets (WIDGET (TREE_VIEW));
+
+ column = gtk_tree_view_column_new ();
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_append_column (view, column);
+
+ gtk_tree_view_column_set_cell_data_func (
+ column, renderer, (GtkTreeCellDataFunc)
+ contact_list_editor_render_destination, NULL, NULL);
+
+ editor->priv->name_selector = e_name_selector_new (client_cache);
+
+ e_name_selector_model_add_section (
+ e_name_selector_peek_model (editor->priv->name_selector),
+ "Members", _("_Members"), NULL);
+
+ g_signal_connect (
+ editor, "notify::book",
+ G_CALLBACK (contact_list_editor_notify_cb), NULL);
+ g_signal_connect (
+ editor, "notify::editable",
+ G_CALLBACK (contact_list_editor_notify_cb), NULL);
+
+ gtk_widget_show_all (WIDGET (DIALOG));
+
+ setup_custom_widgets (editor);
+
+ e_name_selector_load_books (editor->priv->name_selector);
+
+ contact_list_editor_update (E_CONTACT_LIST_EDITOR (object));
}
+/**************************** EABEditor Callbacks ****************************/
+
static void
-list_name_changed_cb (GtkWidget *w, EContactListEditor *editor)
+contact_list_editor_show (EABEditor *editor)
{
- editor->changed = TRUE;
- command_state_changed (editor);
+ gtk_widget_show (WIDGET (DIALOG));
}
static void
-visible_addrs_toggled_cb (GtkWidget *w, EContactListEditor *editor)
+contact_list_editor_close (EABEditor *editor)
{
- editor->changed = TRUE;
- command_state_changed (editor);
+ gtk_widget_destroy (WIDGET (DIALOG));
+ eab_editor_closed (editor);
}
static void
-set_editable (EContactListEditor *editor)
+contact_list_editor_raise (EABEditor *editor)
{
- gtk_widget_set_sensitive (editor->email_entry, editor->editable);
- gtk_widget_set_sensitive (editor->list_name_entry, editor->editable);
- gtk_widget_set_sensitive (editor->add_button, editor->editable);
- gtk_widget_set_sensitive (editor->remove_button, editor->editable);
- gtk_widget_set_sensitive (editor->table, editor->editable);
+ GdkWindow *window;
+
+ window = gtk_widget_get_window (WIDGET (DIALOG));
+ gdk_window_raise (window);
}
-/* Closes the dialog box and emits the appropriate signals */
static void
-close_dialog (EContactListEditor *cle)
+contact_list_editor_save_contact (EABEditor *eab_editor,
+ gboolean should_close)
{
- g_assert (cle->app != NULL);
+ EContactListEditor *editor = E_CONTACT_LIST_EDITOR (eab_editor);
+ EContactListEditorPrivate *priv = editor->priv;
+ ESourceRegistry *registry;
+ EditorCloseStruct *ecs;
+ EContact *contact;
+ EShell *shell;
+
+ shell = eab_editor_get_shell (eab_editor);
+ registry = e_shell_get_registry (shell);
- gtk_widget_destroy (cle->app);
- cle->app = NULL;
+ contact = e_contact_list_editor_get_contact (editor);
- gtk_signal_emit (GTK_OBJECT (cle), contact_list_editor_signals[EDITOR_CLOSED]);
+ if (priv->book_client == NULL)
+ return;
+
+ ecs = g_new (EditorCloseStruct, 1);
+ ecs->editor = g_object_ref (editor);
+ ecs->should_close = should_close;
+
+ gtk_widget_set_sensitive (WIDGET (DIALOG), FALSE);
+ priv->in_async_call = TRUE;
+
+ if (priv->is_new_list)
+ eab_merging_book_add_contact (
+ registry, priv->book_client, contact,
+ contact_list_editor_list_added_cb, ecs);
+ else
+ eab_merging_book_modify_contact (
+ registry, priv->book_client, contact,
+ contact_list_editor_list_modified_cb, ecs);
+
+ priv->changed = FALSE;
}
-/* Callback used when the editor is destroyed */
-static gint
-app_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+static gboolean
+contact_list_editor_is_valid (EABEditor *editor)
{
- EContactListEditor *ce;
+ GtkEditable *editable;
+ gboolean valid;
+ gchar *chars;
- ce = E_CONTACT_LIST_EDITOR (data);
+ editable = GTK_EDITABLE (WIDGET (LIST_NAME_ENTRY));
+ chars = gtk_editable_get_chars (editable, 0, -1);
+ valid = (chars != NULL && *chars != '\0');
+ g_free (chars);
- /* if we're in an async call, don't allow the dialog to close */
- if (ce->in_async_call)
- return TRUE;
+ return valid;
+}
- if (!prompt_to_save_changes (ce))
- return TRUE;
+static gboolean
+contact_list_editor_is_changed (EABEditor *editor)
+{
+ return E_CONTACT_LIST_EDITOR_GET_PRIVATE (editor)->changed;
+}
- close_dialog (ce);
- return TRUE;
+static GtkWindow *
+contact_list_editor_get_window (EABEditor *editor)
+{
+ return GTK_WINDOW (WIDGET (DIALOG));
}
-static gboolean
-table_drag_motion_cb (ETable *table, int row, int col,
- GdkDragContext *context,
- gint x, gint y, guint time, EContactListEditor *editor)
+static void
+contact_list_editor_contact_added (EABEditor *editor,
+ const GError *error,
+ EContact *contact)
{
- GList *p;
+ if (!error)
+ return;
- for (p = context->targets; p != NULL; p = p->next) {
- char *possible_type;
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
- possible_type = gdk_atom_name ((GdkAtom) p->data);
- if (!strcmp (possible_type, VCARD_TYPE)) {
- g_free (possible_type);
- gdk_drag_status (context, GDK_ACTION_LINK, time);
- return TRUE;
- }
+ eab_error_dialog (NULL, eab_editor_get_window (editor), _("Error adding list"), error);
+}
- g_free (possible_type);
- }
+static void
+contact_list_editor_contact_modified (EABEditor *editor,
+ const GError *error,
+ EContact *contact)
+{
+ if (!error)
+ return;
- return FALSE;
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
+
+ eab_error_dialog (NULL, eab_editor_get_window (editor), _("Error modifying list"), error);
}
-static gboolean
-table_drag_drop_cb (ETable *table, int row, int col,
- GdkDragContext *context,
- gint x, gint y, guint time, EContactListEditor *editor)
+static void
+contact_list_editor_contact_deleted (EABEditor *editor,
+ const GError *error,
+ EContact *contact)
{
- if (context->targets != NULL) {
- gtk_drag_get_data (GTK_WIDGET (table), context,
- GPOINTER_TO_INT (context->targets->data),
- time);
- return TRUE;
- }
+ if (!error)
+ return;
- return FALSE;
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ return;
+
+ eab_error_dialog (NULL, eab_editor_get_window (editor), _("Error removing list"), error);
}
static void
-table_drag_data_received_cb (ETable *table, int row, int col,
- GdkDragContext *context,
- gint x, gint y,
- GtkSelectionData *selection_data,
- guint info, guint time, EContactListEditor *editor)
+contact_list_editor_closed (EABEditor *editor)
{
- GtkAdjustment *adj = e_scroll_frame_get_vadjustment (E_SCROLL_FRAME (editor->table));
- char *target_type;
- gboolean changed = FALSE;
+ g_object_unref (editor);
+}
- target_type = gdk_atom_name (selection_data->target);
+/****************************** GType Callbacks ******************************/
- if (!strcmp (target_type, VCARD_TYPE)) {
+static void
+e_contact_list_editor_class_init (EContactListEditorClass *class)
+{
+ GObjectClass *object_class;
+ EABEditorClass *editor_class;
+
+ g_type_class_add_private (class, sizeof (EContactListEditorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = contact_list_editor_set_property;
+ object_class->get_property = contact_list_editor_get_property;
+ object_class->dispose = contact_list_editor_dispose;
+ object_class->constructed = contact_list_editor_constructed;
+
+ editor_class = EAB_EDITOR_CLASS (class);
+ editor_class->show = contact_list_editor_show;
+ editor_class->close = contact_list_editor_close;
+ editor_class->raise = contact_list_editor_raise;
+ editor_class->save_contact = contact_list_editor_save_contact;
+ editor_class->is_valid = contact_list_editor_is_valid;
+ editor_class->is_changed = contact_list_editor_is_changed;
+ editor_class->get_window = contact_list_editor_get_window;
+ editor_class->contact_added = contact_list_editor_contact_added;
+ editor_class->contact_modified = contact_list_editor_contact_modified;
+ editor_class->contact_deleted = contact_list_editor_contact_deleted;
+ editor_class->editor_closed = contact_list_editor_closed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLIENT,
+ g_param_spec_object (
+ "client",
+ "EBookClient",
+ NULL,
+ E_TYPE_BOOK_CLIENT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CONTACT,
+ g_param_spec_object (
+ "contact",
+ "Contact",
+ NULL,
+ E_TYPE_CONTACT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_IS_NEW_LIST,
+ g_param_spec_boolean (
+ "is_new_list",
+ "Is New List",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ "Editable",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+}
- GList *card_list = e_card_load_cards_from_string_with_default_charset (selection_data->data, "ISO-8859-1");
- GList *c;
+static void
+e_contact_list_editor_init (EContactListEditor *editor)
+{
+ editor->priv = E_CONTACT_LIST_EDITOR_GET_PRIVATE (editor);
+}
- for (c = card_list; c; c = c->next) {
- ECard *ecard = c->data;
+/***************************** Public Interface ******************************/
- if (!e_card_evolution_list (ecard)) {
- ECardSimple *simple = e_card_simple_new (ecard);
+EABEditor *
+e_contact_list_editor_new (EShell *shell,
+ EBookClient *book_client,
+ EContact *list_contact,
+ gboolean is_new_list,
+ gboolean editable)
+{
+ EABEditor *editor;
- e_contact_list_model_add_card (E_CONTACT_LIST_MODEL (editor->model),
- simple);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
- gtk_object_unref (GTK_OBJECT (simple));
+ editor = g_object_new (
+ E_TYPE_CONTACT_LIST_EDITOR,
+ "shell", shell, NULL);
- changed = TRUE;
- }
- }
- g_list_foreach (card_list, (GFunc)gtk_object_unref, NULL);
- g_list_free (card_list);
+ g_object_set (
+ editor,
+ "client", book_client,
+ "contact", list_contact,
+ "is_new_list", is_new_list,
+ "editable", editable,
+ NULL);
- /* Skip to the end of the list */
- if (adj->upper - adj->lower > adj->page_size)
- gtk_adjustment_set_value (adj, adj->upper);
- }
+ return editor;
+}
- if (changed) {
- editor->changed = TRUE;
- command_state_changed (editor);
- }
+EBookClient *
+e_contact_list_editor_get_client (EContactListEditor *editor)
+{
+ g_return_val_if_fail (E_IS_CONTACT_LIST_EDITOR (editor), NULL);
+
+ return editor->priv->book_client;
}
-static void
-command_state_changed (EContactListEditor *editor)
+void
+e_contact_list_editor_set_client (EContactListEditor *editor,
+ EBookClient *book_client)
{
- gboolean named = is_named (editor);
-
- bonobo_ui_component_set_prop (editor->uic,
- "/commands/ContactListEditorSaveClose",
- "sensitive",
- editor->changed && named && editor->editable ? "1" : "0", NULL);
-
- bonobo_ui_component_set_prop (editor->uic,
- "/commands/ContactListEditorSave",
- "sensitive",
- editor->changed && named && editor->editable ? "1" : "0", NULL);
-
- bonobo_ui_component_set_prop (editor->uic,
- "/commands/ContactListEditorDelete",
- "sensitive",
- editor->editable && !editor->is_new_list ? "1" : "0", NULL);
+ g_return_if_fail (E_IS_CONTACT_LIST_EDITOR (editor));
+ g_return_if_fail (E_IS_BOOK_CLIENT (book_client));
+
+ if (book_client == editor->priv->book_client)
+ return;
+
+ if (editor->priv->book_client != NULL)
+ g_object_unref (editor->priv->book_client);
+ editor->priv->book_client = g_object_ref (book_client);
+
+ editor->priv->allows_contact_lists = e_client_check_capability (
+ E_CLIENT (editor->priv->book_client), "contact-lists");
+
+ contact_list_editor_update (editor);
+
+ g_object_notify (G_OBJECT (editor), "client");
}
static void
-extract_info(EContactListEditor *editor)
+save_contact_list (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GSList **attrs,
+ gint *parent_id)
{
- ECard *card = editor->card;
- if (card) {
- int i;
- EList *email_list;
- EIterator *email_iter;
- char *string = e_utf8_gtk_editable_get_chars(GTK_EDITABLE (editor->list_name_entry), 0, -1);
-
- if (string && *string)
- gtk_object_set(GTK_OBJECT(card),
- "file_as", string,
- "full_name", string,
- NULL);
-
- g_free (string);
-
-
- gtk_object_set (GTK_OBJECT(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);
-
- gtk_object_get (GTK_OBJECT(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));
- }
- gtk_object_unref (GTK_OBJECT (email_iter));
-
- /* 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);
+ EDestination *dest;
+ EVCardAttribute *attr;
+ gchar *pid_str = g_strdup_printf ("%d", *parent_id);
+
+ do {
+ gtk_tree_model_get (model, iter, 0, &dest, -1);
+
+ if (gtk_tree_model_iter_has_child (model, iter)) {
+ GtkTreeIter new_iter;
+ gchar *uid;
+
+ (*parent_id)++;
+ uid = g_strdup_printf ("%d", *parent_id);
+
+ attr = e_vcard_attribute_new (NULL, EVC_CONTACT_LIST);
+ e_vcard_attribute_add_param_with_value (
+ attr,
+ e_vcard_attribute_param_new (EVC_CL_UID), uid);
+ e_vcard_attribute_add_value (
+ attr,
+ e_destination_get_name (dest));
+
+ g_free (uid);
+
+ /* Set new_iter to first child of iter */
+ gtk_tree_model_iter_children (model, &new_iter, iter);
+
+ /* Go recursive */
+ save_contact_list (model, &new_iter, attrs, parent_id);
+ } else {
+ attr = e_vcard_attribute_new (NULL, EVC_EMAIL);
+ e_destination_export_to_vcard_attribute (dest, attr);
}
+
+ e_vcard_attribute_add_param_with_value (
+ attr,
+ e_vcard_attribute_param_new (EVC_PARENT_CL), pid_str);
+
+ *attrs = g_slist_prepend (*attrs, attr);
+
+ g_object_unref (dest);
+
+ } while (gtk_tree_model_iter_next (model, iter));
+
+ g_free (pid_str);
+}
+
+EContact *
+e_contact_list_editor_get_contact (EContactListEditor *editor)
+{
+ GtkTreeModel *model;
+ EContact *contact;
+ GtkTreeIter iter;
+ const gchar *text;
+ GSList *attrs = NULL, *a;
+ gint parent_id = 0;
+
+ g_return_val_if_fail (E_IS_CONTACT_LIST_EDITOR (editor), NULL);
+
+ model = editor->priv->model;
+ contact = editor->priv->contact;
+
+ if (contact == NULL)
+ return NULL;
+
+ text = gtk_entry_get_text (GTK_ENTRY (WIDGET (LIST_NAME_ENTRY)));
+ if (text != NULL && *text != '\0') {
+ e_contact_set (contact, E_CONTACT_FILE_AS, text);
+ e_contact_set (contact, E_CONTACT_FULL_NAME, text);
}
+
+ e_contact_set (contact, E_CONTACT_LOGO, NULL);
+ 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 (WIDGET (CHECK_BUTTON)))));
+
+ e_vcard_remove_attributes (E_VCARD (contact), "", EVC_EMAIL);
+ e_vcard_remove_attributes (E_VCARD (contact), "", EVC_CONTACT_LIST);
+
+ if (gtk_tree_model_get_iter_first (model, &iter))
+ save_contact_list (model, &iter, &attrs, &parent_id);
+
+ /* Put it in reverse order because e_vcard_add_attribute also uses prepend,
+ * but we want to keep order of mails there. Hopefully noone will change
+ * the behaviour of the e_vcard_add_attribute. */
+ for (a = attrs; a; a = a->next) {
+ e_vcard_add_attribute (E_VCARD (contact), a->data);
+ }
+
+ g_slist_free (attrs);
+
+ return contact;
}
-static void
-fill_in_info(EContactListEditor *editor)
+void
+e_contact_list_editor_set_contact (EContactListEditor *editor,
+ EContact *contact)
{
- if (editor->card) {
- char *file_as;
- gboolean show_addresses = FALSE;
- gboolean is_evolution_list = FALSE;
- EList *email_list;
- EIterator *email_iter;
-
- gtk_object_get (GTK_OBJECT (editor->card),
- "file_as", &file_as,
- "email", &email_list,
- "list", &is_evolution_list,
- "list_show_addresses", &show_addresses,
- NULL);
-
- gtk_editable_delete_text (GTK_EDITABLE (editor->list_name_entry), 0, -1);
- if (file_as) {
- int position = 0;
- gchar *u = e_utf8_to_gtk_string (editor->list_name_entry, file_as);
- gtk_editable_insert_text (GTK_EDITABLE (editor->list_name_entry), u, strlen (u), &position);
- g_free (u);
- }
+ EContactListEditorPrivate *priv;
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(editor->visible_addrs_checkbutton), !show_addresses);
+ g_return_if_fail (E_IS_CONTACT_LIST_EDITOR (editor));
+ g_return_if_fail (E_IS_CONTACT (contact));
- e_contact_list_model_remove_all (E_CONTACT_LIST_MODEL (editor->model));
+ priv = editor->priv;
- 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;
+ if (priv->contact != NULL)
+ g_object_unref (priv->contact);
- /* g_message ("incoming xml: [%s]", dest_xml); */
- dest = e_destination_import (dest_xml);
+ priv->contact = e_contact_duplicate (contact);
- if (dest != NULL) {
- e_contact_list_model_add_destination (E_CONTACT_LIST_MODEL (editor->model), dest);
- }
+ if (priv->contact != NULL) {
+ const gchar *file_as;
+ gboolean show_addresses;
+ const GList *dests, *dest;
+
+ /* The root destination */
+ EDestination *list_dest = e_destination_new ();
+
+ file_as = e_contact_get_const (
+ priv->contact, E_CONTACT_FILE_AS);
+ show_addresses = GPOINTER_TO_INT (e_contact_get (
+ priv->contact, E_CONTACT_LIST_SHOW_ADDRESSES));
+
+ if (file_as == NULL)
+ file_as = "";
+
+ gtk_entry_set_text (
+ GTK_ENTRY (WIDGET (LIST_NAME_ENTRY)), file_as);
+
+ gtk_toggle_button_set_active (
+ GTK_TOGGLE_BUTTON (WIDGET (CHECK_BUTTON)),
+ !show_addresses);
+
+ e_contact_list_model_remove_all (
+ E_CONTACT_LIST_MODEL (priv->model));
+
+ e_destination_set_name (list_dest, file_as);
+ e_destination_set_contact (list_dest, priv->contact, 0);
- e_iterator_next (email_iter);
+ dests = e_destination_list_get_root_dests (list_dest);
+ for (dest = dests; dest; dest = dest->next) {
+ GtkTreePath *path;
+ path = e_contact_list_model_add_destination (
+ E_CONTACT_LIST_MODEL (priv->model),
+ dest->data, NULL, TRUE);
+ gtk_tree_path_free (path);
}
+
+ g_object_unref (list_dest);
+
+ gtk_tree_view_expand_all (GTK_TREE_VIEW (WIDGET (TREE_VIEW)));
+ }
+
+ if (priv->book_client != NULL) {
+ e_source_combo_box_set_active (
+ E_SOURCE_COMBO_BOX (WIDGET (CLIENT_COMBO_BOX)),
+ e_client_get_source (E_CLIENT (priv->book_client)));
+ gtk_widget_set_sensitive (
+ WIDGET (CLIENT_COMBO_BOX), priv->is_new_list);
}
+
+ priv->changed = FALSE;
+ contact_list_editor_update (editor);
+
+ g_object_notify (G_OBJECT (editor), "contact");
+
}
+gboolean
+e_contact_list_editor_get_is_new_list (EContactListEditor *editor)
+{
+ g_return_val_if_fail (E_IS_CONTACT_LIST_EDITOR (editor), FALSE);
+
+ return editor->priv->is_new_list;
+}
+
+void
+e_contact_list_editor_set_is_new_list (EContactListEditor *editor,
+ gboolean is_new_list)
+{
+
+ g_return_if_fail (E_IS_CONTACT_LIST_EDITOR (editor));
+
+ if (editor->priv->is_new_list == is_new_list)
+ return;
+
+ editor->priv->is_new_list = is_new_list;
+ contact_list_editor_update (editor);
+
+ g_object_notify (G_OBJECT (editor), "is_new_list");
+}
gboolean
-e_contact_list_editor_request_close_all (void)
+e_contact_list_editor_get_editable (EContactListEditor *editor)
{
- GSList *p;
- GSList *pnext;
- gboolean retval;
-
- retval = TRUE;
- for (p = all_contact_list_editors; p != NULL; p = pnext) {
- pnext = p->next;
-
- e_contact_list_editor_raise (E_CONTACT_LIST_EDITOR (p->data));
- if (! prompt_to_save_changes (E_CONTACT_LIST_EDITOR (p->data))) {
- retval = FALSE;
- break;
- }
+ g_return_val_if_fail (E_IS_CONTACT_LIST_EDITOR (editor), FALSE);
- close_dialog (E_CONTACT_LIST_EDITOR (p->data));
- }
+ return editor->priv->editable;
+}
+
+void
+e_contact_list_editor_set_editable (EContactListEditor *editor,
+ gboolean editable)
+{
+ g_return_if_fail (E_IS_CONTACT_LIST_EDITOR (editor));
+
+ if (editor->priv->editable == editable)
+ return;
+
+ editor->priv->editable = editable;
+ contact_list_editor_update (editor);
- return retval;
+ g_object_notify (G_OBJECT (editor), "editable");
}
diff --git a/addressbook/gui/contact-list-editor/e-contact-list-editor.etspec b/addressbook/gui/contact-list-editor/e-contact-list-editor.etspec
deleted file mode 100644
index 6d5f4f2514..0000000000
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.etspec
+++ /dev/null
@@ -1,7 +0,0 @@
-<ETableSpecification no-headers="true" cursor-mode="line" selection-mode="single">
-<ETableColumn model_col= "0" _title="Contact" expansion="1.0" minimum_width="20" resizable="true" cell="string" compare="string" />
- <ETableState>
- <column source="0"/>
- <grouping> </grouping>
- </ETableState>
-</ETableSpecification>
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 a091c6c680..bafd7845b1 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-editor.h
+++ b/addressbook/gui/contact-list-editor/e-contact-list-editor.h
@@ -1,112 +1,93 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-contact-list-editor.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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_LIST_EDITOR_H__
#define __E_CONTACT_LIST_EDITOR_H__
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-app-helper.h>
-#include <bonobo/bonobo-ui-component.h>
-#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"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define E_CONTACT_LIST_EDITOR_TYPE (e_contact_list_editor_get_type ())
-#define E_CONTACT_LIST_EDITOR(obj) (GTK_CHECK_CAST ((obj), E_CONTACT_LIST_EDITOR_TYPE, EContactListEditor))
-#define E_CONTACT_LIST_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_CONTACT_LIST_EDITOR_TYPE, EContactListEditorClass))
-#define E_IS_CONTACT_LIST_EDITOR(obj) (GTK_CHECK_TYPE ((obj), E_CONTACT_LIST_EDITOR_TYPE))
-#define E_IS_CONTACT_LIST_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_CONTACT_LIST_EDITOR_TYPE))
-
-
-typedef struct _EContactListEditor EContactListEditor;
-typedef struct _EContactListEditorClass EContactListEditorClass;
+#include "addressbook/gui/contact-editor/eab-editor.h"
+
+#define E_TYPE_CONTACT_LIST_EDITOR \
+ (e_contact_list_editor_get_type ())
+#define E_CONTACT_LIST_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CONTACT_LIST_EDITOR, EContactListEditor))
+#define E_CONTACT_LIST_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CONTACT_LIST_EDITOR, EContactListEditorClass))
+#define E_IS_CONTACT_LIST_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CONTACT_LIST_EDITOR))
+#define E_IS_CONTACT_LIST_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_CONTACT_LIST_EDITOR))
+#define E_CONTACT_LIST_EDITOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CONTACT_LIST_EDITOR, EContactListEditorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EContactListEditor EContactListEditor;
+typedef struct _EContactListEditorClass EContactListEditorClass;
+typedef struct _EContactListEditorPrivate EContactListEditorPrivate;
struct _EContactListEditor
{
- GtkObject object;
-
- /* item specific fields */
- EBook *book;
- ECard *card;
-
- /* UI handler */
- BonoboUIComponent *uic;
-
- GladeXML *gui;
- GtkWidget *app;
-
- GtkWidget *table;
- ETableModel *model;
- GtkWidget *email_entry;
- GtkWidget *list_name_entry;
- GtkWidget *add_button;
- GtkWidget *remove_button;
- GtkWidget *visible_addrs_checkbutton;
-
- /* Whether we are editing a new card or an existing one */
- guint is_new_list : 1;
-
- /* Whether the card has been changed since bringing up the contact editor */
- guint changed : 1;
-
- /* Whether the contact editor will accept modifications */
- guint editable : 1;
-
- /* Whether an async wombat call is in progress */
- guint in_async_call : 1;
+ EABEditor parent;
+ EContactListEditorPrivate *priv;
};
struct _EContactListEditorClass
{
- GtkObjectClass parent_class;
-
- /* 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 (* editor_closed) (EContactListEditor *cle);
+ EABEditorClass parent_class;
};
-EContactListEditor *e_contact_list_editor_new (EBook *book,
- ECard *list_card,
- gboolean is_new_list,
- gboolean editable);
-GtkType e_contact_list_editor_get_type (void);
-void e_contact_list_editor_show (EContactListEditor *editor);
-void e_contact_list_editor_raise (EContactListEditor *editor);
-
-gboolean e_contact_list_editor_confirm_delete (GtkWindow *parent);
-
-gboolean e_contact_list_editor_request_close_all (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
+GType e_contact_list_editor_get_type (void);
+EABEditor * e_contact_list_editor_new (EShell *shell,
+ EBookClient *book_client,
+ EContact *list_contact,
+ gboolean is_new_list,
+ gboolean editable);
+EBookClient * e_contact_list_editor_get_client
+ (EContactListEditor *editor);
+void e_contact_list_editor_set_client
+ (EContactListEditor *editor,
+ EBookClient *book_client);
+EContact * e_contact_list_editor_get_contact
+ (EContactListEditor *editor);
+void e_contact_list_editor_set_contact
+ (EContactListEditor *editor,
+ EContact *contact);
+gboolean e_contact_list_editor_get_is_new_list
+ (EContactListEditor *editor);
+void e_contact_list_editor_set_is_new_list
+ (EContactListEditor *editor,
+ gboolean is_new_list);
+gboolean e_contact_list_editor_get_editable
+ (EContactListEditor *editor);
+void e_contact_list_editor_set_editable
+ (EContactListEditor *editor,
+ gboolean editable);
+gboolean e_contact_list_editor_request_close_all (void);
+
+G_END_DECLS
#endif /* __E_CONTACT_LIST_EDITOR_H__ */
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 c4321c2820..d2aae534fa 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-model.c
+++ b/addressbook/gui/contact-list-editor/e-contact-list-model.c
@@ -1,253 +1,329 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
#include <config.h>
-#include "e-contact-list-model.h"
+#endif
-#define PARENT_TYPE e_table_model_get_type()
-static ETableModelClass *parent_class;
+#include <string.h>
-#define COLS 1
+#include "e-contact-list-model.h"
+#include "shell/e-shell.h"
-/* This function returns the number of columns in our ETableModel. */
-static int
-contact_list_col_count (ETableModel *etc)
-{
- return COLS;
-}
+#define E_CONTACT_LIST_MODEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CONTACT_LIST_MODEL, EContactListModelPrivate))
-/* This function returns the number of rows in our ETableModel. */
-static int
-contact_list_row_count (ETableModel *etc)
-{
- EContactListModel *model = E_CONTACT_LIST_MODEL (etc);
- return model->data_count;
-}
+G_DEFINE_TYPE (EContactListModel, e_contact_list_model, GTK_TYPE_TREE_STORE);
-/* This function returns the value at a particular point in our ETableModel. */
-static void *
-contact_list_value_at (ETableModel *etc, int col, int row)
-{
- EContactListModel *model = E_CONTACT_LIST_MODEL (etc);
+struct _EContactListModelPrivate {
- return (void *) e_destination_get_address (model->data[row]);
-}
+ GHashTable *uids_table;
+ GHashTable *emails_table;
-/* This function sets the value at a particular point in our ETableModel. */
-static void
-contact_list_set_value_at (ETableModel *etc, int col, int row, const void *val)
-{
- /* nothing */
-}
+};
-/* This function returns whether a particular cell is editable. */
static gboolean
-contact_list_is_cell_editable (ETableModel *etc, int col, int row)
+contact_list_get_iter (EContactListModel *model,
+ GtkTreeIter *iter,
+ gint row)
{
- return FALSE;
-}
+ GtkTreePath *path;
+ gboolean iter_valid;
-/* This function duplicates the value passed to it. */
-static void *
-contact_list_duplicate_value (ETableModel *etc, int col, const void *value)
-{
- return g_strdup(value);
-}
+ path = gtk_tree_path_new_from_indices (row, -1);
+ iter_valid = gtk_tree_model_get_iter (
+ GTK_TREE_MODEL (model), iter, path);
+ gtk_tree_path_free (path);
-/* This function frees the value passed to it. */
-static void
-contact_list_free_value (ETableModel *etc, int col, void *value)
-{
- g_free(value);
+ return iter_valid;
}
-static void *
-contact_list_initialize_value (ETableModel *etc, int col)
+static GObject *
+contact_list_model_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
{
- return g_strdup("");
-}
+ GObject *object;
+ GType types[1];
-static gboolean
-contact_list_value_is_empty (ETableModel *etc, int col, const void *value)
-{
- return !(value && *(char *)value);
-}
+ types[0] = E_TYPE_DESTINATION;
-static char *
-contact_list_value_to_string (ETableModel *etc, int col, const void *value)
-{
- return g_strdup(value);
+ /* Chain up to parent's constructor() method. */
+ object = G_OBJECT_CLASS (e_contact_list_model_parent_class)->
+ constructor (type, n_construct_properties, construct_properties);
+
+ gtk_tree_store_set_column_types (
+ GTK_TREE_STORE (object), G_N_ELEMENTS (types), types);
+
+ return object;
}
static void
-contact_list_model_destroy (GtkObject *o)
+contact_list_model_dispose (GObject *object)
{
- EContactListModel *model = E_CONTACT_LIST_MODEL (o);
- int i;
+ EContactListModelPrivate *priv = E_CONTACT_LIST_MODEL (object)->priv;
- for (i = 0; i < model->data_count; i ++) {
- gtk_object_unref (GTK_OBJECT (model->data[i]));
+ if (priv->uids_table) {
+ g_hash_table_destroy (priv->uids_table);
+ priv->uids_table = NULL;
}
- g_free (model->data);
- model->data_count = 0;
- model->data_alloc = 0;
+ if (priv->emails_table) {
+ g_hash_table_destroy (priv->emails_table);
+ priv->emails_table = NULL;
+ }
+
+ G_OBJECT_CLASS (e_contact_list_model_parent_class)->dispose (object);
}
static void
-e_contact_list_model_class_init (GtkObjectClass *object_class)
+e_contact_list_model_class_init (EContactListModelClass *class)
{
- ETableModelClass *model_class = (ETableModelClass *) object_class;
-
- parent_class = gtk_type_class (PARENT_TYPE);
-
- object_class->destroy = contact_list_model_destroy;
-
- model_class->column_count = contact_list_col_count;
- model_class->row_count = contact_list_row_count;
- model_class->value_at = contact_list_value_at;
- model_class->set_value_at = contact_list_set_value_at;
- model_class->is_cell_editable = contact_list_is_cell_editable;
- model_class->duplicate_value = contact_list_duplicate_value;
- model_class->free_value = contact_list_free_value;
- model_class->initialize_value = contact_list_initialize_value;
- model_class->value_is_empty = contact_list_value_is_empty;
- model_class->value_to_string = contact_list_value_to_string;
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EContactListModelPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructor = contact_list_model_constructor;
+ object_class->dispose = contact_list_model_dispose;
}
static void
-e_contact_list_model_init (GtkObject *object)
+e_contact_list_model_init (EContactListModel *model)
{
- EContactListModel *model = E_CONTACT_LIST_MODEL(object);
+ model->priv = E_CONTACT_LIST_MODEL_GET_PRIVATE (model);
- model->data_alloc = 10;
- model->data_count = 0;
- model->data = g_new (EDestination*, model->data_alloc);
+ model->priv->uids_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ model->priv->emails_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
}
-GtkType
-e_contact_list_model_get_type (void)
+GtkTreeModel *
+e_contact_list_model_new (void)
{
- static GtkType type = 0;
-
- if (!type){
- GtkTypeInfo info = {
- "EContactListModel",
- sizeof (EContactListModel),
- sizeof (EContactListModelClass),
- (GtkClassInitFunc) e_contact_list_model_class_init,
- (GtkObjectInitFunc) e_contact_list_model_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
-
- return type;
+ return g_object_new (E_TYPE_CONTACT_LIST_MODEL, NULL);
}
-void
-e_contact_list_model_construct (EContactListModel *model)
+gboolean
+e_contact_list_model_has_email (EContactListModel *model,
+ const gchar *email)
{
+ return (g_hash_table_lookup (model->priv->emails_table, email) != NULL);
}
-ETableModel *
-e_contact_list_model_new ()
+gboolean
+e_contact_list_model_has_uid (EContactListModel *model,
+ const gchar *uid)
{
- EContactListModel *model;
-
- model = gtk_type_new (e_contact_list_model_get_type ());
-
- e_contact_list_model_construct (model);
-
- return E_TABLE_MODEL(model);
+ return (g_hash_table_lookup (model->priv->uids_table, uid) != NULL);
}
-void
-e_contact_list_model_add_destination (EContactListModel *model, EDestination *dest)
+GtkTreePath *
+e_contact_list_model_add_destination (EContactListModel *model,
+ EDestination *destination,
+ GtkTreeIter *parent,
+ gboolean ignore_conflicts)
{
- g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
- g_return_if_fail (E_IS_DESTINATION (dest));
+ GtkTreeIter iter;
+ GtkTreePath *path = NULL;
- if (model->data_count + 1 >= model->data_alloc) {
- model->data_alloc *= 2;
- model->data = g_renew (EDestination*, model->data, model->data_alloc);
+ g_return_val_if_fail (E_IS_CONTACT_LIST_MODEL (model), NULL);
+ g_return_val_if_fail (E_IS_DESTINATION (destination), NULL);
+
+ if (e_destination_is_evolution_list (destination)) {
+ const GList *dest, *dests = e_destination_list_get_root_dests (destination);
+ /* Get number of instances of this list in the model */
+ gint list_refs = GPOINTER_TO_INT (
+ g_hash_table_lookup (model->priv->uids_table,
+ e_destination_get_contact_uid (destination)));
+
+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 0, destination, -1);
+
+ for (dest = dests; dest; dest = dest->next) {
+ path = e_contact_list_model_add_destination (model, dest->data, &iter, ignore_conflicts);
+ if (dest->next && path) {
+ gtk_tree_path_free (path);
+ path = NULL;
+ }
+ }
+
+ /* When the list has no children the remove it. We don't want empty sublists displayed. */
+ if (!gtk_tree_model_iter_has_child (GTK_TREE_MODEL (model), &iter)) {
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &iter);
+ } else {
+ g_hash_table_insert (
+ model->priv->uids_table,
+ g_strdup (e_destination_get_contact_uid (destination)),
+ GINT_TO_POINTER (list_refs + 1));
+ }
+ } else {
+ gint dest_refs;
+
+ if (e_contact_list_model_has_email (model, e_destination_get_email (destination)) &&
+ ignore_conflicts == FALSE) {
+ return NULL;
+ }
+
+ dest_refs = GPOINTER_TO_INT (
+ g_hash_table_lookup (model->priv->emails_table,
+ e_destination_get_email (destination)));
+
+ g_hash_table_insert (
+ model->priv->emails_table,
+ g_strdup (e_destination_get_email (destination)),
+ GINT_TO_POINTER (dest_refs + 1));
+
+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter, parent);
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter, 0, destination, -1);
+
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
}
- model->data[model->data_count ++] = dest;
- gtk_object_ref (GTK_OBJECT (dest));
- gtk_object_sink (GTK_OBJECT (dest));
-
- e_table_model_changed (E_TABLE_MODEL (model));
+ return path;
}
void
-e_contact_list_model_add_email (EContactListModel *model,
- const char *email)
+e_contact_list_model_add_contact (EContactListModel *model,
+ EContact *contact,
+ gint email_num)
{
- EDestination *new_dest;
+ EDestination *destination;
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);
+ g_return_if_fail (E_IS_CONTACT (contact));
- e_contact_list_model_add_destination (model, new_dest);
+ destination = e_destination_new ();
+ e_destination_set_contact (destination, contact, email_num);
+ e_contact_list_model_add_destination (model, destination, NULL, TRUE);
}
-void
-e_contact_list_model_add_card (EContactListModel *model,
- ECardSimple *simple)
+static void
+contact_list_model_unref_row_dest (EContactListModel *model,
+ GtkTreeIter *iter)
{
- EDestination *new_dest;
-
- g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
- g_return_if_fail (E_IS_CARD_SIMPLE (simple));
-
- new_dest = e_destination_new ();
- e_destination_set_card (new_dest, simple->card, 0); /* Hard-wired for default e-mail */
+ EDestination *dest;
+ GtkTreeModel *tree_model;
+
+ tree_model = GTK_TREE_MODEL (model);
+ gtk_tree_model_get (tree_model, iter, 0, &dest, -1);
+
+ if (gtk_tree_model_iter_has_child (tree_model, iter)) {
+ GtkTreeIter child_iter;
+ gint list_refs = GPOINTER_TO_INT (
+ g_hash_table_lookup (model->priv->uids_table,
+ e_destination_get_contact_uid (dest)));
+
+ /* If the list is only once in the model, then remove it from the hash table,
+ * otherwise decrease the counter by one */
+ if (list_refs <= 1) {
+ g_hash_table_remove (
+ model->priv->uids_table,
+ e_destination_get_contact_uid (dest));
+ } else {
+ g_hash_table_insert (
+ model->priv->uids_table,
+ g_strdup (e_destination_get_contact_uid (dest)),
+ GINT_TO_POINTER (list_refs - 1));
+ }
+
+ if (gtk_tree_model_iter_children (tree_model, &child_iter, iter)) {
+ do {
+ contact_list_model_unref_row_dest (model, &child_iter);
+ } while (gtk_tree_model_iter_next (tree_model, &child_iter));
+ }
+
+ } else {
+ gint dest_refs = GPOINTER_TO_INT (
+ g_hash_table_lookup (
+ model->priv->emails_table,
+ e_destination_get_email (dest)));
+
+ if (dest_refs <= 1) {
+ g_hash_table_remove (
+ model->priv->emails_table,
+ e_destination_get_email (dest));
+ } else {
+ g_hash_table_insert (
+ model->priv->emails_table,
+ g_strdup (e_destination_get_email (dest)),
+ GINT_TO_POINTER (dest_refs - 1));
+ }
+ }
- e_contact_list_model_add_destination (model, new_dest);
+ g_object_unref (dest);
}
void
-e_contact_list_model_remove_row (EContactListModel *model, int row)
+e_contact_list_model_remove_row (EContactListModel *model,
+ GtkTreeIter *iter)
{
- g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
- g_return_if_fail (0 <= row && row < model->data_count);
+ GtkTreeIter parent_iter;
- gtk_object_unref (GTK_OBJECT (model->data[row]));
- memmove (model->data + row, model->data + row + 1, sizeof (EDestination*) * (model->data_count - row - 1));
- model->data_count --;
-
- e_table_model_changed (E_TABLE_MODEL (model));
+ g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
+ g_return_if_fail (iter);
+
+ /* Use helper function to update our reference counters in
+ * hash tables but don't remove any row. */
+ contact_list_model_unref_row_dest (model, iter);
+
+ /* Get iter of parent of the row to be removed. After the row is removed, check if there are
+ * any more children left for the parent_iter, an eventually remove the parent_iter as well */
+ if (gtk_tree_model_iter_parent (GTK_TREE_MODEL (model), &parent_iter, iter)) {
+ gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
+ if (!gtk_tree_model_iter_has_child (GTK_TREE_MODEL (model), &parent_iter)) {
+ contact_list_model_unref_row_dest (model, &parent_iter);
+ gtk_tree_store_remove (GTK_TREE_STORE (model), &parent_iter);
+ }
+ } else {
+ gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
+ }
}
void
e_contact_list_model_remove_all (EContactListModel *model)
{
- int i;
-
g_return_if_fail (E_IS_CONTACT_LIST_MODEL (model));
- for (i = 0; i < model->data_count; i ++) {
- gtk_object_unref (GTK_OBJECT (model->data[i]));
- model->data[i] = NULL;
- }
-
- model->data_count = 0;
+ g_hash_table_remove_all (model->priv->uids_table);
+ g_hash_table_remove_all (model->priv->emails_table);
- e_table_model_changed (E_TABLE_MODEL (model));
+ gtk_tree_store_clear (GTK_TREE_STORE (model));
}
-
-const EDestination *
-e_contact_list_model_get_destination (EContactListModel *model, int row)
+EDestination *
+e_contact_list_model_get_destination (EContactListModel *model,
+ gint row)
{
+ EDestination *destination;
+ GtkTreeIter iter;
+ gboolean iter_valid;
+
g_return_val_if_fail (E_IS_CONTACT_LIST_MODEL (model), NULL);
- g_return_val_if_fail (0 <= row && row < model->data_count, NULL);
- return model->data[row];
+ iter_valid = contact_list_get_iter (model, &iter, row);
+ g_return_val_if_fail (iter_valid, NULL);
+
+ gtk_tree_model_get (
+ GTK_TREE_MODEL (model), &iter, 0, &destination, -1);
+
+ return destination;
}
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 1c2d6ac8d0..ad10d7d539 100644
--- a/addressbook/gui/contact-list-editor/e-contact-list-model.h
+++ b/addressbook/gui/contact-list-editor/e-contact-list-model.h
@@ -1,47 +1,85 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
#ifndef _E_CONTACT_LIST_MODEL_H_
#define _E_CONTACT_LIST_MODEL_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 <gtk/gtk.h>
+#include <libebook/libebook.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CONTACT_LIST_MODEL \
+ (e_contact_list_model_get_type ())
+#define E_CONTACT_LIST_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CONTACT_LIST_MODEL, EContactListModel))
+#define E_CONTACT_LIST_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CONTACT_LIST_MODEL, EContactListModelClass))
+#define E_IS_CONTACT_LIST_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CONTACT_LIST_MODEL))
+#define E_IS_CONTACT_LIST_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CONTACT_LIST_MODEL))
+#define E_CONTACT_LIST_MODEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CONTACT_LIST_MODEL, EContactListModelClass))
-#define E_CONTACT_LIST_MODEL_TYPE (e_contact_list_model_get_type ())
-#define E_CONTACT_LIST_MODEL(o) (GTK_CHECK_CAST ((o), E_CONTACT_LIST_MODEL_TYPE, EContactListModel))
-#define E_CONTACT_LIST_MODEL_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_CONTACT_LIST_MODEL_TYPE, EContactListModelClass))
-#define E_IS_CONTACT_LIST_MODEL(o) (GTK_CHECK_TYPE ((o), E_CONTACT_LIST_MODEL_TYPE))
-#define E_IS_CONTACT_LIST_MODEL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_CONTACT_LIST_MODEL_TYPE))
+G_BEGIN_DECLS
typedef struct _EContactListModel EContactListModel;
+typedef struct _EContactListModelPrivate EContactListModelPrivate;
typedef struct _EContactListModelClass EContactListModelClass;
struct _EContactListModel {
- ETableModel parent;
-
- EDestination **data;
- int data_count;
- int data_alloc;
+ GtkTreeStore parent;
+ EContactListModelPrivate *priv;
};
-
struct _EContactListModelClass {
- ETableModelClass parent_class;
+ GtkTreeStoreClass parent_class;
};
+GType e_contact_list_model_get_type (void);
+GtkTreeModel * e_contact_list_model_new (void);
+gboolean e_contact_list_model_has_email (EContactListModel *model,
+ const gchar *email);
-GtkType 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_email (EContactListModel *model, const char *email);
-void e_contact_list_model_add_card (EContactListModel *model, ECardSimple *simple);
+gboolean e_contact_list_model_has_uid (EContactListModel *model,
+ const gchar *uid);
-void e_contact_list_model_remove_row (EContactListModel *model, int row);
-void e_contact_list_model_remove_all (EContactListModel *model);
+GtkTreePath * e_contact_list_model_add_destination
+ (EContactListModel *model,
+ EDestination *dest,
+ GtkTreeIter *parent,
+ gboolean ignore_conflicts);
+void e_contact_list_model_add_contact (EContactListModel *model,
+ EContact *contact,
+ gint email_num);
+void e_contact_list_model_remove_row (EContactListModel *model,
+ GtkTreeIter *iter);
+void e_contact_list_model_remove_all (EContactListModel *model);
+EDestination * e_contact_list_model_get_destination
+ (EContactListModel *model,
+ gint row);
-const EDestination *e_contact_list_model_get_destination (EContactListModel *model, int row);
+G_END_DECLS
#endif /* _E_CONTACT_LIST_MODEL_H_ */
diff --git a/addressbook/gui/merging/.cvsignore b/addressbook/gui/merging/.cvsignore
deleted file mode 100644
index d6c55c7345..0000000000
--- a/addressbook/gui/merging/.cvsignore
+++ /dev/null
@@ -1,7 +0,0 @@
-.deps
-.libs
-.pure
-Makefile
-Makefile.in
-*.lo
-*.la
diff --git a/addressbook/gui/merging/Makefile.am b/addressbook/gui/merging/Makefile.am
index a063f17819..319c1221fc 100644
--- a/addressbook/gui/merging/Makefile.am
+++ b/addressbook/gui/merging/Makefile.am
@@ -1,23 +1,25 @@
-INCLUDES = \
- -DG_LOG_DOMAIN=\"e-card-gui\" \
- -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
- -DEVOLUTION_DATADIR=\""$(datadir)"\" \
- -I$(top_srcdir) \
- -I$(top_srcdir)/addressbook/backend \
- -I$(top_builddir)/addressbook/backend \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
+noinst_LTLIBRARIES = libeabbookmerging.la
-noinst_LIBRARIES = \
- libecardmerging.a
+libeabbookmerging_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DG_LOG_DOMAIN=\"eab-contact-merging\" \
+ -DEVOLUTION_UIDIR=\""$(uidir)"\" \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/addressbook \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS)
-libecardmerging_a_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
+ui_DATA = \
+ eab-contact-duplicate-detected.ui \
+ eab-contact-commit-duplicate-detected.ui
-gladedir = $(datadir)/evolution/glade
-glade_DATA = e-card-duplicate-detected.glade \
- e-card-merging-book-commit-duplicate-detected.glade
+EXTRA_DIST = $(ui_DATA)
-EXTRA_DIST = \
- $(glade_DATA)
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/gui/merging/e-card-duplicate-detected.glade b/addressbook/gui/merging/e-card-duplicate-detected.glade
deleted file mode 100644
index bc6624e8fd..0000000000
--- a/addressbook/gui/merging/e-card-duplicate-detected.glade
+++ /dev/null
@@ -1,255 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>e-card-duplicate-detected</name>
- <program_name>e-card-duplicate-detected</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
- <use_widget_names>True</use_widget_names>
- <output_main_file>False</output_main_file>
- <output_support_files>False</output_support_files>
- <output_build_files>False</output_build_files>
- <gnome_help_support>True</gnome_help_support>
-</project>
-
-<widget>
- <class>GnomeDialog</class>
- <name>dialog-duplicate-contact</name>
- <title>Duplicate Contact Detected</title>
- <type>GTK_WINDOW_POPUP</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>dialog-vbox1</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>dialog-action_area1</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button3</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>Add Anyway</label>
- <stock_pixmap>GNOME_STOCK_PIXMAP_ADD</stock_pixmap>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button4</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table1</name>
- <rows>5</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>6</row_spacing>
- <column_spacing>6</column_spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>Custom</class>
- <name>custom-old-card</name>
- <creation_function>e_card_merging_create_old_card</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Fri, 08 Jun 2001 01:33:22 GMT</last_modification_time>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label1</name>
- <label>The name or email address of this contact already exists
-in this folder. Would you like to add it anyway?</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label3</name>
- <label>Original Contact:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label4</name>
- <label>New Contact:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>custom-new-card</name>
- <creation_function>e_card_merging_create_old_card</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Fri, 08 Jun 2001 01:33:22 GMT</last_modification_time>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment1</name>
- <xalign>0.5</xalign>
- <yalign>0</yalign>
- <xscale>1</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>Custom</class>
- <name>custom2</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>malehead.png</string1>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Fri, 08 Jun 2001 00:18:39 GMT</last_modification_time>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/addressbook/gui/merging/e-card-merging-book-commit-duplicate-detected.glade b/addressbook/gui/merging/e-card-merging-book-commit-duplicate-detected.glade
deleted file mode 100644
index 0bc60ba13a..0000000000
--- a/addressbook/gui/merging/e-card-merging-book-commit-duplicate-detected.glade
+++ /dev/null
@@ -1,255 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>e-card-merging-book-commit-duplicate-detected</name>
- <program_name>e-card-merging-book-commit-duplicate-detected</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
- <use_widget_names>True</use_widget_names>
- <output_main_file>False</output_main_file>
- <output_support_files>False</output_support_files>
- <output_build_files>False</output_build_files>
- <gnome_help_support>True</gnome_help_support>
-</project>
-
-<widget>
- <class>GnomeDialog</class>
- <name>dialog-duplicate-contact</name>
- <title>Duplicate Contact Detected</title>
- <type>GTK_WINDOW_POPUP</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>dialog-vbox1</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>dialog-action_area1</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button3</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>Change Anyway</label>
- <stock_pixmap>GNOME_STOCK_PIXMAP_ADD</stock_pixmap>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button4</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkTable</class>
- <name>table1</name>
- <rows>5</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>6</row_spacing>
- <column_spacing>6</column_spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>Custom</class>
- <name>custom-old-card</name>
- <creation_function>e_card_merging_create_old_card</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Fri, 08 Jun 2001 01:33:22 GMT</last_modification_time>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label1</name>
- <label>The changed email or name of this contact already
-exists in this folder. Would you like to add it anyway?</label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label3</name>
- <label>Conflicting Contact:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label4</name>
- <label>Changed Contact:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>custom-new-card</name>
- <creation_function>e_card_merging_create_old_card</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Fri, 08 Jun 2001 01:33:22 GMT</last_modification_time>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment1</name>
- <xalign>0.5</xalign>
- <yalign>0</yalign>
- <xscale>1</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>Custom</class>
- <name>custom2</name>
- <creation_function>e_create_image_widget</creation_function>
- <string1>malehead.png</string1>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Fri, 08 Jun 2001 00:18:39 GMT</last_modification_time>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/addressbook/gui/merging/e-card-merging.c b/addressbook/gui/merging/e-card-merging.c
deleted file mode 100644
index 14ed261405..0000000000
--- a/addressbook/gui/merging/e-card-merging.c
+++ /dev/null
@@ -1,168 +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 <libgnomeui/gnome-dialog.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
-doit (ECardMergingLookup *lookup)
-{
- if (lookup->op == E_CARD_MERGING_ADD)
- e_book_add_card (lookup->book, lookup->card, lookup->id_cb, lookup->closure);
- else if (lookup->op == E_CARD_MERGING_COMMIT)
- e_book_commit_card (lookup->book, lookup->card, lookup->cb, lookup->closure);
-}
-
-static void
-cancelit (ECardMergingLookup *lookup)
-{
- if (lookup->op == E_CARD_MERGING_ADD) {
- if (lookup->id_cb)
- lookup->id_cb (lookup->book, E_BOOK_STATUS_CANCELLED, NULL, lookup->closure);
- } else if (lookup->op == E_CARD_MERGING_COMMIT) {
- if (lookup->cb)
- lookup->cb (lookup->book, E_BOOK_STATUS_CANCELLED, lookup->closure);
- }
-}
-
-static void
-clicked (GnomeDialog *dialog, int button, ECardMergingLookup *lookup)
-{
- switch (button) {
- case 0:
- doit (lookup);
- break;
- case 1:
- cancelit (lookup);
- break;
- }
- g_free (lookup);
- gnome_dialog_close (dialog);
-}
-
-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);
- g_free (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);
- else if (lookup->op == E_CARD_MERGING_COMMIT)
- ui = glade_xml_new (EVOLUTION_GLADEDIR "/e-card-merging-book-commit-duplicate-detected.glade", NULL);
- else {
- doit (lookup);
- g_free (lookup);
- return;
- }
-
- widget = glade_xml_get_widget (ui, "custom-old-card");
- gtk_object_set (GTK_OBJECT (widget),
- "card", match,
- NULL);
-
- widget = glade_xml_get_widget (ui, "custom-new-card");
- gtk_object_set (GTK_OBJECT (widget),
- "card", card,
- NULL);
-
- widget = glade_xml_get_widget (ui, "dialog-duplicate-contact");
-
- gtk_signal_connect (GTK_OBJECT (widget), "clicked",
- GTK_SIGNAL_FUNC (clicked), lookup);
- }
-}
-
-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 = book;
- lookup->card = 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 = book;
- lookup->card = 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 c4d9483beb..0000000000
--- a/addressbook/gui/merging/e-card-merging.h
+++ /dev/null
@@ -1,31 +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 <libgnome/gnome-defs.h>
-
-#include <addressbook/backend/ebook/e-book.h>
-
-BEGIN_GNOME_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);
-
-END_GNOME_DECLS
-
-#endif /* ! __E_CARD_MERGING_H__ */
diff --git a/addressbook/gui/merging/eab-contact-commit-duplicate-detected.ui b/addressbook/gui/merging/eab-contact-commit-duplicate-detected.ui
new file mode 100644
index 0000000000..04ed728a56
--- /dev/null
+++ b/addressbook/gui/merging/eab-contact-commit-duplicate-detected.ui
@@ -0,0 +1,185 @@
+<?xml version="1.0"?>
+<!--*- mode: xml -*-->
+<interface>
+ <object class="GtkDialog" id="dialog-duplicate-contact">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Duplicate Contact Detected</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <object class="GtkButton" id="button3">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="button4">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-save</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="table1">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="n_rows">5</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="EABContactDisplay" type-func="eab_contact_display_get_type" id="custom-old-contact">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">The name or email of this contact already exists in this folder. Would you like to save the changes anyway?</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes" comments="Translators: Heading of the contact which has same name or email address in this folder already.">Conflicting Contact:</property>
+ <property name="use_underline">False</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">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Changed Contact:</property>
+ <property name="use_underline">False</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">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="EABContactDisplay" type-func="eab_contact_display_get_type" id="custom-new-contact">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0</property>
+ <property name="xscale">1</property>
+ <property name="yscale">0</property>
+ <child>
+ <object class="GtkImage" id="custom2">
+ <property name="visible">True</property>
+ <property name="icon-name">avatar-default</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="1">button3</action-widget>
+ <action-widget response="0">button4</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/addressbook/gui/merging/eab-contact-compare.c b/addressbook/gui/merging/eab-contact-compare.c
new file mode 100644
index 0000000000..bfca37cbff
--- /dev/null
+++ b/addressbook/gui/merging/eab-contact-compare.c
@@ -0,0 +1,839 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Jon Trowbridge <trow@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <string.h>
+
+#include "e-util/e-util.h"
+
+#include "addressbook/util/eab-book-util.h"
+#include "eab-contact-compare.h"
+
+/* This is an "optimistic" combiner: the best of the two outcomes is
+ * selected. */
+static EABContactMatchType
+combine_comparisons (EABContactMatchType prev,
+ EABContactMatchType new_info)
+{
+ if (new_info == EAB_CONTACT_MATCH_NOT_APPLICABLE)
+ return prev;
+ return (EABContactMatchType) MAX ((gint) prev, (gint) new_info);
+}
+
+/*** Name comparisons ***/
+
+/* This *so* doesn't belong here... at least not implemented in a
+ * sucky way like this. But it can be fixed later. */
+
+/* This is very Anglocentric. */
+static const gchar *name_synonyms[][2] = {
+ { "jon", "john" }, /* Ah, the hacker's perogative */
+ { "joseph", "joe" },
+ { "robert", "bob" },
+ { "gene", "jean" },
+ { "jesse", "jessie" },
+ { "ian", "iain" },
+ { "richard", "dick" },
+ { "william", "bill" },
+ { "william", "will" },
+ { "anthony", "tony" },
+ { "michael", "mike" },
+ { "eric", "erik" },
+ { "elizabeth", "liz" },
+ { "jeff", "geoff" },
+ { "jeff", "geoffrey" },
+ { "tom", "thomas" },
+ { "dave", "david" },
+ { "jim", "james" },
+ { "abigal", "abby" },
+ { "amanda", "amy" },
+ { "amanda", "manda" },
+ { "jennifer", "jenny" },
+ { "christopher", "chris" },
+ { "rebecca", "becca" },
+ { "rebecca", "becky" },
+ { "anderson", "andersen" },
+ { "johnson", "johnsen" },
+ /* We could go on and on... */
+ /* We should add soundex here. */
+ { NULL, NULL }
+};
+
+static gboolean
+name_fragment_match_with_synonyms (const gchar *a,
+ const gchar *b,
+ gboolean strict)
+{
+ gint i;
+
+ if (!(a && b && *a && *b))
+ return FALSE;
+
+ if (!e_utf8_casefold_collate (a, b))
+ return TRUE;
+
+ /* Check for nicknames. Yes, the linear search blows. */
+ for (i = 0; name_synonyms[i][0]; ++i) {
+
+ if (!e_utf8_casefold_collate (name_synonyms[i][0], a)
+ && !e_utf8_casefold_collate (name_synonyms[i][1], b))
+ return TRUE;
+
+ if (!e_utf8_casefold_collate (name_synonyms[i][0], b)
+ && !e_utf8_casefold_collate (name_synonyms[i][1], a))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+EABContactMatchType
+eab_contact_compare_name_to_string (EContact *contact,
+ const gchar *str)
+{
+ return eab_contact_compare_name_to_string_full (contact, str, FALSE, NULL, NULL, NULL);
+}
+
+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 = 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_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) {
+ if (*s == ',' || *s == '"')
+ *s = ' ';
+ ++s;
+ }
+ namev = g_strsplit (str_cpy, " ", 0);
+ g_free (str_cpy);
+
+ 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)
+ ++fragment_count;
+ for (i = 0; addv && addv[i]; ++i)
+ ++fragment_count;
+ for (i = 0; familyv && familyv[i]; ++i)
+ ++fragment_count;
+
+ for (i = 0; namev[i] && this_part_match != EAB_CONTACT_MATCH_PART_NONE; ++i) {
+
+ if (*namev[i]) {
+
+ 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 == 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 = 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". */
+ g_free (givenv[j]);
+ givenv[j] = g_strdup ("");
+ break;
+ }
+ }
+ }
+
+ 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 = EAB_CONTACT_MATCH_PART_ADDITIONAL_NAME;
+
+ g_free (addv[j]);
+ addv[j] = g_strdup ("");
+ break;
+ }
+ }
+ }
+
+ 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 = EAB_CONTACT_MATCH_PART_FAMILY_NAME;
+
+ g_free (familyv[j]);
+ familyv[j] = g_strdup ("");
+ break;
+ }
+ }
+ }
+
+ 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 == EAB_CONTACT_MATCH_PART_NONE)
+ first_matched_part = this_part_match;
+ }
+ }
+ }
+
+ match_type = EAB_CONTACT_MATCH_NONE;
+
+ if (this_part_match != EAB_CONTACT_MATCH_PART_NONE) {
+
+ if (match_count > 0)
+ match_type = EAB_CONTACT_MATCH_VAGUE;
+
+ if (fragment_count == match_count) {
+
+ match_type = EAB_CONTACT_MATCH_EXACT;
+
+ } else if (fragment_count == match_count + 1) {
+
+ match_type = EAB_CONTACT_MATCH_PARTIAL;
+
+ }
+ }
+
+ if (matched_parts_out)
+ *matched_parts_out = matched_parts;
+ if (first_matched_part_out)
+ *first_matched_part_out = first_matched_part;
+ if (matched_character_count_out)
+ *matched_character_count_out = matched_character_count;
+
+ g_strfreev (namev);
+ g_strfreev (givenv);
+ g_strfreev (addv);
+ g_strfreev (familyv);
+
+ return match_type;
+}
+
+EABContactMatchType
+eab_contact_compare_file_as (EContact *contact1,
+ EContact *contact2)
+{
+ EABContactMatchType match_type;
+ gchar *a, *b;
+
+ 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 = e_contact_get (contact1, E_CONTACT_FILE_AS);
+ b = e_contact_get (contact2, E_CONTACT_FILE_AS);
+
+ if (a == NULL || b == NULL) {
+ g_free (a);
+ g_free (b);
+ return EAB_CONTACT_MATCH_NOT_APPLICABLE;
+ }
+
+ if (!strcmp (a, b))
+ match_type = EAB_CONTACT_MATCH_EXACT;
+ else if (g_utf8_validate (a, -1, NULL) && g_utf8_validate (b, -1, NULL) &&
+ !g_utf8_collate (a, b))
+ match_type = EAB_CONTACT_MATCH_PARTIAL;
+ else
+ match_type = EAB_CONTACT_MATCH_NONE;
+
+ g_free (a);
+ g_free (b);
+ return match_type;
+}
+
+EABContactMatchType
+eab_contact_compare_name (EContact *contact1,
+ EContact *contact2)
+{
+ EContactName *a, *b;
+ gint matches = 0, possible = 0;
+ gboolean family_match = FALSE;
+
+ 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 = e_contact_get (contact1, E_CONTACT_NAME);
+ b = e_contact_get (contact2, E_CONTACT_NAME);
+
+ if (a == NULL || b == NULL) {
+ g_free (a);
+ g_free (b);
+ return EAB_CONTACT_MATCH_NOT_APPLICABLE;
+ }
+
+ if (a->given && b->given && *a->given && *b->given) {
+ ++possible;
+ if (name_fragment_match_with_synonyms (a->given, b->given, FALSE /* both inputs are complete */)) {
+ ++matches;
+ }
+ }
+
+ if (a->additional && b->additional && *a->additional && *b->additional) {
+ ++possible;
+ if (name_fragment_match_with_synonyms (a->additional, b->additional, FALSE /* both inputs are complete */)) {
+ ++matches;
+ }
+ }
+
+ if (a->family && b->family && *a->family && *b->family) {
+ ++possible;
+ /* We don't allow "loose matching" (i.e. John vs. Jon) on family names */
+ if (!e_utf8_casefold_collate (a->family, b->family)) {
+ ++matches;
+ family_match = TRUE;
+ }
+ }
+
+ e_contact_name_free (a);
+ e_contact_name_free (b);
+
+ /* Now look at the # of matches and try to intelligently map
+ * an EAB_CONTACT_MATCH_* type to it. Special consideration is given
+ * to family-name matches. */
+
+ if (possible == 0)
+ return EAB_CONTACT_MATCH_NOT_APPLICABLE;
+
+ if (possible == 1)
+ return family_match ? EAB_CONTACT_MATCH_VAGUE : EAB_CONTACT_MATCH_NONE;
+
+ if (possible == matches)
+ return family_match ? EAB_CONTACT_MATCH_EXACT : EAB_CONTACT_MATCH_PARTIAL;
+
+ if (possible == matches + 1)
+ return family_match ? EAB_CONTACT_MATCH_VAGUE : EAB_CONTACT_MATCH_NONE;
+
+ return EAB_CONTACT_MATCH_NONE;
+}
+
+/*** Nickname Comparisons ***/
+
+EABContactMatchType
+eab_contact_compare_nickname (EContact *contact1,
+ EContact *contact2)
+{
+ 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 EAB_CONTACT_MATCH_NOT_APPLICABLE;
+}
+
+/*** E-mail Comparisons ***/
+
+static gboolean
+match_email_username (const gchar *addr1,
+ const gchar *addr2)
+{
+ gint c1, c2;
+ if (addr1 == NULL || addr2 == NULL)
+ return FALSE;
+
+ while (*addr1 && *addr2 && *addr1 != '@' && *addr2 != '@') {
+ c1 = isupper (*addr1) ? tolower (*addr1) : *addr1;
+ c2 = isupper (*addr2) ? tolower (*addr2) : *addr2;
+ if (c1 != c2)
+ return FALSE;
+ ++addr1;
+ ++addr2;
+ }
+
+ return *addr1 == *addr2;
+}
+
+static gboolean
+match_email_hostname (const gchar *addr1,
+ const gchar *addr2)
+{
+ gint c1, c2;
+ gboolean seen_at1, seen_at2;
+ if (addr1 == NULL || addr2 == NULL)
+ return FALSE;
+
+ /* Walk to the end of each string. */
+ seen_at1 = FALSE;
+ if (*addr1) {
+ while (*addr1) {
+ if (*addr1 == '@')
+ seen_at1 = TRUE;
+ ++addr1;
+ }
+ --addr1;
+ }
+
+ seen_at2 = FALSE;
+ if (*addr2) {
+ while (*addr2) {
+ if (*addr2 == '@')
+ seen_at2 = TRUE;
+ ++addr2;
+ }
+ --addr2;
+ }
+
+ if (!seen_at1 && !seen_at2)
+ return TRUE;
+ if (!seen_at1 || !seen_at2)
+ return FALSE;
+
+ while (*addr1 != '@' && *addr2 != '@') {
+ c1 = isupper (*addr1) ? tolower (*addr1) : *addr1;
+ c2 = isupper (*addr2) ? tolower (*addr2) : *addr2;
+ if (c1 != c2)
+ return FALSE;
+ --addr1;
+ --addr2;
+ }
+ if ((*addr1 == '@' && *addr2 != '@') || (*addr2 == '@' && *addr1 != '@'))
+ return FALSE;
+
+ return TRUE;
+}
+
+static EABContactMatchType
+compare_email_addresses (const gchar *addr1,
+ const gchar *addr2)
+{
+ if (addr1 == NULL || *addr1 == 0 ||
+ addr2 == NULL || *addr2 == 0)
+ return EAB_CONTACT_MATCH_NOT_APPLICABLE;
+
+ if (match_email_username (addr1, addr2))
+ return match_email_hostname (addr1, addr2) ? EAB_CONTACT_MATCH_EXACT : EAB_CONTACT_MATCH_VAGUE;
+
+ return EAB_CONTACT_MATCH_NONE;
+}
+
+EABContactMatchType
+eab_contact_compare_email (EContact *contact1,
+ EContact *contact2)
+{
+ 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);
+
+ if (contact1_email == NULL || contact2_email == NULL) {
+ 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 EAB_CONTACT_MATCH_NOT_APPLICABLE;
+ }
+
+ 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. */
+ while (i1 && match != EAB_CONTACT_MATCH_EXACT) {
+ gchar *addr1 = (gchar *) i1->data;
+
+ i2 = contact2_email;
+ while (i2 && match != EAB_CONTACT_MATCH_EXACT) {
+ gchar *addr2 = (gchar *) i2->data;
+
+ match = combine_comparisons (match, compare_email_addresses (addr1, addr2));
+
+ i2 = i2->next;
+ }
+
+ i1 = i1->next;
+ }
+
+ 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;
+}
+
+EABContactMatchType
+eab_contact_compare_address (EContact *contact1,
+ EContact *contact2)
+{
+ 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 EAB_CONTACT_MATCH_NOT_APPLICABLE;
+}
+
+EABContactMatchType
+eab_contact_compare_telephone (EContact *contact1,
+ EContact *contact2)
+{
+ 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 EAB_CONTACT_MATCH_NOT_APPLICABLE;
+}
+
+EABContactMatchType
+eab_contact_compare (EContact *contact1,
+ EContact *contact2)
+{
+ EABContactMatchType result;
+
+ 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 = EAB_CONTACT_MATCH_NONE;
+ if (!e_contact_get (contact1, E_CONTACT_IS_LIST)) {
+ result = combine_comparisons (result, eab_contact_compare_name (contact1, contact2));
+ result = combine_comparisons (result, eab_contact_compare_nickname (contact1, contact2));
+ if (!e_contact_get (contact2, E_CONTACT_IS_LIST))
+ 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));
+ }
+ result = combine_comparisons (result, eab_contact_compare_file_as (contact1, contact2));
+
+ return result;
+}
+
+typedef struct _MatchSearchInfo MatchSearchInfo;
+struct _MatchSearchInfo {
+ EContact *contact;
+ GList *avoid;
+ EABContactMatchQueryCallback cb;
+ gpointer closure;
+};
+
+static void
+match_search_info_free (MatchSearchInfo *info)
+{
+ if (info) {
+ g_object_unref (info->contact);
+
+ /* This should already have been deallocated, but just in case... */
+ if (info->avoid) {
+ g_list_foreach (info->avoid, (GFunc) g_object_unref, NULL);
+ g_list_free (info->avoid);
+ info->avoid = NULL;
+ }
+
+ g_free (info);
+ }
+}
+
+static void
+query_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ MatchSearchInfo *info = (MatchSearchInfo *) user_data;
+ EABContactMatchType best_match = EAB_CONTACT_MATCH_NONE;
+ EContact *best_contact = NULL;
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ GSList *remaining_contacts = NULL;
+ GSList *contacts = NULL;
+ GError *error = NULL;
+ const GSList *ii;
+
+ if (result != NULL)
+ e_book_client_get_contacts_finish (
+ book_client, result, &contacts, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to get contacts: %s\n",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+
+ info->cb (
+ info->contact, NULL,
+ EAB_CONTACT_MATCH_NONE,
+ info->closure);
+
+ match_search_info_free (info);
+ g_object_unref (book_client);
+ return;
+ }
+
+ /* remove the contacts we're to avoid from the list, if they're present */
+ for (ii = contacts; ii != NULL; ii = g_slist_next (ii)) {
+ EContact *this_contact = E_CONTACT (ii->data);
+ const gchar *this_uid;
+ GList *iterator;
+ gboolean avoid = FALSE;
+
+ this_uid = e_contact_get_const (this_contact, E_CONTACT_UID);
+ if (!this_uid)
+ continue;
+
+ for (iterator = info->avoid; iterator; iterator = iterator->next) {
+ const gchar *avoid_uid;
+
+ avoid_uid = e_contact_get_const (iterator->data, E_CONTACT_UID);
+ if (!avoid_uid)
+ continue;
+
+ if (!strcmp (avoid_uid, this_uid)) {
+ avoid = TRUE;
+ break;
+ }
+ }
+ if (!avoid)
+ remaining_contacts = g_slist_prepend (remaining_contacts, g_object_ref (this_contact));
+ }
+
+ remaining_contacts = g_slist_reverse (remaining_contacts);
+
+ for (ii = remaining_contacts; ii != NULL; ii = g_slist_next (ii)) {
+ EContact *this_contact = E_CONTACT (ii->data);
+ EABContactMatchType this_match = eab_contact_compare (info->contact, this_contact);
+ if ((gint) this_match > (gint) best_match) {
+ best_match = this_match;
+ best_contact = this_contact;
+ }
+ }
+
+ if (best_contact)
+ best_contact = g_object_ref (best_contact);
+
+ g_slist_free_full (contacts, (GDestroyNotify) g_object_unref);
+ g_slist_free_full (remaining_contacts, (GDestroyNotify) g_object_unref);
+
+ info->cb (info->contact, best_contact, best_match, info->closure);
+ match_search_info_free (info);
+ g_object_unref (book_client);
+ if (best_contact)
+ g_object_unref (best_contact);
+}
+
+#define MAX_QUERY_PARTS 10
+static void
+use_common_book_client (EBookClient *book_client,
+ MatchSearchInfo *info)
+{
+ EContact *contact = info->contact;
+ EContactName *contact_name;
+ GList *contact_email;
+ gchar *query_parts[MAX_QUERY_PARTS + 1];
+ gint p = 0;
+ gchar *contact_file_as, *qj;
+ EBookQuery *query = NULL;
+ gint i;
+
+ if (book_client == NULL) {
+ info->cb (info->contact, NULL, EAB_CONTACT_MATCH_NONE, info->closure);
+ match_search_info_free (info);
+ return;
+ }
+
+ contact_file_as = e_contact_get (contact, E_CONTACT_FILE_AS);
+ if (contact_file_as) {
+ query_parts[p++] = g_strdup_printf ("(contains \"file_as\" \"%s\")", contact_file_as);
+ g_free (contact_file_as);
+ }
+
+ if (!e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ 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 (contact_name->additional && *contact_name->additional)
+ query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", contact_name->additional);
+
+ if (contact_name->family && *contact_name->family)
+ query_parts[p++] = g_strdup_printf ("(contains \"full_name\" \"%s\")", contact_name->family);
+
+ e_contact_name_free (contact_name);
+ }
+
+ 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) {
+ if (*s == '@') {
+ *s = '\0';
+ break;
+ }
+ ++s;
+ }
+ query_parts[p++] = g_strdup_printf ("(beginswith \"email\" \"%s\")", addr);
+ g_free (addr);
+ }
+ }
+ }
+ g_list_foreach (contact_email, (GFunc) g_free, NULL);
+ g_list_free (contact_email);
+ }
+
+ /* Build up our full query from the parts. */
+ query_parts[p] = NULL;
+ qj = g_strjoinv (" ", query_parts);
+ for (i = 0; query_parts[i] != NULL; i++)
+ g_free (query_parts[i]);
+ if (p > 1) {
+ gchar *s;
+ s = g_strdup_printf ("(or %s)", qj);
+ query = e_book_query_from_string (s);
+ g_free (s);
+ }
+ else if (p == 1) {
+ query = e_book_query_from_string (qj);
+ }
+ else {
+ query = NULL;
+ }
+
+ if (query) {
+ gchar *query_str = e_book_query_to_string (query);
+
+ e_book_client_get_contacts (book_client, query_str, NULL, query_cb, info);
+
+ g_free (query_str);
+ } else
+ query_cb (G_OBJECT (book_client), NULL, info);
+
+ g_free (qj);
+ if (query)
+ e_book_query_unref (query);
+}
+
+static void
+book_client_connect_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ MatchSearchInfo *info = user_data;
+ EClient *client;
+
+ client = e_book_client_connect_finish (result, NULL);
+
+ /* Client may be NULL; don't use a type cast macro. */
+ use_common_book_client ((EBookClient *) client, info);
+}
+
+void
+eab_contact_locate_match (ESourceRegistry *registry,
+ EContact *contact,
+ EABContactMatchQueryCallback cb,
+ gpointer closure)
+{
+ eab_contact_locate_match_full (
+ registry, NULL, contact, NULL, cb, closure);
+}
+
+/**
+ * e_contact_locate_match_full:
+ * @registry: an #ESourceRegistry
+ * @book: The book to look in. If this is NULL, use the default
+ * addressbook.
+ * @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 EABContactMatchQueryCallback.
+ **/
+void
+eab_contact_locate_match_full (ESourceRegistry *registry,
+ EBookClient *book_client,
+ EContact *contact,
+ GList *avoid,
+ EABContactMatchQueryCallback cb,
+ gpointer closure)
+{
+ MatchSearchInfo *info;
+ ESource *source;
+
+ g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+ g_return_if_fail (E_IS_CONTACT (contact));
+ g_return_if_fail (cb != NULL);
+
+ info = g_new0 (MatchSearchInfo, 1);
+ info->contact = g_object_ref (contact);
+ info->cb = cb;
+ info->closure = closure;
+ info->avoid = g_list_copy (avoid);
+ g_list_foreach (info->avoid, (GFunc) g_object_ref, NULL);
+
+ if (book_client) {
+ use_common_book_client (g_object_ref (book_client), info);
+ return;
+ }
+
+ source = e_source_registry_ref_default_address_book (registry);
+
+ e_book_client_connect (source, NULL, book_client_connect_cb, info);
+
+ g_object_unref (source);
+}
+
diff --git a/addressbook/gui/merging/eab-contact-compare.h b/addressbook/gui/merging/eab-contact-compare.h
new file mode 100644
index 0000000000..f6b05705cf
--- /dev/null
+++ b/addressbook/gui/merging/eab-contact-compare.h
@@ -0,0 +1,101 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Jon Trowbridge <trow@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+#ifndef __EAB_CONTACT_COMPARE_H__
+#define __EAB_CONTACT_COMPARE_H__
+
+#include <libebook/libebook.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_file_as (EContact *contact1,
+ EContact *contact2);
+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 (ESourceRegistry *registry,
+ EContact *contact,
+ EABContactMatchQueryCallback cb,
+ gpointer closure);
+void eab_contact_locate_match_full (ESourceRegistry *registry,
+ EBookClient *book_client,
+ EContact *contact,
+ GList *avoid,
+ EABContactMatchQueryCallback cb,
+ gpointer closure);
+
+#endif /* __E_CONTACT_COMPARE_H__ */
+
diff --git a/addressbook/gui/merging/eab-contact-duplicate-detected.ui b/addressbook/gui/merging/eab-contact-duplicate-detected.ui
new file mode 100644
index 0000000000..124b9c2787
--- /dev/null
+++ b/addressbook/gui/merging/eab-contact-duplicate-detected.ui
@@ -0,0 +1,219 @@
+<?xml version="1.0"?>
+<!--*- mode: xml -*-->
+<interface>
+ <object class="GtkDialog" id="dialog-duplicate-contact">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Duplicate Contact Detected</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="height-request">400</property>
+ <property name="width-request">500</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <object class="GtkButton" id="button4">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="button3">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="button5">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Merge</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+ <child>
+ <object class="GtkViewport" id="viewport1">
+ <child>
+ <object class="GtkTable" id="table1">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="n_rows">5</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="EABContactDisplay" type-func="eab_contact_display_get_type" id="custom-old-contact">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">The name or email address of this contact already exists
+in this folder. Would you like to add it anyway?</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Original Contact:</property>
+ <property name="use_underline">False</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">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">New Contact:</property>
+ <property name="use_underline">False</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">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="EABContactDisplay" type-func="eab_contact_display_get_type" id="custom-new-contact">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0</property>
+ <property name="xscale">1</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
+ <child>
+ <object class="GtkImage" id="custom2">
+ <property name="visible">True</property>
+ <property name="icon-name">avatar-default</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="1">button4</action-widget>
+ <action-widget response="0">button3</action-widget>
+ <action-widget response="2">button5</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/addressbook/gui/merging/eab-contact-merging.c b/addressbook/gui/merging/eab-contact-merging.c
new file mode 100644
index 0000000000..fb11e37629
--- /dev/null
+++ b/addressbook/gui/merging/eab-contact-merging.c
@@ -0,0 +1,795 @@
+/*
+ * Code for checking for duplicates when doing EContact work.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "eab-contact-merging.h"
+#include "eab-contact-compare.h"
+#include <gtk/gtk.h>
+#include <string.h>
+#include "addressbook/gui/widgets/eab-contact-display.h"
+#include "e-util/e-util.h"
+#include "e-util/e-util-private.h"
+#include <glib/gi18n.h>
+
+#include <camel/camel.h>
+
+typedef struct dropdown_data dropdown_data;
+typedef enum {
+ E_CONTACT_MERGING_ADD,
+ E_CONTACT_MERGING_COMMIT,
+ E_CONTACT_MERGING_FIND
+} EContactMergingOpType;
+
+typedef struct {
+ EContactMergingOpType op;
+ ESourceRegistry *registry;
+ EBookClient *book_client;
+ /*contact is the new contact which the user has tried to add to the addressbook*/
+ EContact *contact;
+ /*match is the duplicate contact already existing in the addressbook*/
+ EContact *match;
+ GList *avoid;
+ EABMergingAsyncCallback cb;
+ EABMergingIdAsyncCallback id_cb;
+ EABMergingContactAsyncCallback c_cb;
+ gpointer closure;
+} EContactMergingLookup;
+
+struct dropdown_data {
+ EContact *match;
+ EContactField field;
+
+ /* for E_CONTACT_EMAIL field */
+ GList *email_attr_list_item;
+ EVCardAttribute *email_attr;
+};
+static void match_query_callback (EContact *contact, EContact *match, EABContactMatchType type, gpointer closure);
+
+#define SIMULTANEOUS_MERGING_REQUESTS 20
+
+static GList *merging_queue = NULL;
+static gint running_merge_requests = 0;
+
+static void
+add_lookup (EContactMergingLookup *lookup)
+{
+ if (running_merge_requests < SIMULTANEOUS_MERGING_REQUESTS) {
+ running_merge_requests++;
+ eab_contact_locate_match_full (
+ lookup->registry, lookup->book_client,
+ lookup->contact, lookup->avoid,
+ match_query_callback, lookup);
+ }
+ else {
+ merging_queue = g_list_append (merging_queue, lookup);
+ }
+}
+
+static void
+finished_lookup (void)
+{
+ running_merge_requests--;
+
+ while (running_merge_requests < SIMULTANEOUS_MERGING_REQUESTS) {
+ EContactMergingLookup *lookup;
+
+ if (!merging_queue)
+ break;
+
+ lookup = merging_queue->data;
+
+ merging_queue = g_list_remove_link (merging_queue, merging_queue);
+
+ running_merge_requests++;
+ eab_contact_locate_match_full (
+ lookup->registry, lookup->book_client,
+ lookup->contact, lookup->avoid,
+ match_query_callback, lookup);
+ }
+}
+
+static void
+free_lookup (EContactMergingLookup *lookup)
+{
+ g_object_unref (lookup->registry);
+ g_object_unref (lookup->book_client);
+ g_object_unref (lookup->contact);
+ g_list_free (lookup->avoid);
+ if (lookup->match)
+ g_object_unref (lookup->match);
+ g_free (lookup);
+}
+
+static void
+final_id_cb (EBookClient *book_client,
+ const GError *error,
+ const gchar *id,
+ gpointer closure)
+{
+ EContactMergingLookup *lookup = closure;
+
+ if (lookup->id_cb)
+ lookup->id_cb (
+ lookup->book_client,
+ error, id, lookup->closure);
+
+ free_lookup (lookup);
+
+ finished_lookup ();
+}
+
+static void
+final_cb_as_id (EBookClient *book_client,
+ const GError *error,
+ gpointer closure)
+{
+ EContactMergingLookup *lookup = closure;
+
+ if (lookup->id_cb)
+ lookup->id_cb (
+ lookup->book_client,
+ error, lookup->contact ?
+ e_contact_get_const (
+ lookup->contact, E_CONTACT_UID) : NULL,
+ lookup->closure);
+
+ free_lookup (lookup);
+
+ finished_lookup ();
+}
+
+static void
+final_cb (EBookClient *book_client,
+ const GError *error,
+ gpointer closure)
+{
+ EContactMergingLookup *lookup = closure;
+
+ if (lookup->cb)
+ lookup->cb (lookup->book_client, error, lookup->closure);
+
+ free_lookup (lookup);
+
+ finished_lookup ();
+}
+
+static void
+modify_contact_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ EContactMergingLookup *lookup = user_data;
+ GError *error = NULL;
+
+ g_return_if_fail (book_client != NULL);
+ g_return_if_fail (lookup != NULL);
+
+ e_book_client_modify_contact_finish (book_client, result, &error);
+
+ if (lookup->op == E_CONTACT_MERGING_ADD)
+ final_cb_as_id (book_client, error, lookup);
+ else
+ final_cb (book_client, error, lookup);
+
+ if (error)
+ g_error_free (error);
+}
+
+static void
+add_contact_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ EContactMergingLookup *lookup = user_data;
+ gchar *uid = NULL;
+ GError *error = NULL;
+
+ g_return_if_fail (book_client != NULL);
+ g_return_if_fail (lookup != NULL);
+
+ if (!e_book_client_add_contact_finish (book_client, result, &uid, &error))
+ uid = NULL;
+
+ final_id_cb (book_client, error, uid, lookup);
+
+ if (error)
+ g_error_free (error);
+}
+
+static void
+doit (EContactMergingLookup *lookup,
+ gboolean force_modify)
+{
+ if (lookup->op == E_CONTACT_MERGING_ADD) {
+ if (force_modify)
+ e_book_client_modify_contact (lookup->book_client, lookup->contact, NULL, modify_contact_ready_cb, lookup);
+ else
+ e_book_client_add_contact (lookup->book_client, lookup->contact, NULL, add_contact_ready_cb, lookup);
+ } else if (lookup->op == E_CONTACT_MERGING_COMMIT)
+ e_book_client_modify_contact (lookup->book_client, lookup->contact, NULL, modify_contact_ready_cb, lookup);
+}
+
+static void
+cancelit (EContactMergingLookup *lookup)
+{
+ GError *error = e_client_error_create (E_CLIENT_ERROR_CANCELLED, NULL);
+
+ if (lookup->op == E_CONTACT_MERGING_ADD) {
+ final_id_cb (lookup->book_client, error, NULL, lookup);
+ } else if (lookup->op == E_CONTACT_MERGING_COMMIT) {
+ final_cb (lookup->book_client, error, lookup);
+ }
+
+ g_error_free (error);
+}
+
+static void
+dialog_map (GtkWidget *window,
+ GdkEvent *event,
+ GtkWidget *table)
+{
+ GtkAllocation allocation;
+ gint h, w;
+
+ gtk_widget_get_allocation (table, &allocation);
+
+ /* Spacing around the table */
+ w = allocation.width + 30;
+ /* buttons and outer spacing */
+ h = allocation.height + 60;
+ if (w > 400)
+ w = 400;
+ if (h > 450)
+ h = 450;
+
+ gtk_widget_set_size_request (window, w, h);
+}
+
+static void
+dropdown_changed (GtkWidget *dropdown,
+ dropdown_data *data)
+{
+ gchar *str = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (dropdown));
+
+ if (str && *str)
+ e_contact_set (data->match, data->field, str);
+ else
+ e_contact_set (data->match, data->field, NULL);
+
+ g_free (str);
+}
+
+static void
+email_dropdown_changed (GtkWidget *dropdown,
+ dropdown_data *data)
+{
+ gchar *str = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (dropdown));
+
+ if (str && *str)
+ data->email_attr_list_item->data = data->email_attr;
+ else
+ data->email_attr_list_item->data = NULL;
+
+ g_free (str);
+}
+
+static void
+remove_contact_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ EContactMergingLookup *lookup = user_data;
+ GError *error = NULL;
+
+ g_return_if_fail (book_client != NULL);
+ g_return_if_fail (lookup != NULL);
+
+ e_book_client_remove_contact_finish (book_client, result, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to remove contact: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ e_book_client_add_contact (
+ book_client, lookup->contact, NULL,
+ add_contact_ready_cb, lookup);
+}
+
+static gint
+mergeit (EContactMergingLookup *lookup)
+{
+ GtkWidget *scrolled_window, *label, *hbox, *dropdown;
+ GtkWidget *content_area;
+ GtkWidget *dialog;
+ GtkTable *table;
+ EContactField field;
+ gchar *string = NULL, *string1 = NULL;
+ GList *match_email_attr_list, *contact_email_attr_list, *miter, *citer, *use_email_attr_list;
+ GHashTable *match_emails; /* emails in the 'match' contact */
+ gint row = -1;
+ gint value = 0, result;
+
+ dialog = gtk_dialog_new ();
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Merge Contact"));
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ table = (GtkTable *) gtk_table_new (20, 2, FALSE);
+ gtk_container_set_border_width ((GtkContainer *) table, 12);
+ gtk_table_set_row_spacings (table, 6);
+ gtk_table_set_col_spacings (table, 2);
+
+ gtk_dialog_add_buttons (
+ GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ _("_Merge"), GTK_RESPONSE_OK,
+ NULL);
+
+ match_emails = g_hash_table_new_full (camel_strcase_hash, camel_strcase_equal, g_free, NULL);
+ match_email_attr_list = e_contact_get_attributes (lookup->match, E_CONTACT_EMAIL);
+ contact_email_attr_list = e_contact_get_attributes (lookup->contact, E_CONTACT_EMAIL);
+ use_email_attr_list = NULL;
+
+ for (miter = match_email_attr_list; miter; miter = g_list_next (miter)) {
+ EVCardAttribute *attr = miter->data;
+ gchar *email;
+
+ email = e_vcard_attribute_get_value (attr);
+ if (email && *email) {
+ g_hash_table_insert (match_emails, email, attr);
+ use_email_attr_list = g_list_prepend (use_email_attr_list, attr);
+ } else {
+ g_free (email);
+ }
+ }
+
+ use_email_attr_list = g_list_reverse (use_email_attr_list);
+
+ /*we match all the string fields of the already existing contact and the new contact.*/
+ for (field = E_CONTACT_FULL_NAME; field != (E_CONTACT_LAST_SIMPLE_STRING -1); field++) {
+ dropdown_data *data = NULL;
+ string = (gchar *) e_contact_get_const (lookup->contact, field);
+ string1 = (gchar *) e_contact_get_const (lookup->match, field);
+
+ /*the field must exist in the new as well as the duplicate contact*/
+ if (string && *string) {
+ if (field == E_CONTACT_EMAIL_1) {
+ for (citer = contact_email_attr_list; citer; citer = g_list_next (citer)) {
+ EVCardAttribute *attr = citer->data;
+ gchar *email;
+
+ email = e_vcard_attribute_get_value (attr);
+ if (email && *email) {
+ if (!g_hash_table_lookup (match_emails, email)) {
+ dropdown_data *data;
+
+ /* the email is not set in both contacts */
+ use_email_attr_list = g_list_append (use_email_attr_list, attr);
+
+ row++;
+ label = gtk_label_new (_("Email"));
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) label, FALSE, FALSE, 0);
+ gtk_table_attach_defaults (table, (GtkWidget *) hbox, 0, 1, row, row + 1);
+
+ dropdown = gtk_combo_box_text_new ();
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), email);
+
+ data = g_new0 (dropdown_data, 1);
+
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), "");
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (dropdown), 0);
+ data->field = E_CONTACT_EMAIL;
+ data->match = lookup->match;
+ data->email_attr_list_item = g_list_last (use_email_attr_list);
+ data->email_attr = attr;
+
+ g_signal_connect (
+ dropdown, "changed",
+ G_CALLBACK (email_dropdown_changed), data);
+ g_object_set_data_full (G_OBJECT (dropdown), "eab-contact-merging::dropdown-data", data, g_free);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) dropdown, FALSE, FALSE, 0);
+ gtk_table_attach_defaults (table, (GtkWidget *) hbox, 1, 2, row, row + 1);
+ gtk_widget_show ((GtkWidget *) dropdown);
+ }
+ }
+ g_free (email);
+ }
+ continue;
+ }
+
+ if (field == E_CONTACT_EMAIL_2 || field == E_CONTACT_EMAIL_3 || field == E_CONTACT_EMAIL_4) {
+ /* emails are compared above */
+ continue;
+ }
+
+ if (((field == E_CONTACT_FULL_NAME) && (!g_ascii_strcasecmp (string, string1)))) {
+ row++;
+ label = gtk_label_new (e_contact_pretty_name (field));
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) label, FALSE, FALSE, 0);
+ gtk_table_attach_defaults (table, (GtkWidget *) hbox, 0, 1, row, row + 1);
+
+ label = gtk_label_new (string);
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) label, FALSE, FALSE, 0);
+ gtk_table_attach_defaults (table, (GtkWidget *) hbox, 1, 2, row, row + 1);
+ continue;
+ }
+
+ /*for all string fields except name and email*/
+ if (!(string1 && *string1) || (g_ascii_strcasecmp (string, string1))) {
+ row++;
+ label = gtk_label_new (e_contact_pretty_name (field));
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) label, FALSE, FALSE, 0);
+ gtk_table_attach_defaults (table, (GtkWidget *) hbox, 0, 1, row, row + 1);
+ data = g_new0 (dropdown_data, 1);
+ dropdown = gtk_combo_box_text_new ();
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), string);
+ e_contact_set (lookup->match, field, string);
+
+ if (string1 && *string1)
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), string1);
+ else
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), "");
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (dropdown), 0);
+ data->field = field;
+ data->match = lookup->match;
+
+ if (field == E_CONTACT_NICKNAME || field == E_CONTACT_GIVEN_NAME)
+ gtk_widget_set_sensitive ((GtkWidget *) dropdown, FALSE);
+
+ g_signal_connect (
+ dropdown, "changed",
+ G_CALLBACK (dropdown_changed), data);
+ g_object_set_data_full (G_OBJECT (dropdown), "eab-contact-merging::dropdown-data", data, g_free);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) dropdown, FALSE, FALSE, 0);
+ gtk_table_attach_defaults (table, (GtkWidget *) hbox, 1, 2, row, row + 1);
+ gtk_widget_show_all ((GtkWidget *) dropdown);
+ }
+ }
+ }
+
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 420, 300);
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), GTK_WIDGET (table));
+ gtk_box_pack_start (GTK_BOX (content_area), GTK_WIDGET (scrolled_window), TRUE, TRUE, 0);
+ gtk_widget_show (scrolled_window);
+ g_signal_connect (
+ dialog, "map-event",
+ G_CALLBACK (dialog_map), table);
+ gtk_widget_show_all ((GtkWidget *) table);
+ result = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ switch (result) {
+ case GTK_RESPONSE_OK:
+ citer = NULL;
+ for (miter = use_email_attr_list; miter; miter = g_list_next (miter)) {
+ if (miter->data)
+ citer = g_list_prepend (citer, miter->data);
+ }
+ citer = g_list_reverse (citer);
+ e_contact_set_attributes (lookup->match, E_CONTACT_EMAIL, citer);
+ g_list_free (citer);
+
+ g_object_unref (lookup->contact);
+ lookup->contact = g_object_ref (lookup->match);
+ e_book_client_remove_contact (
+ lookup->book_client,
+ lookup->match, NULL,
+ remove_contact_ready_cb, lookup);
+ value = 1;
+ break;
+ case GTK_RESPONSE_CANCEL:
+ default:
+ value = 0;
+ break;
+ }
+ gtk_widget_destroy (dialog);
+ g_list_free_full (match_email_attr_list, (GDestroyNotify) e_vcard_attribute_free);
+ g_list_free_full (contact_email_attr_list, (GDestroyNotify) e_vcard_attribute_free);
+ g_list_free (use_email_attr_list);
+ g_hash_table_destroy (match_emails);
+
+ return value;
+}
+
+static gboolean
+check_if_same (EContact *contact,
+ EContact *match)
+{
+ EContactField field;
+ GList *email_attr_list;
+ gint num_of_email;
+ gchar *str = NULL, *string = NULL, *string1 = NULL;
+ gboolean res = TRUE;
+
+ email_attr_list = e_contact_get_attributes (match, E_CONTACT_EMAIL);
+ num_of_email = g_list_length (email_attr_list);
+
+ for (field = E_CONTACT_FULL_NAME; res && field != (E_CONTACT_LAST_SIMPLE_STRING -1); field++) {
+
+ if ((field == E_CONTACT_EMAIL_1 || field == E_CONTACT_EMAIL_2
+ || field == E_CONTACT_EMAIL_3 || field == E_CONTACT_EMAIL_4) && (num_of_email < 4)) {
+ str = (gchar *) e_contact_get_const (contact, field);
+ switch (num_of_email)
+ {
+ case 0:
+ res = FALSE;
+ break;
+ case 1:
+ if ((str && *str) && (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_1),str)))
+ res = FALSE;
+ break;
+ case 2:
+ if ((str && *str) && (g_ascii_strcasecmp (str,e_contact_get_const (match, E_CONTACT_EMAIL_1))) &&
+ (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_2),str)))
+ res = FALSE;
+ break;
+ case 3:
+ if ((str && *str) && (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_1),str)) &&
+ (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_2),str)) &&
+ (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_3),str)))
+ res = FALSE;
+ break;
+ }
+ }
+ else {
+ string = (gchar *) e_contact_get_const (contact, field);
+ string1 = (gchar *) e_contact_get_const (match, field);
+ if ((string && *string) && (string1 && *string1) && (g_ascii_strcasecmp (string1, string))) {
+ res = FALSE;
+ break;
+ /*if the field entry exist in either of the contacts,we'll have to give the choice and thus merge button should be sensitive*/
+ } else if ((string && *string) && !(string1 && *string1)) {
+ res = FALSE;
+ break;
+ }
+ }
+ }
+
+ g_list_free_full (email_attr_list, (GDestroyNotify) e_vcard_attribute_free);
+
+ return res;
+}
+
+static void
+response (GtkWidget *dialog,
+ gint response,
+ EContactMergingLookup *lookup)
+{
+ static gint merge_response;
+
+ switch (response) {
+ case 0:
+ doit (lookup, FALSE);
+ break;
+ case 1:
+ cancelit (lookup);
+ break;
+ case 2:
+ merge_response = mergeit (lookup);
+ if (merge_response)
+ break;
+ return;
+ case GTK_RESPONSE_DELETE_EVENT:
+ cancelit (lookup);
+ break;
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+match_query_callback (EContact *contact,
+ EContact *match,
+ EABContactMatchType type,
+ gpointer closure)
+{
+ EContactMergingLookup *lookup = closure;
+ gint flag;
+ gboolean same_uids;
+
+ if (lookup->op == E_CONTACT_MERGING_FIND) {
+ if (lookup->c_cb)
+ lookup->c_cb (
+ lookup->book_client, NULL,
+ (gint) type <= (gint)
+ EAB_CONTACT_MATCH_VAGUE ? NULL : match,
+ lookup->closure);
+
+ free_lookup (lookup);
+ finished_lookup ();
+ return;
+ }
+
+ /* if had same UID, then we are editing old contact, thus force commit change to it */
+ same_uids = contact && match
+ && e_contact_get_const (contact, E_CONTACT_UID)
+ && e_contact_get_const (match, E_CONTACT_UID)
+ && g_str_equal (e_contact_get_const (contact, E_CONTACT_UID), e_contact_get_const (match, E_CONTACT_UID));
+
+ if ((gint) type <= (gint) EAB_CONTACT_MATCH_VAGUE || same_uids) {
+ doit (lookup, same_uids);
+ } else {
+ GtkBuilder *builder;
+ GtkWidget *container;
+ GtkWidget *merge_button;
+ GtkWidget *widget;
+
+ builder = gtk_builder_new ();
+
+ lookup->match = g_object_ref (match);
+ if (lookup->op == E_CONTACT_MERGING_ADD) {
+ /* Compares all the values of contacts and return true, if they match */
+ flag = check_if_same (contact, match);
+ e_load_ui_builder_definition (
+ builder, "eab-contact-duplicate-detected.ui");
+ merge_button = e_builder_get_widget (builder, "button5");
+ /* Merge Button not sensitive when all values are same */
+ if (flag)
+ gtk_widget_set_sensitive (GTK_WIDGET (merge_button), FALSE);
+ } else if (lookup->op == E_CONTACT_MERGING_COMMIT) {
+ e_load_ui_builder_definition (
+ builder, "eab-contact-commit-duplicate-detected.ui");
+ } else {
+ doit (lookup, FALSE);
+ g_object_unref (builder);
+ return;
+ }
+
+ widget = e_builder_get_widget (builder, "custom-old-contact");
+ eab_contact_display_set_mode (
+ EAB_CONTACT_DISPLAY (widget),
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT);
+ eab_contact_display_set_contact (
+ EAB_CONTACT_DISPLAY (widget), match);
+
+ widget = e_builder_get_widget (builder, "custom-new-contact");
+ eab_contact_display_set_mode (
+ EAB_CONTACT_DISPLAY (widget),
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT);
+ eab_contact_display_set_contact (
+ EAB_CONTACT_DISPLAY (widget), contact);
+
+ widget = e_builder_get_widget (builder, "dialog-duplicate-contact");
+
+ gtk_widget_ensure_style (widget);
+
+ container = gtk_dialog_get_action_area (GTK_DIALOG (widget));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 12);
+
+ container = gtk_dialog_get_content_area (GTK_DIALOG (widget));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 0);
+
+ g_signal_connect (
+ widget, "response",
+ G_CALLBACK (response), lookup);
+
+ gtk_widget_show_all (widget);
+
+ g_object_unref (builder);
+ }
+}
+
+gboolean
+eab_merging_book_add_contact (ESourceRegistry *registry,
+ EBookClient *book_client,
+ EContact *contact,
+ EABMergingIdAsyncCallback cb,
+ gpointer closure)
+{
+ EContactMergingLookup *lookup;
+
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
+
+ lookup = g_new (EContactMergingLookup, 1);
+
+ lookup->op = E_CONTACT_MERGING_ADD;
+ lookup->registry = g_object_ref (registry);
+ lookup->book_client = g_object_ref (book_client);
+ lookup->contact = g_object_ref (contact);
+ lookup->id_cb = cb;
+ lookup->closure = closure;
+ lookup->avoid = NULL;
+ lookup->match = NULL;
+
+ add_lookup (lookup);
+
+ return TRUE;
+}
+
+gboolean
+eab_merging_book_modify_contact (ESourceRegistry *registry,
+ EBookClient *book_client,
+ EContact *contact,
+ EABMergingAsyncCallback cb,
+ gpointer closure)
+{
+ EContactMergingLookup *lookup;
+
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
+
+ lookup = g_new (EContactMergingLookup, 1);
+
+ lookup->op = E_CONTACT_MERGING_COMMIT;
+ lookup->registry = g_object_ref (registry);
+ lookup->book_client = g_object_ref (book_client);
+ lookup->contact = g_object_ref (contact);
+ lookup->cb = cb;
+ lookup->closure = closure;
+ lookup->avoid = g_list_append (NULL, contact);
+ lookup->match = NULL;
+
+ add_lookup (lookup);
+
+ return TRUE;
+}
+
+gboolean
+eab_merging_book_find_contact (ESourceRegistry *registry,
+ EBookClient *book_client,
+ EContact *contact,
+ EABMergingContactAsyncCallback cb,
+ gpointer closure)
+{
+ EContactMergingLookup *lookup;
+
+ lookup = g_new (EContactMergingLookup, 1);
+
+ lookup->op = E_CONTACT_MERGING_FIND;
+ lookup->registry = g_object_ref (registry);
+ lookup->book_client = g_object_ref (book_client);
+ lookup->contact = g_object_ref (contact);
+ lookup->c_cb = cb;
+ lookup->closure = closure;
+ lookup->avoid = g_list_append (NULL, contact);
+ lookup->match = NULL;
+
+ add_lookup (lookup);
+
+ return TRUE;
+}
diff --git a/addressbook/gui/merging/eab-contact-merging.h b/addressbook/gui/merging/eab-contact-merging.h
new file mode 100644
index 0000000000..fbdc9b0889
--- /dev/null
+++ b/addressbook/gui/merging/eab-contact-merging.h
@@ -0,0 +1,66 @@
+/*
+ * The Evolution addressbook client object.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __E_CONTACT_MERGING_H__
+#define __E_CONTACT_MERGING_H__
+
+#include <libebook/libebook.h>
+
+G_BEGIN_DECLS
+
+typedef void (*EABMergingAsyncCallback) (EBookClient *book_client,
+ const GError *error,
+ gpointer closure);
+typedef void (*EABMergingIdAsyncCallback) (EBookClient *book_client,
+ const GError *error,
+ const gchar *id,
+ gpointer closure);
+typedef void (*EABMergingContactAsyncCallback)
+ (EBookClient *book_client,
+ const GError *error,
+ EContact *contact,
+ gpointer closure);
+
+gboolean eab_merging_book_add_contact (ESourceRegistry *registry,
+ EBookClient *book_client,
+ EContact *contact,
+ EABMergingIdAsyncCallback cb,
+ gpointer closure);
+
+gboolean eab_merging_book_modify_contact (ESourceRegistry *registry,
+ EBookClient *book_client,
+ EContact *contact,
+ EABMergingAsyncCallback cb,
+ gpointer closure);
+
+gboolean eab_merging_book_find_contact (ESourceRegistry *registry,
+ EBookClient *book_client,
+ EContact *contact,
+ EABMergingContactAsyncCallback cb,
+ gpointer closure);
+
+G_END_DECLS
+
+#endif /* __EAB_CONTACT_MERGING_H__ */
diff --git a/addressbook/gui/search/.cvsignore b/addressbook/gui/search/.cvsignore
deleted file mode 100644
index d6c55c7345..0000000000
--- a/addressbook/gui/search/.cvsignore
+++ /dev/null
@@ -1,7 +0,0 @@
-.deps
-.libs
-.pure
-Makefile
-Makefile.in
-*.lo
-*.la
diff --git a/addressbook/gui/search/Makefile.am b/addressbook/gui/search/Makefile.am
deleted file mode 100644
index db4117c785..0000000000
--- a/addressbook/gui/search/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-ruledir = $(datadir)/evolution
-rule_DATA = addresstypes.xml
-
-EXTRA_DIST = addresstypes.xml
-
-INCLUDES = \
- -DG_LOG_DOMAIN=\"e-addressbook-search\" \
- -I$(top_srcdir) \
- -I$(top_srcdir)/addressbook/backend \
- -I$(top_builddir)/addressbook/backend \
- -I$(top_srcdir)/addressbook/contact-editor \
- -I$(top_srcdir)/widgets/e-text \
- -I$(top_srcdir)/widgets/misc \
- -I$(top_builddir)/shell \
- -DSEARCH_RULE_DIR=\"$(ruledir)\" \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
-
-noinst_LIBRARIES = \
- libeaddressbooksearch.a
-
-libeaddressbooksearch_a_SOURCES = \
- e-addressbook-search-dialog.c \
- e-addressbook-search-dialog.h
diff --git a/addressbook/gui/search/addresstypes.xml b/addressbook/gui/search/addresstypes.xml
deleted file mode 100644
index 4ee23af613..0000000000
--- a/addressbook/gui/search/addresstypes.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0"?>
-<filterdescription>
-<partset>
- <part name="name">
- <title>Name</title>
- <input type="optionlist" name="name-type">
- <option value="contains">
- <title>contains</title>
- <code>(contains "full_name" ${name})</code>
- </option>
- <option value="not contains">
- <title>does not contain</title>
- <code>(not (contains "full_name" ${name}))</code>
- </option>
- <option value="is">
- <title>is</title>
- <code>(is "full_name" ${name})))</code>
- </option>
- <option value="is not">
- <title>is not</title>
- <code>(not (is "full_name" ${name}))</code>
- </option>
- <option value="begin">
- <title>begins with</title>
- <code>(beginswith "full_name" ${name})</code>
- </option>
- <option value="end">
- <title>ends in</title>
- <code>(endswith "full_name" ${name})</code>
- </option>
- </input>
- <input type="string" name="name"/>
- </part>
- <part name="email">
- <title>Email</title>
- <input type="optionlist" name="email-type">
- <option value="contains">
- <title>contains</title>
- <code>(contains "email" ${email})</code>
- </option>
- <option value="not contains">
- <title>does not contain</title>
- <code>(not (contains "email" ${email}))</code>
- </option>
- <option value="is">
- <title>is</title>
- <code>(is "email" ${email})</code>
- </option>
- <option value="is not">
- <title>is not</title>
- <code>(not (is "email" ${email}))</code>
- </option>
- </input>
- <input type="address" name="email"/>
- </part>
- <part name="category">
- <title>Category</title>
- <input type="optionlist" name="category-type">
- <option value="contains">
- <title>contains</title>
- <code>(contains "category" ${category})</code>
- </option>
- <option value="not contains">
- <title>does not contain</title>
- <code>(not (contains "category" ${category}))</code>
- </option>
- <option value="is">
- <title>is</title>
- <code>(is "category" ${category})</code>
- </option>
- <option value="is not">
- <title>is not</title>
- <code>(not (is "category" ${category}))</code>
- </option>
- </input>
- <input type="string" name="category"/>
- </part>
- <part name="sexp">
- <title>Expression</title>
- <input type="code" name="code"/>
- </part>
-</partset>
-</filterdescription>
diff --git a/addressbook/gui/search/e-addressbook-search-dialog.c b/addressbook/gui/search/e-addressbook-search-dialog.c
deleted file mode 100644
index 2dbe9b1e7a..0000000000
--- a/addressbook/gui/search/e-addressbook-search-dialog.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-addressbook-search-dialog.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 <gtk/gtkbox.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtksignal.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-stock.h>
-
-#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_destroy (GtkObject *object);
-
-static GnomeDialog *parent_class = NULL;
-
-#define PARENT_TYPE (gnome_dialog_get_type())
-
-/* The arguments we take */
-enum {
- ARG_0,
- ARG_BOOK,
-};
-
-GtkType
-e_addressbook_search_dialog_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type)
- {
- static const GtkTypeInfo info =
- {
- "EAddressbookSearchDialog",
- sizeof (EAddressbookSearchDialog),
- sizeof (EAddressbookSearchDialogClass),
- (GtkClassInitFunc) e_addressbook_search_dialog_class_init,
- (GtkObjectInitFunc) e_addressbook_search_dialog_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
-
- return type;
-}
-
-static void
-e_addressbook_search_dialog_class_init (EAddressbookSearchDialogClass *klass)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass*) klass;
-
- parent_class = gtk_type_class (PARENT_TYPE);
-
- gtk_object_add_arg_type ("EAddressbookSearchDialog::book", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_BOOK);
-
- object_class->destroy = e_addressbook_search_dialog_destroy;
-}
-
-static GtkWidget *
-get_widget (EAddressbookSearchDialog *view)
-{
- FilterPart *part;
-
- view->context = rule_context_new();
- /* FIXME: hide this in a class */
- rule_context_add_part_set(view->context, "partset", filter_part_get_type(),
- rule_context_add_part, rule_context_next_part);
- rule_context_load(view->context, SEARCH_RULE_DIR "/addresstypes.xml", "");
- view->rule = filter_rule_new();
- part = rule_context_next_part(view->context, NULL);
- if (part == NULL) {
- g_warning("Problem loading search for addressbook no parts to load");
- return gtk_entry_new();
- } else {
- filter_rule_add_part(view->rule, filter_part_clone(part));
- return filter_rule_get_widget(view->rule, view->context);
- }
-}
-
-static char *
-get_query (EAddressbookSearchDialog *view)
-{
- GString *out = g_string_new("");
- char *ret;
-
- filter_rule_build_code(view->rule, out);
- ret = out->str;
- printf("Searching using %s\n", ret);
- g_string_free(out, FALSE);
- return ret;
-}
-
-static void
-button_press (GtkWidget *widget, int button, EAddressbookSearchDialog *dialog)
-{
- char *query;
-
- if (button == 0) {
- query = get_query(dialog);
- gtk_object_set(GTK_OBJECT(dialog->view),
- "query", query,
- NULL);
- g_free(query);
- }
-
- gnome_dialog_close(GNOME_DIALOG (dialog));
-}
-
-static void
-e_addressbook_search_dialog_init (EAddressbookSearchDialog *view)
-{
- GnomeDialog *dialog = GNOME_DIALOG (view);
-
- gtk_window_set_policy(GTK_WINDOW(view), FALSE, TRUE, FALSE);
- gtk_window_set_default_size (GTK_WINDOW (view), 550, 400);
- gtk_window_set_title(GTK_WINDOW(view), _("Advanced Search"));
- view->search = get_widget(view);
- gtk_box_pack_start(GTK_BOX(dialog->vbox), view->search, TRUE, TRUE, 0);
- gtk_widget_show(view->search);
-
- gnome_dialog_append_buttons(dialog,
- _("Search"),
- GNOME_STOCK_BUTTON_CLOSE, NULL);
-
- gnome_dialog_set_default(dialog, 0);
-
- gtk_signal_connect(GTK_OBJECT(dialog), "clicked",
- GTK_SIGNAL_FUNC(button_press), view);
-}
-
-GtkWidget *
-e_addressbook_search_dialog_new (EAddressbookView *addr_view)
-{
- EAddressbookSearchDialog *view = gtk_type_new (e_addressbook_search_dialog_get_type ());
- view->view = addr_view;
- return GTK_WIDGET(view);
-}
-
-static void
-e_addressbook_search_dialog_destroy (GtkObject *object)
-{
- EAddressbookSearchDialog *view;
-
- view = E_ADDRESSBOOK_SEARCH_DIALOG (object);
-
- gtk_object_unref((GtkObject *)view->context);
- gtk_object_unref((GtkObject *)view->rule);
-
- GTK_OBJECT_CLASS(parent_class)->destroy (object);
-}
diff --git a/addressbook/gui/search/e-addressbook-search-dialog.h b/addressbook/gui/search/e-addressbook-search-dialog.h
deleted file mode 100644
index a8c4067d29..0000000000
--- a/addressbook/gui/search/e-addressbook-search-dialog.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-minicard-view-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_ADDRESSBOOK_SEARCH_DIALOG_H__
-#define __E_ADDRESSBOOK_SEARCH_DIALOG_H__
-
-#include <ebook/e-book.h>
-
-#include "addressbook/gui/widgets/e-addressbook-view.h"
-#include "filter/rule-context.h"
-#include "filter/filter-rule.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#include <libgnomeui/gnome-dialog.h>
-
-#define E_ADDRESSBOOK_SEARCH_DIALOG_TYPE (e_addressbook_search_dialog_get_type ())
-#define E_ADDRESSBOOK_SEARCH_DIALOG(obj) (GTK_CHECK_CAST ((obj), E_ADDRESSBOOK_SEARCH_DIALOG_TYPE, EAddressbookSearchDialog))
-#define E_ADDRESSBOOK_SEARCH_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_ADDRESSBOOK_SEARCH_DIALOG_TYPE, EAddressbookSearchDialogClass))
-#define E_IS_ADDRESSBOOK_SEARCH_DIALOG(obj) (GTK_CHECK_TYPE ((obj), E_ADDRESSBOOK_SEARCH_DIALOG_TYPE))
-#define E_IS_ADDRESSBOOK_SEARCH_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_ADDRESSBOOK_SEARCH_DIALOG_TYPE))
-
-
-typedef struct _EAddressbookSearchDialog EAddressbookSearchDialog;
-typedef struct _EAddressbookSearchDialogClass EAddressbookSearchDialogClass;
-
-struct _EAddressbookSearchDialog
-{
- GnomeDialog parent;
-
- GtkWidget *search;
-
- EAddressbookView *view;
-
- RuleContext *context;
- FilterRule *rule;
-};
-
-struct _EAddressbookSearchDialogClass
-{
- GnomeDialogClass parent_class;
-};
-
-GtkType e_addressbook_search_dialog_get_type (void);
-
-GtkWidget *e_addressbook_search_dialog_new (EAddressbookView *view);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __E_ADDRESSBOOK_SEARCH_DIALOG_H__ */
diff --git a/addressbook/gui/widgets/.cvsignore b/addressbook/gui/widgets/.cvsignore
deleted file mode 100644
index 472fd2593f..0000000000
--- a/addressbook/gui/widgets/.cvsignore
+++ /dev/null
@@ -1,12 +0,0 @@
-.deps
-.libs
-.pure
-Makefile
-Makefile.in
-*.lo
-*.la
-minicard-label-test
-minicard-test
-minicard-view-test
-minicard-widget-test
-reflow-test
diff --git a/addressbook/gui/widgets/Makefile.am b/addressbook/gui/widgets/Makefile.am
index e262e18f5c..f9fea781a8 100644
--- a/addressbook/gui/widgets/Makefile.am
+++ b/addressbook/gui/widgets/Makefile.am
@@ -1,139 +1,92 @@
-INCLUDES = \
- -DG_LOG_DOMAIN=\"e-minicard\" \
- -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
+ruledir = $(privdatadir)
+rule_DATA = addresstypes.xml address_formats.dat countrytransl.map
+
+noinst_LTLIBRARIES = libeabwidgets.la
+
+libeabwidgets_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DG_LOG_DOMAIN=\"eab-widgets\" \
-DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
- -DEVOLUTION_DATADIR=\""$(datadir)"\" \
- -DEVOLUTION_IMAGESDIR=\""$(datadir)"/images/evolution\" \
+ -DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \
+ -DEVOLUTION_RULEDIR=\"$(ruledir)\" \
+ -DEVOLUTION_IMAGESDIR=\"${imagesdir}\" \
+ -DEVOLUTION_PRIVDATADIR=\"${privdatadir}\" \
-I$(top_srcdir) \
- -I$(top_srcdir)/addressbook/backend \
- -I$(top_builddir)/addressbook/backend \
- -I$(top_srcdir)/addressbook/gui/contact-editor \
+ -I$(top_srcdir)/addressbook \
-I$(top_srcdir)/addressbook/gui/merging \
- -I$(top_srcdir)/addressbook/gui/component \
- -I$(top_srcdir)/widgets/misc \
+ -I$(top_srcdir)/addressbook/util \
-I$(top_builddir)/shell \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS) \
+ $(CHAMPLAIN_CFLAGS) \
+ $(GEO_CFLAGS)
+
+eabincludedir = $(privincludedir)/addressbook/gui/widgets
-noinst_LIBRARIES = \
- libeminicard.a
+eabinclude_HEADERS = \
+ eab-config.h
-libeminicard_a_SOURCES = \
+libeabwidgets_la_SOURCES = \
+ eab-config.c \
+ eab-contact-display.c \
+ eab-contact-display.h \
+ eab-contact-formatter.c \
+ eab-contact-formatter.h \
+ eab-gui-util.c \
+ eab-gui-util.h \
+ e-contact-map.c \
+ e-contact-map.h \
+ e-contact-map-window.c \
+ e-contact-map-window.h \
+ e-contact-marker.c \
+ e-contact-marker.h \
+ 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-selector.c \
+ e-addressbook-selector.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
-
-#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)/e-util/libeutil.la \
-# $(top_builddir)/libversit/libversit.la \
-# $(top_builddir)/e-util/ename/libename.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.a \
-# $(top_builddir)/addressbook/gui/component/select-names/libeselectnames.la \
-# $(top_builddir)/e-util/libeutil.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)/e-util/libeutil.la \
-# $(top_builddir)/libversit/libversit.la \
-# $(top_builddir)/e-util/ename/libename.la \
-# $(top_builddir)/addressbook/contact-editor/libecontacteditor.a \
-# $(top_builddir)/addressbook/printing/libecontactprint.a \
-# $(top_builddir)/widgets/misc/libemiscwidgets.a \
-# $(top_builddir)/e-util/libeutil.la \
-# $(EVOLUTION_ADDRESSBOOK_LIBS)
+ gal-view-minicard.h \
+ ea-minicard.c \
+ ea-minicard.h \
+ ea-minicard-view.c \
+ ea-minicard-view.h \
+ ea-addressbook-view.c \
+ ea-addressbook-view.h \
+ ea-addressbook.c \
+ ea-addressbook.h
-#minicard_view_test_SOURCES = \
-# test-minicard-view.c
+libeabwidgets_la_LIBADD = \
+ $(top_builddir)/shell/libevolution-shell.la \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(top_builddir)/addressbook/util/libeabutil.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_LIBS) \
+ $(CHAMPLAIN_LIBS) \
+ $(GEO_LIBS)
-#minicard_view_test_LDADD = \
-# $(EVOLUTION_ADDRESSBOOK_LIBS)
-# libeminicard.a \
-# $(top_builddir)/addressbook/backend/ebook/libebook.la \
-# $(top_builddir)/e-util/libeutil.la \
-# $(top_builddir)/libversit/libversit.la \
-# $(top_builddir)/addressbook/ename/libename.la \
-# $(top_builddir)/addressbook/contact-editor/libecontacteditor.a \
-# $(top_builddir)/addressbook/printing/libecontactprint.a \
-# $(top_builddir)/widgets/misc/libemiscwidgets.a \
-# $(top_builddir)/e-util/libeutil.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)/e-util/libeutil.la \
-# $(top_builddir)/libversit/libversit.la \
-# $(top_builddir)/e-util/ename/libename.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.a \
-# $(top_builddir)/e-util/libeutil.la \
-# $(top_builddir)/addressbook/gui/merging/libecardmerging.a \
-# $(EVOLUTION_ADDRESSBOOK_LIBS)
+dist-hook:
+ cd $(distdir); rm -f $(BUILT_SOURCES)
-gladedir = $(datadir)/evolution/glade
-glade_DATA =
-
-etspecdir = $(datadir)/evolution/etspec
etspec_DATA= e-addressbook-view.etspec
EXTRA_DIST = \
- $(glade_DATA) \
- $(etspec_DATA)
- \ No newline at end of file
+ $(etspec_DATA) \
+ $(rule_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/gui/widgets/address_formats.dat b/addressbook/gui/widgets/address_formats.dat
new file mode 100644
index 0000000000..307831a94c
--- /dev/null
+++ b/addressbook/gui/widgets/address_formats.dat
@@ -0,0 +1,214 @@
+[at]
+AddressFormat=%0(%n\n)%0(%m\n)%0(Postfach %p\n)%0(%s\n)%0(%z)%w%l
+BusinessAddressFormat=%0(%m\n)%0(z.Hd. %n\n)%0(Postfach %p\n)%0(%s\n)%0(%z)%w%l
+CountryPosition=below
+
+[au]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(PO BOX %p\n)%0(%L%w%w%R%w%w)%z
+CountryPosition=BELOW
+
+[ax]
+AddressFormat=%0(%m\n)%0(%n\n)%0(PB %p\n)%0(%s\n)%z%w%L
+CountryPosition=BELOW
+
+[ca]
+AddressFormat=%0(%N\n)%0(%M\n)%0(%S\n)%0(PO BOX %p\n)%0(%L%w%R)%,%z
+CountryPosition=BELOW
+
+[ch]
+AddressFormat=%0(%m\n)%0(%n\n)%0(P.O. Box %p\n)%0(%s\n)%z%w%l
+CountryPosition=BELOW
+
+[ch_de]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Postfach %p\n)%0(%s\n)%z%w%l
+
+[ch_fr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Case postale %p\n)%0(%s\n)%z%w%l
+
+[ch_it]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Casella postale %p\n)%0(%s\n)%z%w%l
+
+[cz]
+AddressFormat=%0(%m\n)%0(%n\n)%0(p. p. %p\n)%0(%s\n)%z%w%w%l
+CountryPosition=below
+
+[de]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Postfach %p\n)%0(%s\n)%z%w%l
+CountryPosition=BELOW
+
+[de_nds]
+AddressFormat=%0(%n\n)%0(- %m -\n)%0(Postfach %p\n)%0(%s\n)%z%w%l
+
+[dk]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(Postboks %p\n)%z%w%l
+CountryPosition=below
+
+[fi]
+AddressFormat=%0(%m\n)%0(%n\n)%0(PB %p\n)%0(%s\n)%z%w%L
+CountryPosition=BELOW
+
+[fr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(BP %p\n)%z%w%L
+CountryPosition=BELOW
+
+[gl]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(Postboks %p\n)%z%w%l
+CountryPosition=below
+
+[hu]
+AddressFormat=%0(%n\n)%0(\n%l)%0(\n%s)%0(\nPF. %p)%0(\n%z)%0(\n%r)
+BusinessAddressFormat=%0(%n\n)%m\n%z%w%l%0(\n%s)%0(\nPF. %p)%0(\n%r)
+CountryPosition=below
+
+[il]
+AddressFormat=%0(%n\n)%0(%m\n)%0(ת.ד. %p\n)%0(%s\n)%0(%l%w%z)
+CountryPosition=BELOW
+
+[jp]
+AddressFormat=%0(%z%w%r)%w%l%0(\n%s)%0(\n%m)%0(\n%n)
+CountryPosition=ABOVE
+
+[kh]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(P.O. Box %p\n)%z%w%L%0(\n%r)
+CountryPosition=BELOW
+
+[me]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(poštanski fah %p\n)%z%w%l
+CountryPosition=BELOW
+
+[me_sr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(поштанÑки фах %p\n)%z%w%l
+
+[na]
+AddressFormat=%0(%m\n)%0(%n\n)%0(P.O. Box %p\n)%l
+
+[nl]
+AddressFormat=%n\n%0(%m\n)%0(Postbus %p\n)%0(%s\n)%z%w%l
+CountryPosition=below
+
+[no]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Postboks %p\n)%0(%s\n)%z%w%w%L
+CountryPosition=BELOW
+
+[rs]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(поштанÑки фах %p\n)%z%w%l
+CountryPosition=BELOW
+
+[rs_sr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(poštanski fah %p\n)%z%w%l
+
+[se]
+AddressFormat=%n\n%0(%m\n)%0(Box %p\n)%0(%s\n)%z%w%w%L
+CountryPosition=below
+
+[us]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(PO BOX %p\n)%0(%l%,%w%r)%w%z
+CountryPosition=BELOW
+
+[at]
+AddressFormat=%0(%n\n)%0(%m\n)%0(Postfach %p\n)%0(%s\n)%0(%z)%w%l
+BusinessAddressFormat=%0(%m\n)%0(z.Hd. %n\n)%0(Postfach %p\n)%0(%s\n)%0(%z)%w%l
+CountryPosition=below
+
+[au]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(PO BOX %p\n)%0(%L%w%w%R%w%w)%z
+CountryPosition=BELOW
+
+[ax]
+AddressFormat=%0(%m\n)%0(%n\n)%0(PB %p\n)%0(%s\n)%z%w%L
+CountryPosition=BELOW
+
+[ca]
+AddressFormat=%0(%N\n)%0(%M\n)%0(%S\n)%0(PO BOX %p\n)%0(%L%w%R)%,%z
+CountryPosition=BELOW
+
+[ch]
+AddressFormat=%0(%m\n)%0(%n\n)%0(P.O. Box %p\n)%0(%s\n)%z%w%l
+CountryPosition=BELOW
+
+[ch_de]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Postfach %p\n)%0(%s\n)%z%w%l
+
+[ch_fr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Case postale %p\n)%0(%s\n)%z%w%l
+
+[ch_it]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Casella postale %p\n)%0(%s\n)%z%w%l
+
+[cz]
+AddressFormat=%0(%m\n)%0(%n\n)%0(p. p. %p\n)%0(%s\n)%z%w%w%l
+CountryPosition=below
+
+[de]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Postfach %p\n)%0(%s\n)%z%w%l
+CountryPosition=BELOW
+
+[de_nds]
+AddressFormat=%0(%n\n)%0(- %m -\n)%0(Postfach %p\n)%0(%s\n)%z%w%l
+
+[dk]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(Postboks %p\n)%z%w%l
+CountryPosition=below
+
+[fi]
+AddressFormat=%0(%m\n)%0(%n\n)%0(PB %p\n)%0(%s\n)%z%w%L
+CountryPosition=BELOW
+
+[fr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(BP %p\n)%z%w%L
+CountryPosition=BELOW
+
+[gl]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(Postboks %p\n)%z%w%l
+CountryPosition=below
+
+[hu]
+AddressFormat=%0(%n\n)%0(\n%l)%0(\n%s)%0(\nPF. %p)%0(\n%z)%0(\n%r)
+BusinessAddressFormat=%0(%n\n)%m\n%z%w%l%0(\n%s)%0(\nPF. %p)%0(\n%r)
+CountryPosition=below
+
+[il]
+AddressFormat=%0(%n\n)%0(%m\n)%0(ת.ד. %p\n)%0(%s\n)%0(%l%w%z)
+CountryPosition=BELOW
+
+[jp]
+AddressFormat=%0(%z%w%r)%w%l%0(\n%s)%0(\n%m)%0(\n%n)
+CountryPosition=ABOVE
+
+[kh]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(P.O. Box %p\n)%z%w%L%0(\n%r)
+CountryPosition=BELOW
+
+[me]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(poštanski fah %p\n)%z%w%l
+CountryPosition=BELOW
+
+[me_sr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(поштанÑки фах %p\n)%z%w%l
+
+[na]
+AddressFormat=%0(%m\n)%0(%n\n)%0(P.O. Box %p\n)%l
+
+[nl]
+AddressFormat=%n\n%0(%m\n)%0(Postbus %p\n)%0(%s\n)%z%w%l
+CountryPosition=below
+
+[no]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Postboks %p\n)%0(%s\n)%z%w%w%L
+CountryPosition=BELOW
+
+[rs]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(поштанÑки фах %p\n)%z%w%l
+CountryPosition=BELOW
+
+[rs_sr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(poštanski fah %p\n)%z%w%l
+
+[se]
+AddressFormat=%n\n%0(%m\n)%0(Box %p\n)%0(%s\n)%z%w%w%L
+CountryPosition=below
+
+[us]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(PO BOX %p\n)%0(%l%,%w%r)%w%z
+CountryPosition=BELOW
+
diff --git a/addressbook/gui/widgets/addresstypes.xml b/addressbook/gui/widgets/addresstypes.xml
new file mode 100644
index 0000000000..cef8000cc4
--- /dev/null
+++ b/addressbook/gui/widgets/addresstypes.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0"?>
+<filterdescription>
+<partset>
+ <part name="name">
+ <title>Name</title>
+ <input type="optionlist" name="name-type">
+ <option value="contains">
+ <title>contains</title>
+ <code>(contains "full_name" ${name})</code>
+ </option>
+ <option value="not contains">
+ <title>does not contain</title>
+ <code>(not (contains "full_name" ${name}))</code>
+ </option>
+ <option value="is">
+ <title>is</title>
+ <code>(is "full_name" ${name})))</code>
+ </option>
+ <option value="is not">
+ <title>is not</title>
+ <code>(not (is "full_name" ${name}))</code>
+ </option>
+ <option value="begin">
+ <title>begins with</title>
+ <code>(beginswith "full_name" ${name})</code>
+ </option>
+ <option value="end">
+ <title>ends in</title>
+ <code>(endswith "full_name" ${name})</code>
+ </option>
+ </input>
+ <input type="string" name="name"/>
+ </part>
+ <part name="email">
+ <title>Email</title>
+ <input type="optionlist" name="email-type">
+ <option value="contains">
+ <title>contains</title>
+ <code>(contains "email" ${email})</code>
+ </option>
+ <option value="not contains">
+ <title>does not contain</title>
+ <code>(not (contains "email" ${email}))</code>
+ </option>
+ <option value="is">
+ <title>is</title>
+ <code>(is "email" ${email})</code>
+ </option>
+ <option value="is not">
+ <title>is not</title>
+ <code>(not (is "email" ${email}))</code>
+ </option>
+ </input>
+ <input type="address" name="email"/>
+ </part>
+ <part name="category">
+ <title>Category</title>
+ <input type="optionlist" name="category-type">
+ <option value="contains">
+ <title>contains</title>
+ <code>(contains "category_list" ${category})</code>
+ </option>
+ <option value="not contains">
+ <title>does not contain</title>
+ <code>(not (contains "category_list" ${category}))</code>
+ </option>
+ <option value="is">
+ <title>is</title>
+ <code>(is "category_list" ${category})</code>
+ </option>
+ <option value="is not">
+ <title>is not</title>
+ <code>(not (is "category_list" ${category}))</code>
+ </option>
+ </input>
+ <input type="optionlist" name="category">
+ <dynamic func="e_util_get_category_filter_options"/>
+ </input>
+ </part>
+ <part name="sexp">
+ <title>Expression</title>
+ <input type="rawcode" name="rawcode"/>
+ </part>
+</partset>
+
+ <ruleset>
+
+ <rule grouping="any" source="demand">
+ <_title>Name contains</_title>
+ <sources/>
+ </rule>
+
+ <rule grouping="any" source="demand">
+ <_title>Email begins with</_title>
+ <sources/>
+ </rule>
+
+ <rule grouping="any" source="demand">
+ <_title>Any field contains</_title>
+ <sources/>
+ </rule>
+
+ </ruleset>
+</filterdescription>
diff --git a/addressbook/gui/widgets/countrytransl.map b/addressbook/gui/widgets/countrytransl.map
new file mode 100644
index 0000000000..1f6757f72f
--- /dev/null
+++ b/addressbook/gui/widgets/countrytransl.map
@@ -0,0 +1,11370 @@
+Andorra ad
+Ðндора ad
+Ðндора ad
+Andora ad
+ອີນເດີຠad
+Andora ad
+Ðндорра ad
+安é“å°” ad
+United Arab Emirates ae
+Vereenigde Arabiese Emirate ae
+الإمارات العربية المتحدة ae
+Ð—Ð»ÑƒÑ‡Ð°Ð½Ñ‹Ñ ÐрабÑÐºÑ–Ñ Ð­Ð¼Ñ–Ñ€Ð°Ñ‚Ñ‹ ae
+Обединени ÐрабÑки ЕмирÑтва ae
+Ujedinjeni arapski emirati ae
+Emirats Àrabs Units ae
+Spojené arabské emiráty ae
+Forenende Arabiske Emirater ae
+Vereinigte Arabische Emirate ae
+Ενωμένα ΑÏαβικά ΕμιÏάτα ae
+Emiratos árabes unidos ae
+Araabia Ühendemiraadid ae
+Arabiar Emirato Batuak ae
+امارات متحده عربی ae
+Yhdistyneet Arabiemiraatit ae
+Émirats Arabes Unis ae
+×יחוד ×”×מירויות הערביות ae
+Ujedinjeni arapski emirati ae
+Egyesült Arab Emirátusok ae
+Emirati arabi uniti ae
+アラブ首長国連邦 ae
+ì•„ëž ì—미레ì´íЏ ì—°í•© ae
+ສະຫະລັດ ae
+Jungtiniai Arabų Emiratai ae
+Emirati Għarab Magħquda ae
+De forente arabiske emirater ae
+Verenigde Arabische Emiraten ae
+Dei sameinte arabiske emirata ae
+Di-Emirate tseo di Kopanego tsa Arab ae
+Zjednoczone Emiraty Arabskie ae
+Emiratos Ãrabes Unidos ae
+Emirados Ãrabes ae
+Emiratele Arabe Unite ae
+Объединенные ÐрабÑкие Эмираты ae
+Spojené arabské emiráty ae
+Združeni arabski Emirati ae
+Förenade arabemiraten ae
+³ì¸¢Â «ÃÒ ¿¡Î¸û ae
+BirleÅŸik Arap Emirlikleri ae
+Об'єднані ÐрабÑькі Емірати ae
+Mashango o tangananaho a Emirates ae
+阿拉伯è”åˆé…‹é•¿å›½ ae
+阿拉伯è¯åˆå¤§å…¬åœ‹ ae
+Izindawo zezinduna zase-United Arab ae
+Afghanistan af
+ÐфганіÑтан af
+ÐфганиÑтан af
+Afganistan af
+Afghanistán af
+Afganisztán af
+ລີທົ່ວເນີຠaf
+Afeganistão af
+Afganistan af
+Afganistan af
+Afganistan af
+ÐфганіÑтан af
+阿富汗 af
+Antigua and Barbuda ag
+Antigue en Barbuda ag
+أنتيغوا و باربودا ag
+Antigua vÉ™ Barbuda ag
+Ðнтыгуа Ñ– Барбуда ag
+Ðнтигуа и Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ ag
+Antigua ha Barbuda ag
+Antigua i Barbuda ag
+Antigua i Barbuda ag
+Antigua a Barbuda ag
+Antigua og Barbuda ag
+Antigua und Barbuda ag
+Antigua και Barbuda ag
+Antigvo kaj Barbudo ag
+Antigua y Barbuda ag
+Antigua ja Barbuda ag
+Antigua eta Barbuda ag
+آنتیگوا و باربودا ag
+Antigua ja Barbados ag
+Antigua og Barbuda ag
+Antigua et Barbuda ag
+Antiga e Barbuda ag
+×נטיגו××” וברבודה ag
+Antigua i Barbuda ag
+Antigua és Barbuda ag
+Antigua dan Barbuda ag
+Antigúa og Barbúda ag
+Antigua e Barbuda ag
+アンティグアãƒãƒ¼ãƒ–ーダ ag
+앤티가 바부다 ag
+Antikva ir Barbuda ag
+Antigva un Barbudas ag
+Antigwa u Barbuda ag
+Antigua og Barbuda ag
+Antigua en Barbuda ag
+Antigua og Barbuda ag
+Antigua le Barbuda ag
+Antigua e Barbuda ag
+Antigua i Barbuda ag
+Antigua e Barbuda ag
+Antigua e Barbuda ag
+Antigua ÅŸi Barbuda ag
+Ðнтигуа и Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ ag
+Antigua a Barbuda ag
+Antigva in Barbuda ag
+Antigua i Barbuda ag
+I-Antigua kanye ne Barbuda ag
+Antigua och Barbuda ag
+¬ýÊÌÅ¡ & À¡÷Ò¼¡ ag
+Antigua ve Barbuda ag
+Трінідад та Тобаго ag
+Antigua và Barbuda ag
+Antigua eyet Barbuda ag
+Antigua ne Barbuda ag
+安地瓜岛和巴布达岛 ag
+安地瓜島和巴布é”å³¶ ag
+Antigua kanye ne-Barbuda ag
+Anguilla ai
+Ðнгуила ai
+à»àºžàº™àº§àº´àº™ ai
+Angvila ai
+ÐÐ½Ð³Ñ–Ð»ÑŒÑ ai
+安圭拉 ai
+Albania al
+ÐÐ»ÑŒÐ±Ð°Ð½Ñ–Ñ al
+ÐÐ»Ð±Ð°Ð½Ð¸Ñ al
+Albanija al
+Albanien al
+Albánia al
+à»àº­àº”à»àº¥àº™àº•ິຠal
+Albânia al
+Albánsko al
+Albanija al
+Albanien al
+ÐÐ»Ð±Ð°Ð½Ñ–Ñ al
+阿尔巴尼亚 al
+Armenia am
+ÐрмÑÐ½Ñ–Ñ am
+ÐÑ€Ð¼ÐµÐ½Ð¸Ñ am
+Armenija am
+Armenien am
+Örményország am
+ອາເຈນຕິນາ am
+Armênia am
+Arménsko am
+Armenija am
+Armenien am
+ÐÑ€Ð¼ÐµÐ½Ñ–Ñ am
+亚美尼亚 am
+Netherlands Antilles an
+ХоландÑки Ðнтили an
+Nizozemski Antili an
+Nederlandske antiller an
+Antillas holandesas an
+Antilla Holandarrak an
+Holland-Antillák an
+ເນເທີà»àº¥àº™ an
+Antilhas an
+Holandské Antily an
+Nizozemski Antili an
+Nederländska Antillerna an
+ГолландÑькі Ðнтилли an
+è·å±žå®‰çš„列斯群岛 an
+Angola ao
+Ðнгола ao
+Ðнгола ao
+ບັນà»àºà»€àº¥àºµàº ao
+Ðнгола ao
+安哥拉 ao
+Argentina ar
+Argentinië ar
+الأرجنتين ar
+Ðргентына ar
+Ðржентина ar
+Arc'hantina ar
+Argentinien ar
+ΑÏγεντινή ar
+Argentino ar
+Argentiina ar
+آرژانتین ar
+Agentiina ar
+Argentine ar
+Arxentina ar
+×רגנטינה ar
+Argentína ar
+Argentína ar
+アルゼンãƒãƒ³ ar
+아르헨티나 ar
+ອາເຈນຕິນາ ar
+Argentīna ar
+Arġentina ar
+Argentinië ar
+Argentyna ar
+Ðргентина ar
+Argentína ar
+I-Argentina ar
+¬÷¦ºƒýÊÉ¡ ar
+อาร์เจนตินา ar
+Arjantin ar
+Ðргентина ar
+Agenthina ar
+Ã…rdjintene ar
+阿根廷 ar
+阿根廷 ar
+American Samoa as
+ÐмÑрыканÑкае Самоа as
+ÐмериканÑка Самоа as
+AmeriÄka Samoa as
+Samoa (USA) as
+Samoa americana as
+Amerikako Samoa as
+Amerikai Szamoa as
+ອາເມລິàºàº²à»€àº«àº™àº·àº­ as
+Samoa Americana as
+Americká Samoa as
+Ameriška Samoa as
+Amerikanska Samoa as
+ÐмериканÑьке Самоа as
+ç¾Žå±žè¨æ‘©äºšç¾¤å²› as
+Austria at
+Oostenryk at
+النمسا at
+Avstriya at
+ÐÑžÑÑ‚Ñ€Ñ‹Ñ at
+ÐвÑÑ‚Ñ€Ð¸Ñ at
+Aostria at
+Austrija at
+Àustria at
+Rakousko at
+Østrig at
+Österreich at
+ΑυστÏία at
+AÅ­strio at
+اتریش at
+Itävalta at
+Eysturríki at
+Autriche at
+×וסטריה at
+Austrija at
+Ausztria at
+Austurríki at
+オーストリア at
+오스트리아 at
+ອອດສະເຕເລີຠat
+Austrija at
+Austrija at
+Awtrija at
+Østerrike at
+Oostenrijk at
+Austerrike at
+Ãustria at
+Ãustria at
+ÐвÑÑ‚Ñ€Ð¸Ñ at
+Rakúsko at
+Avstrija at
+Austrija at
+I-Austria at
+Österrike at
+¬Ãò¾¢Ã¢Â¡ at
+ออสเตรีย at
+Avusturya at
+ÐвÑÑ‚Ñ€Ñ–Ñ at
+Ositiria at
+A'o at
+Ôtriche at
+奥地利 at
+奧地利 at
+Australia au
+Australië au
+أستراليا au
+Avustralya au
+ÐÑžÑÑ‚Ñ€Ð°Ð»Ñ–Ñ au
+ÐвÑÑ‚Ñ€Ð°Ð»Ð¸Ñ au
+Aostralia au
+Australija au
+Austràlia au
+Austrálie au
+Australien au
+Australien au
+ΑυστÏαλία au
+AÅ­stralio au
+Austraalia au
+استرالیا au
+Australie au
+×וסטרליה au
+Australija au
+Ausztrália au
+ÃÂstralía au
+オーストラリア au
+오스트레ì¼ë¦¬ì•„ au
+ອອດສະເຕເລີຠau
+Australija au
+AustrÄlija au
+Awstralja au
+Australië au
+Austrália au
+Austrália au
+ÐвÑÑ‚Ñ€Ð°Ð»Ð¸Ñ au
+Austrália au
+Avstralija au
+Australija au
+I-Australia au
+Australien au
+¬ŠÃò¾¢§ÃĢ¡ au
+ออสเตรเลีย au
+Avusturalya au
+ÐвÑÑ‚Ñ€Ð°Ð»Ñ–Ñ au
+Ositiralia au
+U'c au
+Ôstraleye au
+澳大利亚 au
+澳大利亞 au
+Aruba aw
+Ðруба aw
+ເàºàº¡à»„ັພ່ aw
+Ðруба aw
+阿é²å·´å²› aw
+Azerbaijan az
+أذربيجان az
+Azərbaycan az
+ÐзÑрбайджан az
+Ðзарбайджан az
+Azerbejdžan az
+Azerbaitjan az
+Ãzerbajdžánský az
+Azerbajdjan az
+Aserbaidschan az
+ΑζεÏμπαϊτζάν az
+AzerbajÄana az
+Azerbaiján az
+Aserbaidžaan az
+آذربایجان az
+Azerbaidzan az
+Aserbadsjan az
+×זרביג'ן az
+Azerbejdžan az
+Azerbajdzsán az
+Azerbaigian az
+アゼルãƒã‚¤ã‚¸ãƒ£ãƒ³ az
+아제르바ì´ìž” az
+ອາເຊີໄບຈັນ az
+Azerbaidžanas az
+AzerbaidžÄņu az
+Ażerbajġan az
+Aserbajdsjan az
+Azerbeidjan az
+Aserbajdsjan az
+Azerbejdżan az
+Azerbaijão az
+Turco az
+Azerbadjan az
+Ðзербайджан az
+Ãzerbajdžánsky az
+Azerbajdžan az
+Azerbejdžan az
+I-Azerbaijan az
+«º÷¨Àº¡ý az
+อาร์เซอร์ไบจัน az
+Azerice az
+Ðзербайджан az
+Azerbaydjan az
+阿塞拜疆 az
+亞塞拜然 az
+Bosnia and Herzegovina ba
+Bosnië en Herzegovina ba
+البوسنا و الهرسك ba
+БоÑÑŒÐ½Ñ–Ñ Ñ– Герцагавіна ba
+БоÑнена и Херцеговина ba
+Bosna i Hercegovina ba
+Bòsnia i Hercegovina ba
+Bosna a Herzegovina ba
+Bosnien-Herzegovina ba
+Bosnien und Herzegowina ba
+Βοσνία και ΕÏζεγοβίνη ba
+Bosnio kaj Hercegovino ba
+Bosnia y Herzegovina ba
+Bosnia ja Hertsegovina ba
+Bosnia eta Herzegovina ba
+بوسنی و هرزگوین ba
+Bosnia ja Herzegovina ba
+Bosnia-Herzegovina ba
+Bosnie herzégovine ba
+בוסניה הרצגובינה ba
+Bosna i Hercegovina ba
+Bosznia-Hercegovina ba
+Bosnia e Erzegovina ba
+ボスニアヘルツェゴビナ ba
+보스니아어와 헤르체고비나 ba
+ບອສເນີຠà»àº¥àº° ເຫີເຊີໂàºàº§àº´àº™àº² ba
+Bosnija ir Hercegovina ba
+Bosnija un Hercogovina ba
+Bożnia u Ħerżegovina ba
+Bosnia-Hercegovina ba
+Bosnië en Herzegovina ba
+Bosnia-Hercegovina ba
+Bosnia le Herzegovina ba
+Bośnia i Hercegowina ba
+Bósnia e Herzegovina ba
+Bósnia Herzegóvina ba
+Bosnia şi Herţegovina ba
+БоÑÐ½Ð¸Ñ Ð¸ Герцеговина ba
+Bosna a Hercegovina ba
+Bosna in Hercegovina ba
+I-Bosnia kanye ne Herzegovina ba
+Bosnien och Herzegovina ba
+¦À¡Ãɢ¡ ba
+บอสเนีย à¹à¸¥à¸° เฮอร์เซโà¸à¸§à¸´à¸™à¸² ba
+Bosna Hersek ba
+БоÑÐ½Ñ–Ñ Ñ‚Ð° Герцеговина ba
+Mubosinia na Muhezegovina ba
+Bosneye ba
+Bosnia ne Herzegovina ba
+波斯尼亚和黑塞哥维那 ba
+æ³¢å£«å°¼äºžèˆ‡èµ«å¡žå“¥ç¶­ç´ ba
+Bosnia kanye ne-Herzegovina ba
+Barbados bb
+بربادوس bb
+Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb
+Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb
+ΜπαÏμπάντος bb
+Babadoso bb
+باربادوس bb
+Barbade bb
+ברבדוס bb
+ãƒãƒ«ãƒãƒ‰ã‚¹ bb
+바르바ë„스 bb
+ບາລບາດອດສ bb
+Barbadosas bb
+Barbadosa bb
+Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb
+I-Barbados bb
+À¡÷§À¼¡à bb
+บาร์บาดอส bb
+Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb
+Barbades bb
+巴巴多斯 bb
+å·´è²å¤š bb
+Bangladesh bd
+بنغلاديش bd
+BanqladeÅŸ bd
+БанглÑдÑш bd
+Бангладеш bd
+Bangladeš bd
+Bangladéš bd
+Bangladesch bd
+Μπαγκλαντές bd
+BangladeÅo bd
+بنگلادش bd
+בנגלדש bd
+Bangladeš bd
+Banglades bd
+ãƒãƒ³ã‚°ãƒ©ãƒ‡ã‚·ãƒ¥ bd
+방글ë¼ë°ì‹œ bd
+ບັງຄະລາເທດ bd
+Bangladešas bd
+Bangladeša bd
+Bangladexx bd
+Bangladesz bd
+Banglade bd
+Бангладеш bd
+Bangladéš bd
+Bangladeš bd
+I-Bangladesh bd
+Àí¸Ç¡§¾à bd
+บังคลาเทศ bd
+BangladeÅŸ bd
+Бангладеш bd
+孟加拉 bd
+孟加拉 bd
+Belgium be
+België be
+بلجيكا be
+Belçika be
+БÑÐ»ÑŒÐ³Ñ–Ñ be
+Ð‘ÐµÐ»Ð³Ð¸Ñ be
+Belgia be
+Belgija be
+Bèlgica be
+Belgie be
+Belgien be
+Belgien be
+Βέλγιο be
+Belgio be
+Bélgica be
+Belgia be
+Belgika be
+بلژیک be
+Belgia be
+Belgia be
+Belgique be
+Bélxica be
+בלגיה be
+Belgija be
+Belgia be
+Belgía be
+Belgio be
+ベルギー be
+ë²¨ê¸°ì— be
+ເບລຢ່ງມ be
+Belgija be
+Beļģija be
+Belġju be
+Belgia be
+België be
+Belgia be
+Bèlgica be
+Belgia be
+Bélgica be
+Bélgica be
+Belgia be
+Ð‘ÐµÐ»ÑŒÐ³Ð¸Ñ be
+Belgicko be
+Belgija be
+Belgija be
+I-Belgium be
+Belgien be
+¦Àøº¢Âõ be
+เบลเยียม be
+Belçika be
+Ð‘ÐµÐ»ÑŒÐ³Ñ–Ñ be
+Beljike be
+比利时 be
+比利時 be
+Burkina Faso bf
+Буркіна ФаÑо bf
+Буркина ФаÑко bf
+ຕຸລະàºàºµ bf
+Буркіна ФаÑо bf
+布基纳法索 bf
+Bulgaria bg
+Bulgarye bg
+بلغاريا bg
+Bolgarıstan bg
+Ð‘Ð°ÑžÐ³Ð°Ñ€Ñ‹Ñ bg
+Ð‘ÑŠÐ»Ð³Ð°Ñ€Ð¸Ñ bg
+Bugarska bg
+Bulgària bg
+Bulharsko bg
+Bulgarien bg
+Bulgarien bg
+ΒουλγαÏία bg
+Bulgario bg
+Bulgaaria bg
+بلغارستان bg
+Bulgarie bg
+בולגריה bg
+Bugarska bg
+Bulgária bg
+Búlgaría bg
+ブルガリア bg
+불가리아 bg
+ບັນà»àºà»€àº¥àºµàº bg
+Bulgarija bg
+BulgÄrija bg
+Bulgarija bg
+Bulgarije bg
+Bułgaria bg
+Bulgária bg
+Bulgária bg
+Ð‘Ð¾Ð»Ð³Ð°Ñ€Ð¸Ñ bg
+Bulharsko bg
+Bolgarija bg
+Bugarska bg
+I-Bulgaria bg
+Bulgarien bg
+Àø§¸Ã¢Â¡ bg
+บัลà¹à¸à¹€à¸£à¸µà¸¢ bg
+Bulgaristan bg
+Ð‘Ð¾Ð»Ð³Ð°Ñ€Ñ–Ñ bg
+Baligaria bg
+Bulgåreye bg
+ä¿åŠ åˆ©äºš bg
+ä¿åŠ åˆ©äºž bg
+Bahrain bh
+البحرين bh
+БахрÑйн bh
+Бахрейн bh
+Bahrein bh
+Bahrajn bh
+ΜπαχÏέιν bh
+Bahrein bh
+Bahrein bh
+بحرین bh
+בחריין bh
+ãƒãƒ¼ãƒ¬ãƒ¼ãƒ³ bh
+ë°”ë ˆì¸ bh
+ຖັàºàºà»ˆàº‡àº§ bh
+Bahreinas bh
+Baħrain bh
+Baghrein bh
+Bahrajn bh
+Bahamas bh
+Bahrein bh
+Бахрейн bh
+Bahrajn bh
+Bahrajn bh
+I-Bahrain bh
+Bahrein bh
+À‹¨Ãý bh
+Bahreyn bh
+Бахрейн bh
+å·´æž— bh
+å·´æž— bh
+Burundi bi
+Бурундзі bi
+Бурунди bi
+ເຄອຣດ bi
+Бурунді bi
+布隆迪 bi
+Benin bj
+БÑнін bj
+Бенин bj
+ບອສເນີຠbj
+Бенін bj
+è´å® bj
+Bermuda bm
+БÑрмуды bm
+Бермуда bm
+ເàºàº¥àº¥àº°àº¡àº±àº™ bm
+Bermudy bm
+Bermudi bm
+Бермуди bm
+百慕大 bm
+Brunei Darussalam bn
+БрунÑй bn
+Бруней bn
+Brunei bn
+Brunei Szultánság bn
+ເບລາລັສເຊີຠbn
+Brunei bn
+Brunei Darusalam bn
+Бруней ДаруÑÑалам bn
+Bolivia bo
+Bolivië bo
+بوليÙيا bo
+Boliviya bo
+Ð‘Ð°Ð»Ñ–Ð²Ñ–Ñ bo
+Ð‘Ð¾Ð»Ð¸Ð²Ð¸Ñ bo
+Bolivija bo
+Bolívia bo
+Bolívie bo
+Bolivien bo
+Βολιβία bo
+Bolivio bo
+Boliivia bo
+بولیوی bo
+Bolivie bo
+בוליביה bo
+Bolivija bo
+Bolívia bo
+Bólivía bo
+ボリビア bo
+볼리비아 bo
+ໂບລີເວີຠbo
+Bolivija bo
+Bolīvija bo
+Bolivja bo
+Boliwia bo
+Bolívia bo
+Bolívia bo
+Ð‘Ð¾Ð»Ð¸Ð²Ð¸Ñ bo
+Bolívia bo
+Bolivija bo
+Bolivija bo
+I-Bolivia bo
+¦À¡Ä¢Å¢Â¡ bo
+โบลิเวีย bo
+Bolivya bo
+Ð‘Ð¾Ð»Ñ–Ð²Ñ–Ñ bo
+Boliveye bo
+波利维亚 bo
+玻利維亞 bo
+Brazil br
+Brazilië br
+البرازيل br
+Braziliya br
+Ð‘Ñ€Ð°Ð·Ñ‹Ð»Ñ–Ñ br
+Ð‘Ñ€Ð°Ð·Ð¸Ð»Ð¸Ñ br
+Brasil br
+Brazílie br
+Brasilien br
+Brasilien br
+Î’Ïαζιλία br
+Brazilo br
+Brasil br
+Brasiilia br
+Brasil br
+برزیل br
+Brasilia br
+Brésil br
+Brasil br
+ברזיל br
+Brazília br
+Brasilía br
+Brasile br
+ブラジル br
+브ë¼ì§ˆ br
+ບາຊີລ br
+Brazilija br
+Brazīlija br
+Brażil br
+Brasil br
+Brazilië br
+Brasil br
+Brasil br
+Brazylia br
+Brasil br
+Brasil br
+Brazilia br
+Ð‘Ñ€Ð°Ð·Ð¸Ð»Ð¸Ñ br
+Brazília br
+Brazilija br
+I-Brazil br
+Brasilien br
+À¢§Ãº¢ø br
+บราซิล br
+Brezilya br
+Ð‘Ñ€Ð°Ð·Ð¸Ð»Ñ–Ñ br
+Burazili br
+Braezi br
+巴西 br
+巴西 br
+Bahamas bs
+Багамы bs
+Бахами bs
+Bahami bs
+Bahamák bs
+ປານາມາ bs
+Bahamy bs
+Bahami bs
+Багами bs
+巴哈马 bs
+Bhutan bt
+Бутан bt
+Бутан bt
+Butan bt
+Bhután bt
+Bhután bt
+ຖັàºàºà»ˆàº‡àº§ bt
+Butan bt
+Бутан bt
+ä¸ä¸¹ bt
+Botswana bw
+БатÑвана bw
+Боцвана bw
+Bocvana bw
+ບອດສເນີຠbw
+Botsvana bw
+БотÑвана bw
+åšèŒ¨ç“¦çº³ bw
+Belarus by
+روسيا البيضاء by
+БеларуÑÑŒ by
+Ð‘ÐµÐ»Ð°Ñ€ÑƒÑ by
+Bjelorusija by
+Bělorusko by
+Hviderusland by
+Weißrussland by
+Bjelorusio by
+Valgevene by
+بلاروس by
+Valkovenäjä by
+Hvítarusland by
+Bélarus by
+בלרוס by
+Bjelorusija by
+Fehéroroszország by
+Hvíta-Rússland by
+Bielorussia by
+ベラルーシ by
+벨ë¼ë£¨ìФ by
+ເບລາລັສ by
+Baltarusija by
+Baltkrievu by
+Hviterussland by
+Wit-Rusland by
+Kviterussland by
+Białoruś by
+Bielorússia by
+Bielorusso by
+БеларуÑÑŒ by
+Bielorusko by
+Belorusija by
+I-Belarus by
+Vitryssland by
+¦ÀÄ¡åà by
+เบลารัส by
+БілоруÑÑ–Ñ by
+Belaruss by
+白俄罗斯 by
+白俄羅斯 by
+Belize bz
+БÑлізе bz
+Белиз bz
+ເບລàºà»ˆàº‡àº¡ bz
+Беліз bz
+伯利兹 bz
+Default C
+Verstek C
+Ø§ÙØªØ±Ø§Ø¶ÙŠ C
+Æsas C
+Па ўмаўчаньні C
+По подразбиране C
+Dre ziouer C
+Omissió C
+Výchozí C
+Standard C
+Standard C
+ΠÏοκαθοÏισμένο C
+Apriora C
+Predeterminado C
+Vaikimisi C
+Aurremugatua C
+Ù¾ÛŒØ´â€ŒÙØ±Ø¶ C
+Oletus C
+Forsettur C
+Par défaut C
+Por Omisión C
+ברירת מחדל C
+UobiÄajeno C
+Alapértelmezett C
+Standar C
+Sjálfgefið C
+Predefinito C
+標準 C
+기본 C
+ຄ່າປະລິàºàº²àº C
+Nutylima C
+Noklusētais C
+Normali C
+Standard C
+Standaard C
+Standard C
+Thuso ya Tshoganetso C
+Omission C
+Domyślnie C
+Por Omissão C
+Padrão C
+Implicit C
+По умолчанию C
+Štandardný C
+Privzeto C
+Predefinisano C
+Förval C
+¦¸¡¼¡¿¢¨Ä C
+ค่าปริยาย C
+Öntanımlı C
+Типовий C
+Mặc định C
+Prémetou C
+Okwendalo C
+默认 C
+é è¨­ C
+Okwendalo C
+Canada ca
+Kanada ca
+كندا ca
+Kanada ca
+Канада ca
+Канада ca
+Kanada ca
+Kanada ca
+Canadà ca
+Kanada ca
+Kanada ca
+Καναδάς ca
+Kanado ca
+Canadá ca
+Kanada ca
+Kanada ca
+کانادا ca
+Kanada ca
+Kanada ca
+Canadá ca
+קנדה ca
+Kanada ca
+Kanada ca
+Kanada ca
+Kanada ca
+カナダ ca
+ìºë‚˜ë‹¤ ca
+à»àº„ນາດາ ca
+Kanada ca
+KanÄda ca
+Kanada ca
+Kanada ca
+Canadá ca
+Canadá ca
+Канада ca
+Kanada ca
+Kanada ca
+Kanada ca
+I-Canada ca
+Kanada ca
+¸É¼¡ ca
+à¹à¸„นาดา ca
+Kanada ca
+Канада ca
+加拿大 ca
+加拿大 ca
+Cocos (Keeling) Islands cc
+КокоÑови ОÑтрови cc
+Kokosovo (Keeling) ostrvo cc
+Islas Cocos (Keeling) cc
+Koko Irlak cc
+Kókusz-szigetek (Keeling) cc
+Ilhas Cocos cc
+Kokosove Ostrovy cc
+Kokosovi (Keelingovi) otoki cc
+Kokosöarna cc
+КокоÑові оÑтрови cc
+Congo, the democratic republic of the cd
+ДÑÐ¼Ð°ÐºÑ€Ð°Ñ‚Ñ‹Ñ‡Ð½Ð°Ñ Ð ÑÑпубліка Конга cd
+Конго cd
+Kongo, demokratska republika cd
+Congo, den demokratiske republik cd
+Congo, república democrática del cd
+Kongo, errepublika demokratikoa cd
+Kongói Demokratikus Köztársaság cd
+República Democrática do Congo cd
+Demokratická Republika Kongo cd
+Kongo, demokratiÄna republika cd
+Demokratiska republiken Kongo cd
+刚果民主共和国 cd
+Central African Republic cf
+ЦÐР cf
+CentralnoafriÄka Republika cf
+Central-afrikanske Republik cf
+República Centroafricana cf
+Afrika Erdiko Errepublika cf
+Közép-Afrikai Köztársaság cf
+ໂດມິນິàºàº±àº™ cf
+República da Ãfrica Central cf
+Stredoafrická Republika cf
+Centralnoafriška republika cf
+Centralafrikanska Republiken cf
+ЦентральноафриканÑька реÑпубліка cf
+中éžå…±å’Œå›½ cf
+Congo cg
+Конга cg
+Конго cg
+Kongo cg
+Kongo cg
+Kongó cg
+ຄອນໂà»àºŠàº¥ cg
+Kongo cg
+Kongo cg
+Kongo cg
+Конго cg
+刚果 cg
+Switzerland ch
+Switserland ch
+سويسرا ch
+İsveçrə ch
+ШвÑÐ¹Ñ†Ð°Ñ€Ñ‹Ñ ch
+Ð¨Ð²ÐµÐ¹Ñ†Ð°Ñ€Ð¸Ñ ch
+Suis ch
+Å vicarska ch
+Suïssa ch
+Švýcarsko ch
+Schweiz ch
+Schweiz ch
+Ελβετία ch
+Svislando ch
+Suiza ch
+Å veits ch
+Suitza ch
+سوییس ch
+Sveitsi ch
+Suisse ch
+Suíza ch
+שוייץ ch
+Å vicarska ch
+Svájc ch
+Swiss ch
+Sviss ch
+Svizzera ch
+スイス ch
+스위스 ch
+ສະວິສເຊີà»àº¥àº™ ch
+Å veicarija ch
+Å veice ch
+Svizzera ch
+Sveits ch
+Zwitserland ch
+Sveits ch
+Suissa ch
+Szwajcaria ch
+Suíça ch
+Suíça ch
+Elveţia ch
+Ð¨Ð²ÐµÐ¹Ñ†Ð°Ñ€Ð¸Ñ ch
+Å vajÄiarsko ch
+Å vica ch
+Å vajcarska ch
+I-Switzerland ch
+Schweiz ch
+ÃÅ¢ðº÷Ä¡óà ch
+สวิสเซอร์à¹à¸¥à¸™à¸”์ ch
+İsviçre ch
+Ð¨Ð²ÐµÐ¹Ñ†Ð°Ñ€Ñ–Ñ ch
+Thuỵ Sĩ ch
+Swisse ch
+瑞士 ch
+瑞士 ch
+Cote d'ivoire ci
+Бераг Слановай КоÑьці ci
+Кот'Дивоар ci
+Obala SlonovaÄe ci
+Elfenbenskysten ci
+Costa de Marfil ci
+Elefántcsontpart ci
+ປ່ອàºàº«àº¡àº²àºàºàº°àº¥àº­àº ci
+SlonokoÅ¡Äena obala ci
+Elfenbenskusten ci
+Кот д'Івуар ci
+Cook islands ck
+Kukova ostrva ck
+Cook-øerne ck
+Islas Cook ck
+Cook Irlak ck
+Cook-szigetek ck
+ຄຸàºàºàºµà»‰ ck
+Ilhas Cook ck
+Cookove ostrovy ck
+Cookovi otoki ck
+Cooköarna ck
+ОÑтрови Кука ck
+库克群岛 ck
+Chile cl
+Chilië cl
+تشيلي cl
+Åžili cl
+Чылі cl
+Чили cl
+ÄŒile cl
+Xile cl
+Χιλή cl
+Ĉilio cl
+Tšiili cl
+Txile cl
+شیلی cl
+Chili cl
+צ'ילה cl
+ÄŒile cl
+Chili cl
+Cile cl
+ãƒãƒª cl
+ì¹ ë ˆ cl
+ຊີລີ cl
+ÄŒilÄ— cl
+Čīle cl
+ÄŠile cl
+Chili cl
+Cile cl
+Чили cl
+ÄŒile cl
+ÄŒile cl
+ÄŒile cl
+I-Chile cl
+º¢Ä¢ cl
+ชิลี cl
+Åžili cl
+Чилі cl
+Chi lê cl
+Tchili cl
+智利 cl
+智利 cl
+Cameroon cm
+КамÑрун cm
+Камерун cm
+Kamerun cm
+Cameroun cm
+Camerún cm
+Kamerun cm
+Kamerun cm
+ຕາລາງງານ - K cm
+Camarões cm
+Komerun cm
+Kamerun cm
+Kamerun cm
+Камерун cm
+喀麦隆 cm
+China cn
+Sjina cn
+الصين cn
+Çin cn
+Кітай cn
+Китай cn
+Sina cn
+Kina cn
+Xina cn
+Čína cn
+Kina cn
+Κίνα cn
+Ĉinujo cn
+Hiina cn
+Txina cn
+چین cn
+Kiina cn
+Kina cn
+Chine cn
+סין cn
+Kina cn
+Kína cn
+Cina cn
+Kína cn
+Cina cn
+中国 cn
+중국 cn
+ຈີນ cn
+Kinija cn
+Ķīna cn
+ÄŠina cn
+Kina cn
+Kina cn
+Xina cn
+Chiny cn
+Китай cn
+Čína cn
+Kitajska cn
+Kina cn
+I-China cn
+Kina cn
+º£É¡ cn
+จีน cn
+Çin cn
+Китай cn
+Trung Quốc cn
+Chine cn
+中国 cn
+中國 cn
+Colombia co
+Colombië co
+كولمبيا co
+ÐšÐ°Ð»ÑŽÐ¼Ð±Ñ–Ñ co
+ÐšÐ¾Ð»ÑƒÐ¼Ð±Ð¸Ñ co
+Kolumbija co
+Colòmbia co
+Kolumbie co
+Kolumbien co
+Κολομβία co
+Kolumbio co
+Kolumbia co
+Kolonbia co
+کلمبیا co
+Kolumbia co
+Colombie co
+קולומביה co
+Kolumbija co
+Kolumbia co
+コロンビア co
+콜롬비아 co
+ໂຄລຳເບີຠco
+Kolumbija co
+Kolumbija co
+Kolumbja co
+Columbia co
+Kolumbia co
+Colômbia co
+Colômbia co
+Columbia co
+ÐšÐ¾Ð»ÑƒÐ¼Ð±Ð¸Ñ co
+Kolumbia co
+Kolumbija co
+I-Colombia co
+¦¸¡ÄõÀ¢Â¡ co
+โคลัมเบีย co
+Kolombiya co
+ÐšÐ¾Ð»ÑƒÐ¼Ð±Ñ–Ñ co
+Colombeye co
+Columbia co
+哥伦比亚 co
+哥倫比亞 co
+Costa Rica cr
+كوستاريكا cr
+КоÑта Рыка cr
+КоÑта Рика cr
+Kostarika cr
+Kostarika cr
+Κόστα Ρίκα cr
+کاستاریکا cr
+Kosta Rika cr
+קוסטה ריקה cr
+Costa rica cr
+コスタリカ cr
+코스타 리카 cr
+ໂຄເອເທີຠcr
+Kosta Rika cr
+Kostaryka cr
+КоÑта-Рика cr
+Kostarika cr
+Kostarika cr
+I-Costa Rica cr
+§¸¡Š¼¡ ⸡ cr
+Kosta Rika cr
+КоÑта-Ріка cr
+哥斯达黎加 cr
+哥斯大黎加 cr
+Cuba cu
+Kuba cu
+كوبا cu
+Куба cu
+Куба cu
+Kuba cu
+Kuba cu
+Kuba cu
+ΚοÏβα cu
+Kuuba cu
+Kuba cu
+کوبا cu
+Kuuba cu
+Kuba cu
+קובה cu
+Kuba cu
+キュームcu
+ì¿ ë°” cu
+ເàºàº¡à»„ພ່ cu
+Kuba cu
+Kuba cu
+Kuba cu
+Куба cu
+Kuba cu
+Kuba cu
+I-Cuba cu
+Kuba cu
+¸¢ÔÀ¡ cu
+Küba cu
+Куба cu
+å¤å·´ cu
+å¤å·´ cu
+Cape Verde cv
+Капе Верде cv
+Zelenortska ostrva cv
+Kapverdiske øer cv
+Cabo Verde cv
+Cabo Verde cv
+Zöldfoki-szigetek cv
+ເàºàº¡à»„ພ່ cv
+Cabo Verde cv
+Kap Verde cv
+佛得角 cv
+Christmas Island cx
+BožiÄno ostrvo cx
+Juleøen cx
+Islas Christmas cx
+Eguberri Irla cx
+Karácsony-szigetek cx
+ຄິດສະຕອລ cx
+Ilhas do Natal cx
+VianoÄné Ostrovy cx
+BožiÄni otok cx
+Julön cx
+ОÑтрів Різдва cx
+圣诞岛 cx
+Cyprus cy
+Кіпр cy
+Кипър cy
+Kipar cy
+Cypern cy
+Chipre cy
+Txipre cy
+Ciprus cy
+ບີບອັດ cy
+Chipre cy
+Ciper cy
+Cypern cy
+Кипр cy
+塞浦路斯 cy
+Czechia cz
+Czechië cz
+التشيك cz
+Çex Respublikası cz
+ЧÑÑ…Ñ–Ñ cz
+Ð§ÐµÑ…Ð¸Ñ cz
+Tchekia cz
+Češka cz
+Txèquia cz
+ÄŒesko cz
+Tjekkiet cz
+Tschechien cz
+Τσεχία cz
+Ĉeĥio cz
+República Checa cz
+Tšehhi cz
+Txekia cz
+Ú†Ú© cz
+Tsekki cz
+République tchèque cz
+Chequia cz
+צ'כיה cz
+Češka cz
+Csehország cz
+Tékkland cz
+Repubblica Ceca cz
+ãƒã‚§ã‚³ cz
+ì²´ì½” cz
+ÄŒekija cz
+ÄŒehija cz
+Cżekia cz
+Tsjekkia cz
+Tsjechië cz
+Tsjekkia cz
+Chèquia cz
+Czechy cz
+República Checa cz
+República Tcheca cz
+Cehia cz
+Ð§ÐµÑ…Ð¸Ñ cz
+ÄŒesko cz
+Češka cz
+Češka cz
+I-Czechia cz
+Tjeckien cz
+¦ºì¡ cz
+Çek Cumhuriyeti cz
+Ð§ÐµÑ…Ñ–Ñ cz
+Séc cz
+Tchekeye cz
+æ·å…‹ cz
+æ·å…‹ cz
+Germany de
+Duitsland de
+ألمانيا de
+Almaniya de
+ÐÑмеччына de
+Ð“ÐµÑ€Ð¼Ð°Ð½Ð¸Ñ de
+Alamagn de
+NjemaÄka de
+Alemanya de
+Německo de
+Tyskland de
+Deutschland de
+ΓεÏμανία de
+Germanio de
+Alemania de
+Saksamaa de
+Alemania de
+ آلمان de
+Saksa de
+Týskland de
+Allemagne de
+Alemaña de
+גרמניה de
+NjemaÄka de
+Németország de
+Jerman de
+Þýskaland de
+Germania de
+ドイツ de
+ë…ì¼ de
+ເàºàº¥àº¥àº°àº¡àº±àº™àº™àºµ de
+Vokietija de
+VÄcija de
+Ä ermanja de
+Tyskland de
+Duitsland de
+Tyskland de
+Alemanya de
+Niemcy de
+Alemanha de
+Alemanha de
+Germania de
+Ð“ÐµÑ€Ð¼Ð°Ð½Ð¸Ñ de
+Nemecko de
+NemÄija de
+NemaÄka de
+I-Germany de
+Tyskland de
+§º÷ÃÉ¢ de
+เยอรมันนี de
+Almanya de
+Ðімеччина de
+Äức de
+Almagne de
+德国 de
+德國 de
+IJalimani de
+Djibouti dj
+جيبوتي dj
+Джыбуці dj
+Джибути dj
+Äibuti dj
+Džibuti dj
+Dschibuti dj
+Τζιμπουτί dj
+جیبوتی dj
+ג'יבוטי dj
+Džibuti dj
+Dzsibuti dj
+ジブティ dj
+지부티 dj
+ພັດພາ dj
+Džibuti dj
+Dġibuti dj
+Dżibuti dj
+Djibuti dj
+Djibuti dj
+Джибути dj
+Džibuty dj
+Džibuti dj
+I-Djibouti dj
+Ê¢ƒ¢¦À¡Ê dj
+Cibuti dj
+Джібуті dj
+å‰å¸ƒæ dj
+å‰å¸ƒåœ° dj
+Denmark dk
+Denemarke dk
+الدنمارك dk
+Danimarka dk
+Ð”Ð°Ð½Ñ–Ñ dk
+Ð”Ð°Ð½Ð¸Ñ dk
+Danmark dk
+Danska dk
+Dinamarca dk
+Dánsko dk
+Danmark dk
+Dänemark dk
+Δανία dk
+Danlando dk
+Dinamarca dk
+Taani dk
+Danimarka dk
+دانمارک dk
+Tanska dk
+Danmark dk
+Danemark dk
+Dinamarca dk
+דנמרק dk
+Danska dk
+Dánia dk
+Danmörk dk
+Danimarca dk
+デンマーク dk
+ë´ë§ˆí¬ dk
+ເດນມາຠdk
+Danija dk
+DÄnija dk
+Danimarka dk
+Danmark dk
+Denemarken dk
+Danmark dk
+Dinamarca dk
+Dania dk
+Dinamarca dk
+Dinamarca dk
+Danemarca dk
+Ð”Ð°Ð½Ð¸Ñ dk
+Dánsko dk
+Danska dk
+Danska dk
+I-Denmark dk
+Danmark dk
+¦¼ýá÷ì dk
+เดนมาร์ภdk
+Danimarka dk
+Ð”Ð°Ð½Ñ–Ñ dk
+Äan Mạch dk
+Daenmåtche dk
+丹麦 dk
+丹麥 dk
+Dominica dm
+Дамініка dm
+Доминика dm
+Dominika dm
+Dominika dm
+ໂລມາເນີຠdm
+Dominicana dm
+Dominikánsko dm
+Dominikanska republika dm
+Домініка dm
+多米尼加 dm
+Dominican Republic do
+Dominikiese Republiek do
+جمهورية الدومينيكان do
+Dominik Respublikası do
+ДамініканÑÐºÐ°Ñ Ð ÑÑпубліка do
+ДоминиканÑка република do
+Republik Dominikan do
+Dominikanska Republika do
+República Dominicana do
+Dominikánská republika do
+Dominikanske Republik do
+Dominikanische Republik do
+Δομινικανή ΔημοκÏατία do
+Dominika Respubliko do
+República Dominicana do
+Dominikaani Vabariik do
+Dominikar Errepublika do
+جمهوری دامینیکن do
+Dominikaaninen tasavalta do
+République dominicaine do
+República Dominicana do
+הרפובליקה הדומיניקנית do
+Dominikanska Republika do
+Dominikai Köztársaság do
+Republik Dominika do
+Dóminíska Lýðveldið do
+Repubblica Dominicana do
+ドミニカ共和国 do
+ë„미니카 공화국 do
+ໂດມິນີàºàº±àº™ do
+Dominikos Respublika do
+Dominikas Republika do
+Repubblika Dominikana do
+Den dominikanske republikk do
+Dominicaanse Republiek do
+Den dominikanske republikken do
+Republica Dominicana do
+Dominikana do
+República Dominicana do
+República Dominicana do
+Republica Dominicană do
+ДоминиканÑÐºÐ°Ñ Ñ€ÐµÑпублика do
+Dominikánska republika do
+Dominikanska republika do
+Dominikanska republika do
+I-Dominican Republic do
+Dominikanska republiken do
+¦¼¡Ã¢É¢ì¸ý ÌÊÂÃà do
+โดมินิà¸à¸±à¸™ do
+Dominik Cumhuriyeti do
+ДомініканÑька реÑпубліка do
+Muvhuso wa Dominican do
+Cộng hoà Dominican do
+Republike Dominikinne do
+IRepublic yeDominican do
+多米尼加共和国 do
+多明尼加共和國 do
+Algeria dz
+Algerië dz
+الجزائر dz
+Ðльжыр dz
+Ðлжир dz
+Alžir dz
+Algèria dz
+Alžírsko dz
+Algeriet dz
+Algerien dz
+ΑλγεÏία dz
+Algerio dz
+Argelia dz
+Alžeeria dz
+ الجزیره dz
+Algérie dz
+×לג'יריה dz
+Alžir dz
+Algéria dz
+アルジェリア dz
+알제리 dz
+ບັນàºàº²à»€àº¥àºµàº dz
+Alžyras dz
+Alġerija dz
+Algerie dz
+Algerije dz
+Algerie dz
+Algieria dz
+Argélia dz
+Argélia dz
+Ðлжир dz
+Alžírsko dz
+Alžirija dz
+I-Algeria dz
+Algeriet dz
+«øƒ¢Ã¢Â¡ dz
+Ðлжир dz
+Aldjereye dz
+阿尔åŠåˆ©äºš dz
+阿爾åŠåˆ©äºž dz
+Equador ec
+Ewenaar ec
+الإكوادور ec
+Ekvator ec
+Эквадор ec
+Еквадор ec
+Ecuador ec
+Ekvador ec
+Ekvádor ec
+Ecuador ec
+ΙσημεÏινός ec
+Ekvadoro ec
+Ecuador ec
+Ekvador ec
+Ekuador ec
+اکوادور ec
+Équateur ec
+Ecuador ec
+×קוודור ec
+Ekvador ec
+Ecuador ec
+Ekvador ec
+Ecuador ec
+エクアドル ec
+ì—ì½°ë„르 ec
+ເອàºà»àº”à» ec
+Ekvadoras ec
+Ekvadora ec
+Ekwador ec
+Ecuador ec
+Ecuador ec
+Ekwador ec
+Ecuador ec
+Эквадор ec
+Ekvádor ec
+Ekvador ec
+Ekvador ec
+I-Equador ec
+®ì¦Å§¼¡÷ ec
+เอà¸à¸§à¸²à¸”อร์ ec
+Ekvator ec
+Еквадор ec
+Ecwåteur ec
+厄瓜多尔 ec
+厄瓜多 ec
+Estonia ee
+Estlandies ee
+استونيا ee
+Estoniya ee
+ЭÑÑ‚Ð¾Ð½Ñ–Ñ ee
+ЕÑÑ‚Ð¾Ð½Ð¸Ñ ee
+Estonija ee
+Estònia ee
+Estonsko ee
+Estland ee
+Estland ee
+Εσθονία ee
+Estlando ee
+Eesti ee
+استونی ee
+Eesti ee
+Estonie ee
+×סטוניה ee
+Estonija ee
+Észtország ee
+Eistland ee
+エストニア ee
+ì—스토니아 ee
+ເອໂທເນີຠee
+Estija ee
+Igaunija ee
+Estonja ee
+Estland ee
+Estland ee
+Estland ee
+Estònia ee
+Estónia ee
+Estônia ee
+ЭÑÑ‚Ð¾Ð½Ð¸Ñ ee
+Estónsko ee
+Estonija ee
+Estonija ee
+I-Estonia ee
+Estland ee
+±Ã§¼¡É¢Â¡ ee
+เอสโธเนีย ee
+Estonya ee
+ЕÑÑ‚Ð¾Ð½Ñ–Ñ ee
+Estoneye ee
+爱沙尼亚 ee
+愛沙尼亞 ee
+Egypt eg
+Egipte eg
+مصر eg
+Misir eg
+ЭгіпÑÑ‚ eg
+Египет eg
+Egipat eg
+Egipte eg
+Egypten eg
+Ägypten eg
+Αίγυπτος eg
+Egiptujo eg
+Egipto eg
+Egiptus eg
+Egypto eg
+مصر eg
+Egypti eg
+Egyptaland eg
+Égypte eg
+×ž×¦×¨×™× eg
+Egipat eg
+Egyiptom eg
+Egyptaland eg
+Egitto eg
+エジプト eg
+ì´ì§‘트 eg
+ອີຢີບ eg
+Egiptas eg
+Ä’Ä£ipte eg
+Eġittu eg
+Egypte eg
+Egepeta eg
+Egipt eg
+Egipto eg
+Egito eg
+Egipt eg
+Египет eg
+Egipt eg
+I-Egypt eg
+Egypten eg
+±¸¢ôà eg
+อียิปต์ eg
+Mısır eg
+Єгипет eg
+Edjipe eg
+åŸƒåŠ eg
+åŸƒåŠ eg
+Igibhithe eg
+Western Sahara eh
+Западна Сахара eh
+Zapadna Sahara eh
+Vestsahara eh
+Sahara occidental eh
+Mendebaldeko Sahara eh
+Nyugat-Szahara eh
+ພື້ນທີ່ທຳງານ eh
+Sahara eh
+Západna Sahara eh
+Zahodna Sahara eh
+Västsahara eh
+Західна Сахара eh
+西撒哈拉 eh
+Eritrea er
+ЭрытрÑÑ er
+Ð•Ñ€Ð¸Ñ‚Ñ€ÐµÑ er
+Eritreja er
+à»àºà»‰à»„ຂà»àºŸà»‰àº¡àº—ຳງານ er
+Eritreja er
+Ð•Ñ€Ð¸Ñ‚Ñ€ÐµÑ er
+厄立特里亚 er
+Spain es
+Spanje es
+أسبانيا es
+İspaniya es
+Ð“Ñ–ÑˆÐ¿Ð°Ð½Ñ–Ñ es
+ИÑÐ¿Ð°Ð½Ð¸Ñ es
+Spagn es
+Å panija es
+Espanya es
+Španělsko es
+Spanien es
+Spanien es
+Ισπανία es
+Hispanio es
+España es
+Hispaania es
+Espainia es
+اسپانیا es
+Espanja es
+Spania es
+Espagne es
+España es
+ספרד es
+Å panjolska es
+Spanyolország es
+Spanyol es
+Spánn es
+Spagna es
+スペイン es
+ìŠ¤íŽ˜ì¸ es
+ສະເປັນ es
+Ispanija es
+SpÄnija es
+Spanja es
+Spania es
+Spanje es
+Spania es
+Espanha es
+Hiszpania es
+Espanha es
+Espanha es
+Spania es
+ИÑÐ¿Ð°Ð½Ð¸Ñ es
+Å panielsko es
+Å panija es
+Å panija es
+I-Spain es
+Spanien es
+æÀ¢ý es
+สเปน es
+İspanya es
+ІÑÐ¿Ð°Ð½Ñ–Ñ es
+Tây Ban Nha es
+Sipagne es
+西ç­ç‰™ es
+西ç­ç‰™ es
+Ethiopia et
+Ð­Ñ‚Ñ‹Ñ‘Ð¿Ñ–Ñ et
+Ð•Ñ‚Ð¸Ð¾Ð¿Ð¸Ñ et
+Etiopija et
+Ethiopien et
+Etiopía et
+Etiopia et
+Etiópia et
+ເອໂທເນີຠet
+Etiópia et
+Etiópia et
+Etiopija et
+Etiopien et
+Ð•Ñ„Ñ–Ð¾Ð¿Ñ–Ñ et
+埃塞俄比亚 et
+Finland fi
+Ùنلندا fi
+Finlandiya fi
+ФінлÑÐ½Ð´Ñ‹Ñ fi
+Ð¤Ð¸Ð½Ð»Ð°Ð½Ð´Ð¸Ñ fi
+Finska fi
+Finlàndia fi
+Finsko fi
+Finnland fi
+Φινλανδία fi
+Finlando fi
+Finlandia fi
+Soome fi
+Finlandia fi
+Ùنلاند fi
+Suomi fi
+Finnland fi
+Finlande fi
+Finlandia fi
+פינלנד fi
+Finska fi
+Finnország fi
+Finlandia fi
+Finnland fi
+Finlandia fi
+フィンランド fi
+핀란드 fi
+ຟີນà»àº¥àº™ fi
+Suomija fi
+Somija fi
+Finlandja fi
+Finlandia fi
+Finlandia fi
+Finlândia fi
+Finlândia fi
+Finlanda fi
+ФинлÑÐ½Ð´Ð¸Ñ fi
+Fínsko fi
+Finska fi
+Finska fi
+I-Finland fi
+À¢ýÄ¡óà fi
+ฟินà¹à¸¥à¸™à¸”์ fi
+Finlandiya fi
+ФінлÑÐ½Ð´Ñ–Ñ fi
+Phần Lan fi
+Finlande fi
+芬兰 fi
+芬蘭 fi
+Fiji fj
+Фіджы fj
+Фиджи fj
+Fidži fj
+Fidzsi fj
+ມີດີ fj
+Ilhas Fiji fj
+Fidži fj
+Fidži fj
+Фіджі fj
+æ–æµŽ fj
+Falkland Islands (Malvinas) fk
+ФолклендÑки ОÑтрови fk
+Foklandska ostrva (Malvini) fk
+Falkland-øerne fk
+Islas Falkland (Malvinas) fk
+Falkland Irlak (Malvinak) fk
+Falkland-szigetek fk
+Ilhas Malvinas fk
+Falklandské Ostrovy (Malviny) fk
+Falklandski otoki (Malvini) fk
+Falklandsöarna fk
+ç¦å…‹å…°å²› (马尔维纳斯) fk
+Micronesia, Federated states of fm
+ФедÑÑ€Ð°Ñ†Ñ‹Ñ ÐœiкранÑзіі fm
+ÐœÐ¸ÐºÑ€Ð¾Ð½ÐµÐ·Ð¸Ñ fm
+Mikronezija, Federalne države fm
+Mikronesien, de forenede stater af fm
+Micronesia, Estados federados de fm
+Mikronesia, Estatu Federatuak fm
+Mikronézia fm
+Estados Federados da Micronésia fm
+Spjoené štáty Mikronézie fm
+Mikronezija, Združene države fm
+Mikronesiska federationen fm
+密克罗尼西亚è”邦 fm
+Faroe Islands fo
+ФареорÑки ОÑтрови fo
+Farska ostrva fo
+Færøerne fo
+islas Faroe fo
+Faroe Irlak fo
+Faroe-szigetek fo
+ໄອà»àº¥àº™ fo
+Ilhas Faroe fo
+Ostrovy Faroe fo
+Otoki Faroe fo
+Färöarna fo
+ФарерÑькі оÑтрови fo
+France fr
+Frankryk fr
+ÙØ±Ù†Ø³Ø§ fr
+Fransa fr
+Ð¤Ñ€Ð°Ð½Ñ†Ñ‹Ñ fr
+Ð¤Ñ€Ð°Ð½Ñ†Ð¸Ñ fr
+Frañs fr
+Francuska fr
+França fr
+Francie fr
+Frankrig fr
+Frankreich fr
+Γαλλία fr
+Francio fr
+Francia fr
+Prantsusmaa fr
+Frantzia fr
+ÙØ±Ø§Ù†Ø³Ù‡ fr
+Ranska fr
+Frakland fr
+Francia fr
+צרפת fr
+Francuska fr
+Franciaország fr
+Prancis fr
+Frakkland fr
+Francia fr
+フランス fr
+프랑스 fr
+àºàº£àº±à»ˆàº‡ fr
+Prancūzija fr
+Francija fr
+Franza fr
+Frankrike fr
+Frankrijk fr
+Frankrike fr
+Fora fr
+França fr
+Francja fr
+França fr
+França fr
+Franţa fr
+Ð¤Ñ€Ð°Ð½Ñ†Ð¸Ñ fr
+Francúzsko fr
+Francija fr
+Francuska fr
+I-France fr
+Frankrike fr
+À¢Ã¡ýà fr
+à¸à¸£à¸±à¹ˆà¸‡à¹€à¸¨à¸ª fr
+Fransa fr
+Ð¤Ñ€Ð°Ð½Ñ†Ñ–Ñ fr
+Fura fr
+Pháp fr
+Fransi fr
+法国 fr
+法國 fr
+Gabon ga
+Габон ga
+Габон ga
+Gabón ga
+à»àºàº¥à»ˆàº‡àº™ ga
+Gabão ga
+Габон ga
+加蓬 ga
+United Kingdom gb
+Vereenigde Koninkryk gb
+المملكة المتحدة gb
+Birləşmiş Krallıq gb
+Злучанае КаралеўÑтва gb
+Ð’ÐµÐ»Ð¸ÐºÐ¾Ð±Ñ€Ð¸Ñ‚Ð°Ð½Ð¸Ñ gb
+Rouantelezh Unanet gb
+Velika Britanija gb
+Regne Unit gb
+Spojené království gb
+Storbritannien gb
+Großbritannien gb
+Ηνωμένο Βασίλειο gb
+Britio gb
+Reino Unido gb
+Ühendatud Kuningriigid gb
+Erreinu Batua gb
+بریتانیا gb
+Iso-Britannia gb
+Stórabretland gb
+Royaume Uni gb
+Reino Unido gb
+בריטניה gb
+Ujedinjeno Kraljevstvo gb
+Egyesült Királyság gb
+Inggris gb
+Stóra Bretland gb
+Regno Unito gb
+イギリス gb
+ì˜êµ­ gb
+ສະຫະລາດສະອານາຈັຠgb
+JungtinÄ— KaralystÄ— gb
+ApvienotÄ Karaliste gb
+Renju Unit gb
+Storbritannia gb
+Verenigd Koninkrijk gb
+Storbritannia gb
+Regne Unit gb
+Wielka Brytania gb
+Reino Unido gb
+Reino Unido gb
+Anglia gb
+Ð’ÐµÐ»Ð¸ÐºÐ¾Ð±Ñ€Ð¸Ñ‚Ð°Ð½Ð¸Ñ gb
+Anglicko gb
+Združeno kraljestvo gb
+Velika Britanija gb
+I-United Kingdom gb
+Storbritannien gb
+³ì¸¢Â ­Ã¡îº¢Âõ gb
+สหราชอาณาจัà¸à¸£ gb
+Birleşik Krallık gb
+Ð’ÐµÐ»Ð¸ÐºÐ¾Ð±Ñ€Ð¸Ñ‚Ð°Ð½Ñ–Ñ gb
+Anh gb
+United Kingdom gb
+è”åˆçދ国 gb
+è¯åˆçŽ‹åœ‹ gb
+United Kingdom gb
+Grenada gd
+غرينادا gd
+Qrenada gd
+ГрÑнада gd
+Гренада gd
+Granada gd
+ΓÏενάδα gd
+Grenado gd
+Granada gd
+گرانادا gd
+Grenade gd
+Granada gd
+גרנדה gd
+Grænhöfðaeyjar gd
+Granada gd
+グラナダ gd
+그러네ì´ë‹¤ gd
+ເàºàº™àº²àº”າ gd
+GrenÄda gd
+Granada gd
+Granada gd
+Granada gd
+Гренада gd
+I-Grenada gd
+¸¢¦Ãɼ¡ gd
+เà¸à¸£à¸™à¸²à¸”า gd
+Гренада gd
+格林纳达 gd
+æ ¼ç‘žé‚£é” gd
+Georgia ge
+Ð“Ñ€ÑƒÐ·Ñ–Ñ ge
+Ð“Ñ€ÑƒÐ·Ð¸Ñ ge
+Gruzija ge
+Georgien ge
+Grúzia ge
+ເຊີເບີຠge
+Geórgia ge
+Gruzija ge
+Georgien ge
+Ð“Ñ€ÑƒÐ·Ñ–Ñ ge
+æ ¼é²å‰äºš ge
+Ghana gh
+غانا gh
+Гана gh
+Гана gh
+Gana gh
+Γκάνα gh
+غنا gh
+×’×× ×” gh
+ガーナ gh
+ຈີນ gh
+Gana gh
+Gana gh
+Gana gh
+Гана gh
+Gana gh
+I-Ghana gh
+¸¡É¡ gh
+Гана gh
+加纳 gh
+è¿¦ç´ gh
+Gibraltar gi
+Гибралтар gi
+Gibraltár gi
+ມອລຕາ gi
+Гібралтар gi
+直布罗陀 gi
+Gambia gm
+Ð“Ð°Ð¼Ð±Ñ–Ñ gm
+Ð“Ð°Ð¼Ð±Ð¸Ñ gm
+Gambija gm
+à»àºàº¡àº¡àº² gm
+Gâmbia gm
+Gambija gm
+Ð“Ð°Ð¼Ð±Ñ–Ñ gm
+冈比亚 gm
+Guinea gn
+ГвінÑÑ gn
+Ð“Ð²Ð¸Ð½ÐµÑ gn
+Gvineja gn
+ເຖາວັນ gn
+Guiné gn
+Gvineja gn
+Ð“Ð²Ñ–Ð½ÐµÑ gn
+几内亚 gn
+Guadeloupe gp
+Гвадалупа gp
+Gvadalupe gp
+Guadalupe gp
+ເດີລຸຠgp
+Guadalupe gp
+Гваделупа gp
+瓜德罗普岛 gp
+Equatorial Guinea gq
+ЭкватарыÑÐ»ÑŒÐ½Ð°Ñ Ð“Ð²Ñ–Ð½ÑÑ gq
+ЕкваториÑлна Ð“Ð²Ð¸Ð½ÐµÑ gq
+Ekvatorijalna Gvineja gq
+Ækvatorial Guinea gq
+Guinea equatorial gq
+Ginea Ekuatoriala gq
+Egyenlítői Guinea gq
+àºàº²àº™àºªàº­àº™ gq
+Guiné Equatorial gq
+Rovníkova Guinea gq
+Ekvatorialna Gvineja gq
+Ekvatorialguinea gq
+Екваторіальна Ð“Ð²Ñ–Ð½ÐµÑ gq
+赤é“几内亚 gq
+Greece gr
+Griekeland gr
+اليونان gr
+Yunanıstan gr
+ГрÑÑ†Ñ‹Ñ gr
+Ð“ÑŠÑ€Ñ†Ð¸Ñ gr
+Gres gr
+GrÄka gr
+Grècia gr
+Řecko gr
+Grækenland gr
+Griechenland gr
+Ελλάδα gr
+Grekujo gr
+Grecia gr
+Kreeka gr
+Grezia gr
+یونان gr
+Kreikka gr
+Grikkaland gr
+Grèce gr
+Grecia gr
+יוון gr
+GrÄka gr
+Görögország gr
+Grikkland gr
+Grecia gr
+ギリシャ gr
+그리스 gr
+àºàºµàºŠ gr
+Graikija gr
+GrieÄ·ija gr
+Greċja gr
+Hellas gr
+Griekenland gr
+Hellas gr
+Grèça gr
+Grecja gr
+Grécia gr
+Grécia gr
+Grecia gr
+Ð“Ñ€ÐµÑ†Ð¸Ñ gr
+Grécko gr
+GrÄija gr
+GrÄka gr
+I-Greece gr
+Grekland gr
+¸¢Ã£à gr
+à¸à¸£à¸µà¸‹ gr
+Yunanistan gr
+Ð“Ñ€ÐµÑ†Ñ–Ñ gr
+Hy Lạp gr
+Grece gr
+希腊 gr
+希臘 gr
+Guatemala gt
+Gautemala gt
+غواتيمالا gt
+Quatemala gt
+ГватÑмала gt
+Гватемала gt
+Gvatemala gt
+Γουατεμάλα gt
+Gvatemalo gt
+Guatemaala gt
+گواتمالا gt
+גו×טמלה gt
+Gvatemala gt
+カタロニア gt
+과테ë§ë¼ gt
+àºàº±àº§à»€àº•ມາລາ gt
+Gvatemala gt
+Gvatemala gt
+Gwatemala gt
+Gwatemala gt
+Гватемала gt
+Gvatemala gt
+Gvatemala gt
+I-Guatemala gt
+ÌÅ¡ò¾Ã¡Ä¡ gt
+à¸à¸±à¸§à¹€à¸•มาลา gt
+Гватемала gt
+Gwatemala gt
+瓜地马拉 gt
+瓜地馬拉 gt
+Guam gu
+Гуам gu
+à»àºàº¡àº¡àº² gu
+Гуам gu
+关岛 gu
+Guinea-Bissau gw
+ГвінÑÑ-БіÑаў gw
+ГвинеÑ-БиÑау gw
+Gvineja-Bisau gw
+Ginea-Bissau gw
+Bissau-Guinea gw
+ລັດເຊີຠgw
+Guiné-Bissau gw
+ГвінеÑ-БіÑÑау gw
+å‡ å†…äºšæ¯”ç» gw
+Guyana gy
+ГвіÑна gy
+Гуана gy
+Gvajana gy
+ຈີນ gy
+Guiana gy
+Gvajana gy
+ГаÑна gy
+圭亚那 gy
+Hong Kong hk
+Ганконг hk
+Хонг Конг hk
+Hongkong hk
+ບà»à»ˆàº®àº¹à»‰àºˆàº±àº hk
+Гонконг hk
+香港 hk
+Honduras hn
+هندوراس hn
+Ð“Ð°Ð½Ð´ÑƒÑ€Ð°Ñ hn
+Ð¥Ð¾Ð½Ð´ÑƒÑ€Ð°Ñ hn
+Hondures hn
+ΟνδοÏÏα hn
+Honduraso hn
+Honduuras hn
+هندوراس hn
+הונדורס hn
+ホンデュラス hn
+온ë‘ë¼ìФ hn
+ຫອນດູລັດ hn
+Hondūras hn
+Hondurasa hn
+Ħonduras hn
+Hondures hn
+Ð“Ð¾Ð½Ð´ÑƒÑ€Ð°Ñ hn
+I-Honduras hn
+¬ñÎáŠà hn
+ฮอนดูรัส hn
+Ð“Ð¾Ð½Ð´ÑƒÑ€Ð°Ñ hn
+洪都拉斯 hn
+å®éƒ½æ‹‰æ–¯ hn
+Croatia hr
+Kroatië hr
+كرواتيا hr
+Xırvatıstan hr
+Ð¥Ð°Ñ€Ð²Ð°Ñ‚Ñ‹Ñ hr
+ХърватÑка hr
+Kroatia hr
+Hrvatska hr
+Croàcia hr
+Chorvatsko hr
+Kroatien hr
+Kroatien hr
+ΚÏοατία hr
+Kroatio hr
+Croacia hr
+Horvaatia hr
+Kroazia hr
+کرواسی hr
+Kroatia hr
+Kroatia hr
+Croatie hr
+Croacia hr
+קרו×טיה hr
+Hrvatska hr
+Horvátország hr
+Kroasia hr
+Króatía hr
+Croazia hr
+クロアãƒã‚¢ hr
+í¬ë¡œì•„í‹°ì•„ hr
+ໂຄເອເທີຠhr
+Kroatija hr
+HorvÄtija hr
+Kroazja hr
+Kroatia hr
+Kroatië hr
+Kroatia hr
+Croacia hr
+Chorwacja hr
+Croácia hr
+Croácia hr
+Croaţia hr
+Ð¥Ð¾Ñ€Ð²Ð°Ñ‚Ð¸Ñ hr
+Chorvátsko hr
+Hrvaška hr
+Hrvatska hr
+I-Croatia hr
+Kroatien hr
+̦á§Åº¢Â¡ hr
+โครเอเธีย hr
+Hırvatistan hr
+Ð¥Ð¾Ñ€Ð²Ð°Ñ‚Ñ–Ñ hr
+Crowåceye hr
+克罗地亚 hr
+克羅埃西亞 hr
+Haiti ht
+Гаіці ht
+Хаити ht
+Haití ht
+ວາດຮູບ - K ht
+Гаїті ht
+海地岛 ht
+Hungary hu
+Hongarye hu
+هنغاريا hu
+Macarıstan hu
+Вугоршчына hu
+Ð£Ð½Ð³Ð°Ñ€Ð¸Ñ hu
+Hungaria hu
+Mađarska hu
+Hongria hu
+MaÄarsko hu
+Ungarn hu
+Ungarn hu
+ΟυγγαÏία hu
+Hungario hu
+Hungría hu
+Ungari hu
+Hungaria hu
+مجارستان hu
+Unkari hu
+Ungarn hu
+Hongrie hu
+Hungría hu
+הונגריה hu
+Mađjarska hu
+Magyarország hu
+Hungaria hu
+Ungverjaland hu
+Ungheria hu
+ãƒãƒ³ã‚¬ãƒªãƒ¼ hu
+í—가리 hu
+ຫັງàºàº²àº¥àºµ hu
+Vengrija hu
+UngÄrija hu
+Ungerija hu
+Ungarn hu
+Hongarije hu
+Ungarn hu
+Hongria hu
+Węgry hu
+Hungria hu
+Hungria hu
+Ungaria hu
+Ð’ÐµÐ½Ð³Ñ€Ð¸Ñ hu
+MaÄarsko hu
+Madžarska hu
+Mađarska hu
+I-Hungary hu
+Ungern hu
+¬í§¸Ã¢ hu
+ฮังà¸à¸²à¸£à¸µ hu
+Macaristan hu
+Угорщина hu
+Hongreye hu
+匈牙利 hu
+匈牙利 hu
+Indonesia id
+Indonesië id
+إندونيسيا id
+İndoneziya id
+ІнданÑÐ·Ñ–Ñ id
+Ð˜Ð½Ð´Ð¾Ð½ÐµÐ·Ð¸Ñ id
+Indonezija id
+Indonèsia id
+Indonésie id
+Indonesien id
+Indonesien id
+Ινδονησία id
+Indonezio id
+Indoneesia id
+اندونزی id
+Indonésie id
+×ינדונזיה id
+Indonezija id
+Indonézia id
+Indónesía id
+インドãƒã‚·ã‚¢ id
+ì¸ë„네시아 id
+ອີàºà»‚ດນີເຊີຠid
+Indonezija id
+Indonēzija id
+Indoneżja id
+Indonesië id
+Indonezja id
+Indonésia id
+Indonésia id
+Indonezia id
+Ð˜Ð½Ð´Ð¾Ð½ÐµÐ·Ð¸Ñ id
+Indonézia id
+Indonezija id
+I-Indonesia id
+Indonesien id
+­ó§¾¡É£º¢Â¡ id
+อินโดนีเซีย id
+İndonezya id
+Ð†Ð½Ð´Ð¾Ð½ÐµÐ·Ñ–Ñ id
+Indoneseye id
+å°åº¦å°¼è¥¿äºš id
+å°å°¼ id
+Ireland ie
+Ierland ie
+أيرلندا ie
+İrlandiya ie
+ІрлÑÐ½Ð´Ñ‹Ñ ie
+Ð˜Ñ€Ð»Ð°Ð½Ð´Ð¸Ñ ie
+Iwerzhon ie
+Irska ie
+Irlanda ie
+Irsko ie
+Irland ie
+Irland ie
+ΙÏλανδία ie
+Islando ie
+Irlanda ie
+Island ie
+Irlanda ie
+ایرلند ie
+Irlanti ie
+Ãrland ie
+Irlande ie
+Irlanda ie
+×ירלנד ie
+Irska ie
+Ãrország ie
+Irlandia ie
+ÃÂrland ie
+Irlanda ie
+アイスランド ie
+ì•„ì¼ëžœë“œ ie
+ໄອà»àº¥àº™ ie
+Airija ie
+Īrija ie
+Irlanda ie
+Irland ie
+Ierland ie
+Irland ie
+Irlanda ie
+Irlandia ie
+Irlanda ie
+Irlanda ie
+Irlanda ie
+Ð˜Ñ€Ð»Ð°Ð½Ð´Ð¸Ñ ie
+Ãrsko ie
+Irska ie
+Irska ie
+I-Ireland ie
+Irland ie
+«Â÷Ä¡óà ie
+ไอร์à¹à¸¥à¸™à¸”์ ie
+İrlanda ie
+Ð†Ñ€Ð»Ð°Ð½Ð´Ñ–Ñ ie
+Irlande ie
+爱尔兰 ie
+愛爾蘭 ie
+Israel il
+اسرائيل il
+İzrail il
+Ізраіль il
+Израел il
+Izrael il
+Izrael il
+ΙσÏαήλ il
+Israelo il
+Iisrael il
+اسراییل il
+Ãsrael il
+Israël il
+ישר×ל il
+Izrael il
+Izrael il
+ÃÂsrael il
+Israele il
+イスラエル il
+ì´ìФë¼ì—˜ il
+ອິດສະລະເອລ il
+Izraelis il
+Izraēla il
+Iżrael il
+Izrael il
+Израиль il
+Izrael il
+Izrael il
+Izrael il
+I-Israel il
+­Ã§Ãø il
+อิสราเอล il
+İsrail il
+Ізраїль il
+Israyel il
+USirayeli il
+以色列 il
+以色列 il
+India in
+Indië in
+الهند in
+Hindistan in
+Ð†Ð½Ð´Ñ‹Ñ in
+Ð˜Ð½Ð´Ð¸Ñ in
+Indija in
+Ãndia in
+Indie in
+Indien in
+Indien in
+Ινδία in
+Hindujo in
+هندوستان in
+Intia in
+Inde in
+הודו in
+Indija in
+Indland in
+インド in
+ì¸ë„ in
+ອິນເດີຠin
+Indija in
+Indija in
+Indja in
+Indie in
+Ãndia in
+Ãndia in
+Ð˜Ð½Ð´Ð¸Ñ in
+Indija in
+I-India in
+Indien in
+­ó¾¢Â¡ in
+อินเดีย in
+Hindistan in
+Ð†Ð½Ð´Ñ–Ñ in
+Inde in
+å°åº¦ in
+å°åº¦ in
+Endiya in
+Iraq iq
+Irak iq
+العراق iq
+İraq iq
+Ірак iq
+Ирак iq
+Irak iq
+Irák iq
+Irak iq
+Irak iq
+ΙÏάκ iq
+Irako iq
+Irak iq
+Iraak iq
+عراق iq
+Irak iq
+Irak iq
+Irak iq
+עירק iq
+Irak iq
+Irak iq
+ÃÂrak iq
+Irak iq
+イラク iq
+ì´ë¼í¬ iq
+ອີລັຠiq
+Irakas iq
+IrÄka iq
+Irak iq
+Irak iq
+Irak iq
+Irak iq
+Iraque iq
+Iraque iq
+Irak iq
+Ирак iq
+Irák iq
+Irak iq
+I-Iraq iq
+Irak iq
+®Ã¡ì iq
+อิรัค iq
+Irak iq
+Ірак iq
+Irak iq
+伊拉克 iq
+伊拉克 iq
+Iran ir
+أيران ir
+Іран ir
+Иран ir
+Ãrán ir
+ΙÏάν ir
+Iraan ir
+ایران ir
+×ירן ir
+Irán ir
+イラン ir
+ì´ëž€ ir
+ອີລັຠir
+Iranas ir
+Irão ir
+Irã ir
+Иран ir
+Irán ir
+I-Iran ir
+®Ã¡ý ir
+İran ir
+Іран ir
+伊朗 ir
+伊朗 ir
+Iceland is
+Ysland is
+أيسلندا is
+İslandiya is
+ІÑьлÑÐ½Ð´Ñ‹Ñ is
+ИÑÐ»Ð°Ð½Ð´Ð¸Ñ is
+Island is
+Island is
+Islàndia is
+Island is
+Island is
+Island is
+Ισλανδία is
+Islando is
+Islandia is
+Island is
+Islandia is
+ایسلند is
+Islanti is
+Ãsland is
+Islande is
+Islandia is
+×יסלנד is
+Island is
+Izland is
+Islandia is
+ÃÂsland is
+Islanda is
+アイスランド is
+ì•„ì´ìŠ¬ëž€ë“œ is
+ໄອຊà»àº¥àº™ is
+Islandija is
+Islande is
+Islandja is
+Island is
+IJsland is
+Island is
+Islandia is
+Islandia is
+Islândia is
+Islândia is
+Islanda is
+ИÑÐ»Ð°Ð½Ð´Ð¸Ñ is
+Island is
+Islandija is
+Island is
+I-Iceland is
+Island is
+³ÃÄ¡óà is
+ไอซ์à¹à¸¥à¸™à¸”์ is
+İzlanda is
+ІÑÐ»Ð°Ð½Ð´Ñ–Ñ is
+Izlande is
+冰岛 is
+冰島 is
+Icelandi is
+Italy it
+Italië it
+ايطاليا it
+İtalyia it
+Ð†Ñ‚Ð°Ð»Ñ–Ñ it
+Ð˜Ñ‚Ð°Ð»Ð¸Ñ it
+Italia it
+Italija it
+Itàlia it
+Itálie it
+Italien it
+Italien it
+Ιταλία it
+Italio it
+Italia it
+Itaalia it
+Italia it
+ایتالیا it
+Italia it
+Italia it
+Italie it
+Italia it
+×יטליה it
+Italija it
+Olaszország it
+Italia it
+ÃÂtalía it
+Italia it
+イタリア it
+ì´íƒˆë¦¬ì•„ it
+ອີຕາລີ it
+Italija it
+ItÄlija it
+Italja it
+Italia it
+Italië it
+Italia it
+Italia it
+Włochy it
+Itália it
+Itália it
+Italia it
+Ð˜Ñ‚Ð°Ð»Ð¸Ñ it
+Taliansko it
+Italija it
+Italija it
+I-Italy it
+Italien it
+­ò¾¡Ä¢ it
+อิตาลี it
+İtalya it
+Ð†Ñ‚Ð°Ð»Ñ–Ñ it
+Itåleye it
+Ithali it
+æ„大利 it
+義大利 it
+Jamaica jm
+Jamaika jm
+جامايكا jm
+Yamayka jm
+Ямайка jm
+Ямайка jm
+Jamaika jm
+Jamajka jm
+Jamajka jm
+Jamaika jm
+Τζαμάικα jm
+Ä´amaiko jm
+Jamaika jm
+Jamaika jm
+جاماییکا jm
+Jamaika jm
+Jamaïque jm
+Xamaica jm
+ג'מייקה jm
+Jamajka jm
+Jamaika jm
+Jamaika jm
+Giamaica jm
+ジャマイカ jm
+ìžë©”ì´ì¹´ jm
+ຈາໄມàºàº² jm
+Jamaika jm
+Jamaika jm
+Ä amajka jm
+Jamajka jm
+Ямайка jm
+Jamajka jm
+Jamajka jm
+Jamajka jm
+I-Jamaica jm
+ƒº¦Ãö측 jm
+จาไมà¸à¸² jm
+Jamaika jm
+Ямайка jm
+Djamayike jm
+牙买加 jm
+牙買加 jm
+Jordan jo
+Jordaan jo
+الأردن jo
+İordaniya jo
+Ð¯Ñ€Ð´Ð°Ð½Ñ–Ñ jo
+Ð™Ð¾Ñ€Ð´Ð°Ð½Ð¸Ñ jo
+Jordania jo
+Jordán jo
+Jordanien jo
+ΙοÏδανία jo
+Jordanio jo
+Jordania jo
+اردن jo
+Jordania jo
+Jordanie jo
+ירדן jo
+Jordánia jo
+Jórdanía jo
+Giordania jo
+ヨルダン jo
+요르단 jo
+ຈà»à»àº”ນ jo
+Jordanija jo
+JordÄna jo
+Ä ordan jo
+Jordanië jo
+Jordania jo
+Jordânia jo
+Jordânia jo
+Iordania jo
+Ð˜Ð¾Ñ€Ð´Ð°Ð½Ð¸Ñ jo
+Jordánsko jo
+Jordanija jo
+I-Jordan jo
+Jordanien jo
+§Â¡÷¾¡ý jo
+จอร์à¹à¸”น jo
+Ürdün jo
+Ð™Ð¾Ñ€Ð´Ð°Ð½Ñ–Ñ jo
+Djordaneye jo
+约旦 jo
+ç´„æ—¦ jo
+Ijolidani jo
+Japan jp
+اليابان jp
+Yaponiya jp
+Ð¯Ð¿Ð¾Ð½Ñ–Ñ jp
+Ð¯Ð¿Ð¾Ð½Ð¸Ñ jp
+Japó jp
+Japonsko jp
+Ιαπωνία jp
+Japanio jp
+Japón jp
+Jaapan jp
+Japonia jp
+ژاپن jp
+Japani jp
+Japon jp
+Xapón jp
+יפן jp
+Japán jp
+Jepang jp
+Giappone jp
+日本 jp
+ì¼ë³¸ jp
+àºàºµà»ˆàº›àº¸à»ˆàº™ jp
+Japonija jp
+JapÄna jp
+Ä appun jp
+Japon jp
+Japonia jp
+Japão jp
+Japão jp
+Japonia jp
+Ð¯Ð¿Ð¾Ð½Ð¸Ñ jp
+Japonsko jp
+Japonska jp
+I-Japan jp
+ºôÀ¡ý jp
+à¸à¸µà¹ˆà¸›à¹ˆà¸¸à¸™ jp
+Japonya jp
+Ð¯Ð¿Ð¾Ð½Ñ–Ñ jp
+Nhật bản jp
+Djapon jp
+日本 jp
+日本 jp
+Kenya ke
+ÐšÐµÐ½Ñ–Ñ ke
+ÐšÐµÐ½Ð¸Ñ ke
+Kenija ke
+Kenia ke
+ເວນດາ ke
+Quênia ke
+Keňa ke
+Kenija ke
+ÐšÐµÐ½Ñ–Ñ ke
+肯尼亚 ke
+Kyrgyzstan kg
+КыргызÑтан kg
+КиргиÑтан kg
+Kirgistan kg
+Kirgizistan kg
+Kyrgyzstán kg
+Kirgizisztán kg
+ຄສິຕັລ kg
+Kirgizstan kg
+Kirgizistan kg
+КиргизÑтан kg
+å‰å°”剿–¯å¦ kg
+Cambodia kh
+Камбоджа kh
+Камбоджа kh
+Kambođa kh
+Kambodzsa kh
+ໂຄລຳເບີຠkh
+Cambodja kh
+Kambodža kh
+Kambodža kh
+Kambodja kh
+Камбоджа kh
+柬埔寨 kh
+Kiribati ki
+Кiрыбацi ki
+Кирибати ki
+à»àºŸàº„ທັລ - K ki
+Кірібаті ki
+基里巴斯 ki
+Comoros km
+Каморы km
+КоморÑки km
+Komori km
+Comorerne km
+ສີ km
+Komori km
+Komorerna km
+Комори km
+科摩罗群岛 km
+St. Kitts and Nevis kn
+St. Kitts en Nevis kn
+سانت كيتس Ùˆ نيÙيس kn
+St. Kitts vÉ™ Nevis kn
+Св. КриÑтоф и ÐÐµÐ²Ð¸Ñ kn
+S. Kitts ha Nevis kn
+St. Kitts i Nevis kn
+Sv. Kitts a Nevis kn
+St. Kitts-Nevis kn
+St. Kitts und Nevis kn
+St. Kitts και Nevis kn
+St. Kitts kaj Nevis kn
+St. Kitts y Nevis kn
+St. Kitts ja Nevis kn
+St. Kitts eta Nevis kn
+سن کیتس و نویس kn
+St. Kitts ja Nevis kn
+St Kitts et Nevis kn
+Saint Kitts e Nevis kn
+סנט קיטס ונביס kn
+St. Kitts és Nevis kn
+St. Kitts dan Nevis kn
+Ss. Kitts e Nevis kn
+セントキッツãƒãƒ´ã‚£ã‚¹ kn
+세ì¸íЏ 키츠 네비스 kn
+Å v. Kitts ir Nevis kn
+St. Kitts un Nevis kn
+St. Kitts u Nevis kn
+St. Kitts og Nevis kn
+St. Kitts en Nevis kn
+St. Kitts og Nevis kn
+St. Kitts le Nevis kn
+St. Kitts e Nevis kn
+St. Kitts e Nevis kn
+St Kitts e Nevis kn
+Sf. Kitts ÅŸi Nevis kn
+о. Св. КриÑтофа и ÐевиÑа kn
+St. Kitts a Nevis kn
+St. Kitts in Nevis kn
+St. Kitts i Nevis kn
+I-St. Kitts and Nevis kn
+St. Kitts och Nevis kn
+¦ºÂ¢ý𠸢ðà & ¦¿Å¢à kn
+St. Kitts ve Nevis kn
+Ð¤ÐµÐ´ÐµÑ€Ð°Ñ†Ñ–Ñ Ð¡ÐµÐ½Ñ‚-ÐšÑ–Ñ‚Ñ Ñ– ÐÐµÐ²Ñ–Ñ kn
+St. Kitts na Nevis kn
+St. Kitts neNevis kn
+圣基特和里维斯 kn
+è–å…‹ç†æ–¯å¤šç¦åŠå°¼ç¶­æ–¯ kn
+St. Kitts kanye no-Nevis kn
+North Korea kp
+Noord Korea kp
+كوريا الشمالية kp
+Åžimali Koreya kp
+ÐŸÐ°ÑžÐ½Ð¾Ñ‡Ð½Ð°Ñ ÐšÐ°Ñ€ÑÑ kp
+Северна ÐšÐ¾Ñ€ÐµÑ kp
+Norzh-Korea kp
+Sjeverna Koreja kp
+Corea del Nord kp
+Severní Korea kp
+Nordkorea kp
+Nord-Korea kp
+Î’ÏŒÏεια ΚοÏέα kp
+Nordkoreo kp
+Corea del Norte kp
+Põhja-Korea kp
+Ipar Korea kp
+کره شمالی kp
+Pohjois-Korea kp
+Norðurkorea kp
+Corée du nord kp
+Corea do Norte kp
+צפון קורי××” kp
+Sjeverna Koreja kp
+Észak-Korea kp
+Korea Utara kp
+Kórea - Norðurkórea kp
+Corea del Nord kp
+北æœé®® kp
+ì¡°ì„ ë¯¼ì£¼ì£¼ì˜ ì¸ë¯¼ê³µí™”êµ­ kp
+ເàºàº»àº²àº¥àºµà»€àº«àº™àº·àº­ kp
+Å iaurÄ—s KorÄ—ja kp
+ZiemeļKoreja kp
+Korea ta' Fuq kp
+Nord-Korea kp
+Noord-Korea kp
+Nord-Korea kp
+Lebowa la Korea kp
+Corea dèu Nord kp
+Korea Północna kp
+Coreia do Norte kp
+Coréia do Norte kp
+Coreea de Nord kp
+Ð¡ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐšÐ¾Ñ€ÐµÑ kp
+severná Kórea kp
+Severna Koreja kp
+Severna Koreja kp
+I-North Korea kp
+Nordkorea kp
+ż ¦¸¡Ã¢Â¡ kp
+เà¸à¸²à¸«à¸¥à¸µà¹€à¸«à¸™à¸·à¸­ kp
+Kuzey Kore kp
+Північна ÐšÐ¾Ñ€ÐµÑ kp
+Devhula ha Korea kp
+Bắc Triá»u Tiên kp
+Bijhe Coreye kp
+Umntla Korea kp
+æœé²œ kp
+北韓 kp
+Enyakatho ne-Korea kp
+South Korea kr
+Suid Korea kr
+كوريا الجنوبية kr
+Cənubi Koreya kr
+ÐŸÐ°ÑžÐ´Ð½Ñ‘Ð²Ð°Ñ ÐšÐ°Ñ€ÑÑ kr
+Южна ÐšÐ¾Ñ€ÐµÑ kr
+Su-Korea kr
+Južna Koreja kr
+Corea del Sud kr
+Jižní Korea kr
+Sydkorea kr
+Süd-Korea kr
+Îότια ΚοÏέα kr
+Sudkoreo kr
+Corea del Sur kr
+Lõuna-Korea kr
+Hego Korea kr
+کره جنوبی kr
+Etelä-Korea kr
+Suðurkorea kr
+Corée du sud kr
+Corea do Sur kr
+×“×¨×•× ×§×•×¨×™××” kr
+Južna Koreja kr
+Dél-Korea kr
+Korea Selatan kr
+Kórea - Suðurkórea kr
+Corea del Sud kr
+韓国 kr
+대한민국 kr
+ເàºàº»àº²àº¥àºµà»ƒàº•້ kr
+Pietų Korėja kr
+DievidKoreja kr
+Korea t'Isfel kr
+Sør-Korea kr
+Zuid-Korea kr
+Sør-Korea kr
+Borwa bja Korea kr
+Corea dèu Sud kr
+Korea Południowa kr
+Coreia do Sul kr
+Coréia do Sul kr
+Coreea de Sud kr
+Ð®Ð¶Ð½Ð°Ñ ÐšÐ¾Ñ€ÐµÑ kr
+Južná Kórea kr
+Južna Koreja kr
+Južna Koreja kr
+I-South Korea kr
+Sydkorea kr
+¦¾ý ¦¸¡Ã¢Â¡ kr
+เà¸à¸²à¸«à¸¥à¸µà¹ƒà¸•้ kr
+Güney Kore kr
+Південна ÐšÐ¾Ñ€ÐµÑ kr
+Korea tshipembe kr
+Hàn Quốc kr
+Nonne Coreye kr
+Umzantsi Korea kr
+韩国 kr
+å—韓 kr
+Emzansi Korea kr
+Kuwait kw
+Kuwaït kw
+الكويت kw
+КувÑйт kw
+Кувейт kw
+Kuvajt kw
+Kuvajt kw
+Κουβέιτ kw
+Kuveit kw
+کویت kw
+Kuvait kw
+Kowait kw
+כווית kw
+Kuvajt kw
+Kuvait kw
+クェート kw
+쿠웨ì´íЏ kw
+à»àº•້ມຮູບ- K kw
+Kuveitas kw
+Koeweit kw
+Koweit kw
+Kuveit kw
+Кувейт kw
+Kuvajt kw
+Kuvajt kw
+I-Kuwait kw
+̨Åò kw
+KКувейт kw
+ç§‘å¨ç‰¹ kw
+ç§‘å¨ç‰¹ kw
+Cayman Islands ky
+Кайманови ОÑтрови ky
+Kajmanska ostrva ky
+Cayman-øerne ky
+Islas Caimán ky
+Kaiman Irlak ky
+Kajmán-szigetek ky
+ຄາຕາລັນ ky
+Ilhas Cayman ky
+Kajmanske Ostrovy ky
+Kajmanski otoki ky
+Caymanöarna ky
+КайманÑькі оÑтрови ky
+开曼群岛 ky
+Kazakhstan kz
+КазахÑтан kz
+КазахÑтан kz
+Kazahstan kz
+Kazakhstán kz
+Kazahsztán kz
+à»àºà»àº¥àºàº•ິຠ- K kz
+Kazaquistão kz
+Kazachstan kz
+Kazahstan kz
+Kazakstan kz
+КазахÑтан kz
+哈è¨å…‹æ–¯å¦ kz
+Laos la
+Ð›Ð°Ð¾Ñ la
+Ð›Ð°Ð¾Ñ la
+Laosz la
+ລາວ la
+è€æŒ la
+Lebanon lb
+Libanon lb
+لبنان lb
+Ліван lb
+Ливан lb
+Liban lb
+Libanon lb
+Libanon lb
+Libanon lb
+Λίβανος lb
+Lebanono lb
+Líbano lb
+Liibanon lb
+لبنان lb
+Libanon lb
+Libanon lb
+Liban lb
+לבנון lb
+Libanon lb
+Libanon lb
+Libano lb
+レãƒãƒŽãƒ³ lb
+레바논 lb
+ເດນ່ງນ lb
+Libanas lb
+Libanu lb
+Libanon lb
+Libanon lb
+Libanon lb
+Liban lb
+Líbano lb
+Líbano lb
+Liban lb
+Ливан lb
+Libanon lb
+Libanon lb
+I-Lebanon lb
+Libanon lb
+¦ÄÀÉ¡ý lb
+Ліван lb
+Liban lb
+黎巴嫩 lb
+黎巴嫩 lb
+St. Lucia lc
+سانت لوسيا lc
+Св. ЛюÑиа lc
+S. Lucia lc
+Svatá Lucie lc
+Σάντα Λουτσία lc
+St. Lucio lc
+Santa Lucía lc
+سن لوسیا lc
+Sankta Lusia lc
+Sainte Lucie lc
+Santa Lucía lc
+סנטה לוסיה lc
+Santa Lucia lc
+セントルキア lc
+세ì¸íЏ 루시아 lc
+ເຊັນລູເຊີຠlc
+Å v Liucija lc
+Sv. Lūcija lc
+St. Luċija lc
+Santa Lúcia lc
+Santa Lúcia lc
+Sf. Lucia lc
+о. Св. ЛюÑии lc
+Sv. Júlia lc
+Sv. Lucija lc
+I-St. Lucia lc
+¦ºýð æº¢Â¡ lc
+เซนต์ลูเซีย lc
+Санта Ð›ÑƒÑ‡Ñ–Ñ lc
+圣路西亚 lc
+è–露西亞 lc
+Liechtenstein li
+ЛіхтÑнштÑйн li
+Лихтенщайн li
+Lihtenštajn li
+Liechtestein li
+ຟ້າà»àº¡àºš li
+列支敦士登 li
+Sri Lanka lk
+Шры-Ланка lk
+Шри Ланка lk
+Å ri Lanka lk
+ເຊີເບີຠlk
+Å ri Lanka lk
+æ–¯é‡Œå…°å¡ lk
+Liberia lr
+ЛібÑÑ€Ñ‹Ñ lr
+Ð›Ð¸Ð±ÐµÑ€Ñ lr
+Liberija lr
+Libéria lr
+ລິຊາ lr
+Libéria lr
+Lýbia lr
+Liberija lr
+利比里亚 lr
+Lesotho ls
+ЛеÑота ls
+ЛеÑото ls
+Lesoto ls
+Lesoto ls
+ທົດສອບ ls
+Lesoto ls
+莱索托 ls
+Lithuania lt
+Lithuanië lt
+ليتوانيا lt
+Litvaniya lt
+Літва lt
+Литва lt
+Litvanija lt
+Lituània lt
+Litva lt
+Litauen lt
+Litauen lt
+Λιθουανία lt
+Litovio lt
+Lituania lt
+Leedu lt
+Lituania lt
+لیتوانی lt
+Liettua lt
+Lituanie lt
+×œ×™×˜× lt
+Litva lt
+Litvánia lt
+Litháenska lt
+Lituania lt
+リトアニア lt
+리 투아니아 lt
+ລິທົ່ວເນີຠlt
+Lietuva lt
+Lietuva lt
+Litwanja lt
+Litauen lt
+Litouwen lt
+Litauen lt
+Litwa lt
+Lituânia lt
+Lituânia lt
+Lituania lt
+Литва lt
+Litva lt
+Litva lt
+Litvanija lt
+I-Lithuania lt
+Litauen lt
+Ä¢òçÅɢ¡ lt
+ลิธัวเนีย lt
+Litvanya lt
+Литва lt
+ç«‹é™¶å®› lt
+ç«‹é™¶å®› lt
+Luxembourg lu
+Luxenburg lu
+لوكسمبورغ lu
+Lüksemburq lu
+ЛюкÑÑмбург lu
+ЛюкÑембург lu
+Luksemburg lu
+Luxemburg lu
+Lucembursko lu
+Luxemburg lu
+ΛουξεμβοÏÏγο lu
+Luksemburgo lu
+Luxemburgo lu
+Luksemburg lu
+Luxemburg lu
+لوگزامبورگ lu
+Luxemburg lu
+Luksemborg lu
+לוקסמבורג lu
+Luksemburg lu
+Luxemburg lu
+Lúxemborg lu
+Lussemburgo lu
+ルクセンブルグ lu
+ë£©ì…ˆë¶€ë¥´í¬ lu
+ລັàºà»àºŠàº¡à»€àºšàºµàº lu
+Liuksemburgas lu
+Luksemburga lu
+Lussemburgu lu
+Luxemburg lu
+Luksemburg lu
+Luxemburgo lu
+Luxemburgo lu
+Luxemburg lu
+ЛюкÑембург lu
+Luxemburg lu
+Luksemburg lu
+Luksemburg lu
+I-Luxembourg lu
+Luxemburg lu
+Äìºõ§À¡÷ì lu
+ลัà¸à¹€à¸‹à¸¡à¹€à¸šà¸­à¸£à¹Œà¸ lu
+Lüksemburg lu
+ЛюкÑембург lu
+Lucsimbork lu
+墿£®å ¡ lu
+盧森堡 lu
+Latvia lv
+لاتÙيا lv
+Latviya lv
+Ð›Ð°Ñ‚Ð²Ñ–Ñ lv
+Ð›Ð°Ñ‚Ð²Ð¸Ñ lv
+Latvija lv
+Lotyšsko lv
+Letland lv
+Lettland lv
+Λιθουανία lv
+Latvio lv
+Letonia lv
+Läti lv
+لاتویا lv
+Lettonie lv
+לטביה lv
+Latvija lv
+Lettország lv
+Léttland lv
+Lettonia lv
+ラトビア lv
+ë¼íŠ¸ë¹„ì•„ lv
+ລັດເວີຠlv
+Latvija lv
+Latvija lv
+Latvja lv
+Letland lv
+Åotwa lv
+Letónia lv
+Ð›Ð°Ñ‚Ð²Ð¸Ñ lv
+Lotyšsko lv
+Latvija lv
+Latvija lv
+I-Latvia lv
+Lettland lv
+ÄðŢ¡ lv
+ลัธเวีย lv
+Litvanya lv
+Ð›Ð°Ñ‚Ð²Ñ–Ñ lv
+Lativia lv
+拉脱维亚 lv
+拉脫維亞 lv
+Libya ly
+Libië ly
+ليبيا ly
+Ð›Ñ–Ð²Ñ–Ñ ly
+Ð›Ð¸Ð±Ð¸Ñ ly
+Libija ly
+Líbia ly
+Lýbie ly
+Libyen ly
+Libyen ly
+ΛιβÏη ly
+Libia ly
+Liibüa ly
+Libia ly
+لیبی ly
+Lybie ly
+לוב ly
+Líbia ly
+Libia ly
+リビア ly
+ລິຊາ ly
+Libija ly
+Libië ly
+Libia ly
+Líbia ly
+Líbia ly
+Ð›Ð¸Ð²Ð¸Ñ ly
+Lýbia ly
+Libija ly
+I-Libya ly
+Libyen ly
+Ä¢À¢Â¡ ly
+Ð›Ñ–Ð²Ñ–Ñ ly
+利比亚 ly
+利比亞 ly
+Morocco ma
+Morokko ma
+المغرب ma
+Марока ma
+Мароко ma
+Maroko ma
+Marroc ma
+Maroko ma
+Marokko ma
+Marokko ma
+ΜαÏόκο ma
+Moroko ma
+Marruecos ma
+Maroko ma
+Maroko ma
+مراکش ma
+Marokko ma
+Marokko ma
+Maroc ma
+מרוקו ma
+Maroko ma
+Marokkó ma
+Marocco ma
+モロッコ ma
+모로코 ma
+ເມົາລິ ma
+Marokas ma
+Marokk ma
+Marokko ma
+Marokko ma
+Marokko ma
+Maroko ma
+Marrocos ma
+Marrocos ma
+Maroc ma
+Марокко ma
+Maroko ma
+Maroko ma
+I-Morocco ma
+Marocko ma
+§Ã¡Ã¡§¸¡ ma
+Марокко ma
+Marok ma
+摩洛哥 ma
+摩洛哥 ma
+Monaco mc
+Манака mc
+Монако mc
+Monako mc
+Mónaco mc
+ເມົາລິ mc
+Mônaco mc
+Monako mc
+Monako mc
+摩纳哥 mc
+Moldova md
+Малдова md
+Молдова md
+Moldavia md
+Moldavia md
+ສະໂລວັຠmd
+Moldávsko md
+Moldavien md
+摩尔多瓦 md
+Madagascar mg
+МадагаÑкар mg
+МадагаÑкар mg
+Madagaskar mg
+Madagaszkár mg
+ຄາສະບາລ - K mg
+Madagaskar mg
+Madagaskar mg
+Madagaskar mg
+马达加斯加 mg
+Marshall Islands mh
+Маршаллавы аÑтравы mh
+Маршалови ОÑтрови mh
+Maršalova ostrva mh
+Marshall-øerne mh
+Islas Marshall mh
+Marshall Irlak mh
+Marshall-szigetek mh
+ລາດສະອານາຈັàºà»„ທຠmh
+Ilhas Marshall mh
+Maršálove ostrovy mh
+Marshallovi otoki mh
+Marshallöarna mh
+马ç»å°”群岛 mh
+Macedonia mk
+Makedoniese mk
+مقدونيا mk
+Makedonya mk
+ÐœÐ°ÐºÐµÐ´Ð¾Ð½Ñ–Ñ mk
+ÐœÐ°ÐºÐµÐ´Ð¾Ð½Ð¸Ñ mk
+Makedonia mk
+Makedonija mk
+Macedònia mk
+Makedonie mk
+Makedonien mk
+Makedonien mk
+Μακεδονία mk
+Macedonio mk
+Makedoonia mk
+Mazedonia mk
+مقدونیه mk
+Makedonia mk
+Macédoine mk
+מקדוניה mk
+Makedonija mk
+Macedónia mk
+Masedonia mk
+Makedónía mk
+マケドニア語 mk
+마케ë„니아 mk
+ມາເຊໂດເນີຠmk
+Makedonija mk
+MaÄ·edonija mk
+Maċedonja mk
+Makedonia mk
+Macedonië mk
+Makedonia mk
+Macedònian mk
+Macedónia mk
+Macedônia mk
+ÐœÐ°ÐºÐµÐ´Ð¾Ð½Ð¸Ñ mk
+Macedónsky mk
+Makedonija mk
+Makedonija mk
+I-Macedonia mk
+Makedonien mk
+Ả§¼¡É¢Â¡ mk
+มาเซโดเนีย mk
+Makedonya mk
+ÐœÐ°ÐºÐµÐ´Ð¾Ð½Ñ–Ñ mk
+Masedonia mk
+马其顿 mk
+馬其頓 mk
+Mali ml
+Малі ml
+Мали ml
+ຈົດຫມາຠml
+马里 ml
+Myanmar mm
+М'Ñнма mm
+Майнмар mm
+Mjanmar mm
+Burma mm
+Birmania mm
+ຕົວຮງàºàºžàºµàº·à»‰àº™àº—ີ່ທຳງານ - K mm
+Mjanmar mm
+缅甸 mm
+Mongolia mn
+ÐœÐ°Ð½Ð³Ð¾Ð»Ñ–Ñ mn
+ÐœÐ¾Ð½Ð³Ð¾Ð»Ð¸Ñ mn
+Mongolija mn
+Mongoliet mn
+Mongólia mn
+ລອàºàº­àº´àº™ mn
+Mongólia mn
+Mongolsko mn
+Mongolija mn
+Mongoliet mn
+è’™å¤ mn
+Macau mo
+Макао mo
+Makau mo
+Macao mo
+Makaó mo
+ມອລຕາ mo
+Makao mo
+Macao mo
+澳门 mo
+Martinique mq
+Мартиника mq
+Martinik mq
+Martinica mq
+ເມົາລິ mq
+Martinik mq
+马æå°¼å…‹å²› mq
+Mauritania mr
+ÐœÐ°ÑžÑ€Ñ‹Ñ‚Ð°Ð½Ñ–Ñ mr
+ÐœÐ°Ð²Ñ€Ð¸Ñ‚Ð°Ð½Ð¸Ñ mr
+Mauritanija mr
+Mauretanien mr
+Mauritánia mr
+ລິທົວເນີຠmr
+Mauritânia mr
+Mavretanija mr
+Mauretanien mr
+毛里塔尼亚 mr
+Montserrat ms
+МонÑерат ms
+Monsera ms
+ຈà»àºžàº²àºš ms
+蒙特塞拉特岛 ms
+Malta mt
+مالطة mt
+Мальта mt
+Малта mt
+Μάλτα mt
+Malto mt
+مالت mt
+Malte mt
+מלטה mt
+Málta mt
+マルタ mt
+왈타 mt
+ມອລຕາ mt
+Мальта mt
+I-Malta mt
+áø¼¡ mt
+มอลตา mt
+Мальта mt
+Male mt
+马耳他 mt
+馬爾他 mt
+Mauritius mu
+Маўрыцы mu
+Маурици mu
+Mauricijus mu
+Mauricio mu
+ພາທິຊັ້ນ mu
+Maurícius mu
+Mavricij mu
+毛里求斯 mu
+Maldives mv
+Мальдывы mv
+Малдиви mv
+Maldivi mv
+Maldiverne mv
+Maldivas mv
+Maldív-szigetek mv
+ມັລດິສ mv
+Maldivas mv
+Maldiv mv
+Maldiverna mv
+马尔代夫 mv
+Malawi mw
+Малаві mw
+Малави mw
+Malavi mw
+ມອລຕາ mw
+马拉维 mw
+Mexico mx
+Meksiko mx
+المكسيك mx
+Meksika mx
+МÑкÑыка mx
+МекÑико mx
+Mec'hiko mx
+Meksiko mx
+Mèxic mx
+Mexiko mx
+Mexiko mx
+Μεξικό mx
+Meksikujo mx
+México mx
+Mehhiko mx
+Mexiko mx
+مکزیک mx
+Meksiko mx
+Meksiko mx
+Mexique mx
+México mx
+מקסיקו mx
+Meksiko mx
+Mexikó mx
+Meksiko mx
+Mexíkó mx
+Messico mx
+メキシコ mx
+멕시코 mx
+ເມັàºàºŠàºµà»‚ຠmx
+Meksika mx
+Meksika mx
+Messiku mx
+Mèxic mx
+Meksyk mx
+México mx
+México mx
+Mexic mx
+МекÑика mx
+Mexiko mx
+Mehika mx
+Meksiko mx
+I-Mexico mx
+¦Ã캢§¸¡ mx
+เม็à¸à¸‹à¸´à¹‚ภmx
+Meksika mx
+МекÑика mx
+Mê hi cô mx
+Mecsike mx
+墨西哥 mx
+墨西哥 mx
+Malaysia my
+ÐœÐ°Ð»Ð°Ð¹Ð·Ñ‹Ñ my
+ÐœÐ°Ð»Ð°Ð¹Ð·Ð¸Ñ my
+Malezija my
+Malasia my
+Malasia my
+Malajzia my
+ມອລຕາ my
+Malásia my
+Malajzia my
+Malezija my
+马æ¥è¥¿äºš my
+Mozambique mz
+Мазамбік mz
+Мозамбик mz
+Mozambik mz
+Mozambik mz
+ຫນ່ວàºàº„ວາມຈຳ mz
+Moçambique mz
+Mozambik mz
+Mozambik mz
+Moçambique mz
+莫桑比克 mz
+Namibia na
+ÐÐ°Ð¼Ñ–Ð±Ñ–Ñ na
+ÐÐ°Ð¼Ð¸Ð±Ð¸Ñ na
+Namibija na
+Namíbia na
+ຈາໄມàºàº² na
+Namíbia na
+Namíbia na
+Namibija na
+纳米比亚 na
+New Caledonia nc
+Ðова ÐšÐ°Ð»ÐµÐ´Ð¾Ð½Ð¸Ñ nc
+Nova Kaledonija nc
+Ny Caledonien nc
+Nueva Caledonia nc
+Kaledonia Berria nc
+Új-Kaledónia nc
+ມາເຊໂດເນີຠnc
+Nova Caledônia nc
+Nová Kaledónia nc
+Nova Kaledonija nc
+Nya Caledonien nc
+新喀里多尼亚 nc
+Niger ne
+Ðігер ne
+Ðигер ne
+ຕົວຮງàºàºžàº·à»‰àº™àº—ີ່ທຳງານ ne
+Nigéria ne
+Nigéria ne
+尼日尔 ne
+Norfolk Island nf
+ОÑтров Ðорфолк nf
+Norfolk ostrvo nf
+Norfolk-øerne (Australien) nf
+Isla Norfolk nf
+Norfok Irla nf
+Norfolk-szigetek nf
+ໂປà»àº¥àº™ nf
+Ilhas Norfolk nf
+Ostrov Norfolk nf
+Otok Norfolk nf
+Norfolkön nf
+诺ç¦å…‹å²› nf
+Nigeria ng
+ÐÑ–Ð³ÐµÑ€Ñ‹Ñ ng
+ÐÐ¸Ð³ÐµÑ€Ð¸Ñ ng
+Nigerija ng
+Nigéria ng
+ບັນà»àºà»€àº¥àºµàº ng
+Nigéria ng
+Nigéria ng
+Nigerija ng
+尼日利亚 ng
+Nicaragua ni
+Nikaragua ni
+نيكاراغوا ni
+Ðікарагуа ni
+Ðикарагуа ni
+Nikaragva ni
+Nikaragua ni
+ÎικαÏάγουα ni
+Nikaraagua ni
+نیکاراگویه ni
+Nikaragua ni
+Nikaragua ni
+ניקרגווה ni
+ニカラグア ni
+니카ë¼ê³¼ ni
+ປາລາàºàºàº§àº ni
+Nikaragua ni
+Nikaragwa ni
+Nikaragua ni
+Nicarágua ni
+Nicarágua ni
+Ðикарагуа ni
+Nikaragua ni
+Nikaragva ni
+I-Nicaragua ni
+¿¢¸Ã¡Ì§Å ni
+Nikaragua ni
+Ðікарагуа ni
+尼加拉瓜 ni
+尼加拉瓜 ni
+Netherlands nl
+Nederland nl
+هولندا nl
+Hollandiya nl
+ГалÑÐ½Ð´Ñ‹Ñ nl
+Ð¥Ð¾Ð»Ð°Ð½Ð´Ð¸Ñ nl
+Izelvroioù nl
+Nizozemska nl
+Holanda nl
+Nizozemí nl
+Holland nl
+Niederlande nl
+Κάτω ΧώÏες nl
+Nederlando nl
+Países Bajos nl
+Holland nl
+Holanda nl
+هلند nl
+Alankomaat nl
+Háland nl
+Pays bas nl
+Países Baixos nl
+הולנד nl
+Nizozemska nl
+Hollandia nl
+Belanda nl
+Holland nl
+Paesi Bassi nl
+オランダ nl
+네ëœëž€ë“œ nl
+ເນເທີà»àº¥àº™à¹Œ nl
+Olandija nl
+Nīderlande nl
+Nederland nl
+Nederland nl
+Nederland nl
+Holanda nl
+Holandia nl
+Países Baixos nl
+Holanda nl
+Olanda nl
+Ðидерланды nl
+Holandsko nl
+Nizozemska nl
+Holandija nl
+I-Netherlands nl
+Nederländerna nl
+¦¿¾÷Ä¡óà nl
+เนเธอร์à¹à¸¥à¸™à¸”์ nl
+Hollanda nl
+Ð“Ð¾Ð»Ð»Ð°Ð½Ð´Ñ–Ñ nl
+Hà Lan nl
+è·å…° nl
+è·è˜­ nl
+Norway no
+Noorweë no
+النرويج no
+Norveç no
+ÐарвÑÐ³Ñ–Ñ no
+ÐÐ¾Ñ€Ð²ÐµÐ³Ð¸Ñ no
+Norvegia no
+Norveška no
+Noruega no
+Norsko no
+Norge no
+Norwegen no
+ÎοÏβηγία no
+Norvegio no
+Noruega no
+Norra no
+Norvegia no
+نروژ no
+Norja no
+Norra no
+Norvège no
+Noruega no
+נורבגיה no
+Norveška no
+Norvégia no
+Norwegia no
+Noregur no
+Norvegia no
+ノルウェー no
+ë…¸ë¥´ì›¨ì´ no
+ນà»à»€àº§ no
+Norvegija no
+Norvēģija no
+Norveġja no
+Norge no
+Noorwegen no
+Noreg no
+Noruega no
+Norwegia no
+Noruega no
+Noruega no
+Norvegia no
+ÐÐ¾Ñ€Ð²ÐµÐ³Ð¸Ñ no
+Nórsko no
+Norveška no
+Norveška no
+I-Norway no
+Norge no
+¿¡÷§Å no
+นอร์เวย์ no
+Norveç no
+ÐÐ¾Ñ€Ð²ÐµÐ³Ñ–Ñ no
+Na uy no
+æŒªå¨ no
+æŒªå¨ no
+Nepal np
+ÐÑпал np
+Ðепал np
+Nepál np
+ເວນດາ np
+尼泊尔 np
+Nauru nr
+Ðауру nr
+Ðауру nr
+Naurú nr
+ປາລາàºàºàº§àº nr
+ç‘™é² nr
+Niue nu
+Ðиуе nu
+ເນ໊ຕ nu
+纽埃岛 nu
+New Zealand nz
+Nuwe Seeland nz
+نيوزيلاندا nz
+Yeni Zellandiya nz
+ÐÐ¾Ð²Ð°Ñ Ð—ÑлÑÐ½Ð´Ñ‹Ñ nz
+Ðова Ð—ÐµÐ»Ð°Ð½Ð´Ð¸Ñ nz
+Zeland nevez nz
+Novi Zeland nz
+Nova Zelanda nz
+Nový Zéland nz
+Neuseeland nz
+Îέα Ζηλανδία nz
+Novzelando nz
+Nueva Zelanda nz
+Uus-Meremaa nz
+Zelanda Berria nz
+زلاندنو nz
+Uusi-Seelanti nz
+Nýsæland nz
+Nouvelle Zélande nz
+Nova Celandia nz
+ניו זילנד nz
+Novi Zeland nz
+Új-Zéland nz
+Selandia Baru nz
+Nýja Sjáland nz
+Nuova Zelanda nz
+ニュージーランド nz
+뉴질랜드 nz
+ນີວຊີà»àº¥àº™ nz
+Naujoji Zelandija nz
+JaunZēlande nz
+Nieuw Zeeland nz
+Navera Zelanda nz
+Nowa Zelandia nz
+Nova Zelândia nz
+Nova Zelândia nz
+Noua Zeelandă nz
+ÐÐ¾Ð²Ð°Ñ Ð—ÐµÐ»Ð°Ð½Ð´Ð¸Ñ nz
+Nový Zéland nz
+Nova Zelandija nz
+Novi Zeland nz
+I-New Zealand nz
+Nya Zeeland nz
+¿¢äº¢Ä¡óà nz
+นิวซีà¹à¸¥à¸™à¸”์ nz
+Yeni Zelanda nz
+Ðова Ð—ÐµÐ»Ð°Ð½Ð´Ñ–Ñ nz
+Nouve Zelande nz
+新西兰 nz
+ç´è¥¿è˜­ nz
+Oman om
+عÙمان om
+Ðман om
+Оман om
+Omán om
+Ομάν om
+Omano om
+Omán om
+Omaan om
+عمان om
+עומן om
+Omán om
+オマーン om
+오만 om
+ເàºàºµàºàº¥àº°àº¡àº±àº™ om
+Omanas om
+Omã om
+Оман om
+Omán om
+I-Oman om
+µÃý om
+Umman om
+Оман om
+ Oman om
+阿曼 om
+阿曼 om
+Panama pa
+بنما pa
+Панама pa
+Панама pa
+Panamà pa
+Παναμάς pa
+Panamo pa
+Panamá pa
+پاناما pa
+Panamá pa
+פנמה pa
+パナマ pa
+파나마 pa
+ປານາມາ pa
+Panamá pa
+Panamá pa
+Панама pa
+I-Panama pa
+Àɡá pa
+ปานามา pa
+Панама pa
+巴拿马 pa
+巴拿馬 pa
+Peru pe
+البيرو pe
+ПÑру pe
+Перу pe
+Perou pe
+Perú pe
+ΠεÏÎ¿Ï pe
+Peruo pe
+Perú pe
+Peruu pe
+پرو pe
+Pérou pe
+Perú pe
+פרו pe
+Perú pe
+Perù pe
+ペルー pe
+페루 pe
+ເປລູ pe
+Perū pe
+Pero pe
+Perú pe
+Перу pe
+I-Peru pe
+¦ÀÕ pe
+เปรู pe
+Перу pe
+Perou pe
+ç§˜é² pe
+秘魯 pe
+French Polynesia pf
+ФранцуÑÐºÐ°Ñ ÐŸÐ°Ð»Ñ–Ð½ÑÐ·Ñ–Ñ pf
+ФренÑка ÐŸÐ¾Ð»Ð¸Ð½ÐµÐ·Ð¸Ñ pf
+Francuska Polinezija pf
+Fransk Polynesien pf
+Polinesia francesa pf
+Polinesia Frantziarra pf
+Francia-Polinézia pf
+àºàº£àº±à»ˆàº‡à»€àºªàº” pf
+Polinésia Francesa pf
+Francúzska Polynézia pf
+Francoska Polinezija pf
+Franska Polynesien pf
+法属波利尼西亚 pf
+Papua New Guinea pg
+Папуа–ÐÐ¾Ð²Ð°Ñ Ð“Ð²Ñ–Ð½ÑÑ pg
+Папуа и Ðова Ð“Ð²Ð¸Ð½ÐµÑ pg
+Papua Nova Gvineja pg
+Papua Nueva Guinea pg
+Papua Ginea Berria pg
+Pápua Új-Guinea pg
+ເທົາອ່ອນ pg
+Nova Guiné Papua pg
+Papua Nová Guinea pg
+Papua Nova Gvineja pg
+Papua Nya Guinea pg
+巴布亚新几内亚 pg
+Philippines ph
+Філіпіны ph
+Филипини ph
+Filipini ph
+Filippinerne ph
+Filipinas ph
+Filipinak ph
+Fülöp-szigetek ph
+ອາລະປະໂຫàºàº” ph
+Filipinas ph
+Filipíny ph
+Filipini ph
+Filippinerna ph
+è²å¾‹å®¾ ph
+Pakistan pk
+ПакіÑтан pk
+ПакиÑтан pk
+Pakisztán pk
+ລງບ pk
+Paquistão pk
+å·´åŸºæ–¯å¦ pk
+Poland pl
+Poolland pl
+بولندا pl
+PolÅŸa pl
+Польшча pl
+Полша pl
+Polonia pl
+Poljska pl
+Polònia pl
+Polsko pl
+Polen pl
+Polen pl
+Πολωνία pl
+Pollando pl
+Polonia pl
+Poola pl
+Polonia pl
+لهستان pl
+Puola pl
+Pólland pl
+Pologne pl
+Polonia pl
+פולין pl
+Poljska pl
+Lengyelország pl
+Polandia pl
+Pólland pl
+Polonia pl
+ãƒãƒ¼ãƒ©ãƒ³ãƒ‰ pl
+í´ëž€ë“œ pl
+ໂປà»àº¥àº™ pl
+Lenkija pl
+Polija pl
+Polonja pl
+Polen pl
+Polen pl
+Polen pl
+Polònia pl
+Polska pl
+Polónia pl
+Polônia pl
+Polonia pl
+Польша pl
+Poľsko pl
+Poljska pl
+Poljska pl
+I-Poland pl
+Polen pl
+§À¡Ä¡óà pl
+โปà¹à¸¥à¸™à¸”์ pl
+Polonya pl
+Польща pl
+Pholandi pl
+Ba Lan pl
+Pologne pl
+波兰 pl
+波蘭 pl
+Saint Pierre and Miquelon pm
+Sveti Pjer i Migelon pm
+Saint Pierre og Miquelon pm
+Saint Pierre y Miquelon pm
+Saint Pierre eta Miquelon pm
+Saint Pierre és Miquelon pm
+Saint Pierre e Miquelon pm
+Saint Pierre a Miquelon pm
+Sveti Pierre in Miquelon pm
+Saint Pierre och Miquelon pm
+圣皮埃尔和密克隆岛 pm
+Pitcairn pn
+Pitkern pn
+ລງບ pn
+Puerto Rico pr
+Пуерто Рико pr
+Portoriko pr
+ໂປຣໂຕຄອນ pr
+Porto Rico pr
+Portoriko pr
+æ³¢å¤šå°¼å„ pr
+Palestinian Territory ps
+Palesteinse Gebied ps
+السلطة الÙلسطينية ps
+ПалеÑтынÑÐºÐ°Ñ Ñ‚ÑÑ€Ñ‹Ñ‚Ð¾Ñ€Ñ‹Ñ ps
+ПалеÑтина ps
+Palestinska teritorija ps
+Territori Palestí ps
+Palestinské území ps
+Palæstinensiske selvstyreområder ps
+Palästinensisches Gebiet ps
+Παλαιστίνη ps
+Palestinaj teritorioj ps
+Territorio palestino ps
+Palestiina territoorium ps
+Palestina ps
+Ùلسطین ps
+Palestiinalaisalue ps
+Palestinensiska økið ps
+Territoire palestinien ps
+×”×©×˜×—×™× ×”×¤×œ×¡×˜×™× ×™×™× ps
+Palestinski teritorij ps
+Palesztin területek ps
+Territori palestinesi ps
+パレスãƒãƒŠè‡ªæ²»åŒº ps
+íŒ”ë ˆìŠ¤íƒ€ì¸ ìžì¹˜êµ¬ ps
+àºàº²àº™àºžàº´àº¡àºœàº´àº”ພາດ ps
+Palestinos teritorija ps
+Palestina ps
+Palestinske territorier ps
+Palestijns territorium ps
+Palestinske territorium ps
+Bohwa bja Palestina ps
+Palestyna ps
+Território Palestiniano ps
+Território Palestino ps
+Teritoriul Palestinian ps
+ПалеÑтинÑкие территории ps
+Palestínske územia ps
+Palestinski teritorij ps
+I-Palestinian Territory ps
+Palestina ps
+À¡Äо£É ¬¨½Âõ ps
+Filistin Bölgesi ps
+ПалеÑтинÑька Ñ‚ÐµÑ€Ð¸Ñ‚Ð¾Ñ€Ñ–Ñ ps
+Mukano wa maphalesitina ps
+Palestene ps
+Umhlaba wePalestina ps
+å·´å‹’æ–¯å¦åœ°åŒº ps
+å·´å‹’æ–¯å¦é ˜åœ° ps
+Indawo yama-Phalesitina ps
+Portugal pt
+البرتغال pt
+Portuqaliya pt
+ÐŸÐ°Ñ€Ñ‚ÑƒÐ³Ð°Ð»Ñ–Ñ pt
+ÐŸÐ¾Ñ€Ñ‚ÑƒÐ³Ð°Ð»Ð¸Ñ pt
+Portugalsko pt
+ΠοÏτογαλία pt
+Portugalo pt
+پرتغال pt
+Portugali pt
+פורטוגל pt
+Portugália pt
+Portúgal pt
+Portogallo pt
+ãƒãƒ«ãƒˆã‚¬ãƒ« pt
+í¬ë¥´íˆ¬ê°ˆ pt
+ໂປຣຕຸເàºàºª pt
+Portugalija pt
+PortugÄle pt
+Portugall pt
+Portugalia pt
+Portugalia pt
+ÐŸÐ¾Ñ€Ñ‚ÑƒÐ³Ð°Ð»Ð¸Ñ pt
+Portugalsko pt
+Portugalska pt
+I-Portugal pt
+§À¡÷òøø pt
+โปรตุเà¸à¸ª pt
+Portekiz pt
+ÐŸÐ¾Ñ€Ñ‚ÑƒÐ³Ð°Ð»Ñ–Ñ pt
+Bá»EÄào Nha pt
+è‘¡è„牙 pt
+è‘¡è„牙 pt
+Palau pw
+Палау pw
+Палау pw
+ມອລຕາ pw
+帕劳群岛 pw
+Paraguay py
+Paraguaai py
+باراغواي py
+Paraqvay py
+Парагвай py
+Парагвай py
+Paragvaj py
+Paraguai py
+ΠαÏαγουάη py
+Paragvajo py
+Paraguai py
+پاراگویه py
+Paraguai py
+פרגו××™ py
+Paragvaj py
+パラグアイ py
+파ë¼ê³¼ì´ py
+ປາລາàºàºàº§àº py
+Paragvajus py
+Paragvaja py
+Paragwaj py
+Paraguai py
+Paragwaj py
+Paraguai py
+Paraguai py
+Paraguai py
+Парагвай py
+Portugalsko py
+Paragvaj py
+Paragvaj py
+I-Paraguay py
+Àá̧Špy
+ปาราà¸à¸§à¸±à¸¢ py
+Парагвай py
+Paragway py
+巴拉圭 py
+巴拉圭 py
+Qatar qa
+قطر qa
+Катар qa
+Катар qa
+Katar qa
+Katar qa
+Katar qa
+ÎšÎ±Ï„Î¬Ï qa
+Kataro qa
+Katar qa
+قطر qa
+Katar qa
+קטר qa
+Katar qa
+Katar qa
+カタール qa
+카타르 qa
+ມອລຕາ qa
+Katar qa
+Катар qa
+Katar qa
+Katar qa
+I-Qatar qa
+¸¾¡÷ qa
+Katar qa
+Катар qa
+å¡å¡”å°” qa
+å¡é” qa
+Romania ro
+Romenië ro
+رومانيا ro
+Rumıniya ro
+Ð ÑƒÐ¼Ñ‹Ð½Ñ–Ñ ro
+Ð ÑƒÐ¼ÑŠÐ½Ð¸Ñ ro
+Roumania ro
+Rumunija ro
+Rumunsko ro
+Rumænien ro
+Rumänien ro
+Ρουμανία ro
+Rumanio ro
+Rumanía ro
+Rumeenia ro
+Errumania ro
+رومانی ro
+Rumenia ro
+Roumanie ro
+Romanía ro
+רומניה ro
+Rumunjska ro
+Románia ro
+Rumania ro
+Rúmenía ro
+ルーマニア ro
+루마니아 ro
+ໂລມາເນີຠro
+Rumunija ro
+RumÄnija ro
+Rumanija ro
+Roemenië ro
+Rumunia ro
+Roménia ro
+Romênia ro
+Ð ÑƒÐ¼Ñ‹Ð½Ð¸Ñ ro
+Rumunsko ro
+Romunija ro
+Rumunija ro
+I-Romania ro
+Rumänien ro
+Õ§Ãɢ¡ ro
+โรมาเนีย ro
+Romanya ro
+Ð ÑƒÐ¼ÑƒÐ½Ñ–Ñ ro
+Ru ma ni ro
+Roumaneye ro
+罗马尼亚 ro
+羅馬尼亞 ro
+Russia ru
+Rusland ru
+روسيا ru
+Rusiya ru
+РаÑÐµÑ ru
+РуÑÐ¸Ñ ru
+Rusia ru
+Rusija ru
+Rússia ru
+Rusko ru
+Rusland ru
+Russland ru
+Ρωσία ru
+Ruslando ru
+Rusia ru
+Venemaa ru
+Errusia ru
+روسیه ru
+Venäjä ru
+Russland ru
+Russie ru
+Rusia ru
+רוסיה ru
+Rusija ru
+Oroszország ru
+Rusia ru
+Rússland ru
+ロシア ru
+러시아 ru
+ລັດເຊີຠru
+Rusija ru
+Krievija ru
+Russja ru
+Russland ru
+Rusland ru
+Russland ru
+Rosja ru
+Rússia ru
+Rússia ru
+Rusia ru
+РоÑÑÐ¸Ñ ru
+Rusko ru
+Rusija ru
+Rusija ru
+I-Russia ru
+Ryssland ru
+ú¢Â¡ ru
+รัสเซีย ru
+Rusya ru
+РоÑÑ–Ñ ru
+Rashia ru
+Nga ru
+Russeye ru
+Rashiya ru
+ä¿„ç½—æ–¯ ru
+ä¿„ç¾…æ–¯ ru
+Rwanda rw
+Руанда rw
+Руанда rw
+Ruanda rw
+Ruanda rw
+Ruanda rw
+à»àºžàº™àº”້າ rw
+Ruanda rw
+Ruanda rw
+墿—ºè¾¾ rw
+Saudi Arabia sa
+Saudi Arabië sa
+السعودية sa
+СаудаўÑÐºÐ°Ñ ÐÑ€Ð°Ð±Ñ–Ñ sa
+СаудитÑка ÐÑ€Ð°Ð±Ð¸Ñ sa
+Saudijska Arabija sa
+Aràbia Saudí sa
+Saúdská Arábie sa
+Saudi Arabien sa
+Saudi-Arabien sa
+Σαουδική ΑÏαβία sa
+SaÅ­di-Arabio sa
+Arabia Saudí sa
+Saudi Araabia sa
+عربستان سعودی sa
+Saudi-Arabia sa
+Arabie Saoudite sa
+ערב הסעודית sa
+Saudijska Arabija sa
+Szaúd-Arábia sa
+Arabia saudita sa
+サウジアラビア sa
+사우디 ì•„ë¼ë¹„ì•„ sa
+ອາລະບິຠsa
+Saudi Arabija sa
+Għarabja Sawdita sa
+Saudi-Arabia sa
+Saudi-Arabië sa
+Saudi-Arabia sa
+Arabia Saudyjska sa
+Arábia Saudita sa
+Arábia Saudita sa
+Arabia Saudită sa
+СаудовÑÐºÐ°Ñ ÐÑ€Ð°Ð²Ð¸Ñ sa
+Saudská arábia sa
+Saudova Arabija sa
+I-Saudi Arabia sa
+Saudiarabien sa
+º×¾¢ «§ÃÀ¢Â¡ sa
+Suudi Arabistan sa
+СаудівÑька ÐÑ€Ð°Ð²Ñ–Ñ sa
+沙特阿拉伯 sa
+æ²™çƒåœ°é˜¿æ‹‰ä¼¯ sa
+Solomon Islands sb
+Саламонавы аÑтравы sb
+Соломонови ОÑтрови sb
+Solomonska ostrva sb
+Salomon-øerne sb
+Islas Salomón sb
+Solomon Irlak sb
+Salamon-szigetek sb
+ສະໂລວະເນີຠsb
+Ilhas Salomão sb
+Šalamúnove ostrovy sb
+Solomonovi otoki sb
+Salomonöarna sb
+所罗门群岛 sb
+Seychelles sc
+СÑйшÑлы sc
+СейшелÑки оÑтрови sc
+Sejšeli sc
+Seychellerne sc
+ເຊລ sc
+Sejšeli sc
+Seychellerna sc
+塞舌尔 sc
+Sudan sd
+السودان sd
+Судан sd
+Судан sd
+Sudán sd
+Σουδάν sd
+Sudano sd
+Sudán sd
+Sudaan sd
+سودان sd
+Sudania sd
+Soudan sd
+סודן sd
+Szudán sd
+Súdan sd
+スーダン sd
+수단 sd
+ຊູດານ sd
+Sudanas sd
+SudÄna sd
+Sudão sd
+Sudão sd
+Судан sd
+Sudán sd
+I-Sudan sd
+ü¡ý sd
+ซูดาน sd
+Судан sd
+Sudani sd
+Soudan sd
+è‹ä¸¹ sd
+蘇丹 sd
+Sweden se
+Swede se
+السويد se
+İsveç se
+ШвÑÑ†Ñ‹Ñ se
+Ð¨Ð²ÐµÑ†Ð¸Ñ se
+Sveden se
+Å vedska se
+Suècia se
+Švédsko se
+Sverige se
+Schweden se
+Σουηδία se
+Svedio se
+Suecia se
+Rootsi se
+Suedia se
+سوید se
+Ruotsi se
+Svøriki se
+Suède se
+Suecia se
+שבדיה se
+Å vedska se
+Svédország se
+Swedia se
+Svíþjóð se
+Svezia se
+スウェーデン se
+ìŠ¤ì›¨ë´ se
+ສະວີເດນ se
+Å vedija se
+Zviedrija se
+Svezja se
+Sverige se
+Zweden se
+Sverige se
+Suècia se
+Szwecja se
+Suécia se
+Suécia se
+Suedia se
+Ð¨Ð²ÐµÑ†Ð¸Ñ se
+Švédsko se
+Å vedska se
+Å vedska se
+I-Sweden se
+Sverige se
+ÃÅ£¼ý se
+สวีเดน se
+İsveç se
+Ð¨Ð²ÐµÑ†Ñ–Ñ se
+Swidene se
+Thuỵ Äiển se
+瑞典 se
+瑞典 se
+Singapore sg
+Сынгапур sg
+Сингапур sg
+Singapur sg
+Singapur sg
+Szingapúr sg
+ໂຊນາ sg
+Singapura sg
+Singapur sg
+Singapur sg
+æ–°åŠ å¡ sg
+Saint Helena sh
+Свети Елена sh
+Sveta Helena sh
+St. Helena sh
+Santa Helena sh
+Szent Heléna sh
+ຫົວເລື່ອງ sh
+Santa Helena sh
+Svätá Helena sh
+Sveta Helena sh
+圣赫勒拿岛 sh
+Slovenia si
+Slovenië si
+سلوÙينيا si
+Sloveniya si
+Ð¡Ð»Ð°Ð²ÐµÐ½Ñ–Ñ si
+Ð¡Ð»Ð¾Ð²ÐµÐ½Ð¸Ñ si
+Slovenija si
+Eslovenia si
+Slovinsko si
+Slovenien si
+Slowenien si
+Σλοβενία si
+Slovenio si
+Eslovenia si
+Sloveenia si
+Eslovenia si
+اسلوانی si
+Slovénie si
+Eslovenia si
+סלובניה si
+Slovenija si
+Szlovénia si
+Slóvenía si
+スロベニア si
+슬로베니아 si
+ສະໂລວະເນີຠsi
+SlovÄ—nija si
+Slovēnija si
+Slovenja si
+Slovenië si
+Eslovenia si
+Słowenia si
+Eslovénia si
+Eslovênia si
+Ð¡Ð»Ð¾Ð²ÐµÐ½Ð¸Ñ si
+Slovinsko si
+Slovenija si
+Slovenija si
+I-Slovenia si
+Slovenien si
+çġŢɢ¡ si
+สโลเวเนีย si
+Slovenya si
+Ð¡Ð»Ð¾Ð²ÐµÐ½Ñ–Ñ si
+斯洛文尼亚 si
+斯洛維尼亞 si
+Slovakia sk
+Slovakië sk
+Ø³Ù„ÙˆÙØ§ÙƒÙŠØ§ sk
+Slovakiya sk
+Ð¡Ð»Ð°Ð²Ð°ÐºÑ–Ñ sk
+Ð¡Ð»Ð¾Ð²Ð°ÐºÐ¸Ñ sk
+SlovaÄka sk
+Eslovaquia sk
+Slovensko sk
+Slovakiet sk
+Slowakien sk
+Σλοβακία sk
+Slovakujo sk
+Eslovaquia sk
+Slovakkia sk
+Eslovakia sk
+اسلواکی sk
+Slovaquie sk
+סלובקיה sk
+SlovaÄka sk
+Szlovákia sk
+Slóvakía sk
+Slovacchia sk
+スロãƒã‚­ã‚¢ sk
+슬로바키아 sk
+ສະໂລວັຠsk
+Slovakija sk
+SlovÄkija sk
+Slovakja sk
+Slovakije sk
+Słowacja sk
+Eslováquia sk
+Eslováquia sk
+Slovacia sk
+Ð¡Ð»Ð¾Ð²Ð°ÐºÐ¸Ñ sk
+Slovensko sk
+Slovaška sk
+I-Slovakia sk
+Slovakien sk
+çġš츢 sk
+สโลวัค sk
+Slovakya sk
+Ð¡Ð»Ð¾Ð²Ð°ÐºÑ–Ñ sk
+斯洛ä¼å…‹ sk
+斯洛ä¼å…‹ sk
+San Marino sm
+Сан-Марына sm
+Сан Марино sm
+ໂຊນາ sm
+圣马力诺 sm
+Senegal sn
+СÑнÑгал sn
+Сенегал sn
+Szenegál sn
+ທົ່ວໄປ sn
+塞内加尔 sn
+Somalia so
+Somalië so
+صومال so
+Самалі so
+Ð¡Ð¾Ð¼Ð°Ð»Ð¸Ñ so
+Somalija so
+Somàlia so
+Somálsko so
+Σομαλία so
+Somalio so
+Somaalia so
+سومالی so
+Somalie so
+סומליה so
+Somalija so
+Szomália so
+ソマリア so
+소ë§ë¦¬ì•„ so
+ໂລມາເນີຠso
+Somalis so
+Somalija so
+Somalie so
+Somália so
+Somália so
+Сомали so
+Somálsko so
+Somalija so
+I-Somalia so
+§º¡Ã¡Ä¢Â¡ so
+Somali so
+Сомалі so
+Somaleye so
+索马里 so
+索馬利亞 so
+Suriname sr
+Сурынам sr
+Суринам sr
+Surinam sr
+ເຊີເບີຠsr
+Surinam sr
+Surinam sr
+Surinam sr
+Sao Tome and Principe st
+Сан Томе и Приницпе st
+Sao Tome i Principe st
+Sao Tomé og Principe st
+Sao Tome y Príncipe st
+Sao Tome eta Principe st
+Sao Tome és Principe st
+ບà»àº¥àº´àºàº²àº™ st
+São Tome e Príncipe st
+Sao Tome a Principe st
+Sao Tome in Principe st
+São Tomé och Príncipe st
+El Salvador sv
+Ø§Ù„Ø³Ù„ÙØ§Ø¯ÙˆØ± sv
+Сальвадор sv
+Ел Салвадор sv
+Salvador sv
+Salvador sv
+Ελ Î£Î±Î»Î²Î±Î½Ï„ÏŒÏ sv
+Elsalvadoro sv
+Salvador sv
+السالوادور sv
+Salvador sv
+O Salvador sv
+×ל סלבדור sv
+Salvador sv
+エルサルãƒãƒ‰ãƒ« sv
+엘살바ë„르 sv
+ເອລຊັນວາດດ໠sv
+Salvadoras sv
+Salvadora sv
+Salwador sv
+Salvador sv
+Сальвадор sv
+Salvádor sv
+Salvador sv
+I-El Salvador sv
+±ø º¡øÅ§¼¡÷ sv
+เอลซัลวาดอร์ sv
+Ель-Сальвадор sv
+è¨å°”瓦多 sv
+薩爾瓦多 sv
+Syria sy
+Sirië sy
+سوريا sy
+Ð¡Ñ‹Ñ€Ñ‹Ñ sy
+Ð¡Ð¸Ñ€Ð¸Ñ sy
+Sirija sy
+Síria sy
+Sýrie sy
+Syrien sy
+Syrien sy
+ΣυÏία sy
+Sirio sy
+Siria sy
+Süüria sy
+Siria sy
+سوریه sy
+Syyria sy
+Syrie sy
+סוריה sy
+Sirija sy
+Szíria sy
+Siria sy
+シリア sy
+시리아 sy
+ເຊີເບີຠsy
+Sirija sy
+Siria sy
+Syrië sy
+Síria sy
+Síria sy
+Siria sy
+Ð¡Ð¸Ñ€Ð¸Ñ sy
+Sýria sy
+Sirija sy
+I-Syria sy
+Syrien sy
+º¢Ã¢Â¡ sy
+Suriye sy
+Ð¡Ð¸Ñ€Ñ–Ñ sy
+å™åˆ©äºš sy
+敘利亞 sy
+Swaziland sz
+СвазылÑнд sz
+Свазиленд sz
+Svazilend sz
+Swazilandia sz
+Swazilandia sz
+Szváziföld sz
+ລາດສະນາຈັàºà»„ທຠsz
+Suécia sz
+Swazijsko sz
+Svazi sz
+æ–¯å¨å£«å…° sz
+Turks and Caicos Islands tc
+Turks i Kaikos ostrva tc
+Turks- og Caicosøerne tc
+Islas Turcos y Caicos tc
+Turks eta Caicos Irlak tc
+Turks- és Caicos-szigetek tc
+Ilhas Caicos e Turca tc
+Turks a Caicos ostrovy tc
+Otoka Turks in Caicos tc
+Turks- och Caicosöarna tc
+特克斯和凯科斯群岛 tc
+Chad td
+Чад td
+Чад td
+ÄŒad td
+Tchad td
+Txad td
+Csád td
+ເàºàº¡à»„ພ່ td
+ÄŒad td
+ÄŒad td
+Tchad td
+ä¹å¾— td
+Togo tg
+Тога tg
+Того tg
+ຂອງເລ່ນສະນຸຠtg
+多哥 tg
+Thailand th
+تايلاند th
+Tayland th
+ТайлÑнд th
+Тайланд th
+Tajland th
+Tailàndia th
+Thajsko th
+Ταϊλάνδη th
+Tajlando th
+Tailandia th
+Tai th
+Thailandia th
+تایلند th
+Thaimaa th
+Tailand th
+Thaïlande th
+Tailandia th
+ת×ילנד th
+Tajland th
+Thaiföld th
+Tæland th
+Tailandia th
+タイ th
+태국 (타ì´) th
+ລາດສະນາຈັàºà»„ທຠth
+Tailandas th
+TaivÄna th
+Tajlandja th
+Tailandia th
+Tajlandia th
+Tailândia th
+Tailândia th
+Tailanda th
+Таиланд th
+Thajsko th
+Tajska th
+Tajland th
+I-Thailand th
+¾¡öÄ¡óà th
+ราชอาณาจัà¸à¸£à¹„ทย th
+Tayland th
+Таїланд th
+Thái Lan th
+Taylande th
+泰国 th
+泰國 th
+Tajikistan tj
+ТаджыкіÑтан tj
+ТаджикиÑтан tj
+Tadžikistan tj
+Tajikistán tj
+Tadzsikisztán tj
+ໃຕ້ຫວັນ tj
+Tajiquistão tj
+Tadžikistan tj
+Tadžikistan tj
+Tadzjikistan tj
+å¡”å‰å…‹æ–¯å¦ tj
+Tokelau tk
+Токелао tk
+ເບລາລັສ tk
+Turkmenistan tm
+ТуркмÑніÑтан tm
+ТуркмениÑтан tm
+Turkmenistán tm
+Türkmenisztán tm
+ຕຸລະàºàºµ tm
+Turquia tm
+åœŸåº“æ›¼æ–¯å¦ tm
+Tunisia tn
+Tunisië tn
+تونس tn
+Ð¢ÑƒÐ½Ñ–Ñ tn
+Ð¢ÑƒÐ½Ð¸Ñ tn
+Tunis tn
+Tuníssia tn
+Tunisko tn
+Tunesien tn
+Tunesien tn
+Τυνησία tn
+Tunisio tn
+Túnez tn
+Tuneesia tn
+تونس tn
+Tunesia tn
+Tunisie tn
+תוניסיה tn
+Tunis tn
+Tunézia tn
+ãƒãƒ¥ãƒ‹ã‚¸ã‚¢ tn
+튀니지 tn
+ລັດເຊີຠtn
+Tunisas tn
+Tuneżija tn
+Tunisie tn
+Tunezja tn
+Tunísia tn
+Tunísia tn
+Ð¢ÑƒÐ½Ð¸Ñ tn
+Tunisko tn
+Tunizija tn
+I-Tunisia tn
+Tunisien tn
+ÃÉ¢º¢Â¡ tn
+Tunus tn
+Ð¢ÑƒÐ½Ñ–Ñ tn
+çªå°¼æ–¯ tn
+çªå°¼è¥¿äºž tn
+Tonga to
+Тонга to
+Тонга to
+ໂຊນາ to
+汤加 to
+East Timor tp
+ИÑточен Тимур tp
+IstoÄni Timor tp
+Østtimor tp
+Timor oriental tp
+Ekialdeko Timor tp
+Kelet-Timor tp
+ວັນà»àº¥àº°à»€àº§àº¥àº² tp
+Timor Leste tp
+Východný Timor tp
+Vzhodni Timor tp
+Östtimor tp
+ä¸œå¸æ±¶ tp
+Turkey tr
+Turkeye tr
+تركيا tr
+Türkiyə tr
+Ð¢ÑƒÑ€Ñ†Ñ‹Ñ tr
+Ð¢ÑƒÑ€Ñ†Ð¸Ñ tr
+Turkia tr
+Turska tr
+Turquia tr
+Turecko tr
+Tyrkiet tr
+Türkei tr
+ΤουÏκία tr
+Turkujo tr
+Turquía tr
+Türgi tr
+Turkia tr
+ترکیه tr
+Turkki tr
+Turkaland tr
+Turquie tr
+Turquía tr
+טורקיה tr
+Turska tr
+Törökország tr
+Turki tr
+Tyrkland tr
+Turchia tr
+トルコ tr
+터키 tr
+ຕຸລະàºàºµ tr
+Turkija tr
+Turcija tr
+Turkija tr
+Tyrkia tr
+Turkije tr
+Tyrkia tr
+Turquia tr
+Turcja tr
+Turquia tr
+Turquia tr
+Turcia tr
+Ð¢ÑƒÑ€Ñ†Ð¸Ñ tr
+Turecko tr
+TurÄija tr
+Turska tr
+I-Turkey tr
+Turkiet tr
+ÃÕ츢 tr
+ตุรà¸à¸µ tr
+Türkiye tr
+Туреччина tr
+Thá»ENhÄ© Kì tr
+土耳其 tr
+土耳其 tr
+Trinidad and Tobago tt
+Trinidad en Tobago tt
+ترينيداد و توباغو tt
+Trinidad vÉ™ Tabaqo tt
+Трынідад і Табага tt
+Тринидад и Тобаго tt
+Trinidad ha Tobago tt
+Trinidad i Tobago tt
+Trinidad i Tobago tt
+Trinidad a Tobago tt
+Trinidad og Tobago tt
+Trinidad und Tobago tt
+ΤÏίνινταντ και Τομπάγκο tt
+Trinidado kaj Tobago tt
+Trinidad y Tobago tt
+Trinidad ja Tobago tt
+Trinidad eta Tobago tt
+ترینیداد Ùˆ ØªÙØ¨Ø§Ú¯Ùˆ tt
+Trinidad ja Tobago tt
+Trinidad og Tobago tt
+Trinidad et Tobago tt
+Trindade e Tobago tt
+טרינידד וטובגו tt
+Trinidad i Tobago tt
+Trinidad és Tobago tt
+Trinidad dan Tobago tt
+Trinidad og Tobago tt
+Trinidad e Tobago tt
+トリニダードトãƒã‚³ tt
+트리니다드토바고 tt
+ຕີນິà»àº”ດà»àº¥àº°à»‚ທບາໂຠtt
+Trinidadas ir Tobagas tt
+Trinidada un Tobago tt
+Trinidad u Tobago tt
+Trinidad og Tobago tt
+Trinidad en Tobago tt
+Trinidad og Tobago tt
+Trinidad le Tobago tt
+Trinidad e Tobago tt
+Trinidad i Tobago tt
+Trinidade e Tobago tt
+Trinidad e Tobago tt
+Trinidad ÅŸi Tobago tt
+Тринидад и Тобаго tt
+Trinidad a Tobago tt
+Trinidad in Tabago tt
+Trinidad i Tobago tt
+I-Trinidad kanye neTobago tt
+Trinidad och Tobago tt
+ðâɢ¼¡ð & ¦¼¡À¡§¸¡ tt
+ตรีนิà¹à¸”ดà¹à¸¥à¸°à¹‚ทบาโภtt
+Trinidad veTabago tt
+РеÑпубліка Трінідад та Тобаго tt
+Trinidad na Tobago tt
+Trinidad và Tobago tt
+Trinidad ne Tobago tt
+特里尼达和多巴哥 tt
+åƒé‡Œé”åŠæ‰˜è²å“¥ tt
+Trinidad knaye ne-Tobago tt
+Tuvalu tv
+Тувалу tv
+Тували tv
+ຊູລູ tv
+å›¾ç“¦å¢ tv
+Taiwan tw
+تايوان tw
+Tayvan tw
+Тайвань tw
+Тайван tw
+Tajvan tw
+Ταϊβάν tw
+Tajvano tw
+Taiwán tw
+Taivan tw
+تایوان tw
+Taivan tw
+Taïwan tw
+Taiwán tw
+טיוו×ן tw
+Tajvan tw
+Tajvan tw
+å°æ¹¾ tw
+대만 tw
+ໃຕ້ຫວັນ tw
+Taivanis tw
+TaivÄna tw
+Tajwan tw
+Tajwan tw
+Formosa tw
+Тайвань tw
+Tajvan tw
+Tajvan tw
+I-Taiwan tw
+¾¡öÅ¡ý tw
+ได้หวัน tw
+Tayvan tw
+Тайвань tw
+Äài Loan tw
+䏭国尿¹¾ tw
+å°ç£ tw
+Tanzania, United Republic of tz
+Ð—Ð»ÑƒÑ‡Ð°Ð½Ð°Ñ Ð ÑÑпубліка Ð¢Ð°Ð½Ð·Ð°Ð½Ñ–Ñ tz
+Ð¢Ð°Ð½Ð·Ð°Ð½Ð¸Ñ tz
+Tanzanija, Ujedinjena Republika tz
+Tanzania tz
+Tanzania, Republica de tz
+Tanazia, Errepublika Batua tz
+Tanzánia tz
+ໂດມິນິàºàº±àº™ tz
+República da Tanzânia tz
+Tanzánia, Spojená republika tz
+Tanzanija, Združena republika tz
+Förenade republiken Tanzania tz
+妿¡‘尼亚 tz
+Ukraine ua
+Ukraïne ua
+أوكرانيا ua
+Ukrayna ua
+Украіна ua
+Украйна ua
+Ukraina ua
+Ukrajina ua
+Ucraïna ua
+Ukrajina ua
+ΟυκÏανία ua
+Ukrainio ua
+Ucrania ua
+Ukraina ua
+Ukrania ua
+اکراین ua
+Ukraina ua
+Ukraina ua
+Ucraína ua
+×וקר××™× ×” ua
+Ukrajina ua
+Ukrajna ua
+Ukraina ua
+Úkraína ua
+Ucraina ua
+ウクライナ ua
+ìš°í¬ë¼ì´ë‚˜ ua
+àºàº¹à»€àº„ຣນ ua
+Ukraina ua
+Ukraina ua
+Ukranja ua
+Ukraina ua
+Oekraïne ua
+Ukraina ua
+Ucraina ua
+Ukraina ua
+Ucrânia ua
+Ucrânia ua
+Ucraina ua
+Украина ua
+Ukrajina ua
+Ukrajina ua
+Ukrajna ua
+I-Ukraine ua
+Ukraina ua
+¯ì¦Ãöý ua
+ยูเครน ua
+Ukrayna ua
+Україна ua
+Ukraina ua
+Ucrinne ua
+乌克兰 ua
+çƒå…‹è˜­ ua
+Uganda ug
+Уганда ug
+Уганда ug
+à»àºžàº™àº”້າ ug
+乌干达 ug
+United States of America us
+Vereenigde State van Amerika us
+الولايات المتحدة الأمريكية us
+Amerika Birləşmiş Ştatları us
+Ð—Ð»ÑƒÑ‡Ð°Ð½Ñ‹Ñ Ð¨Ñ‚Ð°Ñ‚Ñ‹ ÐмÑрыкі us
+СÐЩ us
+Stadoù-Unanet Amerika us
+Sjedinjene AmeriÄke Države us
+Estats Units d'Amèrica us
+Spojené státy americké us
+USA us
+USA us
+Ην. Πολιτείες της ΑμεÏικής us
+Usono us
+Estados Unidos de América us
+Ameerika Ühendriigid us
+Amerikako Estatu Batuak us
+ایالات متحده‌ی آمریکا us
+Yhdysvallat us
+Sambandsríki Amerika (USA) us
+États Unis d'Amérique us
+Estados Unidos de América us
+×רצות הברית us
+Sjedinjene AmeriÄke Države us
+Amerikai Egyesült Ãllamok us
+Amerika Serikat us
+Bandaríki Norður Ameríku us
+Stati Uniti d'America us
+アメリカ us
+미 합중국 us
+ສະຫະລັດອາເມລິàºàº² us
+JungtinÄ—s Amerikos Valstijos us
+Amerikas SavienotÄs Valstis us
+Stati Uniti us
+USA us
+Verenigde Staten van Amerika us
+USA us
+Estats Units d'Amèrica us
+Stany Zjednoczone Ameryki us
+Estados Unidos da América us
+Estados Unidos us
+Statele Unite ale Americii us
+Соединенные Штаты Ðмерики us
+USA us
+Združene države Amerike us
+Sjedinjene ameriÄke države us
+I-United States of America us
+Amerikas förenta stater us
+³ì¸¢Â «¦Ãâì¸ ¿¡Î¸û us
+สหรัà¸à¸­à¹€à¸¡à¸£à¸´à¸à¸² us
+Amerika BirleÅŸik Devletleri us
+СШРus
+mashango o tangananaho a America us
+MÄ© us
+United States ye Melika us
+美利åšåˆä¼—国 us
+美利堅åˆçœ¾åœ‹ us
+Uruguay uy
+الأوروغواي uy
+Uruqvay uy
+Уругвай uy
+Уругвай uy
+Urugvaj uy
+Uruguai uy
+ΟυÏουγουάη uy
+Urugvajo uy
+Uruguai uy
+اروگویه uy
+Uruguai uy
+×ורוגו××™ uy
+Urugvaj uy
+ウルグアイ uy
+ìš°ë£¨ê³¼ì´ uy
+ອຸລຸàºàºàº§àº uy
+Urugvajus uy
+Urugvaja uy
+Urugwaj uy
+Uruguai uy
+Urugwaj uy
+Uruguai uy
+Uruguai uy
+Uruguai uy
+Уругвай uy
+Uruguaj uy
+Urugvaj uy
+Urugvaj uy
+I-Uruguay uy
+¯Õ̧Šuy
+อุรุà¸à¸§à¸±à¸¢ uy
+Уругвай uy
+Ourougway uy
+乌拉圭 uy
+çƒæ‹‰åœ­ uy
+Uzbekistan uz
+УзбÑкіÑтан uz
+УзбекиÑтан uz
+Uzbekistán uz
+Üzbegisztán uz
+ເດນ່ງນ uz
+Uzbequistão uz
+ä¹Œå…¹åˆ«å…‹æ–¯å¦ uz
+Vatican City va
+Ватыкан va
+Ватикана va
+Vatikan va
+Vatikanstaten va
+Vaticano va
+Batikano Hiria va
+Vatikán va
+ລັດເວີຠva
+Cidade do Vaticano va
+Vatikán va
+Vatikan va
+Vatikanstaten va
+梵蒂冈 va
+St. Vincent and the Grenadines vc
+St. Vincent en die Grenadene vc
+سانت Ùينسنت Ùˆ الغرينادين vc
+St. Vincent vÉ™ Grenadines vc
+Сент-ВинÑент и Гренадине vc
+S. Visant hag ar Grenadinez vc
+Sveti Vincent i Grenadini vc
+St. Vincent i les Granadines vc
+St. Vincent a Grenadiny vc
+St. Vincent og Grenadinerne vc
+St. Vincent und Grenadinen vc
+St. Vincent kaj la Grenadinoj vc
+San Vicente y las Granadinas vc
+St. Vincent ja Grenadines vc
+St. Vincent eta Grenadines vc
+سن وینسن و گرادینس vc
+St. Vincent ja Grenadiinit vc
+Sankta Vinsent og Grenadinoyggjar vc
+St Vincent et les Grenadines vc
+San Vicente e as Granadinas vc
+סנט וינסנט ×•×”×’×¨× ×“×™× ×™× vc
+St. Vincent és Grenadines vc
+St. Vincent dan the Grenadines vc
+St. Vincent og Grenadines vc
+S. Vincent e the Grenadines vc
+セントヴィンセントグレナディン vc
+세ì¸íЏ 빈센트 그레나딘 vc
+ເຊີນວິນà»àºŠàº™ à»àº¥àº°à»€àºàº™àº²àº”ີນ vc
+Å v. Vincentas ir Grenadinai vc
+Sv. Vincents un Grenadīnes vc
+St. Vinċenz u l-Grenadini vc
+St. Vincent og Grenadinene vc
+St. Vincent en de Grenadines vc
+St. Vincent og Grenadinane vc
+St. Vincent le Grenadines vc
+St. Vincent e les Granadines vc
+St. Vincent i Grenadyny vc
+São Vicente e Grenadinas vc
+São Vicente e Grenadines vc
+Sf. Vincent ÅŸi Grenadines vc
+Сент-ВинÑент и Гренадины vc
+St. Vincent a Grenadines vc
+Sv. Vincent in Grenadini vc
+St. Vincent i Grenadine vc
+I-St. Vincent and the Grenadines vc
+St. Vincent och Grenadinerna vc
+¦ºÂ¢ýð Å¢ý¦ºýð & ¸¢¦ÃÉËý¸û vc
+เซนต์วินเซนต์ à¹à¸¥à¸° เà¸à¸£à¸™à¸²à¸”ีน vc
+St. Vincent ve Grenadines vc
+Сент-ВінÑент Ñ– Гренадіни vc
+St. Vincent na Grenadines vc
+St. Vincent và Grenadines vc
+St. Vincent ne Grenadines vc
+圣文森特和格林那达 vc
+è–æ–‡æ£®åŠæ ¼ç´é‚£ä¸ vc
+I-St. Vincent kanye ne-Grenadines vc
+Venezuela ve
+Ùنزويلا ve
+Ð’ÑнÑÑуÑла ve
+Венецуела ve
+Venecuela ve
+Βενεζουέλα ve
+Venezuelo ve
+Venetsueela ve
+ونزویلا ve
+Venesuela ve
+Vénézuela ve
+ונצו×לה ve
+Venecuela ve
+ベãƒã‚ºã‚§ãƒ© ve
+ë² ë„¤ìˆ˜ì—˜ë¼ ve
+ເວເນຊຸເອລາ ve
+Venesuela ve
+Venecuēla ve
+Veneżwela ve
+Wenezuela ve
+ВенеÑуÑла ve
+Venecuela ve
+I-Venezuela ve
+¦ÅÉ¢ÃÅÄ¡ ve
+เวเนซูเอลา ve
+ВенеÑуела ve
+委内瑞拉 ve
+委內瑞拉 ve
+Virgin Islands, British vg
+ВирджинÑки ОÑтрови, БританÑки vg
+DjeviÄanska ostrva, Britanska vg
+Britiske jomfruøer vg
+Islas Vírgenes Británicas vg
+Irla Birjinak, Britaniar vg
+Virgin-szigetek (brit) vg
+Ilhas Virgens, Inglaterra vg
+Panenské Ostrovy, Britské vg
+Deviški otoki, Britanski vg
+Brittiska Jungfruöarna vg
+维尔京群岛,英国 vg
+Virgin Islands, U.S. vi
+ВирджинÑки ОÑтрови, ÐмериканÑки vi
+DjeviÄanska ostrva, AmeriÄka vi
+Jomfruøerne vi
+Islas Vírgenes Americanas vi
+Irla Birjinak, EE.BB. vi
+Virgin-szigetek (USA) vi
+Ilhas Virgens, EUA vi
+Panenské Ostrovy, Americké vi
+Deviški otoki, ZDA vi
+Amerikanska Jungfruöarna vi
+维尔京群岛,美国 vi
+Vietnam vn
+Viëtnam vn
+Ùييتنام vn
+Vyetnam vn
+Віетнам vn
+Виетнам vn
+Vijetnam vn
+Βιετνάμ vn
+Vjetnamo vn
+ویتنام vn
+וייטנ×× vn
+Vijetnam vn
+Víetnam vn
+ベトナム vn
+베트남 vn
+ຫວງດນາມ vn
+Vietnamas vn
+Vjetnama vn
+Vjetnam vn
+Viëtnam vn
+Wietnam vn
+Vietname vn
+Vietnã vn
+Вьетнам vn
+I-Vietnam vn
+เวียตนาม vn
+В'єтнам vn
+è¶Šå— vn
+è¶Šå— vn
+Vanuatu vu
+Вануату vu
+Ванути vu
+ຈີນ vu
+瓦努阿图 vu
+Wallis and Futuna wf
+Valis i Futuna wf
+Wallis- og Futuna-øerne wf
+Wallis y Futuna wf
+Wallis eta Futuna wf
+Wallis és Futuna wf
+ປັàºàº­àº´àº™àºžàº²àºš wf
+Wallis e Futuna wf
+Wallis a Futuna wf
+Wallis in Futuna wf
+Wallis och Futuna wf
+Samoa ws
+Самоа ws
+Ð¡Ð°Ð¼Ð¾Ñ ws
+Szamoa ws
+ໂຊນາ ws
+è¨æ‘©äºšç¾¤å²› ws
+Yemen ye
+اليمن ye
+Емен ye
+Йемен ye
+Jemen ye
+Iemen ye
+Jemen ye
+Jemen ye
+Υεμένη ye
+Jemeno ye
+Jeemen ye
+یمن ye
+Jemen ye
+Jemen ye
+תימן ye
+Jemen ye
+Jemen ye
+イエメン ye
+예멘 ye
+ເດມອນ ye
+Jemenas ye
+Jemen ye
+Jemen ye
+Jemen ye
+Jemen ye
+Jemen ye
+Iémen ye
+Йемен ye
+Jemen ye
+Jemen ye
+I-Yemen ye
+Jemen ye
+§ÂÃý ye
+Ємен ye
+也门 ye
+葉門 ye
+Yugoslavia yu
+ЮгаÑÐ»Ð°Ð²Ñ–Ñ yu
+ЮгоÑÐ»Ð°Ð²Ð¸Ñ yu
+Jugoslavija yu
+Jugoslavien (Serbien/Montenegro) yu
+Jugoszlávia yu
+ໂບລິເວີຠyu
+Iugoslávia yu
+Juhoslávia yu
+Jugoslavija yu
+Jugoslavien yu
+å—æ–¯æ‹‰å¤« yu
+South Africa za
+Suid Afrika za
+جنوب Ø£ÙØ±ÙŠÙ‚يا za
+Cənubi Afrika za
+ÐŸÐ°ÑžÐ´Ð½Ñ‘Ð²Ð°Ñ Ðфрыка za
+Южна Ðфрика za
+Suafrika za
+Južna Afrika za
+Sudàfrica za
+Jižní Afrika za
+Sydafrikanske republik za
+Südafrika za
+Îότια ΑφÏική za
+Sudafriko za
+Sudáfrica za
+Lõuna Aafrika za
+Hego Afrika za
+Ø¢ÙØ±ÛŒÙ‚ای جنوبی za
+Etelä-Afrikka za
+Suðurafrika za
+Afrique du sud za
+Ãfrica do Sur za
+×“×¨×•× ×פריקה za
+Južna Afrika za
+Dél-Afrika za
+Afrika Selatan za
+Suður Afríka za
+Sud Africa za
+å—アフリカ za
+남 아프리카 공화국 za
+à»àº­àºšàºžàº´àºàº²à»ƒàº•້ za
+Pietų Afrika za
+Dienvid Āfrika za
+Afrika t'Isfel za
+Sør-Afrika za
+Zuid-Afrika za
+Sør-Afrika za
+Afrika Borwa za
+Sudafrica za
+Afryka Południowa za
+Africa do Sul za
+Ãfrica do Sul za
+Africa de Sud za
+Ð®Ð¶Ð½Ð°Ñ Ðфрика za
+Južná Afrika za
+Južna Afrika za
+Južna Afrika za
+I-South Africa za
+Sydafrika za
+¦¾ý ¬ôâ측 za
+à¹à¸­à¸Ÿà¸£à¸´à¸à¸²à¹ƒà¸•้ za
+Güney Afrika za
+Південна Ðфрика za
+Afurika tshipembe za
+Nam Phi za
+Mzantsi Afrika za
+å—éž za
+å—éž za
+Emzantsi Afrika za
+Zambia zm
+Ð—Ð°Ð¼Ð±Ñ–Ñ zm
+Ð—Ð°Ð¼Ð±Ð¸Ñ zm
+ຈາໄມàºàº²à»‰ zm
+Zâmbia zm
+Zambija zm
+赞比亚 zm
+Zimbabwe zw
+Ð—Ñ‹Ð¼Ð±Ð°Ð±Ð²Ñ zw
+Зимбабве zw
+Zimbabve zw
+ລິຊາ zw
+Zimbabve zw
+津巴布韦 zw
+Andorra ad
+Ðндора ad
+Ðндора ad
+Andora ad
+ອີນເດີຠad
+Andora ad
+Ðндорра ad
+安é“å°” ad
+United Arab Emirates ae
+Vereenigde Arabiese Emirate ae
+الإمارات العربية المتحدة ae
+Ð—Ð»ÑƒÑ‡Ð°Ð½Ñ‹Ñ ÐрабÑÐºÑ–Ñ Ð­Ð¼Ñ–Ñ€Ð°Ñ‚Ñ‹ ae
+Обединени ÐрабÑки ЕмирÑтва ae
+Ujedinjeni arapski emirati ae
+Emirats Àrabs Units ae
+Spojené arabské emiráty ae
+Forenende Arabiske Emirater ae
+Vereinigte Arabische Emirate ae
+Ενωμένα ΑÏαβικά ΕμιÏάτα ae
+Emiratos árabes unidos ae
+Araabia Ühendemiraadid ae
+Arabiar Emirato Batuak ae
+امارات متحده عربی ae
+Yhdistyneet Arabiemiraatit ae
+Émirats Arabes Unis ae
+×יחוד ×”×מירויות הערביות ae
+Ujedinjeni arapski emirati ae
+Egyesült Arab Emirátusok ae
+Emirati arabi uniti ae
+アラブ首長国連邦 ae
+ì•„ëž ì—미레ì´íЏ ì—°í•© ae
+ສະຫະລັດ ae
+Jungtiniai Arabų Emiratai ae
+Emirati Għarab Magħquda ae
+De forente arabiske emirater ae
+Verenigde Arabische Emiraten ae
+Dei sameinte arabiske emirata ae
+Di-Emirate tseo di Kopanego tsa Arab ae
+Zjednoczone Emiraty Arabskie ae
+Emiratos Ãrabes Unidos ae
+Emirados Ãrabes ae
+Emiratele Arabe Unite ae
+Объединенные ÐрабÑкие Эмираты ae
+Spojené arabské emiráty ae
+Združeni arabski Emirati ae
+Förenade arabemiraten ae
+³ì¸¢Â «ÃÒ ¿¡Î¸û ae
+BirleÅŸik Arap Emirlikleri ae
+Об'єднані ÐрабÑькі Емірати ae
+Mashango o tangananaho a Emirates ae
+阿拉伯è”åˆé…‹é•¿å›½ ae
+阿拉伯è¯åˆå¤§å…¬åœ‹ ae
+Izindawo zezinduna zase-United Arab ae
+Afghanistan af
+ÐфганіÑтан af
+ÐфганиÑтан af
+Afganistan af
+Afghanistán af
+Afganisztán af
+ລີທົ່ວເນີຠaf
+Afeganistão af
+Afganistan af
+Afganistan af
+Afganistan af
+ÐфганіÑтан af
+阿富汗 af
+Antigua and Barbuda ag
+Antigue en Barbuda ag
+أنتيغوا و باربودا ag
+Antigua vÉ™ Barbuda ag
+Ðнтыгуа Ñ– Барбуда ag
+Ðнтигуа и Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ ag
+Antigua ha Barbuda ag
+Antigua i Barbuda ag
+Antigua i Barbuda ag
+Antigua a Barbuda ag
+Antigua og Barbuda ag
+Antigua und Barbuda ag
+Antigua και Barbuda ag
+Antigvo kaj Barbudo ag
+Antigua y Barbuda ag
+Antigua ja Barbuda ag
+Antigua eta Barbuda ag
+آنتیگوا و باربودا ag
+Antigua ja Barbados ag
+Antigua og Barbuda ag
+Antigua et Barbuda ag
+Antiga e Barbuda ag
+×נטיגו××” וברבודה ag
+Antigua i Barbuda ag
+Antigua és Barbuda ag
+Antigua dan Barbuda ag
+Antigúa og Barbúda ag
+Antigua e Barbuda ag
+アンティグアãƒãƒ¼ãƒ–ーダ ag
+앤티가 바부다 ag
+Antikva ir Barbuda ag
+Antigva un Barbudas ag
+Antigwa u Barbuda ag
+Antigua og Barbuda ag
+Antigua en Barbuda ag
+Antigua og Barbuda ag
+Antigua le Barbuda ag
+Antigua e Barbuda ag
+Antigua i Barbuda ag
+Antigua e Barbuda ag
+Antigua e Barbuda ag
+Antigua ÅŸi Barbuda ag
+Ðнтигуа и Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ ag
+Antigua a Barbuda ag
+Antigva in Barbuda ag
+Antigua i Barbuda ag
+I-Antigua kanye ne Barbuda ag
+Antigua och Barbuda ag
+¬ýÊÌÅ¡ & À¡÷Ò¼¡ ag
+Antigua ve Barbuda ag
+Трінідад та Тобаго ag
+Antigua và Barbuda ag
+Antigua eyet Barbuda ag
+Antigua ne Barbuda ag
+安地瓜岛和巴布达岛 ag
+安地瓜島和巴布é”å³¶ ag
+Antigua kanye ne-Barbuda ag
+Anguilla ai
+Ðнгуила ai
+à»àºžàº™àº§àº´àº™ ai
+Angvila ai
+ÐÐ½Ð³Ñ–Ð»ÑŒÑ ai
+安圭拉 ai
+Albania al
+ÐÐ»ÑŒÐ±Ð°Ð½Ñ–Ñ al
+ÐÐ»Ð±Ð°Ð½Ð¸Ñ al
+Albanija al
+Albanien al
+Albánia al
+à»àº­àº”à»àº¥àº™àº•ິຠal
+Albânia al
+Albánsko al
+Albanija al
+Albanien al
+ÐÐ»Ð±Ð°Ð½Ñ–Ñ al
+阿尔巴尼亚 al
+Armenia am
+ÐрмÑÐ½Ñ–Ñ am
+ÐÑ€Ð¼ÐµÐ½Ð¸Ñ am
+Armenija am
+Armenien am
+Örményország am
+ອາເຈນຕິນາ am
+Armênia am
+Arménsko am
+Armenija am
+Armenien am
+ÐÑ€Ð¼ÐµÐ½Ñ–Ñ am
+亚美尼亚 am
+Netherlands Antilles an
+ХоландÑки Ðнтили an
+Nizozemski Antili an
+Nederlandske antiller an
+Antillas holandesas an
+Antilla Holandarrak an
+Holland-Antillák an
+ເນເທີà»àº¥àº™ an
+Antilhas an
+Holandské Antily an
+Nizozemski Antili an
+Nederländska Antillerna an
+ГолландÑькі Ðнтилли an
+è·å±žå®‰çš„列斯群岛 an
+Angola ao
+Ðнгола ao
+Ðнгола ao
+ບັນà»àºà»€àº¥àºµàº ao
+Ðнгола ao
+安哥拉 ao
+Argentina ar
+Argentinië ar
+الأرجنتين ar
+Ðргентына ar
+Ðржентина ar
+Arc'hantina ar
+Argentinien ar
+ΑÏγεντινή ar
+Argentino ar
+Argentiina ar
+آرژانتین ar
+Agentiina ar
+Argentine ar
+Arxentina ar
+×רגנטינה ar
+Argentína ar
+Argentína ar
+アルゼンãƒãƒ³ ar
+아르헨티나 ar
+ອາເຈນຕິນາ ar
+Argentīna ar
+Arġentina ar
+Argentinië ar
+Argentyna ar
+Ðргентина ar
+Argentína ar
+I-Argentina ar
+¬÷¦ºƒýÊÉ¡ ar
+อาร์เจนตินา ar
+Arjantin ar
+Ðргентина ar
+Agenthina ar
+Ã…rdjintene ar
+阿根廷 ar
+阿根廷 ar
+American Samoa as
+ÐмÑрыканÑкае Самоа as
+ÐмериканÑка Самоа as
+AmeriÄka Samoa as
+Samoa (USA) as
+Samoa americana as
+Amerikako Samoa as
+Amerikai Szamoa as
+ອາເມລິàºàº²à»€àº«àº™àº·àº­ as
+Samoa Americana as
+Americká Samoa as
+Ameriška Samoa as
+Amerikanska Samoa as
+ÐмериканÑьке Самоа as
+ç¾Žå±žè¨æ‘©äºšç¾¤å²› as
+Austria at
+Oostenryk at
+النمسا at
+Avstriya at
+ÐÑžÑÑ‚Ñ€Ñ‹Ñ at
+ÐвÑÑ‚Ñ€Ð¸Ñ at
+Aostria at
+Austrija at
+Àustria at
+Rakousko at
+Østrig at
+Österreich at
+ΑυστÏία at
+AÅ­strio at
+اتریش at
+Itävalta at
+Eysturríki at
+Autriche at
+×וסטריה at
+Austrija at
+Ausztria at
+Austurríki at
+オーストリア at
+오스트리아 at
+ອອດສະເຕເລີຠat
+Austrija at
+Austrija at
+Awtrija at
+Østerrike at
+Oostenrijk at
+Austerrike at
+Ãustria at
+Ãustria at
+ÐвÑÑ‚Ñ€Ð¸Ñ at
+Rakúsko at
+Avstrija at
+Austrija at
+I-Austria at
+Österrike at
+¬Ãò¾¢Ã¢Â¡ at
+ออสเตรีย at
+Avusturya at
+ÐвÑÑ‚Ñ€Ñ–Ñ at
+Ositiria at
+A'o at
+Ôtriche at
+奥地利 at
+奧地利 at
+Australia au
+Australië au
+أستراليا au
+Avustralya au
+ÐÑžÑÑ‚Ñ€Ð°Ð»Ñ–Ñ au
+ÐвÑÑ‚Ñ€Ð°Ð»Ð¸Ñ au
+Aostralia au
+Australija au
+Austràlia au
+Austrálie au
+Australien au
+Australien au
+ΑυστÏαλία au
+AÅ­stralio au
+Austraalia au
+استرالیا au
+Australie au
+×וסטרליה au
+Australija au
+Ausztrália au
+ÃÂstralía au
+オーストラリア au
+오스트레ì¼ë¦¬ì•„ au
+ອອດສະເຕເລີຠau
+Australija au
+AustrÄlija au
+Awstralja au
+Australië au
+Austrália au
+Austrália au
+ÐвÑÑ‚Ñ€Ð°Ð»Ð¸Ñ au
+Austrália au
+Avstralija au
+Australija au
+I-Australia au
+Australien au
+¬ŠÃò¾¢§ÃĢ¡ au
+ออสเตรเลีย au
+Avusturalya au
+ÐвÑÑ‚Ñ€Ð°Ð»Ñ–Ñ au
+Ositiralia au
+U'c au
+Ôstraleye au
+澳大利亚 au
+澳大利亞 au
+Aruba aw
+Ðруба aw
+ເàºàº¡à»„ັພ່ aw
+Ðруба aw
+阿é²å·´å²› aw
+Azerbaijan az
+أذربيجان az
+Azərbaycan az
+ÐзÑрбайджан az
+Ðзарбайджан az
+Azerbejdžan az
+Azerbaitjan az
+Ãzerbajdžánský az
+Azerbajdjan az
+Aserbaidschan az
+ΑζεÏμπαϊτζάν az
+AzerbajÄana az
+Azerbaiján az
+Aserbaidžaan az
+آذربایجان az
+Azerbaidzan az
+Aserbadsjan az
+×זרביג'ן az
+Azerbejdžan az
+Azerbajdzsán az
+Azerbaigian az
+アゼルãƒã‚¤ã‚¸ãƒ£ãƒ³ az
+아제르바ì´ìž” az
+ອາເຊີໄບຈັນ az
+Azerbaidžanas az
+AzerbaidžÄņu az
+Ażerbajġan az
+Aserbajdsjan az
+Azerbeidjan az
+Aserbajdsjan az
+Azerbejdżan az
+Azerbaijão az
+Turco az
+Azerbadjan az
+Ðзербайджан az
+Ãzerbajdžánsky az
+Azerbajdžan az
+Azerbejdžan az
+I-Azerbaijan az
+«º÷¨Àº¡ý az
+อาร์เซอร์ไบจัน az
+Azerice az
+Ðзербайджан az
+Azerbaydjan az
+阿塞拜疆 az
+亞塞拜然 az
+Bosnia and Herzegovina ba
+Bosnië en Herzegovina ba
+البوسنا و الهرسك ba
+БоÑÑŒÐ½Ñ–Ñ Ñ– Герцагавіна ba
+БоÑнена и Херцеговина ba
+Bosna i Hercegovina ba
+Bòsnia i Hercegovina ba
+Bosna a Herzegovina ba
+Bosnien-Herzegovina ba
+Bosnien und Herzegowina ba
+Βοσνία και ΕÏζεγοβίνη ba
+Bosnio kaj Hercegovino ba
+Bosnia y Herzegovina ba
+Bosnia ja Hertsegovina ba
+Bosnia eta Herzegovina ba
+بوسنی و هرزگوین ba
+Bosnia ja Herzegovina ba
+Bosnia-Herzegovina ba
+Bosnie herzégovine ba
+בוסניה הרצגובינה ba
+Bosna i Hercegovina ba
+Bosznia-Hercegovina ba
+Bosnia e Erzegovina ba
+ボスニアヘルツェゴビナ ba
+보스니아어와 헤르체고비나 ba
+ບອສເນີຠà»àº¥àº° ເຫີເຊີໂàºàº§àº´àº™àº² ba
+Bosnija ir Hercegovina ba
+Bosnija un Hercogovina ba
+Bożnia u Ħerżegovina ba
+Bosnia-Hercegovina ba
+Bosnië en Herzegovina ba
+Bosnia-Hercegovina ba
+Bosnia le Herzegovina ba
+Bośnia i Hercegowina ba
+Bósnia e Herzegovina ba
+Bósnia Herzegóvina ba
+Bosnia şi Herţegovina ba
+БоÑÐ½Ð¸Ñ Ð¸ Герцеговина ba
+Bosna a Hercegovina ba
+Bosna in Hercegovina ba
+I-Bosnia kanye ne Herzegovina ba
+Bosnien och Herzegovina ba
+¦À¡Ãɢ¡ ba
+บอสเนีย à¹à¸¥à¸° เฮอร์เซโà¸à¸§à¸´à¸™à¸² ba
+Bosna Hersek ba
+БоÑÐ½Ñ–Ñ Ñ‚Ð° Герцеговина ba
+Mubosinia na Muhezegovina ba
+Bosneye ba
+Bosnia ne Herzegovina ba
+波斯尼亚和黑塞哥维那 ba
+æ³¢å£«å°¼äºžèˆ‡èµ«å¡žå“¥ç¶­ç´ ba
+Bosnia kanye ne-Herzegovina ba
+Barbados bb
+بربادوس bb
+Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb
+Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb
+ΜπαÏμπάντος bb
+Babadoso bb
+باربادوس bb
+Barbade bb
+ברבדוס bb
+ãƒãƒ«ãƒãƒ‰ã‚¹ bb
+바르바ë„스 bb
+ບາລບາດອດສ bb
+Barbadosas bb
+Barbadosa bb
+Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb
+I-Barbados bb
+À¡÷§À¼¡à bb
+บาร์บาดอส bb
+Ð‘Ð°Ñ€Ð±Ð°Ð´Ð¾Ñ bb
+Barbades bb
+巴巴多斯 bb
+å·´è²å¤š bb
+Bangladesh bd
+بنغلاديش bd
+BanqladeÅŸ bd
+БанглÑдÑш bd
+Бангладеш bd
+Bangladeš bd
+Bangladéš bd
+Bangladesch bd
+Μπαγκλαντές bd
+BangladeÅo bd
+بنگلادش bd
+בנגלדש bd
+Bangladeš bd
+Banglades bd
+ãƒãƒ³ã‚°ãƒ©ãƒ‡ã‚·ãƒ¥ bd
+방글ë¼ë°ì‹œ bd
+ບັງຄະລາເທດ bd
+Bangladešas bd
+Bangladeša bd
+Bangladexx bd
+Bangladesz bd
+Banglade bd
+Бангладеш bd
+Bangladéš bd
+Bangladeš bd
+I-Bangladesh bd
+Àí¸Ç¡§¾à bd
+บังคลาเทศ bd
+BangladeÅŸ bd
+Бангладеш bd
+孟加拉 bd
+孟加拉 bd
+Belgium be
+België be
+بلجيكا be
+Belçika be
+БÑÐ»ÑŒÐ³Ñ–Ñ be
+Ð‘ÐµÐ»Ð³Ð¸Ñ be
+Belgia be
+Belgija be
+Bèlgica be
+Belgie be
+Belgien be
+Belgien be
+Βέλγιο be
+Belgio be
+Bélgica be
+Belgia be
+Belgika be
+بلژیک be
+Belgia be
+Belgia be
+Belgique be
+Bélxica be
+בלגיה be
+Belgija be
+Belgia be
+Belgía be
+Belgio be
+ベルギー be
+ë²¨ê¸°ì— be
+ເບລຢ່ງມ be
+Belgija be
+Beļģija be
+Belġju be
+Belgia be
+België be
+Belgia be
+Bèlgica be
+Belgia be
+Bélgica be
+Bélgica be
+Belgia be
+Ð‘ÐµÐ»ÑŒÐ³Ð¸Ñ be
+Belgicko be
+Belgija be
+Belgija be
+I-Belgium be
+Belgien be
+¦Àøº¢Âõ be
+เบลเยียม be
+Belçika be
+Ð‘ÐµÐ»ÑŒÐ³Ñ–Ñ be
+Beljike be
+比利时 be
+比利時 be
+Burkina Faso bf
+Буркіна ФаÑо bf
+Буркина ФаÑко bf
+ຕຸລະàºàºµ bf
+Буркіна ФаÑо bf
+布基纳法索 bf
+Bulgaria bg
+Bulgarye bg
+بلغاريا bg
+Bolgarıstan bg
+Ð‘Ð°ÑžÐ³Ð°Ñ€Ñ‹Ñ bg
+Ð‘ÑŠÐ»Ð³Ð°Ñ€Ð¸Ñ bg
+Bugarska bg
+Bulgària bg
+Bulharsko bg
+Bulgarien bg
+Bulgarien bg
+ΒουλγαÏία bg
+Bulgario bg
+Bulgaaria bg
+بلغارستان bg
+Bulgarie bg
+בולגריה bg
+Bugarska bg
+Bulgária bg
+Búlgaría bg
+ブルガリア bg
+불가리아 bg
+ບັນà»àºà»€àº¥àºµàº bg
+Bulgarija bg
+BulgÄrija bg
+Bulgarija bg
+Bulgarije bg
+Bułgaria bg
+Bulgária bg
+Bulgária bg
+Ð‘Ð¾Ð»Ð³Ð°Ñ€Ð¸Ñ bg
+Bulharsko bg
+Bolgarija bg
+Bugarska bg
+I-Bulgaria bg
+Bulgarien bg
+Àø§¸Ã¢Â¡ bg
+บัลà¹à¸à¹€à¸£à¸µà¸¢ bg
+Bulgaristan bg
+Ð‘Ð¾Ð»Ð³Ð°Ñ€Ñ–Ñ bg
+Baligaria bg
+Bulgåreye bg
+ä¿åŠ åˆ©äºš bg
+ä¿åŠ åˆ©äºž bg
+Bahrain bh
+البحرين bh
+БахрÑйн bh
+Бахрейн bh
+Bahrein bh
+Bahrajn bh
+ΜπαχÏέιν bh
+Bahrein bh
+Bahrein bh
+بحرین bh
+בחריין bh
+ãƒãƒ¼ãƒ¬ãƒ¼ãƒ³ bh
+ë°”ë ˆì¸ bh
+ຖັàºàºà»ˆàº‡àº§ bh
+Bahreinas bh
+Baħrain bh
+Baghrein bh
+Bahrajn bh
+Bahamas bh
+Bahrein bh
+Бахрейн bh
+Bahrajn bh
+Bahrajn bh
+I-Bahrain bh
+Bahrein bh
+À‹¨Ãý bh
+Bahreyn bh
+Бахрейн bh
+å·´æž— bh
+å·´æž— bh
+Burundi bi
+Бурундзі bi
+Бурунди bi
+ເຄອຣດ bi
+Бурунді bi
+布隆迪 bi
+Benin bj
+БÑнін bj
+Бенин bj
+ບອສເນີຠbj
+Бенін bj
+è´å® bj
+Bermuda bm
+БÑрмуды bm
+Бермуда bm
+ເàºàº¥àº¥àº°àº¡àº±àº™ bm
+Bermudy bm
+Bermudi bm
+Бермуди bm
+百慕大 bm
+Brunei Darussalam bn
+БрунÑй bn
+Бруней bn
+Brunei bn
+Brunei Szultánság bn
+ເບລາລັສເຊີຠbn
+Brunei bn
+Brunei Darusalam bn
+Бруней ДаруÑÑалам bn
+Bolivia bo
+Bolivië bo
+بوليÙيا bo
+Boliviya bo
+Ð‘Ð°Ð»Ñ–Ð²Ñ–Ñ bo
+Ð‘Ð¾Ð»Ð¸Ð²Ð¸Ñ bo
+Bolivija bo
+Bolívia bo
+Bolívie bo
+Bolivien bo
+Βολιβία bo
+Bolivio bo
+Boliivia bo
+بولیوی bo
+Bolivie bo
+בוליביה bo
+Bolivija bo
+Bolívia bo
+Bólivía bo
+ボリビア bo
+볼리비아 bo
+ໂບລີເວີຠbo
+Bolivija bo
+Bolīvija bo
+Bolivja bo
+Boliwia bo
+Bolívia bo
+Bolívia bo
+Ð‘Ð¾Ð»Ð¸Ð²Ð¸Ñ bo
+Bolívia bo
+Bolivija bo
+Bolivija bo
+I-Bolivia bo
+¦À¡Ä¢Å¢Â¡ bo
+โบลิเวีย bo
+Bolivya bo
+Ð‘Ð¾Ð»Ñ–Ð²Ñ–Ñ bo
+Boliveye bo
+波利维亚 bo
+玻利維亞 bo
+Brazil br
+Brazilië br
+البرازيل br
+Braziliya br
+Ð‘Ñ€Ð°Ð·Ñ‹Ð»Ñ–Ñ br
+Ð‘Ñ€Ð°Ð·Ð¸Ð»Ð¸Ñ br
+Brasil br
+Brazílie br
+Brasilien br
+Brasilien br
+Î’Ïαζιλία br
+Brazilo br
+Brasil br
+Brasiilia br
+Brasil br
+برزیل br
+Brasilia br
+Brésil br
+Brasil br
+ברזיל br
+Brazília br
+Brasilía br
+Brasile br
+ブラジル br
+브ë¼ì§ˆ br
+ບາຊີລ br
+Brazilija br
+Brazīlija br
+Brażil br
+Brasil br
+Brazilië br
+Brasil br
+Brasil br
+Brazylia br
+Brasil br
+Brasil br
+Brazilia br
+Ð‘Ñ€Ð°Ð·Ð¸Ð»Ð¸Ñ br
+Brazília br
+Brazilija br
+I-Brazil br
+Brasilien br
+À¢§Ãº¢ø br
+บราซิล br
+Brezilya br
+Ð‘Ñ€Ð°Ð·Ð¸Ð»Ñ–Ñ br
+Burazili br
+Braezi br
+巴西 br
+巴西 br
+Bahamas bs
+Багамы bs
+Бахами bs
+Bahami bs
+Bahamák bs
+ປານາມາ bs
+Bahamy bs
+Bahami bs
+Багами bs
+巴哈马 bs
+Bhutan bt
+Бутан bt
+Бутан bt
+Butan bt
+Bhután bt
+Bhután bt
+ຖັàºàºà»ˆàº‡àº§ bt
+Butan bt
+Бутан bt
+ä¸ä¸¹ bt
+Botswana bw
+БатÑвана bw
+Боцвана bw
+Bocvana bw
+ບອດສເນີຠbw
+Botsvana bw
+БотÑвана bw
+åšèŒ¨ç“¦çº³ bw
+Belarus by
+روسيا البيضاء by
+БеларуÑÑŒ by
+Ð‘ÐµÐ»Ð°Ñ€ÑƒÑ by
+Bjelorusija by
+Bělorusko by
+Hviderusland by
+Weißrussland by
+Bjelorusio by
+Valgevene by
+بلاروس by
+Valkovenäjä by
+Hvítarusland by
+Bélarus by
+בלרוס by
+Bjelorusija by
+Fehéroroszország by
+Hvíta-Rússland by
+Bielorussia by
+ベラルーシ by
+벨ë¼ë£¨ìФ by
+ເບລາລັສ by
+Baltarusija by
+Baltkrievu by
+Hviterussland by
+Wit-Rusland by
+Kviterussland by
+Białoruś by
+Bielorússia by
+Bielorusso by
+БеларуÑÑŒ by
+Bielorusko by
+Belorusija by
+I-Belarus by
+Vitryssland by
+¦ÀÄ¡åà by
+เบลารัส by
+БілоруÑÑ–Ñ by
+Belaruss by
+白俄罗斯 by
+白俄羅斯 by
+Belize bz
+БÑлізе bz
+Белиз bz
+ເບລàºà»ˆàº‡àº¡ bz
+Беліз bz
+伯利兹 bz
+Default C
+Verstek C
+Ø§ÙØªØ±Ø§Ø¶ÙŠ C
+Æsas C
+Па ўмаўчаньні C
+По подразбиране C
+Dre ziouer C
+Omissió C
+Výchozí C
+Standard C
+Standard C
+ΠÏοκαθοÏισμένο C
+Apriora C
+Predeterminado C
+Vaikimisi C
+Aurremugatua C
+Ù¾ÛŒØ´â€ŒÙØ±Ø¶ C
+Oletus C
+Forsettur C
+Par défaut C
+Por Omisión C
+ברירת מחדל C
+UobiÄajeno C
+Alapértelmezett C
+Standar C
+Sjálfgefið C
+Predefinito C
+標準 C
+기본 C
+ຄ່າປະລິàºàº²àº C
+Nutylima C
+Noklusētais C
+Normali C
+Standard C
+Standaard C
+Standard C
+Thuso ya Tshoganetso C
+Omission C
+Domyślnie C
+Por Omissão C
+Padrão C
+Implicit C
+По умолчанию C
+Štandardný C
+Privzeto C
+Predefinisano C
+Förval C
+¦¸¡¼¡¿¢¨Ä C
+ค่าปริยาย C
+Öntanımlı C
+Типовий C
+Mặc định C
+Prémetou C
+Okwendalo C
+默认 C
+é è¨­ C
+Okwendalo C
+Canada ca
+Kanada ca
+كندا ca
+Kanada ca
+Канада ca
+Канада ca
+Kanada ca
+Kanada ca
+Canadà ca
+Kanada ca
+Kanada ca
+Καναδάς ca
+Kanado ca
+Canadá ca
+Kanada ca
+Kanada ca
+کانادا ca
+Kanada ca
+Kanada ca
+Canadá ca
+קנדה ca
+Kanada ca
+Kanada ca
+Kanada ca
+Kanada ca
+カナダ ca
+ìºë‚˜ë‹¤ ca
+à»àº„ນາດາ ca
+Kanada ca
+KanÄda ca
+Kanada ca
+Kanada ca
+Canadá ca
+Canadá ca
+Канада ca
+Kanada ca
+Kanada ca
+Kanada ca
+I-Canada ca
+Kanada ca
+¸É¼¡ ca
+à¹à¸„นาดา ca
+Kanada ca
+Канада ca
+加拿大 ca
+加拿大 ca
+Cocos (Keeling) Islands cc
+КокоÑови ОÑтрови cc
+Kokosovo (Keeling) ostrvo cc
+Islas Cocos (Keeling) cc
+Koko Irlak cc
+Kókusz-szigetek (Keeling) cc
+Ilhas Cocos cc
+Kokosove Ostrovy cc
+Kokosovi (Keelingovi) otoki cc
+Kokosöarna cc
+КокоÑові оÑтрови cc
+Congo, the democratic republic of the cd
+ДÑÐ¼Ð°ÐºÑ€Ð°Ñ‚Ñ‹Ñ‡Ð½Ð°Ñ Ð ÑÑпубліка Конга cd
+Конго cd
+Kongo, demokratska republika cd
+Congo, den demokratiske republik cd
+Congo, república democrática del cd
+Kongo, errepublika demokratikoa cd
+Kongói Demokratikus Köztársaság cd
+República Democrática do Congo cd
+Demokratická Republika Kongo cd
+Kongo, demokratiÄna republika cd
+Demokratiska republiken Kongo cd
+刚果民主共和国 cd
+Central African Republic cf
+ЦÐР cf
+CentralnoafriÄka Republika cf
+Central-afrikanske Republik cf
+República Centroafricana cf
+Afrika Erdiko Errepublika cf
+Közép-Afrikai Köztársaság cf
+ໂດມິນິàºàº±àº™ cf
+República da Ãfrica Central cf
+Stredoafrická Republika cf
+Centralnoafriška republika cf
+Centralafrikanska Republiken cf
+ЦентральноафриканÑька реÑпубліка cf
+中éžå…±å’Œå›½ cf
+Congo cg
+Конга cg
+Конго cg
+Kongo cg
+Kongo cg
+Kongó cg
+ຄອນໂà»àºŠàº¥ cg
+Kongo cg
+Kongo cg
+Kongo cg
+Конго cg
+刚果 cg
+Switzerland ch
+Switserland ch
+سويسرا ch
+İsveçrə ch
+ШвÑÐ¹Ñ†Ð°Ñ€Ñ‹Ñ ch
+Ð¨Ð²ÐµÐ¹Ñ†Ð°Ñ€Ð¸Ñ ch
+Suis ch
+Å vicarska ch
+Suïssa ch
+Švýcarsko ch
+Schweiz ch
+Schweiz ch
+Ελβετία ch
+Svislando ch
+Suiza ch
+Å veits ch
+Suitza ch
+سوییس ch
+Sveitsi ch
+Suisse ch
+Suíza ch
+שוייץ ch
+Å vicarska ch
+Svájc ch
+Swiss ch
+Sviss ch
+Svizzera ch
+スイス ch
+스위스 ch
+ສະວິສເຊີà»àº¥àº™ ch
+Å veicarija ch
+Å veice ch
+Svizzera ch
+Sveits ch
+Zwitserland ch
+Sveits ch
+Suissa ch
+Szwajcaria ch
+Suíça ch
+Suíça ch
+Elveţia ch
+Ð¨Ð²ÐµÐ¹Ñ†Ð°Ñ€Ð¸Ñ ch
+Å vajÄiarsko ch
+Å vica ch
+Å vajcarska ch
+I-Switzerland ch
+Schweiz ch
+ÃÅ¢ðº÷Ä¡óà ch
+สวิสเซอร์à¹à¸¥à¸™à¸”์ ch
+İsviçre ch
+Ð¨Ð²ÐµÐ¹Ñ†Ð°Ñ€Ñ–Ñ ch
+Thuỵ Sĩ ch
+Swisse ch
+瑞士 ch
+瑞士 ch
+Cote d'ivoire ci
+Бераг Слановай КоÑьці ci
+Кот'Дивоар ci
+Obala SlonovaÄe ci
+Elfenbenskysten ci
+Costa de Marfil ci
+Elefántcsontpart ci
+ປ່ອàºàº«àº¡àº²àºàºàº°àº¥àº­àº ci
+SlonokoÅ¡Äena obala ci
+Elfenbenskusten ci
+Кот д'Івуар ci
+Cook islands ck
+Kukova ostrva ck
+Cook-øerne ck
+Islas Cook ck
+Cook Irlak ck
+Cook-szigetek ck
+ຄຸàºàºàºµà»‰ ck
+Ilhas Cook ck
+Cookove ostrovy ck
+Cookovi otoki ck
+Cooköarna ck
+ОÑтрови Кука ck
+库克群岛 ck
+Chile cl
+Chilië cl
+تشيلي cl
+Åžili cl
+Чылі cl
+Чили cl
+ÄŒile cl
+Xile cl
+Χιλή cl
+Ĉilio cl
+Tšiili cl
+Txile cl
+شیلی cl
+Chili cl
+צ'ילה cl
+ÄŒile cl
+Chili cl
+Cile cl
+ãƒãƒª cl
+ì¹ ë ˆ cl
+ຊີລີ cl
+ÄŒilÄ— cl
+Čīle cl
+ÄŠile cl
+Chili cl
+Cile cl
+Чили cl
+ÄŒile cl
+ÄŒile cl
+ÄŒile cl
+I-Chile cl
+º¢Ä¢ cl
+ชิลี cl
+Åžili cl
+Чилі cl
+Chi lê cl
+Tchili cl
+智利 cl
+智利 cl
+Cameroon cm
+КамÑрун cm
+Камерун cm
+Kamerun cm
+Cameroun cm
+Camerún cm
+Kamerun cm
+Kamerun cm
+ຕາລາງງານ - K cm
+Camarões cm
+Komerun cm
+Kamerun cm
+Kamerun cm
+Камерун cm
+喀麦隆 cm
+China cn
+Sjina cn
+الصين cn
+Çin cn
+Кітай cn
+Китай cn
+Sina cn
+Kina cn
+Xina cn
+Čína cn
+Kina cn
+Κίνα cn
+Ĉinujo cn
+Hiina cn
+Txina cn
+چین cn
+Kiina cn
+Kina cn
+Chine cn
+סין cn
+Kina cn
+Kína cn
+Cina cn
+Kína cn
+Cina cn
+中国 cn
+중국 cn
+ຈີນ cn
+Kinija cn
+Ķīna cn
+ÄŠina cn
+Kina cn
+Kina cn
+Xina cn
+Chiny cn
+Китай cn
+Čína cn
+Kitajska cn
+Kina cn
+I-China cn
+Kina cn
+º£É¡ cn
+จีน cn
+Çin cn
+Китай cn
+Trung Quốc cn
+Chine cn
+中国 cn
+中國 cn
+Colombia co
+Colombië co
+كولمبيا co
+ÐšÐ°Ð»ÑŽÐ¼Ð±Ñ–Ñ co
+ÐšÐ¾Ð»ÑƒÐ¼Ð±Ð¸Ñ co
+Kolumbija co
+Colòmbia co
+Kolumbie co
+Kolumbien co
+Κολομβία co
+Kolumbio co
+Kolumbia co
+Kolonbia co
+کلمبیا co
+Kolumbia co
+Colombie co
+קולומביה co
+Kolumbija co
+Kolumbia co
+コロンビア co
+콜롬비아 co
+ໂຄລຳເບີຠco
+Kolumbija co
+Kolumbija co
+Kolumbja co
+Columbia co
+Kolumbia co
+Colômbia co
+Colômbia co
+Columbia co
+ÐšÐ¾Ð»ÑƒÐ¼Ð±Ð¸Ñ co
+Kolumbia co
+Kolumbija co
+I-Colombia co
+¦¸¡ÄõÀ¢Â¡ co
+โคลัมเบีย co
+Kolombiya co
+ÐšÐ¾Ð»ÑƒÐ¼Ð±Ñ–Ñ co
+Colombeye co
+Columbia co
+哥伦比亚 co
+哥倫比亞 co
+Costa Rica cr
+كوستاريكا cr
+КоÑта Рыка cr
+КоÑта Рика cr
+Kostarika cr
+Kostarika cr
+Κόστα Ρίκα cr
+کاستاریکا cr
+Kosta Rika cr
+קוסטה ריקה cr
+Costa rica cr
+コスタリカ cr
+코스타 리카 cr
+ໂຄເອເທີຠcr
+Kosta Rika cr
+Kostaryka cr
+КоÑта-Рика cr
+Kostarika cr
+Kostarika cr
+I-Costa Rica cr
+§¸¡Š¼¡ ⸡ cr
+Kosta Rika cr
+КоÑта-Ріка cr
+哥斯达黎加 cr
+哥斯大黎加 cr
+Cuba cu
+Kuba cu
+كوبا cu
+Куба cu
+Куба cu
+Kuba cu
+Kuba cu
+Kuba cu
+ΚοÏβα cu
+Kuuba cu
+Kuba cu
+کوبا cu
+Kuuba cu
+Kuba cu
+קובה cu
+Kuba cu
+キュームcu
+ì¿ ë°” cu
+ເàºàº¡à»„ພ່ cu
+Kuba cu
+Kuba cu
+Kuba cu
+Куба cu
+Kuba cu
+Kuba cu
+I-Cuba cu
+Kuba cu
+¸¢ÔÀ¡ cu
+Küba cu
+Куба cu
+å¤å·´ cu
+å¤å·´ cu
+Cape Verde cv
+Капе Верде cv
+Zelenortska ostrva cv
+Kapverdiske øer cv
+Cabo Verde cv
+Cabo Verde cv
+Zöldfoki-szigetek cv
+ເàºàº¡à»„ພ່ cv
+Cabo Verde cv
+Kap Verde cv
+佛得角 cv
+Christmas Island cx
+BožiÄno ostrvo cx
+Juleøen cx
+Islas Christmas cx
+Eguberri Irla cx
+Karácsony-szigetek cx
+ຄິດສະຕອລ cx
+Ilhas do Natal cx
+VianoÄné Ostrovy cx
+BožiÄni otok cx
+Julön cx
+ОÑтрів Різдва cx
+圣诞岛 cx
+Cyprus cy
+Кіпр cy
+Кипър cy
+Kipar cy
+Cypern cy
+Chipre cy
+Txipre cy
+Ciprus cy
+ບີບອັດ cy
+Chipre cy
+Ciper cy
+Cypern cy
+Кипр cy
+塞浦路斯 cy
+Czechia cz
+Czechië cz
+التشيك cz
+Çex Respublikası cz
+ЧÑÑ…Ñ–Ñ cz
+Ð§ÐµÑ…Ð¸Ñ cz
+Tchekia cz
+Češka cz
+Txèquia cz
+ÄŒesko cz
+Tjekkiet cz
+Tschechien cz
+Τσεχία cz
+Ĉeĥio cz
+República Checa cz
+Tšehhi cz
+Txekia cz
+Ú†Ú© cz
+Tsekki cz
+République tchèque cz
+Chequia cz
+צ'כיה cz
+Češka cz
+Csehország cz
+Tékkland cz
+Repubblica Ceca cz
+ãƒã‚§ã‚³ cz
+ì²´ì½” cz
+ÄŒekija cz
+ÄŒehija cz
+Cżekia cz
+Tsjekkia cz
+Tsjechië cz
+Tsjekkia cz
+Chèquia cz
+Czechy cz
+República Checa cz
+República Tcheca cz
+Cehia cz
+Ð§ÐµÑ…Ð¸Ñ cz
+ÄŒesko cz
+Češka cz
+Češka cz
+I-Czechia cz
+Tjeckien cz
+¦ºì¡ cz
+Çek Cumhuriyeti cz
+Ð§ÐµÑ…Ñ–Ñ cz
+Séc cz
+Tchekeye cz
+æ·å…‹ cz
+æ·å…‹ cz
+Germany de
+Duitsland de
+ألمانيا de
+Almaniya de
+ÐÑмеччына de
+Ð“ÐµÑ€Ð¼Ð°Ð½Ð¸Ñ de
+Alamagn de
+NjemaÄka de
+Alemanya de
+Německo de
+Tyskland de
+Deutschland de
+ΓεÏμανία de
+Germanio de
+Alemania de
+Saksamaa de
+Alemania de
+ آلمان de
+Saksa de
+Týskland de
+Allemagne de
+Alemaña de
+גרמניה de
+NjemaÄka de
+Németország de
+Jerman de
+Þýskaland de
+Germania de
+ドイツ de
+ë…ì¼ de
+ເàºàº¥àº¥àº°àº¡àº±àº™àº™àºµ de
+Vokietija de
+VÄcija de
+Ä ermanja de
+Tyskland de
+Duitsland de
+Tyskland de
+Alemanya de
+Niemcy de
+Alemanha de
+Alemanha de
+Germania de
+Ð“ÐµÑ€Ð¼Ð°Ð½Ð¸Ñ de
+Nemecko de
+NemÄija de
+NemaÄka de
+I-Germany de
+Tyskland de
+§º÷ÃÉ¢ de
+เยอรมันนี de
+Almanya de
+Ðімеччина de
+Äức de
+Almagne de
+德国 de
+德國 de
+IJalimani de
+Djibouti dj
+جيبوتي dj
+Джыбуці dj
+Джибути dj
+Äibuti dj
+Džibuti dj
+Dschibuti dj
+Τζιμπουτί dj
+جیبوتی dj
+ג'יבוטי dj
+Džibuti dj
+Dzsibuti dj
+ジブティ dj
+지부티 dj
+ພັດພາ dj
+Džibuti dj
+Dġibuti dj
+Dżibuti dj
+Djibuti dj
+Djibuti dj
+Джибути dj
+Džibuty dj
+Džibuti dj
+I-Djibouti dj
+Ê¢ƒ¢¦À¡Ê dj
+Cibuti dj
+Джібуті dj
+å‰å¸ƒæ dj
+å‰å¸ƒåœ° dj
+Denmark dk
+Denemarke dk
+الدنمارك dk
+Danimarka dk
+Ð”Ð°Ð½Ñ–Ñ dk
+Ð”Ð°Ð½Ð¸Ñ dk
+Danmark dk
+Danska dk
+Dinamarca dk
+Dánsko dk
+Danmark dk
+Dänemark dk
+Δανία dk
+Danlando dk
+Dinamarca dk
+Taani dk
+Danimarka dk
+دانمارک dk
+Tanska dk
+Danmark dk
+Danemark dk
+Dinamarca dk
+דנמרק dk
+Danska dk
+Dánia dk
+Danmörk dk
+Danimarca dk
+デンマーク dk
+ë´ë§ˆí¬ dk
+ເດນມາຠdk
+Danija dk
+DÄnija dk
+Danimarka dk
+Danmark dk
+Denemarken dk
+Danmark dk
+Dinamarca dk
+Dania dk
+Dinamarca dk
+Dinamarca dk
+Danemarca dk
+Ð”Ð°Ð½Ð¸Ñ dk
+Dánsko dk
+Danska dk
+Danska dk
+I-Denmark dk
+Danmark dk
+¦¼ýá÷ì dk
+เดนมาร์ภdk
+Danimarka dk
+Ð”Ð°Ð½Ñ–Ñ dk
+Äan Mạch dk
+Daenmåtche dk
+丹麦 dk
+丹麥 dk
+Dominica dm
+Дамініка dm
+Доминика dm
+Dominika dm
+Dominika dm
+ໂລມາເນີຠdm
+Dominicana dm
+Dominikánsko dm
+Dominikanska republika dm
+Домініка dm
+多米尼加 dm
+Dominican Republic do
+Dominikiese Republiek do
+جمهورية الدومينيكان do
+Dominik Respublikası do
+ДамініканÑÐºÐ°Ñ Ð ÑÑпубліка do
+ДоминиканÑка република do
+Republik Dominikan do
+Dominikanska Republika do
+República Dominicana do
+Dominikánská republika do
+Dominikanske Republik do
+Dominikanische Republik do
+Δομινικανή ΔημοκÏατία do
+Dominika Respubliko do
+República Dominicana do
+Dominikaani Vabariik do
+Dominikar Errepublika do
+جمهوری دامینیکن do
+Dominikaaninen tasavalta do
+République dominicaine do
+República Dominicana do
+הרפובליקה הדומיניקנית do
+Dominikanska Republika do
+Dominikai Köztársaság do
+Republik Dominika do
+Dóminíska Lýðveldið do
+Repubblica Dominicana do
+ドミニカ共和国 do
+ë„미니카 공화국 do
+ໂດມິນີàºàº±àº™ do
+Dominikos Respublika do
+Dominikas Republika do
+Repubblika Dominikana do
+Den dominikanske republikk do
+Dominicaanse Republiek do
+Den dominikanske republikken do
+Republica Dominicana do
+Dominikana do
+República Dominicana do
+República Dominicana do
+Republica Dominicană do
+ДоминиканÑÐºÐ°Ñ Ñ€ÐµÑпублика do
+Dominikánska republika do
+Dominikanska republika do
+Dominikanska republika do
+I-Dominican Republic do
+Dominikanska republiken do
+¦¼¡Ã¢É¢ì¸ý ÌÊÂÃà do
+โดมินิà¸à¸±à¸™ do
+Dominik Cumhuriyeti do
+ДомініканÑька реÑпубліка do
+Muvhuso wa Dominican do
+Cộng hoà Dominican do
+Republike Dominikinne do
+IRepublic yeDominican do
+多米尼加共和国 do
+多明尼加共和國 do
+Algeria dz
+Algerië dz
+الجزائر dz
+Ðльжыр dz
+Ðлжир dz
+Alžir dz
+Algèria dz
+Alžírsko dz
+Algeriet dz
+Algerien dz
+ΑλγεÏία dz
+Algerio dz
+Argelia dz
+Alžeeria dz
+ الجزیره dz
+Algérie dz
+×לג'יריה dz
+Alžir dz
+Algéria dz
+アルジェリア dz
+알제리 dz
+ບັນàºàº²à»€àº¥àºµàº dz
+Alžyras dz
+Alġerija dz
+Algerie dz
+Algerije dz
+Algerie dz
+Algieria dz
+Argélia dz
+Argélia dz
+Ðлжир dz
+Alžírsko dz
+Alžirija dz
+I-Algeria dz
+Algeriet dz
+«øƒ¢Ã¢Â¡ dz
+Ðлжир dz
+Aldjereye dz
+阿尔åŠåˆ©äºš dz
+阿爾åŠåˆ©äºž dz
+Equador ec
+Ewenaar ec
+الإكوادور ec
+Ekvator ec
+Эквадор ec
+Еквадор ec
+Ecuador ec
+Ekvador ec
+Ekvádor ec
+Ecuador ec
+ΙσημεÏινός ec
+Ekvadoro ec
+Ecuador ec
+Ekvador ec
+Ekuador ec
+اکوادور ec
+Équateur ec
+Ecuador ec
+×קוודור ec
+Ekvador ec
+Ecuador ec
+Ekvador ec
+Ecuador ec
+エクアドル ec
+ì—ì½°ë„르 ec
+ເອàºà»àº”à» ec
+Ekvadoras ec
+Ekvadora ec
+Ekwador ec
+Ecuador ec
+Ecuador ec
+Ekwador ec
+Ecuador ec
+Эквадор ec
+Ekvádor ec
+Ekvador ec
+Ekvador ec
+I-Equador ec
+®ì¦Å§¼¡÷ ec
+เอà¸à¸§à¸²à¸”อร์ ec
+Ekvator ec
+Еквадор ec
+Ecwåteur ec
+厄瓜多尔 ec
+厄瓜多 ec
+Estonia ee
+Estlandies ee
+استونيا ee
+Estoniya ee
+ЭÑÑ‚Ð¾Ð½Ñ–Ñ ee
+ЕÑÑ‚Ð¾Ð½Ð¸Ñ ee
+Estonija ee
+Estònia ee
+Estonsko ee
+Estland ee
+Estland ee
+Εσθονία ee
+Estlando ee
+Eesti ee
+استونی ee
+Eesti ee
+Estonie ee
+×סטוניה ee
+Estonija ee
+Észtország ee
+Eistland ee
+エストニア ee
+ì—스토니아 ee
+ເອໂທເນີຠee
+Estija ee
+Igaunija ee
+Estonja ee
+Estland ee
+Estland ee
+Estland ee
+Estònia ee
+Estónia ee
+Estônia ee
+ЭÑÑ‚Ð¾Ð½Ð¸Ñ ee
+Estónsko ee
+Estonija ee
+Estonija ee
+I-Estonia ee
+Estland ee
+±Ã§¼¡É¢Â¡ ee
+เอสโธเนีย ee
+Estonya ee
+ЕÑÑ‚Ð¾Ð½Ñ–Ñ ee
+Estoneye ee
+爱沙尼亚 ee
+愛沙尼亞 ee
+Egypt eg
+Egipte eg
+مصر eg
+Misir eg
+ЭгіпÑÑ‚ eg
+Египет eg
+Egipat eg
+Egipte eg
+Egypten eg
+Ägypten eg
+Αίγυπτος eg
+Egiptujo eg
+Egipto eg
+Egiptus eg
+Egypto eg
+مصر eg
+Egypti eg
+Egyptaland eg
+Égypte eg
+×ž×¦×¨×™× eg
+Egipat eg
+Egyiptom eg
+Egyptaland eg
+Egitto eg
+エジプト eg
+ì´ì§‘트 eg
+ອີຢີບ eg
+Egiptas eg
+Ä’Ä£ipte eg
+Eġittu eg
+Egypte eg
+Egepeta eg
+Egipt eg
+Egipto eg
+Egito eg
+Egipt eg
+Египет eg
+Egipt eg
+I-Egypt eg
+Egypten eg
+±¸¢ôà eg
+อียิปต์ eg
+Mısır eg
+Єгипет eg
+Edjipe eg
+åŸƒåŠ eg
+åŸƒåŠ eg
+Igibhithe eg
+Western Sahara eh
+Западна Сахара eh
+Zapadna Sahara eh
+Vestsahara eh
+Sahara occidental eh
+Mendebaldeko Sahara eh
+Nyugat-Szahara eh
+ພື້ນທີ່ທຳງານ eh
+Sahara eh
+Západna Sahara eh
+Zahodna Sahara eh
+Västsahara eh
+Західна Сахара eh
+西撒哈拉 eh
+Eritrea er
+ЭрытрÑÑ er
+Ð•Ñ€Ð¸Ñ‚Ñ€ÐµÑ er
+Eritreja er
+à»àºà»‰à»„ຂà»àºŸà»‰àº¡àº—ຳງານ er
+Eritreja er
+Ð•Ñ€Ð¸Ñ‚Ñ€ÐµÑ er
+厄立特里亚 er
+Spain es
+Spanje es
+أسبانيا es
+İspaniya es
+Ð“Ñ–ÑˆÐ¿Ð°Ð½Ñ–Ñ es
+ИÑÐ¿Ð°Ð½Ð¸Ñ es
+Spagn es
+Å panija es
+Espanya es
+Španělsko es
+Spanien es
+Spanien es
+Ισπανία es
+Hispanio es
+España es
+Hispaania es
+Espainia es
+اسپانیا es
+Espanja es
+Spania es
+Espagne es
+España es
+ספרד es
+Å panjolska es
+Spanyolország es
+Spanyol es
+Spánn es
+Spagna es
+スペイン es
+ìŠ¤íŽ˜ì¸ es
+ສະເປັນ es
+Ispanija es
+SpÄnija es
+Spanja es
+Spania es
+Spanje es
+Spania es
+Espanha es
+Hiszpania es
+Espanha es
+Espanha es
+Spania es
+ИÑÐ¿Ð°Ð½Ð¸Ñ es
+Å panielsko es
+Å panija es
+Å panija es
+I-Spain es
+Spanien es
+æÀ¢ý es
+สเปน es
+İspanya es
+ІÑÐ¿Ð°Ð½Ñ–Ñ es
+Tây Ban Nha es
+Sipagne es
+西ç­ç‰™ es
+西ç­ç‰™ es
+Ethiopia et
+Ð­Ñ‚Ñ‹Ñ‘Ð¿Ñ–Ñ et
+Ð•Ñ‚Ð¸Ð¾Ð¿Ð¸Ñ et
+Etiopija et
+Ethiopien et
+Etiopía et
+Etiopia et
+Etiópia et
+ເອໂທເນີຠet
+Etiópia et
+Etiópia et
+Etiopija et
+Etiopien et
+Ð•Ñ„Ñ–Ð¾Ð¿Ñ–Ñ et
+埃塞俄比亚 et
+Finland fi
+Ùنلندا fi
+Finlandiya fi
+ФінлÑÐ½Ð´Ñ‹Ñ fi
+Ð¤Ð¸Ð½Ð»Ð°Ð½Ð´Ð¸Ñ fi
+Finska fi
+Finlàndia fi
+Finsko fi
+Finnland fi
+Φινλανδία fi
+Finlando fi
+Finlandia fi
+Soome fi
+Finlandia fi
+Ùنلاند fi
+Suomi fi
+Finnland fi
+Finlande fi
+Finlandia fi
+פינלנד fi
+Finska fi
+Finnország fi
+Finlandia fi
+Finnland fi
+Finlandia fi
+フィンランド fi
+핀란드 fi
+ຟີນà»àº¥àº™ fi
+Suomija fi
+Somija fi
+Finlandja fi
+Finlandia fi
+Finlandia fi
+Finlândia fi
+Finlândia fi
+Finlanda fi
+ФинлÑÐ½Ð´Ð¸Ñ fi
+Fínsko fi
+Finska fi
+Finska fi
+I-Finland fi
+À¢ýÄ¡óà fi
+ฟินà¹à¸¥à¸™à¸”์ fi
+Finlandiya fi
+ФінлÑÐ½Ð´Ñ–Ñ fi
+Phần Lan fi
+Finlande fi
+芬兰 fi
+芬蘭 fi
+Fiji fj
+Фіджы fj
+Фиджи fj
+Fidži fj
+Fidzsi fj
+ມີດີ fj
+Ilhas Fiji fj
+Fidži fj
+Fidži fj
+Фіджі fj
+æ–æµŽ fj
+Falkland Islands (Malvinas) fk
+ФолклендÑки ОÑтрови fk
+Foklandska ostrva (Malvini) fk
+Falkland-øerne fk
+Islas Falkland (Malvinas) fk
+Falkland Irlak (Malvinak) fk
+Falkland-szigetek fk
+Ilhas Malvinas fk
+Falklandské Ostrovy (Malviny) fk
+Falklandski otoki (Malvini) fk
+Falklandsöarna fk
+ç¦å…‹å…°å²› (马尔维纳斯) fk
+Micronesia, Federated states of fm
+ФедÑÑ€Ð°Ñ†Ñ‹Ñ ÐœiкранÑзіі fm
+ÐœÐ¸ÐºÑ€Ð¾Ð½ÐµÐ·Ð¸Ñ fm
+Mikronezija, Federalne države fm
+Mikronesien, de forenede stater af fm
+Micronesia, Estados federados de fm
+Mikronesia, Estatu Federatuak fm
+Mikronézia fm
+Estados Federados da Micronésia fm
+Spjoené štáty Mikronézie fm
+Mikronezija, Združene države fm
+Mikronesiska federationen fm
+密克罗尼西亚è”邦 fm
+Faroe Islands fo
+ФареорÑки ОÑтрови fo
+Farska ostrva fo
+Færøerne fo
+islas Faroe fo
+Faroe Irlak fo
+Faroe-szigetek fo
+ໄອà»àº¥àº™ fo
+Ilhas Faroe fo
+Ostrovy Faroe fo
+Otoki Faroe fo
+Färöarna fo
+ФарерÑькі оÑтрови fo
+France fr
+Frankryk fr
+ÙØ±Ù†Ø³Ø§ fr
+Fransa fr
+Ð¤Ñ€Ð°Ð½Ñ†Ñ‹Ñ fr
+Ð¤Ñ€Ð°Ð½Ñ†Ð¸Ñ fr
+Frañs fr
+Francuska fr
+França fr
+Francie fr
+Frankrig fr
+Frankreich fr
+Γαλλία fr
+Francio fr
+Francia fr
+Prantsusmaa fr
+Frantzia fr
+ÙØ±Ø§Ù†Ø³Ù‡ fr
+Ranska fr
+Frakland fr
+Francia fr
+צרפת fr
+Francuska fr
+Franciaország fr
+Prancis fr
+Frakkland fr
+Francia fr
+フランス fr
+프랑스 fr
+àºàº£àº±à»ˆàº‡ fr
+Prancūzija fr
+Francija fr
+Franza fr
+Frankrike fr
+Frankrijk fr
+Frankrike fr
+Fora fr
+França fr
+Francja fr
+França fr
+França fr
+Franţa fr
+Ð¤Ñ€Ð°Ð½Ñ†Ð¸Ñ fr
+Francúzsko fr
+Francija fr
+Francuska fr
+I-France fr
+Frankrike fr
+À¢Ã¡ýà fr
+à¸à¸£à¸±à¹ˆà¸‡à¹€à¸¨à¸ª fr
+Fransa fr
+Ð¤Ñ€Ð°Ð½Ñ†Ñ–Ñ fr
+Fura fr
+Pháp fr
+Fransi fr
+法国 fr
+法國 fr
+Gabon ga
+Габон ga
+Габон ga
+Gabón ga
+à»àºàº¥à»ˆàº‡àº™ ga
+Gabão ga
+Габон ga
+加蓬 ga
+United Kingdom gb
+Vereenigde Koninkryk gb
+المملكة المتحدة gb
+Birləşmiş Krallıq gb
+Злучанае КаралеўÑтва gb
+Ð’ÐµÐ»Ð¸ÐºÐ¾Ð±Ñ€Ð¸Ñ‚Ð°Ð½Ð¸Ñ gb
+Rouantelezh Unanet gb
+Velika Britanija gb
+Regne Unit gb
+Spojené království gb
+Storbritannien gb
+Großbritannien gb
+Ηνωμένο Βασίλειο gb
+Britio gb
+Reino Unido gb
+Ühendatud Kuningriigid gb
+Erreinu Batua gb
+بریتانیا gb
+Iso-Britannia gb
+Stórabretland gb
+Royaume Uni gb
+Reino Unido gb
+בריטניה gb
+Ujedinjeno Kraljevstvo gb
+Egyesült Királyság gb
+Inggris gb
+Stóra Bretland gb
+Regno Unito gb
+イギリス gb
+ì˜êµ­ gb
+ສະຫະລາດສະອານາຈັຠgb
+JungtinÄ— KaralystÄ— gb
+ApvienotÄ Karaliste gb
+Renju Unit gb
+Storbritannia gb
+Verenigd Koninkrijk gb
+Storbritannia gb
+Regne Unit gb
+Wielka Brytania gb
+Reino Unido gb
+Reino Unido gb
+Anglia gb
+Ð’ÐµÐ»Ð¸ÐºÐ¾Ð±Ñ€Ð¸Ñ‚Ð°Ð½Ð¸Ñ gb
+Anglicko gb
+Združeno kraljestvo gb
+Velika Britanija gb
+I-United Kingdom gb
+Storbritannien gb
+³ì¸¢Â ­Ã¡îº¢Âõ gb
+สหราชอาณาจัà¸à¸£ gb
+Birleşik Krallık gb
+Ð’ÐµÐ»Ð¸ÐºÐ¾Ð±Ñ€Ð¸Ñ‚Ð°Ð½Ñ–Ñ gb
+Anh gb
+United Kingdom gb
+è”åˆçދ国 gb
+è¯åˆçŽ‹åœ‹ gb
+United Kingdom gb
+Grenada gd
+غرينادا gd
+Qrenada gd
+ГрÑнада gd
+Гренада gd
+Granada gd
+ΓÏενάδα gd
+Grenado gd
+Granada gd
+گرانادا gd
+Grenade gd
+Granada gd
+גרנדה gd
+Grænhöfðaeyjar gd
+Granada gd
+グラナダ gd
+그러네ì´ë‹¤ gd
+ເàºàº™àº²àº”າ gd
+GrenÄda gd
+Granada gd
+Granada gd
+Granada gd
+Гренада gd
+I-Grenada gd
+¸¢¦Ãɼ¡ gd
+เà¸à¸£à¸™à¸²à¸”า gd
+Гренада gd
+格林纳达 gd
+æ ¼ç‘žé‚£é” gd
+Georgia ge
+Ð“Ñ€ÑƒÐ·Ñ–Ñ ge
+Ð“Ñ€ÑƒÐ·Ð¸Ñ ge
+Gruzija ge
+Georgien ge
+Grúzia ge
+ເຊີເບີຠge
+Geórgia ge
+Gruzija ge
+Georgien ge
+Ð“Ñ€ÑƒÐ·Ñ–Ñ ge
+æ ¼é²å‰äºš ge
+Ghana gh
+غانا gh
+Гана gh
+Гана gh
+Gana gh
+Γκάνα gh
+غنا gh
+×’×× ×” gh
+ガーナ gh
+ຈີນ gh
+Gana gh
+Gana gh
+Gana gh
+Гана gh
+Gana gh
+I-Ghana gh
+¸¡É¡ gh
+Гана gh
+加纳 gh
+è¿¦ç´ gh
+Gibraltar gi
+Гибралтар gi
+Gibraltár gi
+ມອລຕາ gi
+Гібралтар gi
+直布罗陀 gi
+Gambia gm
+Ð“Ð°Ð¼Ð±Ñ–Ñ gm
+Ð“Ð°Ð¼Ð±Ð¸Ñ gm
+Gambija gm
+à»àºàº¡àº¡àº² gm
+Gâmbia gm
+Gambija gm
+Ð“Ð°Ð¼Ð±Ñ–Ñ gm
+冈比亚 gm
+Guinea gn
+ГвінÑÑ gn
+Ð“Ð²Ð¸Ð½ÐµÑ gn
+Gvineja gn
+ເຖາວັນ gn
+Guiné gn
+Gvineja gn
+Ð“Ð²Ñ–Ð½ÐµÑ gn
+几内亚 gn
+Guadeloupe gp
+Гвадалупа gp
+Gvadalupe gp
+Guadalupe gp
+ເດີລຸຠgp
+Guadalupe gp
+Гваделупа gp
+瓜德罗普岛 gp
+Equatorial Guinea gq
+ЭкватарыÑÐ»ÑŒÐ½Ð°Ñ Ð“Ð²Ñ–Ð½ÑÑ gq
+ЕкваториÑлна Ð“Ð²Ð¸Ð½ÐµÑ gq
+Ekvatorijalna Gvineja gq
+Ækvatorial Guinea gq
+Guinea equatorial gq
+Ginea Ekuatoriala gq
+Egyenlítői Guinea gq
+àºàº²àº™àºªàº­àº™ gq
+Guiné Equatorial gq
+Rovníkova Guinea gq
+Ekvatorialna Gvineja gq
+Ekvatorialguinea gq
+Екваторіальна Ð“Ð²Ñ–Ð½ÐµÑ gq
+赤é“几内亚 gq
+Greece gr
+Griekeland gr
+اليونان gr
+Yunanıstan gr
+ГрÑÑ†Ñ‹Ñ gr
+Ð“ÑŠÑ€Ñ†Ð¸Ñ gr
+Gres gr
+GrÄka gr
+Grècia gr
+Řecko gr
+Grækenland gr
+Griechenland gr
+Ελλάδα gr
+Grekujo gr
+Grecia gr
+Kreeka gr
+Grezia gr
+یونان gr
+Kreikka gr
+Grikkaland gr
+Grèce gr
+Grecia gr
+יוון gr
+GrÄka gr
+Görögország gr
+Grikkland gr
+Grecia gr
+ギリシャ gr
+그리스 gr
+àºàºµàºŠ gr
+Graikija gr
+GrieÄ·ija gr
+Greċja gr
+Hellas gr
+Griekenland gr
+Hellas gr
+Grèça gr
+Grecja gr
+Grécia gr
+Grécia gr
+Grecia gr
+Ð“Ñ€ÐµÑ†Ð¸Ñ gr
+Grécko gr
+GrÄija gr
+GrÄka gr
+I-Greece gr
+Grekland gr
+¸¢Ã£à gr
+à¸à¸£à¸µà¸‹ gr
+Yunanistan gr
+Ð“Ñ€ÐµÑ†Ñ–Ñ gr
+Hy Lạp gr
+Grece gr
+希腊 gr
+希臘 gr
+Guatemala gt
+Gautemala gt
+غواتيمالا gt
+Quatemala gt
+ГватÑмала gt
+Гватемала gt
+Gvatemala gt
+Γουατεμάλα gt
+Gvatemalo gt
+Guatemaala gt
+گواتمالا gt
+גו×טמלה gt
+Gvatemala gt
+カタロニア gt
+과테ë§ë¼ gt
+àºàº±àº§à»€àº•ມາລາ gt
+Gvatemala gt
+Gvatemala gt
+Gwatemala gt
+Gwatemala gt
+Гватемала gt
+Gvatemala gt
+Gvatemala gt
+I-Guatemala gt
+ÌÅ¡ò¾Ã¡Ä¡ gt
+à¸à¸±à¸§à¹€à¸•มาลา gt
+Гватемала gt
+Gwatemala gt
+瓜地马拉 gt
+瓜地馬拉 gt
+Guam gu
+Гуам gu
+à»àºàº¡àº¡àº² gu
+Гуам gu
+关岛 gu
+Guinea-Bissau gw
+ГвінÑÑ-БіÑаў gw
+ГвинеÑ-БиÑау gw
+Gvineja-Bisau gw
+Ginea-Bissau gw
+Bissau-Guinea gw
+ລັດເຊີຠgw
+Guiné-Bissau gw
+ГвінеÑ-БіÑÑау gw
+å‡ å†…äºšæ¯”ç» gw
+Guyana gy
+ГвіÑна gy
+Гуана gy
+Gvajana gy
+ຈີນ gy
+Guiana gy
+Gvajana gy
+ГаÑна gy
+圭亚那 gy
+Hong Kong hk
+Ганконг hk
+Хонг Конг hk
+Hongkong hk
+ບà»à»ˆàº®àº¹à»‰àºˆàº±àº hk
+Гонконг hk
+香港 hk
+Honduras hn
+هندوراس hn
+Ð“Ð°Ð½Ð´ÑƒÑ€Ð°Ñ hn
+Ð¥Ð¾Ð½Ð´ÑƒÑ€Ð°Ñ hn
+Hondures hn
+ΟνδοÏÏα hn
+Honduraso hn
+Honduuras hn
+هندوراس hn
+הונדורס hn
+ホンデュラス hn
+온ë‘ë¼ìФ hn
+ຫອນດູລັດ hn
+Hondūras hn
+Hondurasa hn
+Ħonduras hn
+Hondures hn
+Ð“Ð¾Ð½Ð´ÑƒÑ€Ð°Ñ hn
+I-Honduras hn
+¬ñÎáŠà hn
+ฮอนดูรัส hn
+Ð“Ð¾Ð½Ð´ÑƒÑ€Ð°Ñ hn
+洪都拉斯 hn
+å®éƒ½æ‹‰æ–¯ hn
+Croatia hr
+Kroatië hr
+كرواتيا hr
+Xırvatıstan hr
+Ð¥Ð°Ñ€Ð²Ð°Ñ‚Ñ‹Ñ hr
+ХърватÑка hr
+Kroatia hr
+Hrvatska hr
+Croàcia hr
+Chorvatsko hr
+Kroatien hr
+Kroatien hr
+ΚÏοατία hr
+Kroatio hr
+Croacia hr
+Horvaatia hr
+Kroazia hr
+کرواسی hr
+Kroatia hr
+Kroatia hr
+Croatie hr
+Croacia hr
+קרו×טיה hr
+Hrvatska hr
+Horvátország hr
+Kroasia hr
+Króatía hr
+Croazia hr
+クロアãƒã‚¢ hr
+í¬ë¡œì•„í‹°ì•„ hr
+ໂຄເອເທີຠhr
+Kroatija hr
+HorvÄtija hr
+Kroazja hr
+Kroatia hr
+Kroatië hr
+Kroatia hr
+Croacia hr
+Chorwacja hr
+Croácia hr
+Croácia hr
+Croaţia hr
+Ð¥Ð¾Ñ€Ð²Ð°Ñ‚Ð¸Ñ hr
+Chorvátsko hr
+Hrvaška hr
+Hrvatska hr
+I-Croatia hr
+Kroatien hr
+̦á§Åº¢Â¡ hr
+โครเอเธีย hr
+Hırvatistan hr
+Ð¥Ð¾Ñ€Ð²Ð°Ñ‚Ñ–Ñ hr
+Crowåceye hr
+克罗地亚 hr
+克羅埃西亞 hr
+Haiti ht
+Гаіці ht
+Хаити ht
+Haití ht
+ວາດຮູບ - K ht
+Гаїті ht
+海地岛 ht
+Hungary hu
+Hongarye hu
+هنغاريا hu
+Macarıstan hu
+Вугоршчына hu
+Ð£Ð½Ð³Ð°Ñ€Ð¸Ñ hu
+Hungaria hu
+Mađarska hu
+Hongria hu
+MaÄarsko hu
+Ungarn hu
+Ungarn hu
+ΟυγγαÏία hu
+Hungario hu
+Hungría hu
+Ungari hu
+Hungaria hu
+مجارستان hu
+Unkari hu
+Ungarn hu
+Hongrie hu
+Hungría hu
+הונגריה hu
+Mađjarska hu
+Magyarország hu
+Hungaria hu
+Ungverjaland hu
+Ungheria hu
+ãƒãƒ³ã‚¬ãƒªãƒ¼ hu
+í—가리 hu
+ຫັງàºàº²àº¥àºµ hu
+Vengrija hu
+UngÄrija hu
+Ungerija hu
+Ungarn hu
+Hongarije hu
+Ungarn hu
+Hongria hu
+Węgry hu
+Hungria hu
+Hungria hu
+Ungaria hu
+Ð’ÐµÐ½Ð³Ñ€Ð¸Ñ hu
+MaÄarsko hu
+Madžarska hu
+Mađarska hu
+I-Hungary hu
+Ungern hu
+¬í§¸Ã¢ hu
+ฮังà¸à¸²à¸£à¸µ hu
+Macaristan hu
+Угорщина hu
+Hongreye hu
+匈牙利 hu
+匈牙利 hu
+Indonesia id
+Indonesië id
+إندونيسيا id
+İndoneziya id
+ІнданÑÐ·Ñ–Ñ id
+Ð˜Ð½Ð´Ð¾Ð½ÐµÐ·Ð¸Ñ id
+Indonezija id
+Indonèsia id
+Indonésie id
+Indonesien id
+Indonesien id
+Ινδονησία id
+Indonezio id
+Indoneesia id
+اندونزی id
+Indonésie id
+×ינדונזיה id
+Indonezija id
+Indonézia id
+Indónesía id
+インドãƒã‚·ã‚¢ id
+ì¸ë„네시아 id
+ອີàºà»‚ດນີເຊີຠid
+Indonezija id
+Indonēzija id
+Indoneżja id
+Indonesië id
+Indonezja id
+Indonésia id
+Indonésia id
+Indonezia id
+Ð˜Ð½Ð´Ð¾Ð½ÐµÐ·Ð¸Ñ id
+Indonézia id
+Indonezija id
+I-Indonesia id
+Indonesien id
+­ó§¾¡É£º¢Â¡ id
+อินโดนีเซีย id
+İndonezya id
+Ð†Ð½Ð´Ð¾Ð½ÐµÐ·Ñ–Ñ id
+Indoneseye id
+å°åº¦å°¼è¥¿äºš id
+å°å°¼ id
+Ireland ie
+Ierland ie
+أيرلندا ie
+İrlandiya ie
+ІрлÑÐ½Ð´Ñ‹Ñ ie
+Ð˜Ñ€Ð»Ð°Ð½Ð´Ð¸Ñ ie
+Iwerzhon ie
+Irska ie
+Irlanda ie
+Irsko ie
+Irland ie
+Irland ie
+ΙÏλανδία ie
+Islando ie
+Irlanda ie
+Island ie
+Irlanda ie
+ایرلند ie
+Irlanti ie
+Ãrland ie
+Irlande ie
+Irlanda ie
+×ירלנד ie
+Irska ie
+Ãrország ie
+Irlandia ie
+ÃÂrland ie
+Irlanda ie
+アイスランド ie
+ì•„ì¼ëžœë“œ ie
+ໄອà»àº¥àº™ ie
+Airija ie
+Īrija ie
+Irlanda ie
+Irland ie
+Ierland ie
+Irland ie
+Irlanda ie
+Irlandia ie
+Irlanda ie
+Irlanda ie
+Irlanda ie
+Ð˜Ñ€Ð»Ð°Ð½Ð´Ð¸Ñ ie
+Ãrsko ie
+Irska ie
+Irska ie
+I-Ireland ie
+Irland ie
+«Â÷Ä¡óà ie
+ไอร์à¹à¸¥à¸™à¸”์ ie
+İrlanda ie
+Ð†Ñ€Ð»Ð°Ð½Ð´Ñ–Ñ ie
+Irlande ie
+爱尔兰 ie
+愛爾蘭 ie
+Israel il
+اسرائيل il
+İzrail il
+Ізраіль il
+Израел il
+Izrael il
+Izrael il
+ΙσÏαήλ il
+Israelo il
+Iisrael il
+اسراییل il
+Ãsrael il
+Israël il
+ישר×ל il
+Izrael il
+Izrael il
+ÃÂsrael il
+Israele il
+イスラエル il
+ì´ìФë¼ì—˜ il
+ອິດສະລະເອລ il
+Izraelis il
+Izraēla il
+Iżrael il
+Izrael il
+Израиль il
+Izrael il
+Izrael il
+Izrael il
+I-Israel il
+­Ã§Ãø il
+อิสราเอล il
+İsrail il
+Ізраїль il
+Israyel il
+USirayeli il
+以色列 il
+以色列 il
+India in
+Indië in
+الهند in
+Hindistan in
+Ð†Ð½Ð´Ñ‹Ñ in
+Ð˜Ð½Ð´Ð¸Ñ in
+Indija in
+Ãndia in
+Indie in
+Indien in
+Indien in
+Ινδία in
+Hindujo in
+هندوستان in
+Intia in
+Inde in
+הודו in
+Indija in
+Indland in
+インド in
+ì¸ë„ in
+ອິນເດີຠin
+Indija in
+Indija in
+Indja in
+Indie in
+Ãndia in
+Ãndia in
+Ð˜Ð½Ð´Ð¸Ñ in
+Indija in
+I-India in
+Indien in
+­ó¾¢Â¡ in
+อินเดีย in
+Hindistan in
+Ð†Ð½Ð´Ñ–Ñ in
+Inde in
+å°åº¦ in
+å°åº¦ in
+Endiya in
+Iraq iq
+Irak iq
+العراق iq
+İraq iq
+Ірак iq
+Ирак iq
+Irak iq
+Irák iq
+Irak iq
+Irak iq
+ΙÏάκ iq
+Irako iq
+Irak iq
+Iraak iq
+عراق iq
+Irak iq
+Irak iq
+Irak iq
+עירק iq
+Irak iq
+Irak iq
+ÃÂrak iq
+Irak iq
+イラク iq
+ì´ë¼í¬ iq
+ອີລັຠiq
+Irakas iq
+IrÄka iq
+Irak iq
+Irak iq
+Irak iq
+Irak iq
+Iraque iq
+Iraque iq
+Irak iq
+Ирак iq
+Irák iq
+Irak iq
+I-Iraq iq
+Irak iq
+®Ã¡ì iq
+อิรัค iq
+Irak iq
+Ірак iq
+Irak iq
+伊拉克 iq
+伊拉克 iq
+Iran ir
+أيران ir
+Іран ir
+Иран ir
+Ãrán ir
+ΙÏάν ir
+Iraan ir
+ایران ir
+×ירן ir
+Irán ir
+イラン ir
+ì´ëž€ ir
+ອີລັຠir
+Iranas ir
+Irão ir
+Irã ir
+Иран ir
+Irán ir
+I-Iran ir
+®Ã¡ý ir
+İran ir
+Іран ir
+伊朗 ir
+伊朗 ir
+Iceland is
+Ysland is
+أيسلندا is
+İslandiya is
+ІÑьлÑÐ½Ð´Ñ‹Ñ is
+ИÑÐ»Ð°Ð½Ð´Ð¸Ñ is
+Island is
+Island is
+Islàndia is
+Island is
+Island is
+Island is
+Ισλανδία is
+Islando is
+Islandia is
+Island is
+Islandia is
+ایسلند is
+Islanti is
+Ãsland is
+Islande is
+Islandia is
+×יסלנד is
+Island is
+Izland is
+Islandia is
+ÃÂsland is
+Islanda is
+アイスランド is
+ì•„ì´ìŠ¬ëž€ë“œ is
+ໄອຊà»àº¥àº™ is
+Islandija is
+Islande is
+Islandja is
+Island is
+IJsland is
+Island is
+Islandia is
+Islandia is
+Islândia is
+Islândia is
+Islanda is
+ИÑÐ»Ð°Ð½Ð´Ð¸Ñ is
+Island is
+Islandija is
+Island is
+I-Iceland is
+Island is
+³ÃÄ¡óà is
+ไอซ์à¹à¸¥à¸™à¸”์ is
+İzlanda is
+ІÑÐ»Ð°Ð½Ð´Ñ–Ñ is
+Izlande is
+冰岛 is
+冰島 is
+Icelandi is
+Italy it
+Italië it
+ايطاليا it
+İtalyia it
+Ð†Ñ‚Ð°Ð»Ñ–Ñ it
+Ð˜Ñ‚Ð°Ð»Ð¸Ñ it
+Italia it
+Italija it
+Itàlia it
+Itálie it
+Italien it
+Italien it
+Ιταλία it
+Italio it
+Italia it
+Itaalia it
+Italia it
+ایتالیا it
+Italia it
+Italia it
+Italie it
+Italia it
+×יטליה it
+Italija it
+Olaszország it
+Italia it
+ÃÂtalía it
+Italia it
+イタリア it
+ì´íƒˆë¦¬ì•„ it
+ອີຕາລີ it
+Italija it
+ItÄlija it
+Italja it
+Italia it
+Italië it
+Italia it
+Italia it
+Włochy it
+Itália it
+Itália it
+Italia it
+Ð˜Ñ‚Ð°Ð»Ð¸Ñ it
+Taliansko it
+Italija it
+Italija it
+I-Italy it
+Italien it
+­ò¾¡Ä¢ it
+อิตาลี it
+İtalya it
+Ð†Ñ‚Ð°Ð»Ñ–Ñ it
+Itåleye it
+Ithali it
+æ„大利 it
+義大利 it
+Jamaica jm
+Jamaika jm
+جامايكا jm
+Yamayka jm
+Ямайка jm
+Ямайка jm
+Jamaika jm
+Jamajka jm
+Jamajka jm
+Jamaika jm
+Τζαμάικα jm
+Ä´amaiko jm
+Jamaika jm
+Jamaika jm
+جاماییکا jm
+Jamaika jm
+Jamaïque jm
+Xamaica jm
+ג'מייקה jm
+Jamajka jm
+Jamaika jm
+Jamaika jm
+Giamaica jm
+ジャマイカ jm
+ìžë©”ì´ì¹´ jm
+ຈາໄມàºàº² jm
+Jamaika jm
+Jamaika jm
+Ä amajka jm
+Jamajka jm
+Ямайка jm
+Jamajka jm
+Jamajka jm
+Jamajka jm
+I-Jamaica jm
+ƒº¦Ãö측 jm
+จาไมà¸à¸² jm
+Jamaika jm
+Ямайка jm
+Djamayike jm
+牙买加 jm
+牙買加 jm
+Jordan jo
+Jordaan jo
+الأردن jo
+İordaniya jo
+Ð¯Ñ€Ð´Ð°Ð½Ñ–Ñ jo
+Ð™Ð¾Ñ€Ð´Ð°Ð½Ð¸Ñ jo
+Jordania jo
+Jordán jo
+Jordanien jo
+ΙοÏδανία jo
+Jordanio jo
+Jordania jo
+اردن jo
+Jordania jo
+Jordanie jo
+ירדן jo
+Jordánia jo
+Jórdanía jo
+Giordania jo
+ヨルダン jo
+요르단 jo
+ຈà»à»àº”ນ jo
+Jordanija jo
+JordÄna jo
+Ä ordan jo
+Jordanië jo
+Jordania jo
+Jordânia jo
+Jordânia jo
+Iordania jo
+Ð˜Ð¾Ñ€Ð´Ð°Ð½Ð¸Ñ jo
+Jordánsko jo
+Jordanija jo
+I-Jordan jo
+Jordanien jo
+§Â¡÷¾¡ý jo
+จอร์à¹à¸”น jo
+Ürdün jo
+Ð™Ð¾Ñ€Ð´Ð°Ð½Ñ–Ñ jo
+Djordaneye jo
+约旦 jo
+ç´„æ—¦ jo
+Ijolidani jo
+Japan jp
+اليابان jp
+Yaponiya jp
+Ð¯Ð¿Ð¾Ð½Ñ–Ñ jp
+Ð¯Ð¿Ð¾Ð½Ð¸Ñ jp
+Japó jp
+Japonsko jp
+Ιαπωνία jp
+Japanio jp
+Japón jp
+Jaapan jp
+Japonia jp
+ژاپن jp
+Japani jp
+Japon jp
+Xapón jp
+יפן jp
+Japán jp
+Jepang jp
+Giappone jp
+日本 jp
+ì¼ë³¸ jp
+àºàºµà»ˆàº›àº¸à»ˆàº™ jp
+Japonija jp
+JapÄna jp
+Ä appun jp
+Japon jp
+Japonia jp
+Japão jp
+Japão jp
+Japonia jp
+Ð¯Ð¿Ð¾Ð½Ð¸Ñ jp
+Japonsko jp
+Japonska jp
+I-Japan jp
+ºôÀ¡ý jp
+à¸à¸µà¹ˆà¸›à¹ˆà¸¸à¸™ jp
+Japonya jp
+Ð¯Ð¿Ð¾Ð½Ñ–Ñ jp
+Nhật bản jp
+Djapon jp
+日本 jp
+日本 jp
+Kenya ke
+ÐšÐµÐ½Ñ–Ñ ke
+ÐšÐµÐ½Ð¸Ñ ke
+Kenija ke
+Kenia ke
+ເວນດາ ke
+Quênia ke
+Keňa ke
+Kenija ke
+ÐšÐµÐ½Ñ–Ñ ke
+肯尼亚 ke
+Kyrgyzstan kg
+КыргызÑтан kg
+КиргиÑтан kg
+Kirgistan kg
+Kirgizistan kg
+Kyrgyzstán kg
+Kirgizisztán kg
+ຄສິຕັລ kg
+Kirgizstan kg
+Kirgizistan kg
+КиргизÑтан kg
+å‰å°”剿–¯å¦ kg
+Cambodia kh
+Камбоджа kh
+Камбоджа kh
+Kambođa kh
+Kambodzsa kh
+ໂຄລຳເບີຠkh
+Cambodja kh
+Kambodža kh
+Kambodža kh
+Kambodja kh
+Камбоджа kh
+柬埔寨 kh
+Kiribati ki
+Кiрыбацi ki
+Кирибати ki
+à»àºŸàº„ທັລ - K ki
+Кірібаті ki
+基里巴斯 ki
+Comoros km
+Каморы km
+КоморÑки km
+Komori km
+Comorerne km
+ສີ km
+Komori km
+Komorerna km
+Комори km
+科摩罗群岛 km
+St. Kitts and Nevis kn
+St. Kitts en Nevis kn
+سانت كيتس Ùˆ نيÙيس kn
+St. Kitts vÉ™ Nevis kn
+Св. КриÑтоф и ÐÐµÐ²Ð¸Ñ kn
+S. Kitts ha Nevis kn
+St. Kitts i Nevis kn
+Sv. Kitts a Nevis kn
+St. Kitts-Nevis kn
+St. Kitts und Nevis kn
+St. Kitts και Nevis kn
+St. Kitts kaj Nevis kn
+St. Kitts y Nevis kn
+St. Kitts ja Nevis kn
+St. Kitts eta Nevis kn
+سن کیتس و نویس kn
+St. Kitts ja Nevis kn
+St Kitts et Nevis kn
+Saint Kitts e Nevis kn
+סנט קיטס ונביס kn
+St. Kitts és Nevis kn
+St. Kitts dan Nevis kn
+Ss. Kitts e Nevis kn
+セントキッツãƒãƒ´ã‚£ã‚¹ kn
+세ì¸íЏ 키츠 네비스 kn
+Å v. Kitts ir Nevis kn
+St. Kitts un Nevis kn
+St. Kitts u Nevis kn
+St. Kitts og Nevis kn
+St. Kitts en Nevis kn
+St. Kitts og Nevis kn
+St. Kitts le Nevis kn
+St. Kitts e Nevis kn
+St. Kitts e Nevis kn
+St Kitts e Nevis kn
+Sf. Kitts ÅŸi Nevis kn
+о. Св. КриÑтофа и ÐевиÑа kn
+St. Kitts a Nevis kn
+St. Kitts in Nevis kn
+St. Kitts i Nevis kn
+I-St. Kitts and Nevis kn
+St. Kitts och Nevis kn
+¦ºÂ¢ý𠸢ðà & ¦¿Å¢à kn
+St. Kitts ve Nevis kn
+Ð¤ÐµÐ´ÐµÑ€Ð°Ñ†Ñ–Ñ Ð¡ÐµÐ½Ñ‚-ÐšÑ–Ñ‚Ñ Ñ– ÐÐµÐ²Ñ–Ñ kn
+St. Kitts na Nevis kn
+St. Kitts neNevis kn
+圣基特和里维斯 kn
+è–å…‹ç†æ–¯å¤šç¦åŠå°¼ç¶­æ–¯ kn
+St. Kitts kanye no-Nevis kn
+North Korea kp
+Noord Korea kp
+كوريا الشمالية kp
+Åžimali Koreya kp
+ÐŸÐ°ÑžÐ½Ð¾Ñ‡Ð½Ð°Ñ ÐšÐ°Ñ€ÑÑ kp
+Северна ÐšÐ¾Ñ€ÐµÑ kp
+Norzh-Korea kp
+Sjeverna Koreja kp
+Corea del Nord kp
+Severní Korea kp
+Nordkorea kp
+Nord-Korea kp
+Î’ÏŒÏεια ΚοÏέα kp
+Nordkoreo kp
+Corea del Norte kp
+Põhja-Korea kp
+Ipar Korea kp
+کره شمالی kp
+Pohjois-Korea kp
+Norðurkorea kp
+Corée du nord kp
+Corea do Norte kp
+צפון קורי××” kp
+Sjeverna Koreja kp
+Észak-Korea kp
+Korea Utara kp
+Kórea - Norðurkórea kp
+Corea del Nord kp
+北æœé®® kp
+ì¡°ì„ ë¯¼ì£¼ì£¼ì˜ ì¸ë¯¼ê³µí™”êµ­ kp
+ເàºàº»àº²àº¥àºµà»€àº«àº™àº·àº­ kp
+Å iaurÄ—s KorÄ—ja kp
+ZiemeļKoreja kp
+Korea ta' Fuq kp
+Nord-Korea kp
+Noord-Korea kp
+Nord-Korea kp
+Lebowa la Korea kp
+Corea dèu Nord kp
+Korea Północna kp
+Coreia do Norte kp
+Coréia do Norte kp
+Coreea de Nord kp
+Ð¡ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÐšÐ¾Ñ€ÐµÑ kp
+severná Kórea kp
+Severna Koreja kp
+Severna Koreja kp
+I-North Korea kp
+Nordkorea kp
+ż ¦¸¡Ã¢Â¡ kp
+เà¸à¸²à¸«à¸¥à¸µà¹€à¸«à¸™à¸·à¸­ kp
+Kuzey Kore kp
+Північна ÐšÐ¾Ñ€ÐµÑ kp
+Devhula ha Korea kp
+Bắc Triá»u Tiên kp
+Bijhe Coreye kp
+Umntla Korea kp
+æœé²œ kp
+北韓 kp
+Enyakatho ne-Korea kp
+South Korea kr
+Suid Korea kr
+كوريا الجنوبية kr
+Cənubi Koreya kr
+ÐŸÐ°ÑžÐ´Ð½Ñ‘Ð²Ð°Ñ ÐšÐ°Ñ€ÑÑ kr
+Южна ÐšÐ¾Ñ€ÐµÑ kr
+Su-Korea kr
+Južna Koreja kr
+Corea del Sud kr
+Jižní Korea kr
+Sydkorea kr
+Süd-Korea kr
+Îότια ΚοÏέα kr
+Sudkoreo kr
+Corea del Sur kr
+Lõuna-Korea kr
+Hego Korea kr
+کره جنوبی kr
+Etelä-Korea kr
+Suðurkorea kr
+Corée du sud kr
+Corea do Sur kr
+×“×¨×•× ×§×•×¨×™××” kr
+Južna Koreja kr
+Dél-Korea kr
+Korea Selatan kr
+Kórea - Suðurkórea kr
+Corea del Sud kr
+韓国 kr
+대한민국 kr
+ເàºàº»àº²àº¥àºµà»ƒàº•້ kr
+Pietų Korėja kr
+DievidKoreja kr
+Korea t'Isfel kr
+Sør-Korea kr
+Zuid-Korea kr
+Sør-Korea kr
+Borwa bja Korea kr
+Corea dèu Sud kr
+Korea Południowa kr
+Coreia do Sul kr
+Coréia do Sul kr
+Coreea de Sud kr
+Ð®Ð¶Ð½Ð°Ñ ÐšÐ¾Ñ€ÐµÑ kr
+Južná Kórea kr
+Južna Koreja kr
+Južna Koreja kr
+I-South Korea kr
+Sydkorea kr
+¦¾ý ¦¸¡Ã¢Â¡ kr
+เà¸à¸²à¸«à¸¥à¸µà¹ƒà¸•้ kr
+Güney Kore kr
+Південна ÐšÐ¾Ñ€ÐµÑ kr
+Korea tshipembe kr
+Hàn Quốc kr
+Nonne Coreye kr
+Umzantsi Korea kr
+韩国 kr
+å—韓 kr
+Emzansi Korea kr
+Kuwait kw
+Kuwaït kw
+الكويت kw
+КувÑйт kw
+Кувейт kw
+Kuvajt kw
+Kuvajt kw
+Κουβέιτ kw
+Kuveit kw
+کویت kw
+Kuvait kw
+Kowait kw
+כווית kw
+Kuvajt kw
+Kuvait kw
+クェート kw
+쿠웨ì´íЏ kw
+à»àº•້ມຮູບ- K kw
+Kuveitas kw
+Koeweit kw
+Koweit kw
+Kuveit kw
+Кувейт kw
+Kuvajt kw
+Kuvajt kw
+I-Kuwait kw
+̨Åò kw
+KКувейт kw
+ç§‘å¨ç‰¹ kw
+ç§‘å¨ç‰¹ kw
+Cayman Islands ky
+Кайманови ОÑтрови ky
+Kajmanska ostrva ky
+Cayman-øerne ky
+Islas Caimán ky
+Kaiman Irlak ky
+Kajmán-szigetek ky
+ຄາຕາລັນ ky
+Ilhas Cayman ky
+Kajmanske Ostrovy ky
+Kajmanski otoki ky
+Caymanöarna ky
+КайманÑькі оÑтрови ky
+开曼群岛 ky
+Kazakhstan kz
+КазахÑтан kz
+КазахÑтан kz
+Kazahstan kz
+Kazakhstán kz
+Kazahsztán kz
+à»àºà»àº¥àºàº•ິຠ- K kz
+Kazaquistão kz
+Kazachstan kz
+Kazahstan kz
+Kazakstan kz
+КазахÑтан kz
+哈è¨å…‹æ–¯å¦ kz
+Laos la
+Ð›Ð°Ð¾Ñ la
+Ð›Ð°Ð¾Ñ la
+Laosz la
+ລາວ la
+è€æŒ la
+Lebanon lb
+Libanon lb
+لبنان lb
+Ліван lb
+Ливан lb
+Liban lb
+Libanon lb
+Libanon lb
+Libanon lb
+Λίβανος lb
+Lebanono lb
+Líbano lb
+Liibanon lb
+لبنان lb
+Libanon lb
+Libanon lb
+Liban lb
+לבנון lb
+Libanon lb
+Libanon lb
+Libano lb
+レãƒãƒŽãƒ³ lb
+레바논 lb
+ເດນ່ງນ lb
+Libanas lb
+Libanu lb
+Libanon lb
+Libanon lb
+Libanon lb
+Liban lb
+Líbano lb
+Líbano lb
+Liban lb
+Ливан lb
+Libanon lb
+Libanon lb
+I-Lebanon lb
+Libanon lb
+¦ÄÀÉ¡ý lb
+Ліван lb
+Liban lb
+黎巴嫩 lb
+黎巴嫩 lb
+St. Lucia lc
+سانت لوسيا lc
+Св. ЛюÑиа lc
+S. Lucia lc
+Svatá Lucie lc
+Σάντα Λουτσία lc
+St. Lucio lc
+Santa Lucía lc
+سن لوسیا lc
+Sankta Lusia lc
+Sainte Lucie lc
+Santa Lucía lc
+סנטה לוסיה lc
+Santa Lucia lc
+セントルキア lc
+세ì¸íЏ 루시아 lc
+ເຊັນລູເຊີຠlc
+Å v Liucija lc
+Sv. Lūcija lc
+St. Luċija lc
+Santa Lúcia lc
+Santa Lúcia lc
+Sf. Lucia lc
+о. Св. ЛюÑии lc
+Sv. Júlia lc
+Sv. Lucija lc
+I-St. Lucia lc
+¦ºýð æº¢Â¡ lc
+เซนต์ลูเซีย lc
+Санта Ð›ÑƒÑ‡Ñ–Ñ lc
+圣路西亚 lc
+è–露西亞 lc
+Liechtenstein li
+ЛіхтÑнштÑйн li
+Лихтенщайн li
+Lihtenštajn li
+Liechtestein li
+ຟ້າà»àº¡àºš li
+列支敦士登 li
+Sri Lanka lk
+Шры-Ланка lk
+Шри Ланка lk
+Å ri Lanka lk
+ເຊີເບີຠlk
+Å ri Lanka lk
+æ–¯é‡Œå…°å¡ lk
+Liberia lr
+ЛібÑÑ€Ñ‹Ñ lr
+Ð›Ð¸Ð±ÐµÑ€Ñ lr
+Liberija lr
+Libéria lr
+ລິຊາ lr
+Libéria lr
+Lýbia lr
+Liberija lr
+利比里亚 lr
+Lesotho ls
+ЛеÑота ls
+ЛеÑото ls
+Lesoto ls
+Lesoto ls
+ທົດສອບ ls
+Lesoto ls
+莱索托 ls
+Lithuania lt
+Lithuanië lt
+ليتوانيا lt
+Litvaniya lt
+Літва lt
+Литва lt
+Litvanija lt
+Lituània lt
+Litva lt
+Litauen lt
+Litauen lt
+Λιθουανία lt
+Litovio lt
+Lituania lt
+Leedu lt
+Lituania lt
+لیتوانی lt
+Liettua lt
+Lituanie lt
+×œ×™×˜× lt
+Litva lt
+Litvánia lt
+Litháenska lt
+Lituania lt
+リトアニア lt
+리 투아니아 lt
+ລິທົ່ວເນີຠlt
+Lietuva lt
+Lietuva lt
+Litwanja lt
+Litauen lt
+Litouwen lt
+Litauen lt
+Litwa lt
+Lituânia lt
+Lituânia lt
+Lituania lt
+Литва lt
+Litva lt
+Litva lt
+Litvanija lt
+I-Lithuania lt
+Litauen lt
+Ä¢òçÅɢ¡ lt
+ลิธัวเนีย lt
+Litvanya lt
+Литва lt
+ç«‹é™¶å®› lt
+ç«‹é™¶å®› lt
+Luxembourg lu
+Luxenburg lu
+لوكسمبورغ lu
+Lüksemburq lu
+ЛюкÑÑмбург lu
+ЛюкÑембург lu
+Luksemburg lu
+Luxemburg lu
+Lucembursko lu
+Luxemburg lu
+ΛουξεμβοÏÏγο lu
+Luksemburgo lu
+Luxemburgo lu
+Luksemburg lu
+Luxemburg lu
+لوگزامبورگ lu
+Luxemburg lu
+Luksemborg lu
+לוקסמבורג lu
+Luksemburg lu
+Luxemburg lu
+Lúxemborg lu
+Lussemburgo lu
+ルクセンブルグ lu
+ë£©ì…ˆë¶€ë¥´í¬ lu
+ລັàºà»àºŠàº¡à»€àºšàºµàº lu
+Liuksemburgas lu
+Luksemburga lu
+Lussemburgu lu
+Luxemburg lu
+Luksemburg lu
+Luxemburgo lu
+Luxemburgo lu
+Luxemburg lu
+ЛюкÑембург lu
+Luxemburg lu
+Luksemburg lu
+Luksemburg lu
+I-Luxembourg lu
+Luxemburg lu
+Äìºõ§À¡÷ì lu
+ลัà¸à¹€à¸‹à¸¡à¹€à¸šà¸­à¸£à¹Œà¸ lu
+Lüksemburg lu
+ЛюкÑембург lu
+Lucsimbork lu
+墿£®å ¡ lu
+盧森堡 lu
+Latvia lv
+لاتÙيا lv
+Latviya lv
+Ð›Ð°Ñ‚Ð²Ñ–Ñ lv
+Ð›Ð°Ñ‚Ð²Ð¸Ñ lv
+Latvija lv
+Lotyšsko lv
+Letland lv
+Lettland lv
+Λιθουανία lv
+Latvio lv
+Letonia lv
+Läti lv
+لاتویا lv
+Lettonie lv
+לטביה lv
+Latvija lv
+Lettország lv
+Léttland lv
+Lettonia lv
+ラトビア lv
+ë¼íŠ¸ë¹„ì•„ lv
+ລັດເວີຠlv
+Latvija lv
+Latvija lv
+Latvja lv
+Letland lv
+Åotwa lv
+Letónia lv
+Ð›Ð°Ñ‚Ð²Ð¸Ñ lv
+Lotyšsko lv
+Latvija lv
+Latvija lv
+I-Latvia lv
+Lettland lv
+ÄðŢ¡ lv
+ลัธเวีย lv
+Litvanya lv
+Ð›Ð°Ñ‚Ð²Ñ–Ñ lv
+Lativia lv
+拉脱维亚 lv
+拉脫維亞 lv
+Libya ly
+Libië ly
+ليبيا ly
+Ð›Ñ–Ð²Ñ–Ñ ly
+Ð›Ð¸Ð±Ð¸Ñ ly
+Libija ly
+Líbia ly
+Lýbie ly
+Libyen ly
+Libyen ly
+ΛιβÏη ly
+Libia ly
+Liibüa ly
+Libia ly
+لیبی ly
+Lybie ly
+לוב ly
+Líbia ly
+Libia ly
+リビア ly
+ລິຊາ ly
+Libija ly
+Libië ly
+Libia ly
+Líbia ly
+Líbia ly
+Ð›Ð¸Ð²Ð¸Ñ ly
+Lýbia ly
+Libija ly
+I-Libya ly
+Libyen ly
+Ä¢À¢Â¡ ly
+Ð›Ñ–Ð²Ñ–Ñ ly
+利比亚 ly
+利比亞 ly
+Morocco ma
+Morokko ma
+المغرب ma
+Марока ma
+Мароко ma
+Maroko ma
+Marroc ma
+Maroko ma
+Marokko ma
+Marokko ma
+ΜαÏόκο ma
+Moroko ma
+Marruecos ma
+Maroko ma
+Maroko ma
+مراکش ma
+Marokko ma
+Marokko ma
+Maroc ma
+מרוקו ma
+Maroko ma
+Marokkó ma
+Marocco ma
+モロッコ ma
+모로코 ma
+ເມົາລິ ma
+Marokas ma
+Marokk ma
+Marokko ma
+Marokko ma
+Marokko ma
+Maroko ma
+Marrocos ma
+Marrocos ma
+Maroc ma
+Марокко ma
+Maroko ma
+Maroko ma
+I-Morocco ma
+Marocko ma
+§Ã¡Ã¡§¸¡ ma
+Марокко ma
+Marok ma
+摩洛哥 ma
+摩洛哥 ma
+Monaco mc
+Манака mc
+Монако mc
+Monako mc
+Mónaco mc
+ເມົາລິ mc
+Mônaco mc
+Monako mc
+Monako mc
+摩纳哥 mc
+Moldova md
+Малдова md
+Молдова md
+Moldavia md
+Moldavia md
+ສະໂລວັຠmd
+Moldávsko md
+Moldavien md
+摩尔多瓦 md
+Madagascar mg
+МадагаÑкар mg
+МадагаÑкар mg
+Madagaskar mg
+Madagaszkár mg
+ຄາສະບາລ - K mg
+Madagaskar mg
+Madagaskar mg
+Madagaskar mg
+马达加斯加 mg
+Marshall Islands mh
+Маршаллавы аÑтравы mh
+Маршалови ОÑтрови mh
+Maršalova ostrva mh
+Marshall-øerne mh
+Islas Marshall mh
+Marshall Irlak mh
+Marshall-szigetek mh
+ລາດສະອານາຈັàºà»„ທຠmh
+Ilhas Marshall mh
+Maršálove ostrovy mh
+Marshallovi otoki mh
+Marshallöarna mh
+马ç»å°”群岛 mh
+Macedonia mk
+Makedoniese mk
+مقدونيا mk
+Makedonya mk
+ÐœÐ°ÐºÐµÐ´Ð¾Ð½Ñ–Ñ mk
+ÐœÐ°ÐºÐµÐ´Ð¾Ð½Ð¸Ñ mk
+Makedonia mk
+Makedonija mk
+Macedònia mk
+Makedonie mk
+Makedonien mk
+Makedonien mk
+Μακεδονία mk
+Macedonio mk
+Makedoonia mk
+Mazedonia mk
+مقدونیه mk
+Makedonia mk
+Macédoine mk
+מקדוניה mk
+Makedonija mk
+Macedónia mk
+Masedonia mk
+Makedónía mk
+マケドニア語 mk
+마케ë„니아 mk
+ມາເຊໂດເນີຠmk
+Makedonija mk
+MaÄ·edonija mk
+Maċedonja mk
+Makedonia mk
+Macedonië mk
+Makedonia mk
+Macedònian mk
+Macedónia mk
+Macedônia mk
+ÐœÐ°ÐºÐµÐ´Ð¾Ð½Ð¸Ñ mk
+Macedónsky mk
+Makedonija mk
+Makedonija mk
+I-Macedonia mk
+Makedonien mk
+Ả§¼¡É¢Â¡ mk
+มาเซโดเนีย mk
+Makedonya mk
+ÐœÐ°ÐºÐµÐ´Ð¾Ð½Ñ–Ñ mk
+Masedonia mk
+马其顿 mk
+馬其頓 mk
+Mali ml
+Малі ml
+Мали ml
+ຈົດຫມາຠml
+马里 ml
+Myanmar mm
+М'Ñнма mm
+Майнмар mm
+Mjanmar mm
+Burma mm
+Birmania mm
+ຕົວຮງàºàºžàºµàº·à»‰àº™àº—ີ່ທຳງານ - K mm
+Mjanmar mm
+缅甸 mm
+Mongolia mn
+ÐœÐ°Ð½Ð³Ð¾Ð»Ñ–Ñ mn
+ÐœÐ¾Ð½Ð³Ð¾Ð»Ð¸Ñ mn
+Mongolija mn
+Mongoliet mn
+Mongólia mn
+ລອàºàº­àº´àº™ mn
+Mongólia mn
+Mongolsko mn
+Mongolija mn
+Mongoliet mn
+è’™å¤ mn
+Macau mo
+Макао mo
+Makau mo
+Macao mo
+Makaó mo
+ມອລຕາ mo
+Makao mo
+Macao mo
+澳门 mo
+Martinique mq
+Мартиника mq
+Martinik mq
+Martinica mq
+ເມົາລິ mq
+Martinik mq
+马æå°¼å…‹å²› mq
+Mauritania mr
+ÐœÐ°ÑžÑ€Ñ‹Ñ‚Ð°Ð½Ñ–Ñ mr
+ÐœÐ°Ð²Ñ€Ð¸Ñ‚Ð°Ð½Ð¸Ñ mr
+Mauritanija mr
+Mauretanien mr
+Mauritánia mr
+ລິທົວເນີຠmr
+Mauritânia mr
+Mavretanija mr
+Mauretanien mr
+毛里塔尼亚 mr
+Montserrat ms
+МонÑерат ms
+Monsera ms
+ຈà»àºžàº²àºš ms
+蒙特塞拉特岛 ms
+Malta mt
+مالطة mt
+Мальта mt
+Малта mt
+Μάλτα mt
+Malto mt
+مالت mt
+Malte mt
+מלטה mt
+Málta mt
+マルタ mt
+왈타 mt
+ມອລຕາ mt
+Мальта mt
+I-Malta mt
+áø¼¡ mt
+มอลตา mt
+Мальта mt
+Male mt
+马耳他 mt
+馬爾他 mt
+Mauritius mu
+Маўрыцы mu
+Маурици mu
+Mauricijus mu
+Mauricio mu
+ພາທິຊັ້ນ mu
+Maurícius mu
+Mavricij mu
+毛里求斯 mu
+Maldives mv
+Мальдывы mv
+Малдиви mv
+Maldivi mv
+Maldiverne mv
+Maldivas mv
+Maldív-szigetek mv
+ມັລດິສ mv
+Maldivas mv
+Maldiv mv
+Maldiverna mv
+马尔代夫 mv
+Malawi mw
+Малаві mw
+Малави mw
+Malavi mw
+ມອລຕາ mw
+马拉维 mw
+Mexico mx
+Meksiko mx
+المكسيك mx
+Meksika mx
+МÑкÑыка mx
+МекÑико mx
+Mec'hiko mx
+Meksiko mx
+Mèxic mx
+Mexiko mx
+Mexiko mx
+Μεξικό mx
+Meksikujo mx
+México mx
+Mehhiko mx
+Mexiko mx
+مکزیک mx
+Meksiko mx
+Meksiko mx
+Mexique mx
+México mx
+מקסיקו mx
+Meksiko mx
+Mexikó mx
+Meksiko mx
+Mexíkó mx
+Messico mx
+メキシコ mx
+멕시코 mx
+ເມັàºàºŠàºµà»‚ຠmx
+Meksika mx
+Meksika mx
+Messiku mx
+Mèxic mx
+Meksyk mx
+México mx
+México mx
+Mexic mx
+МекÑика mx
+Mexiko mx
+Mehika mx
+Meksiko mx
+I-Mexico mx
+¦Ã캢§¸¡ mx
+เม็à¸à¸‹à¸´à¹‚ภmx
+Meksika mx
+МекÑика mx
+Mê hi cô mx
+Mecsike mx
+墨西哥 mx
+墨西哥 mx
+Malaysia my
+ÐœÐ°Ð»Ð°Ð¹Ð·Ñ‹Ñ my
+ÐœÐ°Ð»Ð°Ð¹Ð·Ð¸Ñ my
+Malezija my
+Malasia my
+Malasia my
+Malajzia my
+ມອລຕາ my
+Malásia my
+Malajzia my
+Malezija my
+马æ¥è¥¿äºš my
+Mozambique mz
+Мазамбік mz
+Мозамбик mz
+Mozambik mz
+Mozambik mz
+ຫນ່ວàºàº„ວາມຈຳ mz
+Moçambique mz
+Mozambik mz
+Mozambik mz
+Moçambique mz
+莫桑比克 mz
+Namibia na
+ÐÐ°Ð¼Ñ–Ð±Ñ–Ñ na
+ÐÐ°Ð¼Ð¸Ð±Ð¸Ñ na
+Namibija na
+Namíbia na
+ຈາໄມàºàº² na
+Namíbia na
+Namíbia na
+Namibija na
+纳米比亚 na
+New Caledonia nc
+Ðова ÐšÐ°Ð»ÐµÐ´Ð¾Ð½Ð¸Ñ nc
+Nova Kaledonija nc
+Ny Caledonien nc
+Nueva Caledonia nc
+Kaledonia Berria nc
+Új-Kaledónia nc
+ມາເຊໂດເນີຠnc
+Nova Caledônia nc
+Nová Kaledónia nc
+Nova Kaledonija nc
+Nya Caledonien nc
+新喀里多尼亚 nc
+Niger ne
+Ðігер ne
+Ðигер ne
+ຕົວຮງàºàºžàº·à»‰àº™àº—ີ່ທຳງານ ne
+Nigéria ne
+Nigéria ne
+尼日尔 ne
+Norfolk Island nf
+ОÑтров Ðорфолк nf
+Norfolk ostrvo nf
+Norfolk-øerne (Australien) nf
+Isla Norfolk nf
+Norfok Irla nf
+Norfolk-szigetek nf
+ໂປà»àº¥àº™ nf
+Ilhas Norfolk nf
+Ostrov Norfolk nf
+Otok Norfolk nf
+Norfolkön nf
+诺ç¦å…‹å²› nf
+Nigeria ng
+ÐÑ–Ð³ÐµÑ€Ñ‹Ñ ng
+ÐÐ¸Ð³ÐµÑ€Ð¸Ñ ng
+Nigerija ng
+Nigéria ng
+ບັນà»àºà»€àº¥àºµàº ng
+Nigéria ng
+Nigéria ng
+Nigerija ng
+尼日利亚 ng
+Nicaragua ni
+Nikaragua ni
+نيكاراغوا ni
+Ðікарагуа ni
+Ðикарагуа ni
+Nikaragva ni
+Nikaragua ni
+ÎικαÏάγουα ni
+Nikaraagua ni
+نیکاراگویه ni
+Nikaragua ni
+Nikaragua ni
+ניקרגווה ni
+ニカラグア ni
+니카ë¼ê³¼ ni
+ປາລາàºàºàº§àº ni
+Nikaragua ni
+Nikaragwa ni
+Nikaragua ni
+Nicarágua ni
+Nicarágua ni
+Ðикарагуа ni
+Nikaragua ni
+Nikaragva ni
+I-Nicaragua ni
+¿¢¸Ã¡Ì§Å ni
+Nikaragua ni
+Ðікарагуа ni
+尼加拉瓜 ni
+尼加拉瓜 ni
+Netherlands nl
+Nederland nl
+هولندا nl
+Hollandiya nl
+ГалÑÐ½Ð´Ñ‹Ñ nl
+Ð¥Ð¾Ð»Ð°Ð½Ð´Ð¸Ñ nl
+Izelvroioù nl
+Nizozemska nl
+Holanda nl
+Nizozemí nl
+Holland nl
+Niederlande nl
+Κάτω ΧώÏες nl
+Nederlando nl
+Países Bajos nl
+Holland nl
+Holanda nl
+هلند nl
+Alankomaat nl
+Háland nl
+Pays bas nl
+Países Baixos nl
+הולנד nl
+Nizozemska nl
+Hollandia nl
+Belanda nl
+Holland nl
+Paesi Bassi nl
+オランダ nl
+네ëœëž€ë“œ nl
+ເນເທີà»àº¥àº™à¹Œ nl
+Olandija nl
+Nīderlande nl
+Nederland nl
+Nederland nl
+Nederland nl
+Holanda nl
+Holandia nl
+Países Baixos nl
+Holanda nl
+Olanda nl
+Ðидерланды nl
+Holandsko nl
+Nizozemska nl
+Holandija nl
+I-Netherlands nl
+Nederländerna nl
+¦¿¾÷Ä¡óà nl
+เนเธอร์à¹à¸¥à¸™à¸”์ nl
+Hollanda nl
+Ð“Ð¾Ð»Ð»Ð°Ð½Ð´Ñ–Ñ nl
+Hà Lan nl
+è·å…° nl
+è·è˜­ nl
+Norway no
+Noorweë no
+النرويج no
+Norveç no
+ÐарвÑÐ³Ñ–Ñ no
+ÐÐ¾Ñ€Ð²ÐµÐ³Ð¸Ñ no
+Norvegia no
+Norveška no
+Noruega no
+Norsko no
+Norge no
+Norwegen no
+ÎοÏβηγία no
+Norvegio no
+Noruega no
+Norra no
+Norvegia no
+نروژ no
+Norja no
+Norra no
+Norvège no
+Noruega no
+נורבגיה no
+Norveška no
+Norvégia no
+Norwegia no
+Noregur no
+Norvegia no
+ノルウェー no
+ë…¸ë¥´ì›¨ì´ no
+ນà»à»€àº§ no
+Norvegija no
+Norvēģija no
+Norveġja no
+Norge no
+Noorwegen no
+Noreg no
+Noruega no
+Norwegia no
+Noruega no
+Noruega no
+Norvegia no
+ÐÐ¾Ñ€Ð²ÐµÐ³Ð¸Ñ no
+Nórsko no
+Norveška no
+Norveška no
+I-Norway no
+Norge no
+¿¡÷§Å no
+นอร์เวย์ no
+Norveç no
+ÐÐ¾Ñ€Ð²ÐµÐ³Ñ–Ñ no
+Na uy no
+æŒªå¨ no
+æŒªå¨ no
+Nepal np
+ÐÑпал np
+Ðепал np
+Nepál np
+ເວນດາ np
+尼泊尔 np
+Nauru nr
+Ðауру nr
+Ðауру nr
+Naurú nr
+ປາລາàºàºàº§àº nr
+ç‘™é² nr
+Niue nu
+Ðиуе nu
+ເນ໊ຕ nu
+纽埃岛 nu
+New Zealand nz
+Nuwe Seeland nz
+نيوزيلاندا nz
+Yeni Zellandiya nz
+ÐÐ¾Ð²Ð°Ñ Ð—ÑлÑÐ½Ð´Ñ‹Ñ nz
+Ðова Ð—ÐµÐ»Ð°Ð½Ð´Ð¸Ñ nz
+Zeland nevez nz
+Novi Zeland nz
+Nova Zelanda nz
+Nový Zéland nz
+Neuseeland nz
+Îέα Ζηλανδία nz
+Novzelando nz
+Nueva Zelanda nz
+Uus-Meremaa nz
+Zelanda Berria nz
+زلاندنو nz
+Uusi-Seelanti nz
+Nýsæland nz
+Nouvelle Zélande nz
+Nova Celandia nz
+ניו זילנד nz
+Novi Zeland nz
+Új-Zéland nz
+Selandia Baru nz
+Nýja Sjáland nz
+Nuova Zelanda nz
+ニュージーランド nz
+뉴질랜드 nz
+ນີວຊີà»àº¥àº™ nz
+Naujoji Zelandija nz
+JaunZēlande nz
+Nieuw Zeeland nz
+Navera Zelanda nz
+Nowa Zelandia nz
+Nova Zelândia nz
+Nova Zelândia nz
+Noua Zeelandă nz
+ÐÐ¾Ð²Ð°Ñ Ð—ÐµÐ»Ð°Ð½Ð´Ð¸Ñ nz
+Nový Zéland nz
+Nova Zelandija nz
+Novi Zeland nz
+I-New Zealand nz
+Nya Zeeland nz
+¿¢äº¢Ä¡óà nz
+นิวซีà¹à¸¥à¸™à¸”์ nz
+Yeni Zelanda nz
+Ðова Ð—ÐµÐ»Ð°Ð½Ð´Ñ–Ñ nz
+Nouve Zelande nz
+新西兰 nz
+ç´è¥¿è˜­ nz
+Oman om
+عÙمان om
+Ðман om
+Оман om
+Omán om
+Ομάν om
+Omano om
+Omán om
+Omaan om
+عمان om
+עומן om
+Omán om
+オマーン om
+오만 om
+ເàºàºµàºàº¥àº°àº¡àº±àº™ om
+Omanas om
+Omã om
+Оман om
+Omán om
+I-Oman om
+µÃý om
+Umman om
+Оман om
+ Oman om
+阿曼 om
+阿曼 om
+Panama pa
+بنما pa
+Панама pa
+Панама pa
+Panamà pa
+Παναμάς pa
+Panamo pa
+Panamá pa
+پاناما pa
+Panamá pa
+פנמה pa
+パナマ pa
+파나마 pa
+ປານາມາ pa
+Panamá pa
+Panamá pa
+Панама pa
+I-Panama pa
+Àɡá pa
+ปานามา pa
+Панама pa
+巴拿马 pa
+巴拿馬 pa
+Peru pe
+البيرو pe
+ПÑру pe
+Перу pe
+Perou pe
+Perú pe
+ΠεÏÎ¿Ï pe
+Peruo pe
+Perú pe
+Peruu pe
+پرو pe
+Pérou pe
+Perú pe
+פרו pe
+Perú pe
+Perù pe
+ペルー pe
+페루 pe
+ເປລູ pe
+Perū pe
+Pero pe
+Perú pe
+Перу pe
+I-Peru pe
+¦ÀÕ pe
+เปรู pe
+Перу pe
+Perou pe
+ç§˜é² pe
+秘魯 pe
+French Polynesia pf
+ФранцуÑÐºÐ°Ñ ÐŸÐ°Ð»Ñ–Ð½ÑÐ·Ñ–Ñ pf
+ФренÑка ÐŸÐ¾Ð»Ð¸Ð½ÐµÐ·Ð¸Ñ pf
+Francuska Polinezija pf
+Fransk Polynesien pf
+Polinesia francesa pf
+Polinesia Frantziarra pf
+Francia-Polinézia pf
+àºàº£àº±à»ˆàº‡à»€àºªàº” pf
+Polinésia Francesa pf
+Francúzska Polynézia pf
+Francoska Polinezija pf
+Franska Polynesien pf
+法属波利尼西亚 pf
+Papua New Guinea pg
+Папуа–ÐÐ¾Ð²Ð°Ñ Ð“Ð²Ñ–Ð½ÑÑ pg
+Папуа и Ðова Ð“Ð²Ð¸Ð½ÐµÑ pg
+Papua Nova Gvineja pg
+Papua Nueva Guinea pg
+Papua Ginea Berria pg
+Pápua Új-Guinea pg
+ເທົາອ່ອນ pg
+Nova Guiné Papua pg
+Papua Nová Guinea pg
+Papua Nova Gvineja pg
+Papua Nya Guinea pg
+巴布亚新几内亚 pg
+Philippines ph
+Філіпіны ph
+Филипини ph
+Filipini ph
+Filippinerne ph
+Filipinas ph
+Filipinak ph
+Fülöp-szigetek ph
+ອາລະປະໂຫàºàº” ph
+Filipinas ph
+Filipíny ph
+Filipini ph
+Filippinerna ph
+è²å¾‹å®¾ ph
+Pakistan pk
+ПакіÑтан pk
+ПакиÑтан pk
+Pakisztán pk
+ລງບ pk
+Paquistão pk
+å·´åŸºæ–¯å¦ pk
+Poland pl
+Poolland pl
+بولندا pl
+PolÅŸa pl
+Польшча pl
+Полша pl
+Polonia pl
+Poljska pl
+Polònia pl
+Polsko pl
+Polen pl
+Polen pl
+Πολωνία pl
+Pollando pl
+Polonia pl
+Poola pl
+Polonia pl
+لهستان pl
+Puola pl
+Pólland pl
+Pologne pl
+Polonia pl
+פולין pl
+Poljska pl
+Lengyelország pl
+Polandia pl
+Pólland pl
+Polonia pl
+ãƒãƒ¼ãƒ©ãƒ³ãƒ‰ pl
+í´ëž€ë“œ pl
+ໂປà»àº¥àº™ pl
+Lenkija pl
+Polija pl
+Polonja pl
+Polen pl
+Polen pl
+Polen pl
+Polònia pl
+Polska pl
+Polónia pl
+Polônia pl
+Polonia pl
+Польша pl
+Poľsko pl
+Poljska pl
+Poljska pl
+I-Poland pl
+Polen pl
+§À¡Ä¡óà pl
+โปà¹à¸¥à¸™à¸”์ pl
+Polonya pl
+Польща pl
+Pholandi pl
+Ba Lan pl
+Pologne pl
+波兰 pl
+波蘭 pl
+Saint Pierre and Miquelon pm
+Sveti Pjer i Migelon pm
+Saint Pierre og Miquelon pm
+Saint Pierre y Miquelon pm
+Saint Pierre eta Miquelon pm
+Saint Pierre és Miquelon pm
+Saint Pierre e Miquelon pm
+Saint Pierre a Miquelon pm
+Sveti Pierre in Miquelon pm
+Saint Pierre och Miquelon pm
+圣皮埃尔和密克隆岛 pm
+Pitcairn pn
+Pitkern pn
+ລງບ pn
+Puerto Rico pr
+Пуерто Рико pr
+Portoriko pr
+ໂປຣໂຕຄອນ pr
+Porto Rico pr
+Portoriko pr
+æ³¢å¤šå°¼å„ pr
+Palestinian Territory ps
+Palesteinse Gebied ps
+السلطة الÙلسطينية ps
+ПалеÑтынÑÐºÐ°Ñ Ñ‚ÑÑ€Ñ‹Ñ‚Ð¾Ñ€Ñ‹Ñ ps
+ПалеÑтина ps
+Palestinska teritorija ps
+Territori Palestí ps
+Palestinské území ps
+Palæstinensiske selvstyreområder ps
+Palästinensisches Gebiet ps
+Παλαιστίνη ps
+Palestinaj teritorioj ps
+Territorio palestino ps
+Palestiina territoorium ps
+Palestina ps
+Ùلسطین ps
+Palestiinalaisalue ps
+Palestinensiska økið ps
+Territoire palestinien ps
+×”×©×˜×—×™× ×”×¤×œ×¡×˜×™× ×™×™× ps
+Palestinski teritorij ps
+Palesztin területek ps
+Territori palestinesi ps
+パレスãƒãƒŠè‡ªæ²»åŒº ps
+íŒ”ë ˆìŠ¤íƒ€ì¸ ìžì¹˜êµ¬ ps
+àºàº²àº™àºžàº´àº¡àºœàº´àº”ພາດ ps
+Palestinos teritorija ps
+Palestina ps
+Palestinske territorier ps
+Palestijns territorium ps
+Palestinske territorium ps
+Bohwa bja Palestina ps
+Palestyna ps
+Território Palestiniano ps
+Território Palestino ps
+Teritoriul Palestinian ps
+ПалеÑтинÑкие территории ps
+Palestínske územia ps
+Palestinski teritorij ps
+I-Palestinian Territory ps
+Palestina ps
+À¡Äо£É ¬¨½Âõ ps
+Filistin Bölgesi ps
+ПалеÑтинÑька Ñ‚ÐµÑ€Ð¸Ñ‚Ð¾Ñ€Ñ–Ñ ps
+Mukano wa maphalesitina ps
+Palestene ps
+Umhlaba wePalestina ps
+å·´å‹’æ–¯å¦åœ°åŒº ps
+å·´å‹’æ–¯å¦é ˜åœ° ps
+Indawo yama-Phalesitina ps
+Portugal pt
+البرتغال pt
+Portuqaliya pt
+ÐŸÐ°Ñ€Ñ‚ÑƒÐ³Ð°Ð»Ñ–Ñ pt
+ÐŸÐ¾Ñ€Ñ‚ÑƒÐ³Ð°Ð»Ð¸Ñ pt
+Portugalsko pt
+ΠοÏτογαλία pt
+Portugalo pt
+پرتغال pt
+Portugali pt
+פורטוגל pt
+Portugália pt
+Portúgal pt
+Portogallo pt
+ãƒãƒ«ãƒˆã‚¬ãƒ« pt
+í¬ë¥´íˆ¬ê°ˆ pt
+ໂປຣຕຸເàºàºª pt
+Portugalija pt
+PortugÄle pt
+Portugall pt
+Portugalia pt
+Portugalia pt
+ÐŸÐ¾Ñ€Ñ‚ÑƒÐ³Ð°Ð»Ð¸Ñ pt
+Portugalsko pt
+Portugalska pt
+I-Portugal pt
+§À¡÷òøø pt
+โปรตุเà¸à¸ª pt
+Portekiz pt
+ÐŸÐ¾Ñ€Ñ‚ÑƒÐ³Ð°Ð»Ñ–Ñ pt
+Bá»EÄào Nha pt
+è‘¡è„牙 pt
+è‘¡è„牙 pt
+Palau pw
+Палау pw
+Палау pw
+ມອລຕາ pw
+帕劳群岛 pw
+Paraguay py
+Paraguaai py
+باراغواي py
+Paraqvay py
+Парагвай py
+Парагвай py
+Paragvaj py
+Paraguai py
+ΠαÏαγουάη py
+Paragvajo py
+Paraguai py
+پاراگویه py
+Paraguai py
+פרגו××™ py
+Paragvaj py
+パラグアイ py
+파ë¼ê³¼ì´ py
+ປາລາàºàºàº§àº py
+Paragvajus py
+Paragvaja py
+Paragwaj py
+Paraguai py
+Paragwaj py
+Paraguai py
+Paraguai py
+Paraguai py
+Парагвай py
+Portugalsko py
+Paragvaj py
+Paragvaj py
+I-Paraguay py
+Àá̧Špy
+ปาราà¸à¸§à¸±à¸¢ py
+Парагвай py
+Paragway py
+巴拉圭 py
+巴拉圭 py
+Qatar qa
+قطر qa
+Катар qa
+Катар qa
+Katar qa
+Katar qa
+Katar qa
+ÎšÎ±Ï„Î¬Ï qa
+Kataro qa
+Katar qa
+قطر qa
+Katar qa
+קטר qa
+Katar qa
+Katar qa
+カタール qa
+카타르 qa
+ມອລຕາ qa
+Katar qa
+Катар qa
+Katar qa
+Katar qa
+I-Qatar qa
+¸¾¡÷ qa
+Katar qa
+Катар qa
+å¡å¡”å°” qa
+å¡é” qa
+Romania ro
+Romenië ro
+رومانيا ro
+Rumıniya ro
+Ð ÑƒÐ¼Ñ‹Ð½Ñ–Ñ ro
+Ð ÑƒÐ¼ÑŠÐ½Ð¸Ñ ro
+Roumania ro
+Rumunija ro
+Rumunsko ro
+Rumænien ro
+Rumänien ro
+Ρουμανία ro
+Rumanio ro
+Rumanía ro
+Rumeenia ro
+Errumania ro
+رومانی ro
+Rumenia ro
+Roumanie ro
+Romanía ro
+רומניה ro
+Rumunjska ro
+Románia ro
+Rumania ro
+Rúmenía ro
+ルーマニア ro
+루마니아 ro
+ໂລມາເນີຠro
+Rumunija ro
+RumÄnija ro
+Rumanija ro
+Roemenië ro
+Rumunia ro
+Roménia ro
+Romênia ro
+Ð ÑƒÐ¼Ñ‹Ð½Ð¸Ñ ro
+Rumunsko ro
+Romunija ro
+Rumunija ro
+I-Romania ro
+Rumänien ro
+Õ§Ãɢ¡ ro
+โรมาเนีย ro
+Romanya ro
+Ð ÑƒÐ¼ÑƒÐ½Ñ–Ñ ro
+Ru ma ni ro
+Roumaneye ro
+罗马尼亚 ro
+羅馬尼亞 ro
+Russia ru
+Rusland ru
+روسيا ru
+Rusiya ru
+РаÑÐµÑ ru
+РуÑÐ¸Ñ ru
+Rusia ru
+Rusija ru
+Rússia ru
+Rusko ru
+Rusland ru
+Russland ru
+Ρωσία ru
+Ruslando ru
+Rusia ru
+Venemaa ru
+Errusia ru
+روسیه ru
+Venäjä ru
+Russland ru
+Russie ru
+Rusia ru
+רוסיה ru
+Rusija ru
+Oroszország ru
+Rusia ru
+Rússland ru
+ロシア ru
+러시아 ru
+ລັດເຊີຠru
+Rusija ru
+Krievija ru
+Russja ru
+Russland ru
+Rusland ru
+Russland ru
+Rosja ru
+Rússia ru
+Rússia ru
+Rusia ru
+РоÑÑÐ¸Ñ ru
+Rusko ru
+Rusija ru
+Rusija ru
+I-Russia ru
+Ryssland ru
+ú¢Â¡ ru
+รัสเซีย ru
+Rusya ru
+РоÑÑ–Ñ ru
+Rashia ru
+Nga ru
+Russeye ru
+Rashiya ru
+ä¿„ç½—æ–¯ ru
+ä¿„ç¾…æ–¯ ru
+Rwanda rw
+Руанда rw
+Руанда rw
+Ruanda rw
+Ruanda rw
+Ruanda rw
+à»àºžàº™àº”້າ rw
+Ruanda rw
+Ruanda rw
+墿—ºè¾¾ rw
+Saudi Arabia sa
+Saudi Arabië sa
+السعودية sa
+СаудаўÑÐºÐ°Ñ ÐÑ€Ð°Ð±Ñ–Ñ sa
+СаудитÑка ÐÑ€Ð°Ð±Ð¸Ñ sa
+Saudijska Arabija sa
+Aràbia Saudí sa
+Saúdská Arábie sa
+Saudi Arabien sa
+Saudi-Arabien sa
+Σαουδική ΑÏαβία sa
+SaÅ­di-Arabio sa
+Arabia Saudí sa
+Saudi Araabia sa
+عربستان سعودی sa
+Saudi-Arabia sa
+Arabie Saoudite sa
+ערב הסעודית sa
+Saudijska Arabija sa
+Szaúd-Arábia sa
+Arabia saudita sa
+サウジアラビア sa
+사우디 ì•„ë¼ë¹„ì•„ sa
+ອາລະບິຠsa
+Saudi Arabija sa
+Għarabja Sawdita sa
+Saudi-Arabia sa
+Saudi-Arabië sa
+Saudi-Arabia sa
+Arabia Saudyjska sa
+Arábia Saudita sa
+Arábia Saudita sa
+Arabia Saudită sa
+СаудовÑÐºÐ°Ñ ÐÑ€Ð°Ð²Ð¸Ñ sa
+Saudská arábia sa
+Saudova Arabija sa
+I-Saudi Arabia sa
+Saudiarabien sa
+º×¾¢ «§ÃÀ¢Â¡ sa
+Suudi Arabistan sa
+СаудівÑька ÐÑ€Ð°Ð²Ñ–Ñ sa
+沙特阿拉伯 sa
+æ²™çƒåœ°é˜¿æ‹‰ä¼¯ sa
+Solomon Islands sb
+Саламонавы аÑтравы sb
+Соломонови ОÑтрови sb
+Solomonska ostrva sb
+Salomon-øerne sb
+Islas Salomón sb
+Solomon Irlak sb
+Salamon-szigetek sb
+ສະໂລວະເນີຠsb
+Ilhas Salomão sb
+Šalamúnove ostrovy sb
+Solomonovi otoki sb
+Salomonöarna sb
+所罗门群岛 sb
+Seychelles sc
+СÑйшÑлы sc
+СейшелÑки оÑтрови sc
+Sejšeli sc
+Seychellerne sc
+ເຊລ sc
+Sejšeli sc
+Seychellerna sc
+塞舌尔 sc
+Sudan sd
+السودان sd
+Судан sd
+Судан sd
+Sudán sd
+Σουδάν sd
+Sudano sd
+Sudán sd
+Sudaan sd
+سودان sd
+Sudania sd
+Soudan sd
+סודן sd
+Szudán sd
+Súdan sd
+スーダン sd
+수단 sd
+ຊູດານ sd
+Sudanas sd
+SudÄna sd
+Sudão sd
+Sudão sd
+Судан sd
+Sudán sd
+I-Sudan sd
+ü¡ý sd
+ซูดาน sd
+Судан sd
+Sudani sd
+Soudan sd
+è‹ä¸¹ sd
+蘇丹 sd
+Sweden se
+Swede se
+السويد se
+İsveç se
+ШвÑÑ†Ñ‹Ñ se
+Ð¨Ð²ÐµÑ†Ð¸Ñ se
+Sveden se
+Å vedska se
+Suècia se
+Švédsko se
+Sverige se
+Schweden se
+Σουηδία se
+Svedio se
+Suecia se
+Rootsi se
+Suedia se
+سوید se
+Ruotsi se
+Svøriki se
+Suède se
+Suecia se
+שבדיה se
+Å vedska se
+Svédország se
+Swedia se
+Svíþjóð se
+Svezia se
+スウェーデン se
+ìŠ¤ì›¨ë´ se
+ສະວີເດນ se
+Å vedija se
+Zviedrija se
+Svezja se
+Sverige se
+Zweden se
+Sverige se
+Suècia se
+Szwecja se
+Suécia se
+Suécia se
+Suedia se
+Ð¨Ð²ÐµÑ†Ð¸Ñ se
+Švédsko se
+Å vedska se
+Å vedska se
+I-Sweden se
+Sverige se
+ÃÅ£¼ý se
+สวีเดน se
+İsveç se
+Ð¨Ð²ÐµÑ†Ñ–Ñ se
+Swidene se
+Thuỵ Äiển se
+瑞典 se
+瑞典 se
+Singapore sg
+Сынгапур sg
+Сингапур sg
+Singapur sg
+Singapur sg
+Szingapúr sg
+ໂຊນາ sg
+Singapura sg
+Singapur sg
+Singapur sg
+æ–°åŠ å¡ sg
+Saint Helena sh
+Свети Елена sh
+Sveta Helena sh
+St. Helena sh
+Santa Helena sh
+Szent Heléna sh
+ຫົວເລື່ອງ sh
+Santa Helena sh
+Svätá Helena sh
+Sveta Helena sh
+圣赫勒拿岛 sh
+Slovenia si
+Slovenië si
+سلوÙينيا si
+Sloveniya si
+Ð¡Ð»Ð°Ð²ÐµÐ½Ñ–Ñ si
+Ð¡Ð»Ð¾Ð²ÐµÐ½Ð¸Ñ si
+Slovenija si
+Eslovenia si
+Slovinsko si
+Slovenien si
+Slowenien si
+Σλοβενία si
+Slovenio si
+Eslovenia si
+Sloveenia si
+Eslovenia si
+اسلوانی si
+Slovénie si
+Eslovenia si
+סלובניה si
+Slovenija si
+Szlovénia si
+Slóvenía si
+スロベニア si
+슬로베니아 si
+ສະໂລວະເນີຠsi
+SlovÄ—nija si
+Slovēnija si
+Slovenja si
+Slovenië si
+Eslovenia si
+Słowenia si
+Eslovénia si
+Eslovênia si
+Ð¡Ð»Ð¾Ð²ÐµÐ½Ð¸Ñ si
+Slovinsko si
+Slovenija si
+Slovenija si
+I-Slovenia si
+Slovenien si
+çġŢɢ¡ si
+สโลเวเนีย si
+Slovenya si
+Ð¡Ð»Ð¾Ð²ÐµÐ½Ñ–Ñ si
+斯洛文尼亚 si
+斯洛維尼亞 si
+Slovakia sk
+Slovakië sk
+Ø³Ù„ÙˆÙØ§ÙƒÙŠØ§ sk
+Slovakiya sk
+Ð¡Ð»Ð°Ð²Ð°ÐºÑ–Ñ sk
+Ð¡Ð»Ð¾Ð²Ð°ÐºÐ¸Ñ sk
+SlovaÄka sk
+Eslovaquia sk
+Slovensko sk
+Slovakiet sk
+Slowakien sk
+Σλοβακία sk
+Slovakujo sk
+Eslovaquia sk
+Slovakkia sk
+Eslovakia sk
+اسلواکی sk
+Slovaquie sk
+סלובקיה sk
+SlovaÄka sk
+Szlovákia sk
+Slóvakía sk
+Slovacchia sk
+スロãƒã‚­ã‚¢ sk
+슬로바키아 sk
+ສະໂລວັຠsk
+Slovakija sk
+SlovÄkija sk
+Slovakja sk
+Slovakije sk
+Słowacja sk
+Eslováquia sk
+Eslováquia sk
+Slovacia sk
+Ð¡Ð»Ð¾Ð²Ð°ÐºÐ¸Ñ sk
+Slovensko sk
+Slovaška sk
+I-Slovakia sk
+Slovakien sk
+çġš츢 sk
+สโลวัค sk
+Slovakya sk
+Ð¡Ð»Ð¾Ð²Ð°ÐºÑ–Ñ sk
+斯洛ä¼å…‹ sk
+斯洛ä¼å…‹ sk
+San Marino sm
+Сан-Марына sm
+Сан Марино sm
+ໂຊນາ sm
+圣马力诺 sm
+Senegal sn
+СÑнÑгал sn
+Сенегал sn
+Szenegál sn
+ທົ່ວໄປ sn
+塞内加尔 sn
+Somalia so
+Somalië so
+صومال so
+Самалі so
+Ð¡Ð¾Ð¼Ð°Ð»Ð¸Ñ so
+Somalija so
+Somàlia so
+Somálsko so
+Σομαλία so
+Somalio so
+Somaalia so
+سومالی so
+Somalie so
+סומליה so
+Somalija so
+Szomália so
+ソマリア so
+소ë§ë¦¬ì•„ so
+ໂລມາເນີຠso
+Somalis so
+Somalija so
+Somalie so
+Somália so
+Somália so
+Сомали so
+Somálsko so
+Somalija so
+I-Somalia so
+§º¡Ã¡Ä¢Â¡ so
+Somali so
+Сомалі so
+Somaleye so
+索马里 so
+索馬利亞 so
+Suriname sr
+Сурынам sr
+Суринам sr
+Surinam sr
+ເຊີເບີຠsr
+Surinam sr
+Surinam sr
+Surinam sr
+Sao Tome and Principe st
+Сан Томе и Приницпе st
+Sao Tome i Principe st
+Sao Tomé og Principe st
+Sao Tome y Príncipe st
+Sao Tome eta Principe st
+Sao Tome és Principe st
+ບà»àº¥àº´àºàº²àº™ st
+São Tome e Príncipe st
+Sao Tome a Principe st
+Sao Tome in Principe st
+São Tomé och Príncipe st
+El Salvador sv
+Ø§Ù„Ø³Ù„ÙØ§Ø¯ÙˆØ± sv
+Сальвадор sv
+Ел Салвадор sv
+Salvador sv
+Salvador sv
+Ελ Î£Î±Î»Î²Î±Î½Ï„ÏŒÏ sv
+Elsalvadoro sv
+Salvador sv
+السالوادور sv
+Salvador sv
+O Salvador sv
+×ל סלבדור sv
+Salvador sv
+エルサルãƒãƒ‰ãƒ« sv
+엘살바ë„르 sv
+ເອລຊັນວາດດ໠sv
+Salvadoras sv
+Salvadora sv
+Salwador sv
+Salvador sv
+Сальвадор sv
+Salvádor sv
+Salvador sv
+I-El Salvador sv
+±ø º¡øÅ§¼¡÷ sv
+เอลซัลวาดอร์ sv
+Ель-Сальвадор sv
+è¨å°”瓦多 sv
+薩爾瓦多 sv
+Syria sy
+Sirië sy
+سوريا sy
+Ð¡Ñ‹Ñ€Ñ‹Ñ sy
+Ð¡Ð¸Ñ€Ð¸Ñ sy
+Sirija sy
+Síria sy
+Sýrie sy
+Syrien sy
+Syrien sy
+ΣυÏία sy
+Sirio sy
+Siria sy
+Süüria sy
+Siria sy
+سوریه sy
+Syyria sy
+Syrie sy
+סוריה sy
+Sirija sy
+Szíria sy
+Siria sy
+シリア sy
+시리아 sy
+ເຊີເບີຠsy
+Sirija sy
+Siria sy
+Syrië sy
+Síria sy
+Síria sy
+Siria sy
+Ð¡Ð¸Ñ€Ð¸Ñ sy
+Sýria sy
+Sirija sy
+I-Syria sy
+Syrien sy
+º¢Ã¢Â¡ sy
+Suriye sy
+Ð¡Ð¸Ñ€Ñ–Ñ sy
+å™åˆ©äºš sy
+敘利亞 sy
+Swaziland sz
+СвазылÑнд sz
+Свазиленд sz
+Svazilend sz
+Swazilandia sz
+Swazilandia sz
+Szváziföld sz
+ລາດສະນາຈັàºà»„ທຠsz
+Suécia sz
+Swazijsko sz
+Svazi sz
+æ–¯å¨å£«å…° sz
+Turks and Caicos Islands tc
+Turks i Kaikos ostrva tc
+Turks- og Caicosøerne tc
+Islas Turcos y Caicos tc
+Turks eta Caicos Irlak tc
+Turks- és Caicos-szigetek tc
+Ilhas Caicos e Turca tc
+Turks a Caicos ostrovy tc
+Otoka Turks in Caicos tc
+Turks- och Caicosöarna tc
+特克斯和凯科斯群岛 tc
+Chad td
+Чад td
+Чад td
+ÄŒad td
+Tchad td
+Txad td
+Csád td
+ເàºàº¡à»„ພ່ td
+ÄŒad td
+ÄŒad td
+Tchad td
+ä¹å¾— td
+Togo tg
+Тога tg
+Того tg
+ຂອງເລ່ນສະນຸຠtg
+多哥 tg
+Thailand th
+تايلاند th
+Tayland th
+ТайлÑнд th
+Тайланд th
+Tajland th
+Tailàndia th
+Thajsko th
+Ταϊλάνδη th
+Tajlando th
+Tailandia th
+Tai th
+Thailandia th
+تایلند th
+Thaimaa th
+Tailand th
+Thaïlande th
+Tailandia th
+ת×ילנד th
+Tajland th
+Thaiföld th
+Tæland th
+Tailandia th
+タイ th
+태국 (타ì´) th
+ລາດສະນາຈັàºà»„ທຠth
+Tailandas th
+TaivÄna th
+Tajlandja th
+Tailandia th
+Tajlandia th
+Tailândia th
+Tailândia th
+Tailanda th
+Таиланд th
+Thajsko th
+Tajska th
+Tajland th
+I-Thailand th
+¾¡öÄ¡óà th
+ราชอาณาจัà¸à¸£à¹„ทย th
+Tayland th
+Таїланд th
+Thái Lan th
+Taylande th
+泰国 th
+泰國 th
+Tajikistan tj
+ТаджыкіÑтан tj
+ТаджикиÑтан tj
+Tadžikistan tj
+Tajikistán tj
+Tadzsikisztán tj
+ໃຕ້ຫວັນ tj
+Tajiquistão tj
+Tadžikistan tj
+Tadžikistan tj
+Tadzjikistan tj
+å¡”å‰å…‹æ–¯å¦ tj
+Tokelau tk
+Токелао tk
+ເບລາລັສ tk
+Turkmenistan tm
+ТуркмÑніÑтан tm
+ТуркмениÑтан tm
+Turkmenistán tm
+Türkmenisztán tm
+ຕຸລະàºàºµ tm
+Turquia tm
+åœŸåº“æ›¼æ–¯å¦ tm
+Tunisia tn
+Tunisië tn
+تونس tn
+Ð¢ÑƒÐ½Ñ–Ñ tn
+Ð¢ÑƒÐ½Ð¸Ñ tn
+Tunis tn
+Tuníssia tn
+Tunisko tn
+Tunesien tn
+Tunesien tn
+Τυνησία tn
+Tunisio tn
+Túnez tn
+Tuneesia tn
+تونس tn
+Tunesia tn
+Tunisie tn
+תוניסיה tn
+Tunis tn
+Tunézia tn
+ãƒãƒ¥ãƒ‹ã‚¸ã‚¢ tn
+튀니지 tn
+ລັດເຊີຠtn
+Tunisas tn
+Tuneżija tn
+Tunisie tn
+Tunezja tn
+Tunísia tn
+Tunísia tn
+Ð¢ÑƒÐ½Ð¸Ñ tn
+Tunisko tn
+Tunizija tn
+I-Tunisia tn
+Tunisien tn
+ÃÉ¢º¢Â¡ tn
+Tunus tn
+Ð¢ÑƒÐ½Ñ–Ñ tn
+çªå°¼æ–¯ tn
+çªå°¼è¥¿äºž tn
+Tonga to
+Тонга to
+Тонга to
+ໂຊນາ to
+汤加 to
+East Timor tp
+ИÑточен Тимур tp
+IstoÄni Timor tp
+Østtimor tp
+Timor oriental tp
+Ekialdeko Timor tp
+Kelet-Timor tp
+ວັນà»àº¥àº°à»€àº§àº¥àº² tp
+Timor Leste tp
+Východný Timor tp
+Vzhodni Timor tp
+Östtimor tp
+ä¸œå¸æ±¶ tp
+Turkey tr
+Turkeye tr
+تركيا tr
+Türkiyə tr
+Ð¢ÑƒÑ€Ñ†Ñ‹Ñ tr
+Ð¢ÑƒÑ€Ñ†Ð¸Ñ tr
+Turkia tr
+Turska tr
+Turquia tr
+Turecko tr
+Tyrkiet tr
+Türkei tr
+ΤουÏκία tr
+Turkujo tr
+Turquía tr
+Türgi tr
+Turkia tr
+ترکیه tr
+Turkki tr
+Turkaland tr
+Turquie tr
+Turquía tr
+טורקיה tr
+Turska tr
+Törökország tr
+Turki tr
+Tyrkland tr
+Turchia tr
+トルコ tr
+터키 tr
+ຕຸລະàºàºµ tr
+Turkija tr
+Turcija tr
+Turkija tr
+Tyrkia tr
+Turkije tr
+Tyrkia tr
+Turquia tr
+Turcja tr
+Turquia tr
+Turquia tr
+Turcia tr
+Ð¢ÑƒÑ€Ñ†Ð¸Ñ tr
+Turecko tr
+TurÄija tr
+Turska tr
+I-Turkey tr
+Turkiet tr
+ÃÕ츢 tr
+ตุรà¸à¸µ tr
+Türkiye tr
+Туреччина tr
+Thá»ENhÄ© Kì tr
+土耳其 tr
+土耳其 tr
+Trinidad and Tobago tt
+Trinidad en Tobago tt
+ترينيداد و توباغو tt
+Trinidad vÉ™ Tabaqo tt
+Трынідад і Табага tt
+Тринидад и Тобаго tt
+Trinidad ha Tobago tt
+Trinidad i Tobago tt
+Trinidad i Tobago tt
+Trinidad a Tobago tt
+Trinidad og Tobago tt
+Trinidad und Tobago tt
+ΤÏίνινταντ και Τομπάγκο tt
+Trinidado kaj Tobago tt
+Trinidad y Tobago tt
+Trinidad ja Tobago tt
+Trinidad eta Tobago tt
+ترینیداد Ùˆ ØªÙØ¨Ø§Ú¯Ùˆ tt
+Trinidad ja Tobago tt
+Trinidad og Tobago tt
+Trinidad et Tobago tt
+Trindade e Tobago tt
+טרינידד וטובגו tt
+Trinidad i Tobago tt
+Trinidad és Tobago tt
+Trinidad dan Tobago tt
+Trinidad og Tobago tt
+Trinidad e Tobago tt
+トリニダードトãƒã‚³ tt
+트리니다드토바고 tt
+ຕີນິà»àº”ດà»àº¥àº°à»‚ທບາໂຠtt
+Trinidadas ir Tobagas tt
+Trinidada un Tobago tt
+Trinidad u Tobago tt
+Trinidad og Tobago tt
+Trinidad en Tobago tt
+Trinidad og Tobago tt
+Trinidad le Tobago tt
+Trinidad e Tobago tt
+Trinidad i Tobago tt
+Trinidade e Tobago tt
+Trinidad e Tobago tt
+Trinidad ÅŸi Tobago tt
+Тринидад и Тобаго tt
+Trinidad a Tobago tt
+Trinidad in Tabago tt
+Trinidad i Tobago tt
+I-Trinidad kanye neTobago tt
+Trinidad och Tobago tt
+ðâɢ¼¡ð & ¦¼¡À¡§¸¡ tt
+ตรีนิà¹à¸”ดà¹à¸¥à¸°à¹‚ทบาโภtt
+Trinidad veTabago tt
+РеÑпубліка Трінідад та Тобаго tt
+Trinidad na Tobago tt
+Trinidad và Tobago tt
+Trinidad ne Tobago tt
+特里尼达和多巴哥 tt
+åƒé‡Œé”åŠæ‰˜è²å“¥ tt
+Trinidad knaye ne-Tobago tt
+Tuvalu tv
+Тувалу tv
+Тували tv
+ຊູລູ tv
+å›¾ç“¦å¢ tv
+Taiwan tw
+تايوان tw
+Tayvan tw
+Тайвань tw
+Тайван tw
+Tajvan tw
+Ταϊβάν tw
+Tajvano tw
+Taiwán tw
+Taivan tw
+تایوان tw
+Taivan tw
+Taïwan tw
+Taiwán tw
+טיוו×ן tw
+Tajvan tw
+Tajvan tw
+å°æ¹¾ tw
+대만 tw
+ໃຕ້ຫວັນ tw
+Taivanis tw
+TaivÄna tw
+Tajwan tw
+Tajwan tw
+Formosa tw
+Тайвань tw
+Tajvan tw
+Tajvan tw
+I-Taiwan tw
+¾¡öÅ¡ý tw
+ได้หวัน tw
+Tayvan tw
+Тайвань tw
+Äài Loan tw
+䏭国尿¹¾ tw
+å°ç£ tw
+Tanzania, United Republic of tz
+Ð—Ð»ÑƒÑ‡Ð°Ð½Ð°Ñ Ð ÑÑпубліка Ð¢Ð°Ð½Ð·Ð°Ð½Ñ–Ñ tz
+Ð¢Ð°Ð½Ð·Ð°Ð½Ð¸Ñ tz
+Tanzanija, Ujedinjena Republika tz
+Tanzania tz
+Tanzania, Republica de tz
+Tanazia, Errepublika Batua tz
+Tanzánia tz
+ໂດມິນິàºàº±àº™ tz
+República da Tanzânia tz
+Tanzánia, Spojená republika tz
+Tanzanija, Združena republika tz
+Förenade republiken Tanzania tz
+妿¡‘尼亚 tz
+Ukraine ua
+Ukraïne ua
+أوكرانيا ua
+Ukrayna ua
+Украіна ua
+Украйна ua
+Ukraina ua
+Ukrajina ua
+Ucraïna ua
+Ukrajina ua
+ΟυκÏανία ua
+Ukrainio ua
+Ucrania ua
+Ukraina ua
+Ukrania ua
+اکراین ua
+Ukraina ua
+Ukraina ua
+Ucraína ua
+×וקר××™× ×” ua
+Ukrajina ua
+Ukrajna ua
+Ukraina ua
+Úkraína ua
+Ucraina ua
+ウクライナ ua
+ìš°í¬ë¼ì´ë‚˜ ua
+àºàº¹à»€àº„ຣນ ua
+Ukraina ua
+Ukraina ua
+Ukranja ua
+Ukraina ua
+Oekraïne ua
+Ukraina ua
+Ucraina ua
+Ukraina ua
+Ucrânia ua
+Ucrânia ua
+Ucraina ua
+Украина ua
+Ukrajina ua
+Ukrajina ua
+Ukrajna ua
+I-Ukraine ua
+Ukraina ua
+¯ì¦Ãöý ua
+ยูเครน ua
+Ukrayna ua
+Україна ua
+Ukraina ua
+Ucrinne ua
+乌克兰 ua
+çƒå…‹è˜­ ua
+Uganda ug
+Уганда ug
+Уганда ug
+à»àºžàº™àº”້າ ug
+乌干达 ug
+United States of America us
+Vereenigde State van Amerika us
+الولايات المتحدة الأمريكية us
+Amerika Birləşmiş Ştatları us
+Ð—Ð»ÑƒÑ‡Ð°Ð½Ñ‹Ñ Ð¨Ñ‚Ð°Ñ‚Ñ‹ ÐмÑрыкі us
+СÐЩ us
+Stadoù-Unanet Amerika us
+Sjedinjene AmeriÄke Države us
+Estats Units d'Amèrica us
+Spojené státy americké us
+USA us
+USA us
+Ην. Πολιτείες της ΑμεÏικής us
+Usono us
+Estados Unidos de América us
+Ameerika Ühendriigid us
+Amerikako Estatu Batuak us
+ایالات متحده‌ی آمریکا us
+Yhdysvallat us
+Sambandsríki Amerika (USA) us
+États Unis d'Amérique us
+Estados Unidos de América us
+×רצות הברית us
+Sjedinjene AmeriÄke Države us
+Amerikai Egyesült Ãllamok us
+Amerika Serikat us
+Bandaríki Norður Ameríku us
+Stati Uniti d'America us
+アメリカ us
+미 합중국 us
+ສະຫະລັດອາເມລິàºàº² us
+JungtinÄ—s Amerikos Valstijos us
+Amerikas SavienotÄs Valstis us
+Stati Uniti us
+USA us
+Verenigde Staten van Amerika us
+USA us
+Estats Units d'Amèrica us
+Stany Zjednoczone Ameryki us
+Estados Unidos da América us
+Estados Unidos us
+Statele Unite ale Americii us
+Соединенные Штаты Ðмерики us
+USA us
+Združene države Amerike us
+Sjedinjene ameriÄke države us
+I-United States of America us
+Amerikas förenta stater us
+³ì¸¢Â «¦Ãâì¸ ¿¡Î¸û us
+สหรัà¸à¸­à¹€à¸¡à¸£à¸´à¸à¸² us
+Amerika BirleÅŸik Devletleri us
+СШРus
+mashango o tangananaho a America us
+MÄ© us
+United States ye Melika us
+美利åšåˆä¼—国 us
+美利堅åˆçœ¾åœ‹ us
+Uruguay uy
+الأوروغواي uy
+Uruqvay uy
+Уругвай uy
+Уругвай uy
+Urugvaj uy
+Uruguai uy
+ΟυÏουγουάη uy
+Urugvajo uy
+Uruguai uy
+اروگویه uy
+Uruguai uy
+×ורוגו××™ uy
+Urugvaj uy
+ウルグアイ uy
+ìš°ë£¨ê³¼ì´ uy
+ອຸລຸàºàºàº§àº uy
+Urugvajus uy
+Urugvaja uy
+Urugwaj uy
+Uruguai uy
+Urugwaj uy
+Uruguai uy
+Uruguai uy
+Uruguai uy
+Уругвай uy
+Uruguaj uy
+Urugvaj uy
+Urugvaj uy
+I-Uruguay uy
+¯Õ̧Šuy
+อุรุà¸à¸§à¸±à¸¢ uy
+Уругвай uy
+Ourougway uy
+乌拉圭 uy
+çƒæ‹‰åœ­ uy
+Uzbekistan uz
+УзбÑкіÑтан uz
+УзбекиÑтан uz
+Uzbekistán uz
+Üzbegisztán uz
+ເດນ່ງນ uz
+Uzbequistão uz
+ä¹Œå…¹åˆ«å…‹æ–¯å¦ uz
+Vatican City va
+Ватыкан va
+Ватикана va
+Vatikan va
+Vatikanstaten va
+Vaticano va
+Batikano Hiria va
+Vatikán va
+ລັດເວີຠva
+Cidade do Vaticano va
+Vatikán va
+Vatikan va
+Vatikanstaten va
+梵蒂冈 va
+St. Vincent and the Grenadines vc
+St. Vincent en die Grenadene vc
+سانت Ùينسنت Ùˆ الغرينادين vc
+St. Vincent vÉ™ Grenadines vc
+Сент-ВинÑент и Гренадине vc
+S. Visant hag ar Grenadinez vc
+Sveti Vincent i Grenadini vc
+St. Vincent i les Granadines vc
+St. Vincent a Grenadiny vc
+St. Vincent og Grenadinerne vc
+St. Vincent und Grenadinen vc
+St. Vincent kaj la Grenadinoj vc
+San Vicente y las Granadinas vc
+St. Vincent ja Grenadines vc
+St. Vincent eta Grenadines vc
+سن وینسن و گرادینس vc
+St. Vincent ja Grenadiinit vc
+Sankta Vinsent og Grenadinoyggjar vc
+St Vincent et les Grenadines vc
+San Vicente e as Granadinas vc
+סנט וינסנט ×•×”×’×¨× ×“×™× ×™× vc
+St. Vincent és Grenadines vc
+St. Vincent dan the Grenadines vc
+St. Vincent og Grenadines vc
+S. Vincent e the Grenadines vc
+セントヴィンセントグレナディン vc
+세ì¸íЏ 빈센트 그레나딘 vc
+ເຊີນວິນà»àºŠàº™ à»àº¥àº°à»€àºàº™àº²àº”ີນ vc
+Å v. Vincentas ir Grenadinai vc
+Sv. Vincents un Grenadīnes vc
+St. Vinċenz u l-Grenadini vc
+St. Vincent og Grenadinene vc
+St. Vincent en de Grenadines vc
+St. Vincent og Grenadinane vc
+St. Vincent le Grenadines vc
+St. Vincent e les Granadines vc
+St. Vincent i Grenadyny vc
+São Vicente e Grenadinas vc
+São Vicente e Grenadines vc
+Sf. Vincent ÅŸi Grenadines vc
+Сент-ВинÑент и Гренадины vc
+St. Vincent a Grenadines vc
+Sv. Vincent in Grenadini vc
+St. Vincent i Grenadine vc
+I-St. Vincent and the Grenadines vc
+St. Vincent och Grenadinerna vc
+¦ºÂ¢ýð Å¢ý¦ºýð & ¸¢¦ÃÉËý¸û vc
+เซนต์วินเซนต์ à¹à¸¥à¸° เà¸à¸£à¸™à¸²à¸”ีน vc
+St. Vincent ve Grenadines vc
+Сент-ВінÑент Ñ– Гренадіни vc
+St. Vincent na Grenadines vc
+St. Vincent và Grenadines vc
+St. Vincent ne Grenadines vc
+圣文森特和格林那达 vc
+è–æ–‡æ£®åŠæ ¼ç´é‚£ä¸ vc
+I-St. Vincent kanye ne-Grenadines vc
+Venezuela ve
+Ùنزويلا ve
+Ð’ÑнÑÑуÑла ve
+Венецуела ve
+Venecuela ve
+Βενεζουέλα ve
+Venezuelo ve
+Venetsueela ve
+ونزویلا ve
+Venesuela ve
+Vénézuela ve
+ונצו×לה ve
+Venecuela ve
+ベãƒã‚ºã‚§ãƒ© ve
+ë² ë„¤ìˆ˜ì—˜ë¼ ve
+ເວເນຊຸເອລາ ve
+Venesuela ve
+Venecuēla ve
+Veneżwela ve
+Wenezuela ve
+ВенеÑуÑла ve
+Venecuela ve
+I-Venezuela ve
+¦ÅÉ¢ÃÅÄ¡ ve
+เวเนซูเอลา ve
+ВенеÑуела ve
+委内瑞拉 ve
+委內瑞拉 ve
+Virgin Islands, British vg
+ВирджинÑки ОÑтрови, БританÑки vg
+DjeviÄanska ostrva, Britanska vg
+Britiske jomfruøer vg
+Islas Vírgenes Británicas vg
+Irla Birjinak, Britaniar vg
+Virgin-szigetek (brit) vg
+Ilhas Virgens, Inglaterra vg
+Panenské Ostrovy, Britské vg
+Deviški otoki, Britanski vg
+Brittiska Jungfruöarna vg
+维尔京群岛,英国 vg
+Virgin Islands, U.S. vi
+ВирджинÑки ОÑтрови, ÐмериканÑки vi
+DjeviÄanska ostrva, AmeriÄka vi
+Jomfruøerne vi
+Islas Vírgenes Americanas vi
+Irla Birjinak, EE.BB. vi
+Virgin-szigetek (USA) vi
+Ilhas Virgens, EUA vi
+Panenské Ostrovy, Americké vi
+Deviški otoki, ZDA vi
+Amerikanska Jungfruöarna vi
+维尔京群岛,美国 vi
+Vietnam vn
+Viëtnam vn
+Ùييتنام vn
+Vyetnam vn
+Віетнам vn
+Виетнам vn
+Vijetnam vn
+Βιετνάμ vn
+Vjetnamo vn
+ویتنام vn
+וייטנ×× vn
+Vijetnam vn
+Víetnam vn
+ベトナム vn
+베트남 vn
+ຫວງດນາມ vn
+Vietnamas vn
+Vjetnama vn
+Vjetnam vn
+Viëtnam vn
+Wietnam vn
+Vietname vn
+Vietnã vn
+Вьетнам vn
+I-Vietnam vn
+เวียตนาม vn
+В'єтнам vn
+è¶Šå— vn
+è¶Šå— vn
+Vanuatu vu
+Вануату vu
+Ванути vu
+ຈີນ vu
+瓦努阿图 vu
+Wallis and Futuna wf
+Valis i Futuna wf
+Wallis- og Futuna-øerne wf
+Wallis y Futuna wf
+Wallis eta Futuna wf
+Wallis és Futuna wf
+ປັàºàº­àº´àº™àºžàº²àºš wf
+Wallis e Futuna wf
+Wallis a Futuna wf
+Wallis in Futuna wf
+Wallis och Futuna wf
+Samoa ws
+Самоа ws
+Ð¡Ð°Ð¼Ð¾Ñ ws
+Szamoa ws
+ໂຊນາ ws
+è¨æ‘©äºšç¾¤å²› ws
+Yemen ye
+اليمن ye
+Емен ye
+Йемен ye
+Jemen ye
+Iemen ye
+Jemen ye
+Jemen ye
+Υεμένη ye
+Jemeno ye
+Jeemen ye
+یمن ye
+Jemen ye
+Jemen ye
+תימן ye
+Jemen ye
+Jemen ye
+イエメン ye
+예멘 ye
+ເດມອນ ye
+Jemenas ye
+Jemen ye
+Jemen ye
+Jemen ye
+Jemen ye
+Jemen ye
+Iémen ye
+Йемен ye
+Jemen ye
+Jemen ye
+I-Yemen ye
+Jemen ye
+§ÂÃý ye
+Ємен ye
+也门 ye
+葉門 ye
+Yugoslavia yu
+ЮгаÑÐ»Ð°Ð²Ñ–Ñ yu
+ЮгоÑÐ»Ð°Ð²Ð¸Ñ yu
+Jugoslavija yu
+Jugoslavien (Serbien/Montenegro) yu
+Jugoszlávia yu
+ໂບລິເວີຠyu
+Iugoslávia yu
+Juhoslávia yu
+Jugoslavija yu
+Jugoslavien yu
+å—æ–¯æ‹‰å¤« yu
+South Africa za
+Suid Afrika za
+جنوب Ø£ÙØ±ÙŠÙ‚يا za
+Cənubi Afrika za
+ÐŸÐ°ÑžÐ´Ð½Ñ‘Ð²Ð°Ñ Ðфрыка za
+Южна Ðфрика za
+Suafrika za
+Južna Afrika za
+Sudàfrica za
+Jižní Afrika za
+Sydafrikanske republik za
+Südafrika za
+Îότια ΑφÏική za
+Sudafriko za
+Sudáfrica za
+Lõuna Aafrika za
+Hego Afrika za
+Ø¢ÙØ±ÛŒÙ‚ای جنوبی za
+Etelä-Afrikka za
+Suðurafrika za
+Afrique du sud za
+Ãfrica do Sur za
+×“×¨×•× ×פריקה za
+Južna Afrika za
+Dél-Afrika za
+Afrika Selatan za
+Suður Afríka za
+Sud Africa za
+å—アフリカ za
+남 아프리카 공화국 za
+à»àº­àºšàºžàº´àºàº²à»ƒàº•້ za
+Pietų Afrika za
+Dienvid Āfrika za
+Afrika t'Isfel za
+Sør-Afrika za
+Zuid-Afrika za
+Sør-Afrika za
+Afrika Borwa za
+Sudafrica za
+Afryka Południowa za
+Africa do Sul za
+Ãfrica do Sul za
+Africa de Sud za
+Ð®Ð¶Ð½Ð°Ñ Ðфрика za
+Južná Afrika za
+Južna Afrika za
+Južna Afrika za
+I-South Africa za
+Sydafrika za
+¦¾ý ¬ôâ측 za
+à¹à¸­à¸Ÿà¸£à¸´à¸à¸²à¹ƒà¸•้ za
+Güney Afrika za
+Південна Ðфрика za
+Afurika tshipembe za
+Nam Phi za
+Mzantsi Afrika za
+å—éž za
+å—éž za
+Emzantsi Afrika za
+Zambia zm
+Ð—Ð°Ð¼Ð±Ñ–Ñ zm
+Ð—Ð°Ð¼Ð±Ð¸Ñ zm
+ຈາໄມàºàº²à»‰ zm
+Zâmbia zm
+Zambija zm
+赞比亚 zm
+Zimbabwe zw
+Ð—Ñ‹Ð¼Ð±Ð°Ð±Ð²Ñ zw
+Зимбабве zw
+Zimbabve zw
+ລິຊາ zw
+Zimbabve zw
+津巴布韦 zw
diff --git a/addressbook/gui/widgets/e-addressbook-model.c b/addressbook/gui/widgets/e-addressbook-model.c
index 9244df8a38..683eed3499 100644
--- a/addressbook/gui/widgets/e-addressbook-model.c
+++ b/addressbook/gui/widgets/e-addressbook-model.c
@@ -1,641 +1,993 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
- * Author:
- * Christopher James Lahey <clahey@ximian.com>
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * (C) 1999 Ximian, Inc.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
-#include "e-addressbook-model.h"
-#include <gnome-xml/tree.h>
-#include <gnome-xml/parser.h>
-#include <gnome-xml/xmlmemory.h>
-#include <gnome.h>
-#include <gal/widgets/e-gui-utils.h>
-#include "e-addressbook-util.h"
-
-#define PARENT_TYPE gtk_object_get_type()
-GtkObjectClass *parent_class;
-
-/*
- * EAddressbookModel callbacks
- * These are the callbacks that define the behavior of our custom model.
- */
-static void e_addressbook_model_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_addressbook_model_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+#endif
+#include <string.h>
+#include <glib/gi18n.h>
+#include "e-addressbook-model.h"
+#include <e-util/e-marshal.h>
+#include <e-util/e-util.h>
+#include "eab-gui-util.h"
+
+#define E_ADDRESSBOOK_MODEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModelPrivate))
+
+struct _EAddressbookModelPrivate {
+ EClientCache *client_cache;
+ gulong client_notify_readonly_handler_id;
+
+ EBookClient *book_client;
+ gchar *query_str;
+ EBookClientView *client_view;
+ guint client_view_idle_id;
+
+ /* Query Results */
+ GPtrArray *contacts;
+
+ /* Signal Handler IDs */
+ gulong create_contact_id;
+ gulong remove_contact_id;
+ gulong modify_contact_id;
+ gulong status_message_id;
+ gulong view_complete_id;
+ guint remove_status_id;
+
+ guint search_in_progress : 1;
+ guint editable : 1;
+ guint first_get_view : 1;
+};
enum {
- ARG_0,
- ARG_BOOK,
- ARG_QUERY,
- ARG_EDITABLE,
+ PROP_0,
+ PROP_CLIENT,
+ PROP_CLIENT_CACHE,
+ PROP_EDITABLE,
+ PROP_QUERY
};
enum {
WRITABLE_STATUS,
STATUS_MESSAGE,
+ SEARCH_STARTED,
SEARCH_RESULT,
FOLDER_BAR_MESSAGE,
- CARD_ADDED,
- CARD_REMOVED,
- CARD_CHANGED,
+ CONTACT_ADDED,
+ CONTACTS_REMOVED,
+ CONTACT_CHANGED,
MODEL_CHANGED,
STOP_STATE_CHANGED,
- BACKEND_DIED,
LAST_SIGNAL
};
-#define COLS (E_CARD_SIMPLE_FIELD_LAST)
+static guint signals[LAST_SIGNAL];
-static guint e_addressbook_model_signals [LAST_SIGNAL] = {0, };
+G_DEFINE_TYPE (EAddressbookModel, e_addressbook_model, G_TYPE_OBJECT)
static void
free_data (EAddressbookModel *model)
{
- int i;
-
- for ( i = 0; i < model->data_count; i++ ) {
- gtk_object_unref(GTK_OBJECT(model->data[i]));
- }
+ GPtrArray *array;
- g_free(model->data);
- model->data = NULL;
- model->data_count = 0;
- model->allocated_count = 0;
+ array = model->priv->contacts;
+ g_ptr_array_foreach (array, (GFunc) g_object_unref, NULL);
+ g_ptr_array_set_size (array, 0);
}
static void
-remove_book_view(EAddressbookModel *model)
-{
- if (model->book_view && model->create_card_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book_view),
- model->create_card_id);
- if (model->book_view && model->remove_card_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book_view),
- model->remove_card_id);
- if (model->book_view && model->modify_card_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book_view),
- model->modify_card_id);
- if (model->book_view && model->status_message_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book_view),
- model->status_message_id);
- if (model->book_view && model->sequence_complete_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book_view),
- model->sequence_complete_id);
-
- model->create_card_id = 0;
- model->remove_card_id = 0;
- model->modify_card_id = 0;
- model->status_message_id = 0;
- model->sequence_complete_id = 0;
-
- model->search_in_progress = FALSE;
-
- if (model->book_view) {
- e_book_view_stop (model->book_view);
- gtk_object_unref(GTK_OBJECT(model->book_view));
- }
-
- model->book_view = NULL;
-}
-
-static void
-addressbook_destroy(GtkObject *object)
+remove_book_view (EAddressbookModel *model)
{
- EAddressbookModel *model = E_ADDRESSBOOK_MODEL(object);
-
- if (model->get_view_idle) {
- g_source_remove(model->get_view_idle);
- model->get_view_idle = 0;
- }
-
- remove_book_view(model);
- free_data (model);
-
- if (model->book) {
- if (model->writable_status_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book),
- model->writable_status_id);
+ if (model->priv->client_view && model->priv->create_contact_id)
+ g_signal_handler_disconnect (
+ model->priv->client_view,
+ model->priv->create_contact_id);
+ if (model->priv->client_view && model->priv->remove_contact_id)
+ g_signal_handler_disconnect (
+ model->priv->client_view,
+ model->priv->remove_contact_id);
+ if (model->priv->client_view && model->priv->modify_contact_id)
+ g_signal_handler_disconnect (
+ model->priv->client_view,
+ model->priv->modify_contact_id);
+ if (model->priv->client_view && model->priv->status_message_id)
+ g_signal_handler_disconnect (
+ model->priv->client_view,
+ model->priv->status_message_id);
+ if (model->priv->client_view && model->priv->view_complete_id)
+ g_signal_handler_disconnect (
+ model->priv->client_view,
+ model->priv->view_complete_id);
+ if (model->priv->remove_status_id)
+ g_source_remove (model->priv->remove_status_id);
+
+ model->priv->create_contact_id = 0;
+ model->priv->remove_contact_id = 0;
+ model->priv->modify_contact_id = 0;
+ model->priv->status_message_id = 0;
+ model->priv->view_complete_id = 0;
+ model->priv->remove_status_id = 0;
+
+ model->priv->search_in_progress = FALSE;
+
+ if (model->priv->client_view) {
+ GError *error = NULL;
+
+ e_book_client_view_stop (model->priv->client_view, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to stop client view: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
- model->writable_status_id = 0;
+ g_object_unref (model->priv->client_view);
+ model->priv->client_view = NULL;
- gtk_object_unref(GTK_OBJECT(model->book));
- model->book = NULL;
+ g_signal_emit (model, signals[STATUS_MESSAGE], 0, NULL, -1);
}
-
- g_free (model->query);
}
static void
update_folder_bar_message (EAddressbookModel *model)
{
- int count;
- char *message;
+ guint count;
+ gchar *message;
- count = model->data_count;
+ count = model->priv->contacts->len;
switch (count) {
case 0:
- message = g_strdup (_("No cards"));
- break;
- case 1:
- message = g_strdup (_("1 card"));
+ message = g_strdup (_("No contacts"));
break;
default:
- message = g_strdup_printf (_("%d cards"), count);
+ message = g_strdup_printf (
+ ngettext ("%d contact", "%d contacts", count), count);
break;
}
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [FOLDER_BAR_MESSAGE],
- message);
+ g_signal_emit (model, signals[FOLDER_BAR_MESSAGE], 0, message);
g_free (message);
}
static void
-create_card(EBookView *book_view,
- const GList *cards,
- EAddressbookModel *model)
+view_create_contact_cb (EBookClientView *client_view,
+ const GSList *contact_list,
+ EAddressbookModel *model)
{
- int old_count = model->data_count;
- int length = g_list_length ((GList *)cards);
+ GPtrArray *array;
+ guint count;
+ guint index;
- 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);
- }
+ array = model->priv->contacts;
+ index = array->len;
+ count = g_list_length ((GList *) contact_list);
- for ( ; cards; cards = cards->next) {
- model->data[model->data_count++] = cards->data;
- gtk_object_ref (cards->data);
- }
+ while (contact_list != NULL) {
+ EContact *contact = contact_list->data;
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [CARD_ADDED],
- old_count, model->data_count - old_count);
+ g_ptr_array_add (array, g_object_ref (contact));
+ contact_list = contact_list->next;
+ }
+ g_signal_emit (model, signals[CONTACT_ADDED], 0, index, count);
update_folder_bar_message (model);
}
-static void
-remove_card(EBookView *book_view,
- const char *id,
- EAddressbookModel *model)
-{
- int i;
-
- for ( i = 0; i < model->data_count; i++) {
- if ( !strcmp(e_card_get_id(model->data[i]), id) ) {
- gtk_object_unref(GTK_OBJECT(model->data[i]));
- memmove(model->data + i, model->data + i + 1, (model->data_count - i - 1) * sizeof (ECard *));
- model->data_count--;
-
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [CARD_REMOVED],
- i);
- update_folder_bar_message (model);
- break;
- }
- }
+static gint
+sort_descending (gconstpointer ca,
+ gconstpointer cb)
+{
+ gint a = *((gint *) ca);
+ gint b = *((gint *) cb);
+
+ return (a == b) ? 0 : (a < b) ? 1 : -1;
}
static void
-modify_card(EBookView *book_view,
- const GList *cards,
- EAddressbookModel *model)
-{
- for ( ; cards; cards = cards->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))) ) {
- gtk_object_unref(GTK_OBJECT(model->data[i]));
- model->data[i] = e_card_duplicate(E_CARD(cards->data));
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [CARD_CHANGED],
- i);
+view_remove_contact_cb (EBookClientView *client_view,
+ const GSList *ids,
+ EAddressbookModel *model)
+{
+ /* XXX we should keep a hash around instead of this O(n*m) loop */
+ const GSList *iter;
+ GArray *indices;
+ GPtrArray *array;
+ gint ii;
+
+ array = model->priv->contacts;
+ indices = g_array_new (FALSE, FALSE, sizeof (gint));
+
+ for (iter = ids; iter != NULL; iter = iter->next) {
+ const gchar *target_uid = iter->data;
+
+ for (ii = 0; ii < array->len; ii++) {
+ EContact *contact;
+ const gchar *uid;
+
+ contact = array->pdata[ii];
+ /* check if already removed */
+ if (!contact)
+ continue;
+
+ uid = e_contact_get_const (contact, E_CONTACT_UID);
+ g_return_if_fail (uid != NULL);
+
+ if (strcmp (uid, target_uid) == 0) {
+ g_object_unref (contact);
+ g_array_append_val (indices, ii);
+ array->pdata[ii] = NULL;
break;
}
}
}
-}
-static void
-status_message (EBookView *book_view,
- char* status,
- EAddressbookModel *model)
-{
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [STATUS_MESSAGE],
- status);
-}
+ /* Sort the 'indices' array in descending order, since
+ * g_ptr_array_remove_index() shifts subsequent elements
+ * down one position to fill the gap. */
+ g_array_sort (indices, sort_descending);
-static void
-sequence_complete (EBookView *book_view,
- EBookViewStatus status,
- EAddressbookModel *model)
-{
- model->search_in_progress = FALSE;
- status_message (book_view, NULL, model);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [SEARCH_RESULT],
- status);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [STOP_STATE_CHANGED]);
+ for (ii = 0; ii < indices->len; ii++) {
+ gint index;
+
+ index = g_array_index (indices, gint, ii);
+ g_ptr_array_remove_index (array, index);
+ }
+
+ g_signal_emit (model, signals[CONTACTS_REMOVED], 0, indices);
+ g_array_free (indices, FALSE);
+
+ update_folder_bar_message (model);
}
static void
-writable_status (EBook *book,
- gboolean writable,
- EAddressbookModel *model)
+view_modify_contact_cb (EBookClientView *client_view,
+ const GSList *contact_list,
+ EAddressbookModel *model)
{
- if (!model->editable_set) {
- model->editable = writable;
+ GPtrArray *array;
+
+ array = model->priv->contacts;
+
+ while (contact_list != NULL) {
+ EContact *new_contact = contact_list->data;
+ const gchar *target_uid;
+ gint ii;
+
+ target_uid = e_contact_get_const (new_contact, E_CONTACT_UID);
+ g_warn_if_fail (target_uid != NULL);
+
+ /* skip contacts without UID */
+ if (!target_uid) {
+ contact_list = contact_list->next;
+ continue;
+ }
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [WRITABLE_STATUS],
- writable);
+ for (ii = 0; ii < array->len; ii++) {
+ EContact *old_contact;
+ const gchar *uid;
+
+ old_contact = array->pdata[ii];
+ g_return_if_fail (old_contact != NULL);
+
+ uid = e_contact_get_const (old_contact, E_CONTACT_UID);
+ g_return_if_fail (uid != NULL);
+
+ if (strcmp (uid, target_uid) != 0)
+ continue;
+
+ g_object_unref (old_contact);
+ array->pdata[ii] = e_contact_duplicate (new_contact);
+
+ g_signal_emit (
+ model, signals[CONTACT_CHANGED], 0, ii);
+ break;
+ }
+
+ contact_list = contact_list->next;
}
}
static void
-backend_died (EBook *book,
- EAddressbookModel *model)
+view_progress_cb (EBookClientView *client_view,
+ guint percent,
+ const gchar *message,
+ EAddressbookModel *model)
{
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [BACKEND_DIED]);
+ if (model->priv->remove_status_id)
+ g_source_remove (model->priv->remove_status_id);
+ model->priv->remove_status_id = 0;
+
+ g_signal_emit (model, signals[STATUS_MESSAGE], 0, message, percent);
}
static void
-e_addressbook_model_class_init (GtkObjectClass *object_class)
-{
- parent_class = gtk_type_class (PARENT_TYPE);
-
- object_class->destroy = addressbook_destroy;
- object_class->set_arg = e_addressbook_model_set_arg;
- object_class->get_arg = e_addressbook_model_get_arg;
-
- gtk_object_add_arg_type ("EAddressbookModel::book", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_BOOK);
- gtk_object_add_arg_type ("EAddressbookModel::query", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_QUERY);
- gtk_object_add_arg_type ("EAddressbookModel::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
-
- e_addressbook_model_signals [WRITABLE_STATUS] =
- gtk_signal_new ("writable_status",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, writable_status),
- gtk_marshal_NONE__BOOL,
- GTK_TYPE_NONE, 1, GTK_TYPE_BOOL);
-
- e_addressbook_model_signals [STATUS_MESSAGE] =
- gtk_signal_new ("status_message",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, status_message),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
-
- e_addressbook_model_signals [SEARCH_RESULT] =
- gtk_signal_new ("search_result",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, search_result),
- gtk_marshal_NONE__ENUM,
- GTK_TYPE_NONE, 1, GTK_TYPE_ENUM);
-
- e_addressbook_model_signals [FOLDER_BAR_MESSAGE] =
- gtk_signal_new ("folder_bar_message",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, folder_bar_message),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
-
- e_addressbook_model_signals [CARD_ADDED] =
- gtk_signal_new ("card_added",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, card_added),
- gtk_marshal_NONE__INT_INT,
- GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
-
- e_addressbook_model_signals [CARD_REMOVED] =
- gtk_signal_new ("card_removed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, card_removed),
- gtk_marshal_NONE__INT,
- GTK_TYPE_NONE, 1, GTK_TYPE_INT);
-
- e_addressbook_model_signals [CARD_CHANGED] =
- gtk_signal_new ("card_changed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, card_changed),
- gtk_marshal_NONE__INT,
- GTK_TYPE_NONE, 1, GTK_TYPE_INT);
-
- e_addressbook_model_signals [MODEL_CHANGED] =
- gtk_signal_new ("model_changed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, model_changed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- e_addressbook_model_signals [STOP_STATE_CHANGED] =
- gtk_signal_new ("stop_state_changed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, stop_state_changed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- e_addressbook_model_signals [BACKEND_DIED] =
- gtk_signal_new ("backend_died",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, backend_died),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, e_addressbook_model_signals, LAST_SIGNAL);
+view_complete_cb (EBookClientView *client_view,
+ const GError *error,
+ EAddressbookModel *model)
+{
+ model->priv->search_in_progress = FALSE;
+ view_progress_cb (client_view, -1, NULL, model);
+ g_signal_emit (model, signals[SEARCH_RESULT], 0, error);
+ g_signal_emit (model, signals[STOP_STATE_CHANGED], 0);
}
static void
-e_addressbook_model_init (GtkObject *object)
-{
- EAddressbookModel *model = E_ADDRESSBOOK_MODEL(object);
- model->book = NULL;
- model->query = g_strdup("(contains \"x-evolution-any-field\" \"\")");
- 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->status_message_id = 0;
- model->writable_status_id = 0;
- model->backend_died_id = 0;
- model->sequence_complete_id = 0;
- model->data = NULL;
- model->data_count = 0;
- model->allocated_count = 0;
- model->search_in_progress = FALSE;
- model->editable = FALSE;
- model->editable_set = FALSE;
- model->first_get_view = TRUE;
+addressbook_model_client_notify_readonly_cb (EClientCache *client_cache,
+ EClient *client,
+ GParamSpec *pspec,
+ EAddressbookModel *model)
+{
+ if (!E_IS_BOOK_CLIENT (client))
+ return;
+
+ if (E_BOOK_CLIENT (client) == model->priv->book_client) {
+ gboolean editable = !e_client_is_readonly (client);
+ e_addressbook_model_set_editable (model, editable);
+ }
}
static void
-book_view_loaded (EBook *book, EBookStatus status, EBookView *book_view, gpointer closure)
+client_view_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- EAddressbookModel *model = closure;
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ EBookClientView *client_view = NULL;
+ EAddressbookModel *model = user_data;
+ GError *error = NULL;
- remove_book_view(model);
+ if (!e_book_client_get_view_finish (book_client, result, &client_view, &error))
+ client_view = NULL;
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (_("Error getting book view"), status);
+ if (error) {
+ eab_error_dialog (NULL, NULL, _("Error getting book view"), error);
+ g_error_free (error);
return;
}
- model->book_view = book_view;
- if (model->book_view)
- gtk_object_ref(GTK_OBJECT(model->book_view));
- model->create_card_id = gtk_signal_connect(GTK_OBJECT(model->book_view),
- "card_added",
- GTK_SIGNAL_FUNC(create_card),
- model);
- model->remove_card_id = gtk_signal_connect(GTK_OBJECT(model->book_view),
- "card_removed",
- GTK_SIGNAL_FUNC(remove_card),
- model);
- model->modify_card_id = gtk_signal_connect(GTK_OBJECT(model->book_view),
- "card_changed",
- GTK_SIGNAL_FUNC(modify_card),
- model);
- model->status_message_id = gtk_signal_connect(GTK_OBJECT(model->book_view),
- "status_message",
- GTK_SIGNAL_FUNC(status_message),
- model);
- model->sequence_complete_id = gtk_signal_connect(GTK_OBJECT(model->book_view),
- "sequence_complete",
- GTK_SIGNAL_FUNC(sequence_complete),
- model);
-
+ remove_book_view (model);
free_data (model);
- model->search_in_progress = TRUE;
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [MODEL_CHANGED]);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [STOP_STATE_CHANGED]);
+ model->priv->client_view = client_view;
+ if (model->priv->client_view) {
+ model->priv->create_contact_id = g_signal_connect (
+ model->priv->client_view, "objects-added",
+ G_CALLBACK (view_create_contact_cb), model);
+ model->priv->remove_contact_id = g_signal_connect (
+ model->priv->client_view, "objects-removed",
+ G_CALLBACK (view_remove_contact_cb), model);
+ model->priv->modify_contact_id = g_signal_connect (
+ model->priv->client_view, "objects-modified",
+ G_CALLBACK (view_modify_contact_cb), model);
+ model->priv->status_message_id = g_signal_connect (
+ model->priv->client_view, "progress",
+ G_CALLBACK (view_progress_cb), model);
+ model->priv->view_complete_id = g_signal_connect (
+ model->priv->client_view, "complete",
+ G_CALLBACK (view_complete_cb), model);
+
+ model->priv->search_in_progress = TRUE;
+ }
+
+ g_signal_emit (model, signals[MODEL_CHANGED], 0);
+ g_signal_emit (model, signals[SEARCH_STARTED], 0);
+ g_signal_emit (model, signals[STOP_STATE_CHANGED], 0);
+
+ if (model->priv->client_view) {
+ e_book_client_view_start (model->priv->client_view, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to start client view: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+ }
}
static gboolean
-get_view (EAddressbookModel *model)
-{
- if (model->book && model->query) {
- if (model->first_get_view) {
- char *capabilities;
- capabilities = e_book_get_static_capabilities (model->book);
- if (capabilities && strstr (capabilities, "do-initial-query")) {
- e_book_get_book_view (model->book, model->query, book_view_loaded, model);
+addressbook_model_idle_cb (EAddressbookModel *model)
+{
+ model->priv->client_view_idle_id = 0;
+
+ if (model->priv->book_client && model->priv->query_str) {
+ remove_book_view (model);
+
+ if (model->priv->first_get_view) {
+ model->priv->first_get_view = FALSE;
+
+ if (e_client_check_capability (E_CLIENT (model->priv->book_client), "do-initial-query")) {
+ e_book_client_get_view (
+ model->priv->book_client, model->priv->query_str,
+ NULL, client_view_ready_cb, model);
} else {
- remove_book_view(model);
free_data (model);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [MODEL_CHANGED]);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [STOP_STATE_CHANGED]);
+
+ g_signal_emit (
+ model, signals[MODEL_CHANGED], 0);
+ g_signal_emit (
+ model, signals[STOP_STATE_CHANGED], 0);
}
- model->first_get_view = FALSE;
- g_free (capabilities);
- }
- else
- e_book_get_book_view (model->book, model->query, book_view_loaded, model);
+ } else
+ e_book_client_get_view (
+ model->priv->book_client, model->priv->query_str,
+ NULL, client_view_ready_cb, model);
+
}
- model->get_view_idle = 0;
+ g_object_unref (model);
+
return FALSE;
}
-ECard *
-e_addressbook_model_get_card(EAddressbookModel *model,
- int row)
+static gboolean
+remove_status_cb (gpointer data)
{
- if (model->data && 0 <= row && row < model->data_count) {
- ECard *card;
- card = e_card_duplicate (model->data[row]);
- return card;
+ EAddressbookModel *model = data;
+
+ g_return_val_if_fail (model != NULL, FALSE);
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), FALSE);
+
+ g_signal_emit (model, signals[STATUS_MESSAGE], 0, NULL, -1);
+ model->priv->remove_status_id = 0;
+
+ return FALSE;
+}
+
+static void
+addressbook_model_set_client_cache (EAddressbookModel *model,
+ EClientCache *client_cache)
+{
+ g_return_if_fail (E_IS_CLIENT_CACHE (client_cache));
+ g_return_if_fail (model->priv->client_cache == NULL);
+
+ model->priv->client_cache = g_object_ref (client_cache);
+}
+
+static void
+addressbook_model_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CLIENT:
+ e_addressbook_model_set_client (
+ E_ADDRESSBOOK_MODEL (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_CLIENT_CACHE:
+ addressbook_model_set_client_cache (
+ E_ADDRESSBOOK_MODEL (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_EDITABLE:
+ e_addressbook_model_set_editable (
+ E_ADDRESSBOOK_MODEL (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_QUERY:
+ e_addressbook_model_set_query (
+ E_ADDRESSBOOK_MODEL (object),
+ g_value_get_string (value));
+ return;
}
- return NULL;
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+
}
-const ECard *
-e_addressbook_model_peek_card(EAddressbookModel *model,
- int row)
+static void
+addressbook_model_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- if (model->data && 0 <= row && row < model->data_count) {
- return model->data[row];
+ switch (property_id) {
+ case PROP_CLIENT:
+ g_value_set_object (
+ value, e_addressbook_model_get_client (
+ E_ADDRESSBOOK_MODEL (object)));
+ return;
+
+ case PROP_CLIENT_CACHE:
+ g_value_set_object (
+ value, e_addressbook_model_get_client_cache (
+ E_ADDRESSBOOK_MODEL (object)));
+ return;
+
+ case PROP_EDITABLE:
+ g_value_set_boolean (
+ value, e_addressbook_model_get_editable (
+ E_ADDRESSBOOK_MODEL (object)));
+ return;
+
+ case PROP_QUERY:
+ g_value_set_string (
+ value, e_addressbook_model_get_query (
+ E_ADDRESSBOOK_MODEL (object)));
+ return;
}
- return NULL;
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-e_addressbook_model_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+addressbook_model_dispose (GObject *object)
{
- EAddressbookModel *model;
+ EAddressbookModel *model = E_ADDRESSBOOK_MODEL (object);
- model = E_ADDRESSBOOK_MODEL (o);
-
- switch (arg_id){
- case ARG_BOOK:
- if (model->book) {
- if (model->writable_status_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book),
- model->writable_status_id);
- model->writable_status_id = 0;
-
- if (model->backend_died_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book),
- model->backend_died_id);
- model->backend_died_id = 0;
-
- gtk_object_unref(GTK_OBJECT(model->book));
- }
- model->book = E_BOOK(GTK_VALUE_OBJECT (*arg));
- if (model->book) {
- model->first_get_view = TRUE;
- gtk_object_ref(GTK_OBJECT(model->book));
- if (model->get_view_idle == 0)
- model->get_view_idle = g_idle_add((GSourceFunc)get_view, model);
- gtk_signal_connect (GTK_OBJECT(model->book),
- "writable_status",
- writable_status, model);
- gtk_signal_connect (GTK_OBJECT(model->book),
- "backend_died",
- backend_died, model);
- }
- break;
- case ARG_QUERY:
- if (model->query)
- g_free(model->query);
- model->query = g_strdup(GTK_VALUE_STRING (*arg));
- if (model->get_view_idle == 0)
- model->get_view_idle = g_idle_add((GSourceFunc)get_view, model);
- break;
- case ARG_EDITABLE:
- model->editable = GTK_VALUE_BOOL (*arg);
- model->editable_set = TRUE;
- break;
+ remove_book_view (model);
+ free_data (model);
+
+ if (model->priv->client_notify_readonly_handler_id > 0) {
+ g_signal_handler_disconnect (
+ model->priv->client_cache,
+ model->priv->client_notify_readonly_handler_id);
+ model->priv->client_notify_readonly_handler_id = 0;
}
+
+ g_clear_object (&model->priv->client_cache);
+ g_clear_object (&model->priv->book_client);
+
+ if (model->priv->query_str) {
+ g_free (model->priv->query_str);
+ model->priv->query_str = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_addressbook_model_parent_class)->dispose (object);
}
static void
-e_addressbook_model_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+addressbook_model_finalize (GObject *object)
{
- EAddressbookModel *e_addressbook_model;
+ EAddressbookModelPrivate *priv;
- e_addressbook_model = E_ADDRESSBOOK_MODEL (object);
+ priv = E_ADDRESSBOOK_MODEL_GET_PRIVATE (object);
- switch (arg_id) {
- case ARG_BOOK:
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(e_addressbook_model->book);
- break;
- case ARG_QUERY:
- GTK_VALUE_STRING (*arg) = g_strdup(e_addressbook_model->query);
- break;
- case ARG_EDITABLE:
- GTK_VALUE_BOOL (*arg) = e_addressbook_model->editable;
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
+ g_ptr_array_free (priv->contacts, TRUE);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_addressbook_model_parent_class)->finalize (object);
}
-GtkType
-e_addressbook_model_get_type (void)
+static void
+addressbook_model_constructed (GObject *object)
{
- static GtkType type = 0;
+ EAddressbookModel *model;
+ EClientCache *client_cache;
+ gulong handler_id;
- if (!type){
- GtkTypeInfo info = {
- "EAddressbookModel",
- sizeof (EAddressbookModel),
- sizeof (EAddressbookModelClass),
- (GtkClassInitFunc) e_addressbook_model_class_init,
- (GtkObjectInitFunc) e_addressbook_model_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
+ model = E_ADDRESSBOOK_MODEL (object);
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_addressbook_model_parent_class)->constructed (object);
- return type;
+ client_cache = e_addressbook_model_get_client_cache (model);
+
+ handler_id = g_signal_connect (
+ client_cache, "client-notify::readonly",
+ G_CALLBACK (addressbook_model_client_notify_readonly_cb),
+ model);
+ model->priv->client_notify_readonly_handler_id = handler_id;
}
-EAddressbookModel*
-e_addressbook_model_new (void)
+static void
+e_addressbook_model_class_init (EAddressbookModelClass *class)
{
- EAddressbookModel *et;
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EAddressbookModelPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = addressbook_model_set_property;
+ object_class->get_property = addressbook_model_get_property;
+ object_class->dispose = addressbook_model_dispose;
+ object_class->finalize = addressbook_model_finalize;
+ object_class->constructed = addressbook_model_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLIENT,
+ g_param_spec_object (
+ "client",
+ "EBookClient",
+ NULL,
+ E_TYPE_BOOK_CLIENT,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLIENT_CACHE,
+ g_param_spec_object (
+ "client-cache",
+ "Client Cache",
+ "Shared EClient instances",
+ E_TYPE_CLIENT_CACHE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ "Editable",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_QUERY,
+ g_param_spec_string (
+ "query",
+ "Query",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ signals[WRITABLE_STATUS] = g_signal_new (
+ "writable_status",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, writable_status),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1,
+ G_TYPE_BOOLEAN);
+
+ signals[STATUS_MESSAGE] = g_signal_new (
+ "status_message",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, status_message),
+ NULL, NULL,
+ e_marshal_VOID__STRING_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_INT);
+
+ signals[SEARCH_STARTED] = g_signal_new (
+ "search_started",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, search_started),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[SEARCH_RESULT] = g_signal_new (
+ "search_result",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, search_result),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ G_TYPE_ERROR);
+
+ 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),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ signals[CONTACT_ADDED] = g_signal_new (
+ "contact_added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, contact_added),
+ NULL, NULL,
+ e_marshal_NONE__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT,
+ G_TYPE_INT);
+
+ signals[CONTACTS_REMOVED] = g_signal_new (
+ "contacts_removed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, contacts_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ signals[CONTACT_CHANGED] = g_signal_new (
+ "contact_changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, contact_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+
+ signals[MODEL_CHANGED] = g_signal_new (
+ "model_changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, model_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ 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),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
- et = gtk_type_new (e_addressbook_model_get_type ());
-
- return et;
+static void
+e_addressbook_model_init (EAddressbookModel *model)
+{
+ model->priv = E_ADDRESSBOOK_MODEL_GET_PRIVATE (model);
+ model->priv->contacts = g_ptr_array_new ();
+ model->priv->first_get_view = TRUE;
}
-void e_addressbook_model_stop (EAddressbookModel *model)
+EAddressbookModel *
+e_addressbook_model_new (EClientCache *client_cache)
{
- remove_book_view(model);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [STOP_STATE_CHANGED]);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [STATUS_MESSAGE],
- "Search Interrupted.");
+ g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL);
+
+ return g_object_new (
+ E_TYPE_ADDRESSBOOK_MODEL,
+ "client-cache", client_cache, NULL);
+}
+
+EClientCache *
+e_addressbook_model_get_client_cache (EAddressbookModel *model)
+{
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
+
+ return model->priv->client_cache;
+}
+
+EContact *
+e_addressbook_model_get_contact (EAddressbookModel *model,
+ gint row)
+{
+ GPtrArray *array;
+
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
+
+ array = model->priv->contacts;
+
+ if (0 <= row && row < array->len)
+ return e_contact_duplicate (array->pdata[row]);
+
+ return NULL;
+}
+
+void
+e_addressbook_model_stop (EAddressbookModel *model)
+{
+ const gchar *message;
+
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
+
+ remove_book_view (model);
+
+ message = _("Search Interrupted");
+ g_signal_emit (model, signals[STOP_STATE_CHANGED], 0);
+ g_signal_emit (model, signals[STATUS_MESSAGE], 0, message, -1);
+
+ if (!model->priv->remove_status_id)
+ model->priv->remove_status_id =
+ g_timeout_add_seconds (3, remove_status_cb, model);
}
gboolean
e_addressbook_model_can_stop (EAddressbookModel *model)
{
- return model->search_in_progress;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), FALSE);
+
+ return model->priv->search_in_progress;
}
void
e_addressbook_model_force_folder_bar_message (EAddressbookModel *model)
{
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
+
update_folder_bar_message (model);
}
-int
-e_addressbook_model_card_count (EAddressbookModel *model)
+gint
+e_addressbook_model_contact_count (EAddressbookModel *model)
+{
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), 0);
+
+ return model->priv->contacts->len;
+}
+
+EContact *
+e_addressbook_model_contact_at (EAddressbookModel *model,
+ gint index)
+{
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
+
+ return model->priv->contacts->pdata[index];
+}
+
+gint
+e_addressbook_model_find (EAddressbookModel *model,
+ EContact *contact)
+{
+ GPtrArray *array;
+ gint ii;
+
+ /* XXX This searches for a particular EContact instance,
+ * as opposed to an equivalent but possibly different
+ * EContact instance. Might have to revise this in
+ * the future. */
+
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), -1);
+ g_return_val_if_fail (E_IS_CONTACT (contact), -1);
+
+ array = model->priv->contacts;
+ for (ii = 0; ii < array->len; ii++) {
+ EContact *candidate = array->pdata[ii];
+
+ if (contact == candidate)
+ return ii;
+ }
+
+ return -1;
+}
+
+EBookClient *
+e_addressbook_model_get_client (EAddressbookModel *model)
{
- return model->data_count;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
+
+ return model->priv->book_client;
}
-ECard *
-e_addressbook_model_card_at (EAddressbookModel *model, int index)
+void
+e_addressbook_model_set_client (EAddressbookModel *model,
+ EBookClient *book_client)
{
- return model->data[index];
+ gboolean editable;
+
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
+ g_return_if_fail (E_IS_BOOK_CLIENT (book_client));
+
+ if (model->priv->book_client == book_client)
+ return;
+
+ if (model->priv->book_client != NULL)
+ g_object_unref (model->priv->book_client);
+
+ model->priv->book_client = g_object_ref (book_client);
+ model->priv->first_get_view = TRUE;
+
+ editable = !e_client_is_readonly (E_CLIENT (book_client));
+ e_addressbook_model_set_editable (model, editable);
+
+ if (model->priv->client_view_idle_id == 0)
+ model->priv->client_view_idle_id = g_idle_add (
+ (GSourceFunc) addressbook_model_idle_cb,
+ g_object_ref (model));
+
+ g_object_notify (G_OBJECT (model), "client");
}
gboolean
-e_addressbook_model_editable (EAddressbookModel *model)
+e_addressbook_model_get_editable (EAddressbookModel *model)
{
- return model->editable;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), FALSE);
+
+ return model->priv->editable;
}
-EBook *
-e_addressbook_model_get_ebook (EAddressbookModel *model)
+void
+e_addressbook_model_set_editable (EAddressbookModel *model,
+ gboolean editable)
{
- return model->book;
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
+
+ if (model->priv->editable != editable) {
+ model->priv->editable = editable;
+
+ g_signal_emit (
+ model, signals[WRITABLE_STATUS], 0,
+ model->priv->editable);
+
+ g_object_notify (G_OBJECT (model), "editable");
+ }
+}
+
+gchar *
+e_addressbook_model_get_query (EAddressbookModel *model)
+{
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
+
+ return model->priv->query_str;
+}
+
+void
+e_addressbook_model_set_query (EAddressbookModel *model,
+ const gchar *query)
+{
+ EBookQuery *book_query;
+
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
+
+ if (query == NULL)
+ book_query = e_book_query_any_field_contains ("");
+ else
+ book_query = e_book_query_from_string (query);
+
+ /* also checks whether the query is a valid query string */
+ if (!book_query)
+ return;
+
+ if (model->priv->query_str != NULL) {
+ gchar *new_query;
+
+ new_query = e_book_query_to_string (book_query);
+
+ if (new_query && g_str_equal (model->priv->query_str, new_query)) {
+ g_free (new_query);
+ e_book_query_unref (book_query);
+ return;
+ }
+
+ g_free (new_query);
+ }
+
+ g_free (model->priv->query_str);
+ model->priv->query_str = e_book_query_to_string (book_query);
+ e_book_query_unref (book_query);
+
+ if (model->priv->client_view_idle_id == 0)
+ model->priv->client_view_idle_id = g_idle_add (
+ (GSourceFunc) addressbook_model_idle_cb,
+ g_object_ref (model));
+
+ g_object_notify (G_OBJECT (model), "query");
}
diff --git a/addressbook/gui/widgets/e-addressbook-model.h b/addressbook/gui/widgets/e-addressbook-model.h
index eb1004499a..c08fdb4319 100644
--- a/addressbook/gui/widgets/e-addressbook-model.h
+++ b/addressbook/gui/widgets/e-addressbook-model.h
@@ -1,80 +1,119 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-#ifndef _E_ADDRESSBOOK_MODEL_H_
-#define _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-simple.h"
-
-#define E_ADDRESSBOOK_MODEL_TYPE (e_addressbook_model_get_type ())
-#define E_ADDRESSBOOK_MODEL(o) (GTK_CHECK_CAST ((o), E_ADDRESSBOOK_MODEL_TYPE, EAddressbookModel))
-#define E_ADDRESSBOOK_MODEL_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_ADDRESSBOOK_MODEL_TYPE, EAddressbookModelClass))
-#define E_IS_ADDRESSBOOK_MODEL(o) (GTK_CHECK_TYPE ((o), E_ADDRESSBOOK_MODEL_TYPE))
-#define E_IS_ADDRESSBOOK_MODEL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_ADDRESSBOOK_MODEL_TYPE))
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_ADDRESSBOOK_MODEL_H
+#define E_ADDRESSBOOK_MODEL_H
+
+#include <libebook/libebook.h>
+
+#include <e-util/e-util.h>
+
+/* Standard GObject macros */
+#define E_TYPE_ADDRESSBOOK_MODEL \
+ (e_addressbook_model_get_type ())
+#define E_ADDRESSBOOK_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModel))
+#define E_ADDRESSBOOK_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModelClass))
+#define E_IS_ADDRESSBOOK_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ADDRESSBOOK_MODEL))
+#define E_IS_ADDRESSBOOK_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ADDRESSBOOK_MODEL))
+#define E_ADDRESSBOOK_MODEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ADDRESSBOOK_MODEL))
+
+G_BEGIN_DECLS
typedef struct _EAddressbookModel EAddressbookModel;
typedef struct _EAddressbookModelClass EAddressbookModelClass;
+typedef struct _EAddressbookModelPrivate EAddressbookModelPrivate;
struct _EAddressbookModel {
- GtkObject parent;
-
- /* item specific fields */
- EBook *book;
- char *query;
- EBookView *book_view;
-
- int get_view_idle;
-
- ECard **data;
- int data_count;
- int allocated_count;
-
- int create_card_id, remove_card_id, modify_card_id, status_message_id, writable_status_id, sequence_complete_id, backend_died_id;
-
- guint search_in_progress : 1;
- guint editable : 1;
- guint editable_set : 1;
- guint first_get_view : 1;
+ GObject parent;
+ EAddressbookModelPrivate *priv;
};
-
struct _EAddressbookModelClass {
- GtkObjectClass parent_class;
-
- /*
- * Signals
- */
- void (*writable_status) (EAddressbookModel *model, gboolean writable);
- 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);
+ GObjectClass parent_class;
+
+ /* Signals */
+ void (*writable_status) (EAddressbookModel *model,
+ gboolean writable);
+ void (*search_started) (EAddressbookModel *model);
+ void (*search_result) (EAddressbookModel *model,
+ const GError *error);
+ void (*status_message) (EAddressbookModel *model,
+ const gchar *message,
+ gint percent);
+ void (*folder_bar_message) (EAddressbookModel *model,
+ const gchar *message);
+ void (*contact_added) (EAddressbookModel *model,
+ gint index,
+ gint count);
+ void (*contacts_removed) (EAddressbookModel *model,
+ gpointer id_list);
+ void (*contact_changed) (EAddressbookModel *model,
+ gint index);
+ void (*model_changed) (EAddressbookModel *model);
+ void (*stop_state_changed) (EAddressbookModel *model);
};
-
-GtkType e_addressbook_model_get_type (void);
-EAddressbookModel *e_addressbook_model_new (void);
+GType e_addressbook_model_get_type (void);
+EAddressbookModel *
+ e_addressbook_model_new (EClientCache *client_cache);
+EClientCache * e_addressbook_model_get_client_cache
+ (EAddressbookModel *model);
/* 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);
-
-void e_addressbook_model_stop (EAddressbookModel *model);
-gboolean e_addressbook_model_can_stop (EAddressbookModel *model);
-
-void e_addressbook_model_force_folder_bar_message (EAddressbookModel *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);
-
-#endif /* _E_ADDRESSBOOK_MODEL_H_ */
+EContact * e_addressbook_model_get_contact (EAddressbookModel *model,
+ gint row);
+
+void e_addressbook_model_stop (EAddressbookModel *model);
+gboolean e_addressbook_model_can_stop (EAddressbookModel *model);
+
+void e_addressbook_model_force_folder_bar_message
+ (EAddressbookModel *model);
+
+gint e_addressbook_model_contact_count
+ (EAddressbookModel *model);
+EContact * e_addressbook_model_contact_at (EAddressbookModel *model,
+ gint index);
+gint e_addressbook_model_find (EAddressbookModel *model,
+ EContact *contact);
+EBookClient * e_addressbook_model_get_client (EAddressbookModel *model);
+void e_addressbook_model_set_client (EAddressbookModel *model,
+ EBookClient *book_client);
+gboolean e_addressbook_model_get_editable
+ (EAddressbookModel *model);
+void e_addressbook_model_set_editable
+ (EAddressbookModel *model,
+ gboolean editable);
+gchar * e_addressbook_model_get_query (EAddressbookModel *model);
+void e_addressbook_model_set_query (EAddressbookModel *model,
+ const gchar *query);
+
+G_END_DECLS
+
+#endif /* E_ADDRESSBOOK_MODEL_H */
diff --git a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
index 16e61a2d89..48ed73bb25 100644
--- a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
+++ b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
@@ -1,452 +1,613 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
+#include <string.h>
+
+#include <glib/gi18n.h>
#include "e-addressbook-reflow-adapter.h"
#include "e-addressbook-model.h"
-#include "e-addressbook-view.h"
-#include "e-addressbook-util.h"
-
-#include <gal/util/e-i18n.h>
+#include "eab-gui-util.h"
#include "e-minicard.h"
-#include <gal/widgets/e-unicode.h>
-#include <gal/widgets/e-font.h>
-#include <gal/widgets/e-popup-menu.h>
-#include <gal/widgets/e-gui-utils.h>
-#include <gal/unicode/gunicode.h>
-#include "e-contact-save-as.h"
+#include <e-util/e-util.h>
#include "addressbook/printing/e-contact-print.h"
-#include "addressbook/printing/e-contact-print-envelope.h"
+#define E_ADDRESSBOOK_REFLOW_ADAPTER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER, EAddressbookReflowAdapterPrivate))
struct _EAddressbookReflowAdapterPrivate {
EAddressbookModel *model;
-
- int create_card_id, remove_card_id, modify_card_id, model_changed_id;
-};
-#define PARENT_TYPE e_reflow_model_get_type()
-EReflowModel *parent_class;
+ gboolean loading;
+
+ gint create_contact_id, remove_contact_id, modify_contact_id, model_changed_id;
+ gint search_started_id, search_result_id;
+};
#define d(x)
enum {
- ARG_0,
- ARG_BOOK,
- ARG_QUERY,
- ARG_EDITABLE,
- ARG_MODEL,
+ PROP_0,
+ PROP_CLIENT,
+ PROP_QUERY,
+ PROP_EDITABLE,
+ PROP_MODEL
};
enum {
DRAG_BEGIN,
+ OPEN_CONTACT,
LAST_SIGNAL
};
-static guint e_addressbook_reflow_adapter_signals [LAST_SIGNAL] = {0, };
+static guint signals[LAST_SIGNAL] = {0, };
+
+G_DEFINE_TYPE (
+ EAddressbookReflowAdapter,
+ e_addressbook_reflow_adapter,
+ E_TYPE_REFLOW_MODEL)
static void
-unlink_model(EAddressbookReflowAdapter *adapter)
+unlink_model (EAddressbookReflowAdapter *adapter)
{
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->create_card_id);
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->remove_card_id);
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->modify_card_id);
-
- priv->create_card_id = 0;
- priv->remove_card_id = 0;
- priv->modify_card_id = 0;
+ if (priv->model && priv->create_contact_id)
+ g_signal_handler_disconnect (
+ priv->model,
+ priv->create_contact_id);
+ if (priv->model && priv->remove_contact_id)
+ g_signal_handler_disconnect (
+ priv->model,
+ priv->remove_contact_id);
+ if (priv->model && priv->modify_contact_id)
+ g_signal_handler_disconnect (
+ priv->model,
+ priv->modify_contact_id);
+ if (priv->model && priv->model_changed_id)
+ g_signal_handler_disconnect (
+ priv->model,
+ priv->model_changed_id);
+ if (priv->model && priv->search_started_id)
+ g_signal_handler_disconnect (
+ priv->model,
+ priv->search_started_id);
+ if (priv->model && priv->search_result_id)
+ g_signal_handler_disconnect (
+ priv->model,
+ priv->search_result_id);
+
+ 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;
- gtk_object_unref(GTK_OBJECT(priv->model));
+ if (priv->model)
+ g_object_unref (priv->model);
priv->model = NULL;
}
-
-static int
-count_lines (const gchar *text)
+static gint
+text_height (PangoLayout *layout,
+ const gchar *text)
{
- int num_lines = 1;
- gunichar unival;
+ gint height;
- for (text = e_unicode_get_utf8 (text, &unival); (unival && text); text = e_unicode_get_utf8 (text, &unival)) {
- if (unival == '\n') {
- num_lines ++;
- }
- }
+ pango_layout_set_text (layout, text, -1);
- return num_lines;
-}
-
-static int
-text_height (GnomeCanvas *canvas, const gchar *text)
-{
- EFont *font = e_font_from_gdk_font (((GtkWidget *) canvas)->style->font);
- gint height = e_font_height (font) * count_lines (text) / canvas->pixels_per_unit;
+ pango_layout_get_pixel_size (layout, NULL, &height);
- e_font_unref (font);
return height;
}
static void
-addressbook_finalize(GtkObject *object)
+addressbook_dispose (GObject *object)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(object);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (object);
unlink_model (adapter);
}
static void
-addressbook_set_width (EReflowModel *erm, int width)
+addressbook_set_width (EReflowModel *erm,
+ gint width)
{
}
/* This function returns the number of items in our EReflowModel. */
-static int
+static gint
addressbook_count (EReflowModel *erm)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- return e_addressbook_model_card_count (priv->model);
+ return e_addressbook_model_contact_count (priv->model);
}
-/* This function returns the number of items in our EReflowModel. */
-static int
-addressbook_height (EReflowModel *erm, int i, GnomeCanvasGroup *parent)
+/* This function returns the height of the minicontact in question */
+static gint
+addressbook_height (EReflowModel *erm,
+ gint i,
+ GnomeCanvasGroup *parent)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- /* FIXME */
- ECardSimpleField field;
- int count = 0;
- int height;
- char *string;
- ECardSimple *simple = e_card_simple_new (e_addressbook_model_card_at (priv->model, i));
+ EContactField field;
+ gint count = 0;
+ gchar *string;
+ EContact *contact = (EContact *) e_addressbook_model_contact_at (priv->model, i);
+ PangoLayout *layout;
+ gint height;
- string = e_card_simple_get(simple, E_CARD_SIMPLE_FIELD_FILE_AS);
- height = text_height (GNOME_CANVAS_ITEM (parent)->canvas, string ? string : "") + 10.0;
- g_free(string);
+ layout = gtk_widget_create_pango_layout (
+ GTK_WIDGET (GNOME_CANVAS_ITEM (parent)->canvas), "");
- for(field = E_CARD_SIMPLE_FIELD_FULL_NAME; field != E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING && count < 5; field++) {
+ string = e_contact_get (contact, E_CONTACT_FILE_AS);
+ height = text_height (layout, string ? string : "") + 10.0;
+ g_free (string);
- if (field == E_CARD_SIMPLE_FIELD_FAMILY_NAME)
+ for (field = E_CONTACT_FULL_NAME;
+ field != E_CONTACT_LAST_SIMPLE_STRING && count < 5; field++) {
+
+ 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;
+ gint this_height;
+ gint field_text_height;
- this_height = text_height (GNOME_CANVAS_ITEM (parent)->canvas, e_card_simple_get_name(simple, field));
+ this_height = text_height (layout, e_contact_pretty_name (field));
- field_text_height = text_height (GNOME_CANVAS_ITEM (parent)->canvas, string);
+ field_text_height = text_height (layout, string);
if (this_height < field_text_height)
this_height = field_text_height;
this_height += 3;
height += this_height;
- count ++;
+ count++;
}
g_free (string);
}
height += 2;
- gtk_object_unref (GTK_OBJECT (simple));
+ g_object_unref (layout);
return height;
}
-static int
-addressbook_compare (EReflowModel *erm, int n1, int n2)
+static GHashTable *
+addressbook_create_cmp_cache (EReflowModel *erm)
+{
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (erm);
+ EAddressbookReflowAdapterPrivate *priv = adapter->priv;
+ GHashTable *cmp_cache;
+ gint ii, count;
+
+ count = e_reflow_model_count (erm);
+
+ if (priv->loading || count <= 0)
+ return NULL;
+
+ cmp_cache = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
+
+ for (ii = 0; ii < count; ii++) {
+ EContact *contact;
+
+ contact = (EContact *)
+ e_addressbook_model_contact_at (priv->model, ii);
+ if (contact != NULL) {
+ const gchar *file_as;
+
+ file_as = e_contact_get_const (
+ contact, E_CONTACT_FILE_AS);
+ if (file_as != NULL)
+ g_hash_table_insert (
+ cmp_cache, GINT_TO_POINTER (ii),
+ g_utf8_collate_key (file_as, -1));
+ }
+ }
+
+ return cmp_cache;
+}
+
+static gint
+addressbook_compare (EReflowModel *erm,
+ gint n1,
+ gint n2,
+ GHashTable *cmp_cache)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- ECard *card1, *card2;
-
- card1 = e_addressbook_model_card_at (priv->model, n1);
- card2 = e_addressbook_model_card_at (priv->model, n2);
-
- if (card1 && card2) {
- char *file_as1, *file_as2;
- file_as1 = card1->file_as;
- file_as2 = card2->file_as;
- if (file_as1 && file_as2)
- return g_utf8_collate(file_as1, file_as2);
- if (file_as1)
+ EContact *contact1, *contact2;
+
+ if (priv->loading) {
+ return n1 - n2;
+ }
+ else {
+ contact1 = (EContact *) e_addressbook_model_contact_at (priv->model, n1);
+ contact2 = (EContact *) e_addressbook_model_contact_at (priv->model, n2);
+
+ if (contact1 && contact2) {
+ const gchar *file_as1, *file_as2;
+ const gchar *uid1, *uid2;
+
+ if (cmp_cache) {
+ file_as1 = g_hash_table_lookup (cmp_cache, GINT_TO_POINTER (n1));
+ file_as2 = g_hash_table_lookup (cmp_cache, GINT_TO_POINTER (n2));
+ if (file_as1 && file_as2)
+ return strcmp (file_as1, file_as2);
+ } else {
+ 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;
+ uid1 = e_contact_get_const (contact1, E_CONTACT_UID);
+ uid2 = e_contact_get_const (contact2, E_CONTACT_UID);
+ if (uid1 && uid2)
+ return strcmp (uid1, uid2);
+ if (uid1)
+ return -1;
+ if (uid2)
+ return 1;
+ }
+ if (contact1)
return -1;
- if (file_as2)
+ if (contact2)
return 1;
- return strcmp(e_card_get_id(card1), e_card_get_id(card2));
+ return 0;
}
- if (card1)
- return -1;
- if (card2)
- return 1;
- return 0;
}
-static int
-adapter_drag_begin (EMinicard *card, GdkEvent *event, EAddressbookReflowAdapter *adapter)
+static gint
+adapter_drag_begin (EMinicard *card,
+ GdkEvent *event,
+ EAddressbookReflowAdapter *adapter)
{
gint ret_val = 0;
- gtk_signal_emit (GTK_OBJECT(adapter),
- e_addressbook_reflow_adapter_signals[DRAG_BEGIN],
- event, &ret_val);
+ g_signal_emit (
+ adapter,
+ signals[DRAG_BEGIN], 0,
+ event, &ret_val);
return ret_val;
}
+static void
+adapter_open_contact (EMinicard *card,
+ EContact *contact,
+ EAddressbookReflowAdapter *adapter)
+{
+ g_signal_emit (adapter, signals[OPEN_CONTACT], 0, contact);
+}
+
static GnomeCanvasItem *
-addressbook_incarnate (EReflowModel *erm, int i, GnomeCanvasGroup *parent)
+addressbook_incarnate (EReflowModel *erm,
+ gint i,
+ GnomeCanvasGroup *parent)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
GnomeCanvasItem *item;
- 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),
- NULL);
+ item = gnome_canvas_item_new (
+ parent, e_minicard_get_type (),
+ "contact", e_addressbook_model_contact_at (priv->model, i),
+ "editable", e_addressbook_model_get_editable (priv->model),
+ NULL);
-#if 0
- gtk_signal_connect (GTK_OBJECT (item), "selected",
- GTK_SIGNAL_FUNC(card_selected), emvm);
-#endif
+ g_signal_connect (
+ item, "drag_begin",
+ G_CALLBACK (adapter_drag_begin), adapter);
- gtk_signal_connect (GTK_OBJECT (item), "drag_begin",
- GTK_SIGNAL_FUNC(adapter_drag_begin), adapter);
+ g_signal_connect (
+ item, "open-contact",
+ G_CALLBACK (adapter_open_contact), adapter);
return item;
}
static void
-addressbook_reincarnate (EReflowModel *erm, int i, GnomeCanvasItem *item)
+addressbook_reincarnate (EReflowModel *erm,
+ gint i,
+ GnomeCanvasItem *item)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- gnome_canvas_item_set(item,
- "card", e_addressbook_model_card_at (priv->model, i),
- NULL);
+ gnome_canvas_item_set (
+ item,
+ "contact", e_addressbook_model_contact_at (priv->model, i),
+ NULL);
}
+static void
+create_contact (EAddressbookModel *model,
+ gint index,
+ gint count,
+ EAddressbookReflowAdapter *adapter)
+{
+ e_reflow_model_items_inserted (
+ E_REFLOW_MODEL (adapter),
+ index,
+ count);
+}
+
+static void
+remove_contacts (EAddressbookModel *model,
+ gpointer data,
+ EAddressbookReflowAdapter *adapter)
+{
+ GArray *indices = (GArray *) data;
+ gint count = indices->len;
+
+ if (count == 1)
+ e_reflow_model_item_removed (
+ E_REFLOW_MODEL (adapter),
+ g_array_index (indices, gint, 0));
+ else
+ e_reflow_model_changed (E_REFLOW_MODEL (adapter));
+}
static void
-create_card(EAddressbookModel *model,
- gint index, gint count,
- EAddressbookReflowAdapter *adapter)
+modify_contact (EAddressbookModel *model,
+ gint index,
+ EAddressbookReflowAdapter *adapter)
{
- e_reflow_model_items_inserted (E_REFLOW_MODEL (adapter),
- index,
- count);
+ e_reflow_model_item_changed (E_REFLOW_MODEL (adapter), index);
}
static void
-remove_card(EAddressbookModel *model,
- gint index,
- EAddressbookReflowAdapter *adapter)
+model_changed (EAddressbookModel *model,
+ EAddressbookReflowAdapter *adapter)
{
e_reflow_model_changed (E_REFLOW_MODEL (adapter));
}
static void
-modify_card(EAddressbookModel *model,
- gint index,
- EAddressbookReflowAdapter *adapter)
+search_started (EAddressbookModel *model,
+ EAddressbookReflowAdapter *adapter)
{
- e_reflow_model_item_changed (E_REFLOW_MODEL (adapter), index);
+ EAddressbookReflowAdapterPrivate *priv = adapter->priv;
+
+ priv->loading = TRUE;
}
static void
-model_changed(EAddressbookModel *model,
- EAddressbookReflowAdapter *adapter)
+search_result (EAddressbookModel *model,
+ const GError *error,
+ EAddressbookReflowAdapter *adapter)
{
- e_reflow_model_changed (E_REFLOW_MODEL (adapter));
+ EAddressbookReflowAdapterPrivate *priv = adapter->priv;
+
+ priv->loading = FALSE;
+
+ e_reflow_model_comparison_changed (E_REFLOW_MODEL (adapter));
}
static void
-addressbook_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+addressbook_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(o);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (object);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- switch (arg_id){
- case ARG_BOOK:
- gtk_object_set (GTK_OBJECT (priv->model),
- "book", GTK_VALUE_OBJECT (*arg),
- NULL);
+ switch (property_id) {
+ case PROP_CLIENT:
+ g_object_set (
+ priv->model,
+ "client", g_value_get_object (value),
+ NULL);
break;
- case ARG_QUERY:
- gtk_object_set (GTK_OBJECT (priv->model),
- "query", GTK_VALUE_STRING (*arg),
- NULL);
+ case PROP_QUERY:
+ g_object_set (
+ priv->model,
+ "query", g_value_get_string (value),
+ NULL);
break;
- case ARG_EDITABLE:
- gtk_object_set (GTK_OBJECT (priv->model),
- "editable", GTK_VALUE_BOOL (*arg),
- NULL);
+ case PROP_EDITABLE:
+ g_object_set (
+ priv->model,
+ "editable", g_value_get_boolean (value),
+ NULL);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
-addressbook_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+addressbook_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(o);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (object);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- switch (arg_id) {
- case ARG_BOOK: {
- EBook *book;
- gtk_object_get (GTK_OBJECT (priv->model),
- "book", &book,
- NULL);
- if (book)
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(book);
- else
- GTK_VALUE_OBJECT (*arg) = NULL;
+ switch (property_id) {
+ case PROP_CLIENT: {
+ g_object_get_property (
+ G_OBJECT (priv->model),
+ "client", value);
break;
}
- case ARG_QUERY: {
- char *query;
- gtk_object_get (GTK_OBJECT (priv->model),
- "query", &query,
- NULL);
- GTK_VALUE_STRING (*arg) = query;
+ case PROP_QUERY: {
+ g_object_get_property (
+ G_OBJECT (priv->model),
+ "query", value);
break;
}
- case ARG_EDITABLE: {
- gboolean editable;
- gtk_object_get (GTK_OBJECT (priv->model),
- "editable", &editable,
- NULL);
- GTK_VALUE_BOOL (*arg) = editable;
+ case PROP_EDITABLE: {
+ g_object_get_property (
+ G_OBJECT (priv->model),
+ "editable", value);
break;
}
- case ARG_MODEL:
- if (priv->model)
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT (priv->model);
- else
- GTK_VALUE_OBJECT (*arg) = NULL;
+ case PROP_MODEL:
+ g_value_set_object (value, priv->model);
break;
default:
- arg->type = GTK_TYPE_INVALID;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
-e_addressbook_reflow_adapter_class_init (GtkObjectClass *object_class)
+e_addressbook_reflow_adapter_class_init (EAddressbookReflowAdapterClass *class)
{
- EReflowModelClass *model_class = (EReflowModelClass *) object_class;
-
- parent_class = gtk_type_class (PARENT_TYPE);
-
- object_class->set_arg = addressbook_set_arg;
- object_class->get_arg = addressbook_get_arg;
- object_class->finalize = addressbook_finalize;
-
- gtk_object_add_arg_type ("EAddressbookReflowAdapter::book", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_BOOK);
- gtk_object_add_arg_type ("EAddressbookReflowAdapter::query", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_QUERY);
- gtk_object_add_arg_type ("EAddressbookReflowAdapter::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
- gtk_object_add_arg_type ("EAddressbookReflowAdapter::model", E_ADDRESSBOOK_MODEL_TYPE,
- GTK_ARG_READABLE, ARG_MODEL);
-
- e_addressbook_reflow_adapter_signals [DRAG_BEGIN] =
- gtk_signal_new ("drag_begin",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookReflowAdapterClass, drag_begin),
- gtk_marshal_INT__POINTER,
- GTK_TYPE_INT, 1, GTK_TYPE_POINTER);
-
-
- gtk_object_class_add_signals (object_class, e_addressbook_reflow_adapter_signals, LAST_SIGNAL);
-
- model_class->set_width = addressbook_set_width;
- model_class->count = addressbook_count;
- model_class->height = addressbook_height;
- model_class->compare = addressbook_compare;
- model_class->incarnate = addressbook_incarnate;
- model_class->reincarnate = addressbook_reincarnate;
+ GObjectClass *object_class;
+ EReflowModelClass *reflow_model_class;
+
+ g_type_class_add_private (
+ class, sizeof (EAddressbookReflowAdapterPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = addressbook_set_property;
+ object_class->get_property = addressbook_get_property;
+ object_class->dispose = addressbook_dispose;
+
+ reflow_model_class = E_REFLOW_MODEL_CLASS (class);
+ reflow_model_class->set_width = addressbook_set_width;
+ reflow_model_class->count = addressbook_count;
+ reflow_model_class->height = addressbook_height;
+ reflow_model_class->create_cmp_cache = addressbook_create_cmp_cache;
+ reflow_model_class->compare = addressbook_compare;
+ reflow_model_class->incarnate = addressbook_incarnate;
+ reflow_model_class->reincarnate = addressbook_reincarnate;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLIENT,
+ g_param_spec_object (
+ "client",
+ "EBookClient",
+ NULL,
+ E_TYPE_BOOK_CLIENT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_QUERY,
+ g_param_spec_string (
+ "query",
+ "Query",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ "Editable",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MODEL,
+ g_param_spec_object (
+ "model",
+ "Model",
+ NULL,
+ E_TYPE_ADDRESSBOOK_MODEL,
+ G_PARAM_READABLE));
+
+ signals[DRAG_BEGIN] = g_signal_new (
+ "drag_begin",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookReflowAdapterClass, drag_begin),
+ NULL, NULL,
+ e_marshal_INT__POINTER,
+ G_TYPE_INT, 1,
+ G_TYPE_POINTER);
+
+ signals[OPEN_CONTACT] = g_signal_new (
+ "open-contact",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookReflowAdapterClass, open_contact),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CONTACT);
}
static void
-e_addressbook_reflow_adapter_init (GtkObject *object)
-{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(object);
- EAddressbookReflowAdapterPrivate *priv;
-
- priv = adapter->priv = g_new0 (EAddressbookReflowAdapterPrivate, 1);
-
- priv->create_card_id = 0;
- priv->remove_card_id = 0;
- priv->modify_card_id = 0;
- priv->model_changed_id = 0;
-}
-
-GtkType
-e_addressbook_reflow_adapter_get_type (void)
+e_addressbook_reflow_adapter_init (EAddressbookReflowAdapter *adapter)
{
- static GtkType type = 0;
-
- if (!type){
- GtkTypeInfo info = {
- "EAddressbookReflowAdapter",
- sizeof (EAddressbookReflowAdapter),
- sizeof (EAddressbookReflowAdapterClass),
- (GtkClassInitFunc) e_addressbook_reflow_adapter_class_init,
- (GtkObjectInitFunc) e_addressbook_reflow_adapter_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
-
- return type;
+ adapter->priv = E_ADDRESSBOOK_REFLOW_ADAPTER_GET_PRIVATE (adapter);
}
void
e_addressbook_reflow_adapter_construct (EAddressbookReflowAdapter *adapter,
- EAddressbookModel *model)
+ EAddressbookModel *model)
{
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- priv->model = model;
- gtk_object_ref (GTK_OBJECT (priv->model));
-
- priv->create_card_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "card_added",
- GTK_SIGNAL_FUNC(create_card),
- adapter);
- priv->remove_card_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "card_removed",
- GTK_SIGNAL_FUNC(remove_card),
- adapter);
- priv->modify_card_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "card_changed",
- GTK_SIGNAL_FUNC(modify_card),
- adapter);
- priv->model_changed_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "model_changed",
- GTK_SIGNAL_FUNC(model_changed),
- adapter);
+ priv->model = g_object_ref (model);
+
+ 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, "contacts_removed",
+ G_CALLBACK (remove_contacts), 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);
+
+ priv->search_started_id = g_signal_connect (
+ priv->model, "search_started",
+ G_CALLBACK (search_started), adapter);
+
+ priv->search_result_id = g_signal_connect (
+ priv->model, "search_result",
+ G_CALLBACK (search_result), adapter);
}
EReflowModel *
@@ -454,19 +615,18 @@ e_addressbook_reflow_adapter_new (EAddressbookModel *model)
{
EAddressbookReflowAdapter *et;
- et = gtk_type_new (e_addressbook_reflow_adapter_get_type ());
+ et = g_object_new (E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER, NULL);
e_addressbook_reflow_adapter_construct (et, model);
- return E_REFLOW_MODEL(et);
+ return E_REFLOW_MODEL (et);
}
-
-ECard *
-e_addressbook_reflow_adapter_get_card (EAddressbookReflowAdapter *adapter,
- int index)
+EContact *
+e_addressbook_reflow_adapter_get_contact (EAddressbookReflowAdapter *adapter,
+ gint index)
{
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- return e_addressbook_model_get_card (priv->model, index);
+ return e_addressbook_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 b3f6ab9c0d..fee217c2f1 100644
--- a/addressbook/gui/widgets/e-addressbook-reflow-adapter.h
+++ b/addressbook/gui/widgets/e-addressbook-reflow-adapter.h
@@ -1,19 +1,37 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
#ifndef _E_ADDRESSBOOK_REFLOW_ADAPTER_H_
#define _E_ADDRESSBOOK_REFLOW_ADAPTER_H_
-#include <gal/widgets/e-reflow-model.h>
-#include <gal/widgets/e-selection-model.h>
+#include <libebook/libebook.h>
+
+#include <e-util/e-util.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"
-#define E_ADDRESSBOOK_REFLOW_ADAPTER_TYPE (e_addressbook_reflow_adapter_get_type ())
-#define E_ADDRESSBOOK_REFLOW_ADAPTER(o) (GTK_CHECK_CAST ((o), E_ADDRESSBOOK_REFLOW_ADAPTER_TYPE, EAddressbookReflowAdapter))
-#define E_ADDRESSBOOK_REFLOW_ADAPTER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_ADDRESSBOOK_REFLOW_ADAPTER_TYPE, EAddressbookReflowAdapterClass))
-#define E_IS_ADDRESSBOOK_REFLOW_ADAPTER(o) (GTK_CHECK_TYPE ((o), E_ADDRESSBOOK_REFLOW_ADAPTER_TYPE))
-#define E_IS_ADDRESSBOOK_REFLOW_ADAPTER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_ADDRESSBOOK_REFLOW_ADAPTER_TYPE))
+#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))
+#define E_ADDRESSBOOK_REFLOW_ADAPTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER, EAddressbookReflowAdapterClass))
+#define E_IS_ADDRESSBOOK_REFLOW_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER))
+#define E_IS_ADDRESSBOOK_REFLOW_ADAPTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER))
typedef struct _EAddressbookReflowAdapter EAddressbookReflowAdapter;
typedef struct _EAddressbookReflowAdapterPrivate EAddressbookReflowAdapterPrivate;
@@ -25,23 +43,24 @@ struct _EAddressbookReflowAdapter {
EAddressbookReflowAdapterPrivate *priv;
};
-
struct _EAddressbookReflowAdapterClass {
EReflowModelClass parent_class;
/*
* Signals
*/
- gint (* drag_begin) (EAddressbookReflowAdapter *adapter, GdkEvent *event);
+ gint (*drag_begin) (EAddressbookReflowAdapter *adapter,
+ GdkEvent *event);
+ void (*open_contact) (EAddressbookReflowAdapter *adapter,
+ EContact *contact);
};
-
-GtkType e_addressbook_reflow_adapter_get_type (void);
+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);
/* Returns object with ref count of 1. */
-ECard *e_addressbook_reflow_adapter_get_card (EAddressbookReflowAdapter *adapter,
- int index);
+EContact *e_addressbook_reflow_adapter_get_contact (EAddressbookReflowAdapter *adapter,
+ gint index);
#endif /* _E_ADDRESSBOOK_REFLOW_ADAPTER_H_ */
diff --git a/addressbook/gui/widgets/e-addressbook-selector.c b/addressbook/gui/widgets/e-addressbook-selector.c
new file mode 100644
index 0000000000..7ef9ccd047
--- /dev/null
+++ b/addressbook/gui/widgets/e-addressbook-selector.c
@@ -0,0 +1,443 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-addressbook-selector.c
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-addressbook-selector.h"
+
+#include <e-util/e-util.h>
+
+#include <eab-book-util.h>
+#include <eab-contact-merging.h>
+
+#define E_ADDRESSBOOK_SELECTOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ADDRESSBOOK_SELECTOR, EAddressbookSelectorPrivate))
+
+typedef struct _MergeContext MergeContext;
+
+struct _EAddressbookSelectorPrivate {
+ EAddressbookView *current_view;
+};
+
+struct _MergeContext {
+ ESourceRegistry *registry;
+ EBookClient *source_client;
+ EBookClient *target_client;
+
+ EContact *current_contact;
+ GSList *remaining_contacts;
+ guint pending_removals;
+ gboolean pending_adds;
+
+ gint remove_from_source : 1;
+ gint copy_done : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_CURRENT_VIEW
+};
+
+static GtkTargetEntry drag_types[] = {
+ { (gchar *) "text/x-source-vcard", 0, 0 }
+};
+
+G_DEFINE_TYPE (
+ EAddressbookSelector,
+ e_addressbook_selector,
+ E_TYPE_CLIENT_SELECTOR)
+
+static void
+merge_context_next (MergeContext *merge_context)
+{
+ GSList *list;
+
+ merge_context->current_contact = NULL;
+ if (!merge_context->remaining_contacts)
+ return;
+
+ list = merge_context->remaining_contacts;
+ merge_context->current_contact = list->data;
+ list = g_slist_delete_link (list, list);
+ merge_context->remaining_contacts = list;
+}
+
+static MergeContext *
+merge_context_new (ESourceRegistry *registry,
+ EBookClient *source_client,
+ EBookClient *target_client,
+ GSList *contact_list)
+{
+ MergeContext *merge_context;
+
+ merge_context = g_slice_new0 (MergeContext);
+ merge_context->registry = g_object_ref (registry);
+ merge_context->source_client = source_client;
+ merge_context->target_client = target_client;
+ merge_context->remaining_contacts = contact_list;
+ merge_context_next (merge_context);
+
+ return merge_context;
+}
+
+static void
+merge_context_free (MergeContext *merge_context)
+{
+ if (merge_context->registry != NULL)
+ g_object_unref (merge_context->registry);
+
+ if (merge_context->source_client != NULL)
+ g_object_unref (merge_context->source_client);
+
+ if (merge_context->target_client != NULL)
+ g_object_unref (merge_context->target_client);
+
+ g_slice_free (MergeContext, merge_context);
+}
+
+static void
+addressbook_selector_removed_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ MergeContext *merge_context = user_data;
+ GError *error = NULL;
+
+ e_book_client_remove_contact_finish (book_client, result, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to remove contact: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ merge_context->pending_removals--;
+
+ if (merge_context->pending_adds)
+ return;
+
+ if (merge_context->pending_removals > 0)
+ return;
+
+ merge_context_free (merge_context);
+}
+
+static void
+addressbook_selector_merge_next_cb (EBookClient *book_client,
+ const GError *error,
+ const gchar *id,
+ gpointer closure)
+{
+ MergeContext *merge_context = closure;
+
+ if (merge_context->remove_from_source && !error) {
+ /* Remove previous contact from source. */
+ e_book_client_remove_contact (
+ merge_context->source_client,
+ merge_context->current_contact, NULL,
+ addressbook_selector_removed_cb, merge_context);
+ merge_context->pending_removals++;
+ }
+
+ g_object_unref (merge_context->current_contact);
+
+ if (merge_context->remaining_contacts != NULL) {
+ merge_context_next (merge_context);
+ eab_merging_book_add_contact (
+ merge_context->registry,
+ merge_context->target_client,
+ merge_context->current_contact,
+ addressbook_selector_merge_next_cb, merge_context);
+
+ } else if (merge_context->pending_removals == 0) {
+ merge_context_free (merge_context);
+ } else
+ merge_context->pending_adds = FALSE;
+}
+
+static void
+addressbook_selector_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CURRENT_VIEW:
+ e_addressbook_selector_set_current_view (
+ E_ADDRESSBOOK_SELECTOR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+addressbook_selector_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CURRENT_VIEW:
+ g_value_set_object (
+ value,
+ e_addressbook_selector_get_current_view (
+ E_ADDRESSBOOK_SELECTOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+addressbook_selector_dispose (GObject *object)
+{
+ EAddressbookSelectorPrivate *priv;
+
+ priv = E_ADDRESSBOOK_SELECTOR_GET_PRIVATE (object);
+
+ if (priv->current_view != NULL) {
+ g_object_unref (priv->current_view);
+ priv->current_view = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_addressbook_selector_parent_class)->dispose (object);
+}
+
+static void
+addressbook_selector_constructed (GObject *object)
+{
+ ESourceSelector *selector;
+ ESourceRegistry *registry;
+ ESource *source;
+
+ selector = E_SOURCE_SELECTOR (object);
+ registry = e_source_selector_get_registry (selector);
+ source = e_source_registry_ref_default_address_book (registry);
+ e_source_selector_set_primary_selection (selector, source);
+ g_object_unref (source);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_addressbook_selector_parent_class)->
+ constructed (object);
+}
+
+static void
+target_client_connect_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ MergeContext *merge_context = user_data;
+ EClient *client;
+ GError *error = NULL;
+
+ g_return_if_fail (merge_context != NULL);
+
+ client = e_client_selector_get_client_finish (
+ E_CLIENT_SELECTOR (source_object), result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ if (error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ merge_context->target_client = client ? E_BOOK_CLIENT (client) : NULL;
+
+ if (!merge_context->target_client) {
+ g_slist_foreach (
+ merge_context->remaining_contacts,
+ (GFunc) g_object_unref, NULL);
+ g_slist_free (merge_context->remaining_contacts);
+
+ merge_context_free (merge_context);
+ return;
+ }
+
+ eab_merging_book_add_contact (
+ merge_context->registry,
+ merge_context->target_client,
+ merge_context->current_contact,
+ addressbook_selector_merge_next_cb, merge_context);
+}
+
+static gboolean
+addressbook_selector_data_dropped (ESourceSelector *selector,
+ GtkSelectionData *selection_data,
+ ESource *destination,
+ GdkDragAction action,
+ guint info)
+{
+ EAddressbookSelectorPrivate *priv;
+ MergeContext *merge_context;
+ EAddressbookModel *model;
+ EBookClient *source_client;
+ ESourceRegistry *registry;
+ GSList *list;
+ const gchar *string;
+ gboolean remove_from_source;
+
+ priv = E_ADDRESSBOOK_SELECTOR_GET_PRIVATE (selector);
+ g_return_val_if_fail (priv->current_view != NULL, FALSE);
+
+ string = (const gchar *) gtk_selection_data_get_data (selection_data);
+ remove_from_source = (action == GDK_ACTION_MOVE);
+
+ registry = e_source_selector_get_registry (selector);
+
+ eab_source_and_contact_list_from_string (
+ registry, string, NULL, &list);
+
+ if (list == NULL)
+ return FALSE;
+
+ model = e_addressbook_view_get_model (priv->current_view);
+ source_client = e_addressbook_model_get_client (model);
+ g_return_val_if_fail (E_IS_BOOK_CLIENT (source_client), FALSE);
+
+ merge_context = merge_context_new (
+ registry, g_object_ref (source_client), NULL, list);
+ merge_context->remove_from_source = remove_from_source;
+ merge_context->pending_adds = TRUE;
+
+ e_client_selector_get_client (
+ E_CLIENT_SELECTOR (selector), destination, NULL,
+ target_client_connect_cb, merge_context);
+
+ return TRUE;
+}
+
+static void
+e_addressbook_selector_class_init (EAddressbookSelectorClass *class)
+{
+ GObjectClass *object_class;
+ ESourceSelectorClass *selector_class;
+
+ g_type_class_add_private (class, sizeof (EAddressbookSelectorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = addressbook_selector_set_property;
+ object_class->get_property = addressbook_selector_get_property;
+ object_class->dispose = addressbook_selector_dispose;
+ object_class->constructed = addressbook_selector_constructed;
+
+ selector_class = E_SOURCE_SELECTOR_CLASS (class);
+ selector_class->data_dropped = addressbook_selector_data_dropped;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CURRENT_VIEW,
+ g_param_spec_object (
+ "current-view",
+ NULL,
+ NULL,
+ E_TYPE_ADDRESSBOOK_VIEW,
+ G_PARAM_READWRITE));
+}
+
+static void
+e_addressbook_selector_init (EAddressbookSelector *selector)
+{
+ selector->priv = E_ADDRESSBOOK_SELECTOR_GET_PRIVATE (selector);
+
+ e_source_selector_set_show_colors (
+ E_SOURCE_SELECTOR (selector), FALSE);
+
+ e_source_selector_set_show_toggles (
+ E_SOURCE_SELECTOR (selector), FALSE);
+
+ gtk_drag_dest_set (
+ GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL,
+ drag_types, G_N_ELEMENTS (drag_types),
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+
+ e_drag_dest_add_directory_targets (GTK_WIDGET (selector));
+}
+
+GtkWidget *
+e_addressbook_selector_new (EClientCache *client_cache)
+{
+ ESourceRegistry *registry;
+ GtkWidget *widget;
+
+ g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL);
+
+ registry = e_client_cache_ref_registry (client_cache);
+
+ widget = g_object_new (
+ E_TYPE_ADDRESSBOOK_SELECTOR,
+ "client-cache", client_cache,
+ "extension-name", E_SOURCE_EXTENSION_ADDRESS_BOOK,
+ "registry", registry, NULL);
+
+ g_object_unref (registry);
+
+ return widget;
+}
+
+EAddressbookView *
+e_addressbook_selector_get_current_view (EAddressbookSelector *selector)
+{
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_SELECTOR (selector), NULL);
+
+ return selector->priv->current_view;
+}
+
+void
+e_addressbook_selector_set_current_view (EAddressbookSelector *selector,
+ EAddressbookView *current_view)
+{
+ /* XXX This is only needed for moving contacts via drag-and-drop.
+ * The selection data doesn't include the source of the data
+ * (the model for the currently selected address book view),
+ * so we have to rely on it being provided to us. I would
+ * be happy to see this function go away. */
+
+ g_return_if_fail (E_IS_ADDRESSBOOK_SELECTOR (selector));
+
+ if (current_view != NULL)
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (current_view));
+
+ if (selector->priv->current_view == current_view)
+ return;
+
+ if (selector->priv->current_view != NULL) {
+ g_object_unref (selector->priv->current_view);
+ selector->priv->current_view = NULL;
+ }
+
+ if (current_view != NULL)
+ g_object_ref (current_view);
+
+ selector->priv->current_view = current_view;
+
+ g_object_notify (G_OBJECT (selector), "current-view");
+}
diff --git a/addressbook/gui/widgets/e-addressbook-selector.h b/addressbook/gui/widgets/e-addressbook-selector.h
new file mode 100644
index 0000000000..3746bc3aeb
--- /dev/null
+++ b/addressbook/gui/widgets/e-addressbook-selector.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-addressbook-selector.h
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef E_ADDRESSBOOK_SELECTOR_H
+#define E_ADDRESSBOOK_SELECTOR_H
+
+#include "e-addressbook-view.h"
+
+/* Standard GObject macros */
+#define E_TYPE_ADDRESSBOOK_SELECTOR \
+ (e_addressbook_selector_get_type ())
+#define E_ADDRESSBOOK_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ADDRESSBOOK_SELECTOR, EAddressbookSelector))
+#define E_ADDRESSBOOK_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ADDRESSBOOK_SELECTOR, EAddressbookSelectorClass))
+#define E_IS_ADDRESSBOOK_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ADDRESSBOOK_SELECTOR))
+#define E_IS_ADDRESSBOOK_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ADDRESSBOOK_SELECTOR))
+#define E_ADDRESSBOOK_SELECTOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ADDRESSBOOK_SELECTOR, EAddressbookSelectorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EAddressbookSelector EAddressbookSelector;
+typedef struct _EAddressbookSelectorClass EAddressbookSelectorClass;
+typedef struct _EAddressbookSelectorPrivate EAddressbookSelectorPrivate;
+
+struct _EAddressbookSelector {
+ EClientSelector parent;
+ EAddressbookSelectorPrivate *priv;
+};
+
+struct _EAddressbookSelectorClass {
+ EClientSelectorClass parent_class;
+};
+
+GType e_addressbook_selector_get_type (void);
+GtkWidget * e_addressbook_selector_new (EClientCache *client_cache);
+EAddressbookView *
+ e_addressbook_selector_get_current_view
+ (EAddressbookSelector *selector);
+void e_addressbook_selector_set_current_view
+ (EAddressbookSelector *selector,
+ EAddressbookView *current_view);
+
+G_END_DECLS
+
+#endif /* E_ADDRESSBOOK_SELECTOR_H */
diff --git a/addressbook/gui/widgets/e-addressbook-table-adapter.c b/addressbook/gui/widgets/e-addressbook-table-adapter.c
index abcaf6e6b0..a7f1f6bb5b 100644
--- a/addressbook/gui/widgets/e-addressbook-table-adapter.c
+++ b/addressbook/gui/widgets/e-addressbook-table-adapter.c
@@ -1,398 +1,434 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include <libebook/libebook.h>
+
#include "e-addressbook-model.h"
#include "e-addressbook-table-adapter.h"
-#include "e-card-merging.h"
-#include "e-addressbook-util.h"
-#include <gnome-xml/tree.h>
-#include <gnome-xml/parser.h>
-#include <gnome-xml/xmlmemory.h>
-#include <gnome.h>
+#include "eab-book-util.h"
+#include "eab-contact-merging.h"
+#include "eab-gui-util.h"
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xmlmemory.h>
+
+#define E_ADDRESSBOOK_TABLE_ADAPTER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER, EAddressbookTableAdapterPrivate))
struct _EAddressbookTableAdapterPrivate {
EAddressbookModel *model;
- ECardSimple **simples;
- int count;
+ gint create_contact_id, remove_contact_id, modify_contact_id, model_changed_id;
- int create_card_id, remove_card_id, modify_card_id, model_changed_id;
+ GHashTable *emails;
};
-#define PARENT_TYPE e_table_model_get_type()
-ETableModelClass *parent_class;
+/* Forward Declarations */
+static void e_addressbook_table_adapter_table_model_init
+ (ETableModelInterface *interface);
-#define COLS (E_CARD_SIMPLE_FIELD_LAST)
+G_DEFINE_TYPE_WITH_CODE (
+ EAddressbookTableAdapter,
+ e_addressbook_table_adapter,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_TABLE_MODEL,
+ e_addressbook_table_adapter_table_model_init))
static void
-unlink_model(EAddressbookTableAdapter *adapter)
+unlink_model (EAddressbookTableAdapter *adapter)
{
EAddressbookTableAdapterPrivate *priv = adapter->priv;
- int i;
-
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->create_card_id);
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->remove_card_id);
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->modify_card_id);
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->model_changed_id);
-
- priv->create_card_id = 0;
- priv->remove_card_id = 0;
- priv->modify_card_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 ++)
- gtk_object_unref (GTK_OBJECT (priv->simples[i]));
- g_free (priv->simples);
- priv->simples = NULL;
- }
+ g_signal_handler_disconnect (priv->model, priv->create_contact_id);
+ g_signal_handler_disconnect (priv->model, priv->remove_contact_id);
+ g_signal_handler_disconnect (priv->model, priv->modify_contact_id);
+ g_signal_handler_disconnect (priv->model, priv->model_changed_id);
+
+ priv->create_contact_id = 0;
+ priv->remove_contact_id = 0;
+ priv->modify_contact_id = 0;
+ priv->model_changed_id = 0;
- gtk_object_unref(GTK_OBJECT(priv->model));
+ g_object_unref (priv->model);
priv->model = NULL;
}
static void
-build_simple_mapping(EAddressbookTableAdapter *adapter)
+addressbook_finalize (GObject *object)
{
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
- int i;
+ EAddressbookTableAdapter *adapter;
- /* free up the existing mapping if there is one */
- if (priv->simples) {
- for (i = 0; i < priv->count; i ++)
- gtk_object_unref (GTK_OBJECT (priv->simples[i]));
- g_free (priv->simples);
- }
+ adapter = E_ADDRESSBOOK_TABLE_ADAPTER (object);
- /* 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));
- gtk_object_ref (GTK_OBJECT (priv->simples[i]));
- }
-}
-
-static void
-addressbook_destroy(GtkObject *object)
-{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(object);
+ unlink_model (adapter);
- unlink_model(adapter);
+ g_hash_table_destroy (adapter->priv->emails);
- g_free (adapter->priv);
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_addressbook_table_adapter_parent_class)->finalize (object);
}
/* This function returns the number of columns in our ETableModel. */
-static int
+static gint
addressbook_col_count (ETableModel *etc)
{
- return COLS;
+ return E_CONTACT_FIELD_LAST;
}
/* This function returns the number of rows in our ETableModel. */
-static int
+static gint
addressbook_row_count (ETableModel *etc)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc);
+ EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER (etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
- return e_addressbook_model_card_count (priv->model);
+ return e_addressbook_model_contact_count (priv->model);
+}
+
+static void
+addressbook_append_row (ETableModel *etm,
+ ETableModel *source,
+ gint row)
+{
+ EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER (etm);
+ EAddressbookTableAdapterPrivate *priv = adapter->priv;
+ EClientCache *client_cache;
+ ESourceRegistry *registry;
+ EBookClient *book_client;
+ EContact *contact;
+ gint col;
+
+ contact = e_contact_new ();
+
+ for (col = 1; col < E_CONTACT_LAST_SIMPLE_STRING; col++) {
+ gconstpointer val = e_table_model_value_at (source, col, row);
+ e_contact_set (contact, col, (gpointer) val);
+ }
+
+ client_cache =
+ e_addressbook_model_get_client_cache (priv->model);
+ book_client = e_addressbook_model_get_client (priv->model);
+
+ registry = e_client_cache_ref_registry (client_cache);
+
+ eab_merging_book_add_contact (
+ registry, book_client, contact, NULL, NULL);
+
+ g_object_unref (registry);
+
+ g_object_unref (contact);
}
/* This function returns the value at a particular point in our ETableModel. */
-static void *
-addressbook_value_at (ETableModel *etc, int col, int row)
+static gpointer
+addressbook_value_at (ETableModel *etc,
+ gint col,
+ gint row)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc);
+ EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER (etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
- const char *value;
+ EContact *contact;
+ const gchar *value;
- if ( col >= COLS || row >= e_addressbook_model_card_count (priv->model) )
+ if (col >= E_CONTACT_FIELD_LAST)
return NULL;
- value = e_card_simple_get_const(priv->simples[row], col);
+ if (row >= e_addressbook_model_contact_count (priv->model))
+ return NULL;
+
+ contact = e_addressbook_model_contact_at (priv->model, row);
+ value = e_contact_get_const (contact, col);
+
+ if (value && *value && (col == E_CONTACT_EMAIL_1 ||
+ col == E_CONTACT_EMAIL_2 || col == E_CONTACT_EMAIL_3)) {
+ gchar *val = g_hash_table_lookup (priv->emails, value);
+
+ if (val) {
+ /* we have this already cached, so use value from the cache */
+ value = val;
+ } else {
+ gchar *name = NULL, *mail = NULL;
+
+ if (eab_parse_qp_email (value, &name, &mail))
+ val = g_strdup_printf ("%s <%s>", name, mail);
+ else
+ val = g_strdup (value);
- if (value && !strncmp (value, "<?xml", 5)) {
- EDestination *dest = e_destination_import (value);
- if (dest) {
- g_free ((gchar *) value);
- value = g_strdup (e_destination_get_address (dest));
- gtk_object_unref (GTK_OBJECT (dest));
+ g_free (name);
+ g_free (mail);
+
+ g_hash_table_insert (priv->emails, g_strdup (value), val);
+ value = val;
}
}
-
- return (void *)(value ? value : "");
+ return (gpointer)(value ? value : "");
}
/* This function sets the value at a particular point in our ETableModel. */
static void
-card_modified_cb (EBook* book, EBookStatus status,
- gpointer user_data)
+contact_modified_cb (EBookClient *book_client,
+ const GError *error,
+ gpointer user_data)
{
- /* g_print ("%s: %s(): a card was modified\n", __FILE__, __FUNCTION__); */
- if (status != E_BOOK_STATUS_SUCCESS)
- e_addressbook_error_dialog (_("Error modifying card"), status);
+ if (error)
+ eab_error_dialog (NULL, NULL, _("Error modifying card"), error);
}
+
static void
-addressbook_set_value_at (ETableModel *etc, int col, int row, const void *val)
+addressbook_set_value_at (ETableModel *etc,
+ gint col,
+ gint row,
+ gconstpointer val)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc);
+ EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER (etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
- if (e_addressbook_model_editable (priv->model)) {
- ECard *card;
- if ( col >= COLS|| row >= e_addressbook_model_card_count (priv->model) )
+ if (e_addressbook_model_get_editable (priv->model)) {
+ EClientCache *client_cache;
+ ESourceRegistry *registry;
+ EBookClient *book_client;
+ EContact *contact;
+
+ if (col >= E_CONTACT_FIELD_LAST)
return;
- e_table_model_pre_change(etc);
+ if (row >= e_addressbook_model_contact_count (priv->model))
+ return;
- e_card_simple_set(priv->simples[row],
- col,
- val);
- gtk_object_get(GTK_OBJECT(priv->simples[row]),
- "card", &card,
- NULL);
+ contact = e_addressbook_model_get_contact (priv->model, row);
+ if (!contact)
+ return;
- e_card_merging_book_commit_card(e_addressbook_model_get_ebook(priv->model),
- card, card_modified_cb, NULL);
+ e_table_model_pre_change (etc);
- /* XXX do we need this? shouldn't the commit_card generate a changed signal? */
- e_table_model_cell_changed(etc, col, row);
- }
-}
+ if (col == E_CONTACT_EMAIL_1 ||
+ col == E_CONTACT_EMAIL_2 ||
+ col == E_CONTACT_EMAIL_3) {
+ const gchar *old_value = e_contact_get_const (contact, col);
-/* 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);
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
- ECard *card;
+ /* remove old value from cache and use new one */
+ if (old_value && *old_value)
+ g_hash_table_remove (priv->emails, old_value);
+ }
- if (row >= 0 && row < e_addressbook_model_card_count (priv->model))
- card = e_addressbook_model_card_at (priv->model, row);
- else
- card = NULL;
-
- if (!e_addressbook_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
- lists */
- 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;
-}
+ client_cache =
+ e_addressbook_model_get_client_cache (priv->model);
+ book_client = e_addressbook_model_get_client (priv->model);
-static void
-addressbook_append_row (ETableModel *etm, ETableModel *source, gint row)
-{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etm);
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
- ECard *card;
- ECardSimple *simple;
- int col;
+ registry = e_client_cache_ref_registry (client_cache);
+
+ e_contact_set (contact, col, (gpointer) val);
+ eab_merging_book_modify_contact (
+ registry, book_client,
+ contact, contact_modified_cb, etc);
- card = e_card_new("");
- simple = e_card_simple_new(card);
+ g_object_unref (registry);
- for (col = 0; col < E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING; col++) {
- const void *val = e_table_model_value_at(source, col, row);
- e_card_simple_set(simple, col, val);
+ g_object_unref (contact);
+
+ /* XXX Do we need this? Shouldn't the commit_contact
+ * generate a changed signal? */
+ e_table_model_cell_changed (etc, col, row);
}
- e_card_simple_sync_card(simple);
- e_card_merging_book_add_card (e_addressbook_model_get_ebook (priv->model), card, NULL, NULL);
- gtk_object_unref(GTK_OBJECT(simple));
- gtk_object_unref(GTK_OBJECT(card));
+}
+
+/* This function returns whether a particular cell is editable. */
+static gboolean
+addressbook_is_cell_editable (ETableModel *etc,
+ gint col,
+ gint row)
+{
+ return FALSE;
}
/* This function duplicates the value passed to it. */
-static void *
-addressbook_duplicate_value (ETableModel *etc, int col, const void *value)
+static gpointer
+addressbook_duplicate_value (ETableModel *etc,
+ gint col,
+ gconstpointer value)
{
- return g_strdup(value);
+ return g_strdup (value);
}
/* This function frees the value passed to it. */
static void
-addressbook_free_value (ETableModel *etc, int col, void *value)
+addressbook_free_value (ETableModel *etc,
+ gint col,
+ gpointer value)
{
- g_free(value);
+ g_free (value);
}
-static void *
-addressbook_initialize_value (ETableModel *etc, int col)
+static gpointer
+addressbook_initialize_value (ETableModel *etc,
+ gint col)
{
- return g_strdup("");
+ return g_strdup ("");
}
static gboolean
-addressbook_value_is_empty (ETableModel *etc, int col, const void *value)
+addressbook_value_is_empty (ETableModel *etc,
+ gint col,
+ gconstpointer value)
{
- return !(value && *(char *)value);
+ return !(value && *(gchar *) value);
}
-static char *
-addressbook_value_to_string (ETableModel *etc, int col, const void *value)
+static gchar *
+addressbook_value_to_string (ETableModel *etc,
+ gint col,
+ gconstpointer value)
{
- return g_strdup(value);
+ return g_strdup (value);
}
static void
-e_addressbook_table_adapter_class_init (GtkObjectClass *object_class)
+e_addressbook_table_adapter_class_init (EAddressbookTableAdapterClass *class)
{
- ETableModelClass *model_class = (ETableModelClass *) object_class;
-
- parent_class = gtk_type_class (PARENT_TYPE);
-
- object_class->destroy = addressbook_destroy;
-
- model_class->column_count = addressbook_col_count;
- model_class->row_count = addressbook_row_count;
- model_class->value_at = addressbook_value_at;
- model_class->set_value_at = addressbook_set_value_at;
- model_class->is_cell_editable = addressbook_is_cell_editable;
- model_class->append_row = addressbook_append_row;
- model_class->duplicate_value = addressbook_duplicate_value;
- model_class->free_value = addressbook_free_value;
- model_class->initialize_value = addressbook_initialize_value;
- model_class->value_is_empty = addressbook_value_is_empty;
- model_class->value_to_string = addressbook_value_to_string;
+ GObjectClass *object_class;
+
+ g_type_class_add_private (
+ class, sizeof (EAddressbookTableAdapterPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = addressbook_finalize;
}
static void
-e_addressbook_table_adapter_init (GtkObject *object)
+e_addressbook_table_adapter_table_model_init (ETableModelInterface *interface)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_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->model_changed_id = 0;
- priv->simples = NULL;
- priv->count = 0;
+ interface->column_count = addressbook_col_count;
+ interface->row_count = addressbook_row_count;
+ interface->append_row = addressbook_append_row;
+
+ interface->value_at = addressbook_value_at;
+ interface->set_value_at = addressbook_set_value_at;
+ interface->is_cell_editable = addressbook_is_cell_editable;
+
+ interface->duplicate_value = addressbook_duplicate_value;
+ interface->free_value = addressbook_free_value;
+ interface->initialize_value = addressbook_initialize_value;
+ interface->value_is_empty = addressbook_value_is_empty;
+ interface->value_to_string = addressbook_value_to_string;
}
-
static void
-create_card (EAddressbookModel *model,
- gint index, gint count,
- EAddressbookTableAdapter *adapter)
+e_addressbook_table_adapter_init (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 *));
+ adapter->priv = E_ADDRESSBOOK_TABLE_ADAPTER_GET_PRIVATE (adapter);
+}
+static void
+create_contact (EAddressbookModel *model,
+ gint index,
+ gint count,
+ EAddressbookTableAdapter *adapter)
+{
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_contacts (EAddressbookModel *model,
+ gpointer data,
+ EAddressbookTableAdapter *adapter)
{
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
+ GArray *indices = (GArray *) data;
+ gint count = indices->len;
- e_table_model_pre_change (E_TABLE_MODEL (adapter));
+ /* clear whole cache */
+ g_hash_table_remove_all (adapter->priv->emails);
- gtk_object_unref (GTK_OBJECT (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);
+ e_table_model_pre_change (E_TABLE_MODEL (adapter));
+ if (count == 1)
+ e_table_model_rows_deleted (
+ E_TABLE_MODEL (adapter),
+ g_array_index (indices, gint, 0), 1);
+ else
+ e_table_model_changed (E_TABLE_MODEL (adapter));
}
static void
-modify_card (EAddressbookModel *model,
- gint index,
- EAddressbookTableAdapter *adapter)
+modify_contact (EAddressbookModel *model,
+ gint index,
+ EAddressbookTableAdapter *adapter)
{
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
+ /* clear whole cache */
+ g_hash_table_remove_all (adapter->priv->emails);
e_table_model_pre_change (E_TABLE_MODEL (adapter));
-
- gtk_object_unref (GTK_OBJECT (priv->simples[index]));
- priv->simples[index] = e_card_simple_new (e_addressbook_model_card_at (priv->model, index));
- gtk_object_ref (GTK_OBJECT (priv->simples[index]));
e_table_model_row_changed (E_TABLE_MODEL (adapter), index);
}
static void
model_changed (EAddressbookModel *model,
- EAddressbookTableAdapter *adapter)
+ EAddressbookTableAdapter *adapter)
{
+ /* clear whole cache */
+ g_hash_table_remove_all (adapter->priv->emails);
+
e_table_model_pre_change (E_TABLE_MODEL (adapter));
- build_simple_mapping (adapter);
e_table_model_changed (E_TABLE_MODEL (adapter));
}
-GtkType
-e_addressbook_table_adapter_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type){
- GtkTypeInfo info = {
- "EAddressbookTableAdapter",
- sizeof (EAddressbookTableAdapter),
- sizeof (EAddressbookTableAdapterClass),
- (GtkClassInitFunc) e_addressbook_table_adapter_class_init,
- (GtkObjectInitFunc) e_addressbook_table_adapter_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
-
- return type;
-}
-
void
e_addressbook_table_adapter_construct (EAddressbookTableAdapter *adapter,
- EAddressbookModel *model)
+ EAddressbookModel *model)
{
EAddressbookTableAdapterPrivate *priv = adapter->priv;
priv->model = model;
- gtk_object_ref (GTK_OBJECT (priv->model));
-
- priv->create_card_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "card_added",
- GTK_SIGNAL_FUNC(create_card),
- adapter);
- priv->remove_card_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "card_removed",
- GTK_SIGNAL_FUNC(remove_card),
- adapter);
- priv->modify_card_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "card_changed",
- GTK_SIGNAL_FUNC(modify_card),
- adapter);
- priv->model_changed_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "model_changed",
- GTK_SIGNAL_FUNC(model_changed),
- adapter);
-
- build_simple_mapping (adapter);
+ g_object_ref (priv->model);
+
+ 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, "contacts_removed",
+ G_CALLBACK (remove_contacts), 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);
+
+ priv->emails = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_free);
}
ETableModel *
@@ -400,9 +436,9 @@ e_addressbook_table_adapter_new (EAddressbookModel *model)
{
EAddressbookTableAdapter *et;
- et = gtk_type_new (e_addressbook_table_adapter_get_type ());
+ et = g_object_new (E_TYPE_ADDRESSBOOK_TABLE_ADAPTER, NULL);
e_addressbook_table_adapter_construct (et, model);
- return E_TABLE_MODEL(et);
+ 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 d76434e80a..93b7ae9553 100644
--- a/addressbook/gui/widgets/e-addressbook-table-adapter.h
+++ b/addressbook/gui/widgets/e-addressbook-table-adapter.h
@@ -1,44 +1,70 @@
-/* -*- 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_
-
-#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_ADDRESSBOOK_TABLE_ADAPTER_TYPE (e_addressbook_table_adapter_get_type ())
-#define E_ADDRESSBOOK_TABLE_ADAPTER(o) (GTK_CHECK_CAST ((o), E_ADDRESSBOOK_TABLE_ADAPTER_TYPE, EAddressbookTableAdapter))
-#define E_ADDRESSBOOK_TABLE_ADAPTER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_ADDRESSBOOK_TABLE_ADAPTER_TYPE, EAddressbookTableAdapterClass))
-#define E_IS_ADDRESSBOOK_TABLE_ADAPTER(o) (GTK_CHECK_TYPE ((o), E_ADDRESSBOOK_TABLE_ADAPTER_TYPE))
-#define E_IS_ADDRESSBOOK_TABLE_ADAPTER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_ADDRESSBOOK_TABLE_ADAPTER_TYPE))
-
-/* Virtual Column list:
- 0 Email
- 1 Full Name
- 2 Street
- 3 Phone
-*/
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef _EAB_TABLE_ADAPTER_H_
+#define _EAB_TABLE_ADAPTER_H_
+
+#include <e-util/e-util.h>
+
+/* Standard GObject macros */
+#define E_TYPE_ADDRESSBOOK_TABLE_ADAPTER \
+ (e_addressbook_table_adapter_get_type ())
+#define E_ADDRESSBOOK_TABLE_ADAPTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER, EAddressbookTableAdapter))
+#define E_ADDRESSBOOK_TABLE_ADAPTER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER, EAddressbookTableAdapterClass))
+#define E_IS_ADDRESSBOOK_TABLE_ADAPTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER))
+#define E_IS_ADDRESSBOOK_TABLE_ADAPTER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER))
+#define E_ADDRESSBOOK_TABLE_ADAPTER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER, EAddressbookTableAdapterClass))
+
+G_BEGIN_DECLS
typedef struct _EAddressbookTableAdapter EAddressbookTableAdapter;
-typedef struct _EAddressbookTableAdapterPrivate EAddressbookTableAdapterPrivate;
typedef struct _EAddressbookTableAdapterClass EAddressbookTableAdapterClass;
+typedef struct _EAddressbookTableAdapterPrivate EAddressbookTableAdapterPrivate;
struct _EAddressbookTableAdapter {
- ETableModel parent;
-
+ GObject parent;
EAddressbookTableAdapterPrivate *priv;
};
-
struct _EAddressbookTableAdapterClass {
- ETableModelClass parent_class;
+ GObjectClass parent_class;
};
+GType e_addressbook_table_adapter_get_type
+ (void) G_GNUC_CONST;
+void e_addressbook_table_adapter_construct
+ (EAddressbookTableAdapter *adapter,
+ EAddressbookModel *model);
+ETableModel * e_addressbook_table_adapter_new
+ (EAddressbookModel *model);
-GtkType 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);
+G_END_DECLS
-#endif /* _E_ADDRESSBOOK_TABLE_ADAPTER_H_ */
+#endif /* _EAB_TABLE_ADAPTER_H_ */
diff --git a/addressbook/gui/widgets/e-addressbook-util.c b/addressbook/gui/widgets/e-addressbook-util.c
deleted file mode 100644
index 04f4238fbd..0000000000
--- a/addressbook/gui/widgets/e-addressbook-util.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-table-field-chooser.c
- * 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.
- */
-
-#include <config.h>
-#include "e-addressbook-util.h"
-
-#include <gnome.h>
-
-#include "e-card-merging.h"
-#include <shell/evolution-shell-client.h>
-#include <addressbook/backend/ebook/e-book-util.h>
-
-void
-e_addressbook_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_("Protocol not supported"),
- N_("Cancelled"),
- N_("Authentication Failed"),
- N_("Authentication Required"),
- N_("TLS not Available"),
- N_("Addressbook does not exist"),
- N_("Other error")
- };
- char *error_msg;
-
- error_msg = g_strdup_printf ("%s: %s", msg, _(status_to_string [status]));
-
- gtk_widget_show (gnome_error_dialog (error_msg));
-
- g_free (error_msg);
-}
-
-gint
-e_addressbook_prompt_save_dialog (GtkWindow *parent)
-{
- GtkWidget *dialog;
-
- dialog = gnome_message_box_new (_("Do you want to save changes?"),
- GNOME_MESSAGE_BOX_QUESTION,
- GNOME_STOCK_BUTTON_YES,
- GNOME_STOCK_BUTTON_NO,
- GNOME_STOCK_BUTTON_CANCEL,
- NULL);
-
- gnome_dialog_set_default (GNOME_DIALOG (dialog), 0);
- gnome_dialog_grab_focus (GNOME_DIALOG (dialog), 0);
- gnome_dialog_set_parent (GNOME_DIALOG (dialog), parent);
-
- return gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
-}
-
-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);
- }
-}
-
-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);
- }
-}
-
-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);
- }
-}
-
-static void
-editor_closed_cb (GtkObject *editor, gpointer data)
-{
- gtk_object_unref (editor);
-}
-
-EContactEditor *
-e_addressbook_show_contact_editor (EBook *book, ECard *card,
- gboolean is_new_card,
- gboolean editable)
-{
- EContactEditor *ce;
-
- ce = e_contact_editor_new (book, card, is_new_card, editable);
-
- gtk_signal_connect (GTK_OBJECT (ce), "card_added",
- GTK_SIGNAL_FUNC (added_cb), GINT_TO_POINTER (FALSE));
- gtk_signal_connect (GTK_OBJECT (ce), "card_modified",
- GTK_SIGNAL_FUNC (modified_cb), GINT_TO_POINTER (FALSE));
- gtk_signal_connect (GTK_OBJECT (ce), "card_deleted",
- GTK_SIGNAL_FUNC (deleted_cb), GINT_TO_POINTER (FALSE));
- gtk_signal_connect (GTK_OBJECT (ce), "editor_closed",
- GTK_SIGNAL_FUNC (editor_closed_cb), NULL);
-
- return ce;
-}
-
-EContactListEditor *
-e_addressbook_show_contact_list_editor (EBook *book, ECard *card,
- gboolean is_new_card,
- gboolean editable)
-{
- EContactListEditor *ce;
-
- ce = e_contact_list_editor_new (book, card, is_new_card, editable);
-
- gtk_signal_connect (GTK_OBJECT (ce), "list_added",
- GTK_SIGNAL_FUNC (added_cb), GINT_TO_POINTER (TRUE));
- gtk_signal_connect (GTK_OBJECT (ce), "list_modified",
- GTK_SIGNAL_FUNC (modified_cb), GINT_TO_POINTER (TRUE));
- gtk_signal_connect (GTK_OBJECT (ce), "list_deleted",
- GTK_SIGNAL_FUNC (deleted_cb), GINT_TO_POINTER (TRUE));
- gtk_signal_connect (GTK_OBJECT (ce), "editor_closed",
- GTK_SIGNAL_FUNC (editor_closed_cb), GINT_TO_POINTER (TRUE));
-
- e_contact_list_editor_show (ce);
-
- return ce;
-}
-
-typedef struct {
- EBook *book;
- GList *list;
- gboolean editable;
-} BookAndList;
-
-static void
-view_cards (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);
- else
- e_addressbook_show_contact_editor (book, card, FALSE, editable);
- }
-}
-
-static void
-view_question_clicked (GtkObject *object, int button, BookAndList *bnl)
-{
- GnomeDialog *dialog = GNOME_DIALOG (object);
- switch (button) {
- case 0:
- view_cards (bnl->book, bnl->list, bnl->editable);
- break;
- }
- gnome_dialog_close(dialog);
-}
-
-static void
-view_question_destroyed (GtkObject *object, GList *list)
-{
- gtk_main_quit();
-}
-
-void
-e_addressbook_show_multiple_cards (EBook *book,
- GList *list,
- gboolean editable)
-{
- if (list) {
- int length = g_list_length (list);
- if (length > 5) {
- char *string;
- GtkWidget *dialog;
- BookAndList bnl;
-
- bnl.book = book;
- bnl.list = list;
- bnl.editable = editable;
-
- dialog = gnome_dialog_new (_("Display Cards?"),
- _("Display Cards"),
- GNOME_STOCK_BUTTON_CANCEL,
- NULL);
-
- string = g_strdup_printf (_("Opening %d cards will open %d new windows as well.\n"
- "Do you really want to display all of these cards?"), length, length);
- gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), gtk_label_new (string), FALSE, FALSE, 0);
- g_free (string);
-
- gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
- GTK_SIGNAL_FUNC (view_question_destroyed), &bnl);
- gtk_signal_connect (GTK_OBJECT (dialog), "clicked",
- GTK_SIGNAL_FUNC (view_question_clicked), &bnl);
-
- gtk_widget_show_all (dialog);
-
- gtk_main();
- } else {
- view_cards (book, list, editable);
- }
- }
-}
-
-
-
-typedef struct CardCopyProcess_ CardCopyProcess;
-
-typedef void (*CardCopyDone) (CardCopyProcess *process);
-
-struct CardCopyProcess_ {
- int count;
- GList *cards;
- EBook *source;
- EBook *destination;
- CardCopyDone done_cb;
-};
-
-static void
-card_deleted_cb (EBook* book, EBookStatus status, gpointer user_data)
-{
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (_("Error removing card"), status);
- }
-}
-
-static void
-do_delete (gpointer data, gpointer user_data)
-{
- EBook *book = user_data;
- ECard *card = data;
-
- e_book_remove_card(book, card, card_deleted_cb, NULL);
-}
-
-static void
-delete_cards (CardCopyProcess *process)
-{
- g_list_foreach (process->cards,
- do_delete,
- process->source);
-}
-
-static void
-process_unref (CardCopyProcess *process)
-{
- process->count --;
- if (process->count == 0) {
- if (process->done_cb) {
- process->done_cb (process);
- }
- e_free_object_list(process->cards);
- gtk_object_unref (GTK_OBJECT (process->source));
- gtk_object_unref (GTK_OBJECT (process->destination));
- g_free (process);
- }
-}
-
-static void
-card_added_cb (EBook* book, EBookStatus status, const char *id, gpointer user_data)
-{
- CardCopyProcess *process = user_data;
-
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (_("Error adding card"), status);
- } else {
- process_unref (process);
- }
-}
-
-static void
-do_copy (gpointer data, gpointer user_data)
-{
- EBook *book;
- ECard *card;
- CardCopyProcess *process;
-
- process = user_data;
- card = data;
-
- book = process->destination;
-
- process->count ++;
- e_book_add_card(book, card, card_added_cb, process);
-}
-
-static void
-got_book_cb (EBook *book, gpointer closure)
-{
- CardCopyProcess *process;
- process = closure;
- if (book) {
- process->destination = book;
- gtk_object_ref (GTK_OBJECT (book));
- g_list_foreach (process->cards,
- 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)
-{
- const char *allowed_types[] = { "contacts/*", NULL };
- GNOME_Evolution_Folder *folder;
- static char *last_uri = NULL;
- CardCopyProcess *process;
- char *desc;
-
- if (cards == NULL)
- return;
-
- if (last_uri == NULL)
- last_uri = g_strdup ("");
-
- if (cards->next == NULL) {
- if (delete_from_source)
- desc = _("Move card to");
- else
- desc = _("Copy card to");
- } else {
- if (delete_from_source)
- desc = _("Move cards to");
- else
- desc = _("Copy cards to");
- }
-
- evolution_shell_client_user_select_folder (global_shell_client,
- parent_window,
- desc, last_uri, allowed_types,
- &folder);
- if (!folder)
- return;
-
- if (strcmp (last_uri, folder->evolutionUri) != 0) {
- g_free (last_uri);
- last_uri = g_strdup (folder->evolutionUri);
- }
-
- process = g_new (CardCopyProcess, 1);
- process->count = 1;
- process->source = source;
- gtk_object_ref (GTK_OBJECT (source));
- process->cards = cards;
- process->destination = NULL;
-
- if (delete_from_source)
- process->done_cb = delete_cards;
- else
- process->done_cb = NULL;
-
- e_book_use_address_book_by_uri (folder->physicalUri, got_book_cb, process);
-
- CORBA_free (folder);
-}
diff --git a/addressbook/gui/widgets/e-addressbook-util.h b/addressbook/gui/widgets/e-addressbook-util.h
deleted file mode 100644
index f0681cea4d..0000000000
--- a/addressbook/gui/widgets/e-addressbook-util.h
+++ /dev/null
@@ -1,55 +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);
-
-#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 f9669a20ac..38d7196217 100644
--- a/addressbook/gui/widgets/e-addressbook-view.c
+++ b/addressbook/gui/widgets/e-addressbook-view.c
@@ -1,1977 +1,1695 @@
-/* -*- 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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
-#include <gtk/gtkinvisible.h>
-
-#include <libgnome/gnome-paper.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnome/gnome-util.h>
-#include <gal/e-table/e-table-scrolled.h>
-#include <gal/e-table/e-table-model.h>
-#include <gal/widgets/e-scroll-frame.h>
-#include <gal/widgets/e-popup-menu.h>
-#include <gal/widgets/e-gui-utils.h>
-#include <gal/widgets/e-unicode.h>
-#include <gal/menus/gal-view-factory-etable.h>
-#include <gal/menus/gal-view-etable.h>
-#include <gal/util/e-unicode-i18n.h>
-#include <gal/util/e-xml-utils.h>
-#include <gal/unicode/gunicode.h>
-#include <libgnomeui/gnome-dialog-util.h>
-#include <libgnomeui/gnome-stock.h>
-
-#include <libgnomeprint/gnome-print.h>
-#include <libgnomeprint/gnome-print-dialog.h>
-#include <libgnomeprint/gnome-print-master.h>
-#include <libgnomeprint/gnome-print-master-preview.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "e-addressbook-view.h"
+
+#include "e-util/e-util.h"
+#include "shell/e-shell-sidebar.h"
#include "addressbook/printing/e-contact-print.h"
-#include "addressbook/printing/e-contact-print-envelope.h"
+#include "ea-addressbook.h"
-#include "gal-view-factory-minicard.h"
#include "gal-view-minicard.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"
-#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>
-#include <ctype.h>
+#define E_ADDRESSBOOK_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookViewPrivate))
-#include <gnome-xml/tree.h>
-#include <gnome-xml/parser.h>
+#define d(x)
-#define SHOW_ALL_SEARCH "(contains \"x-evolution-any-field\" \"\")"
+static void status_message (EAddressbookView *view,
+ const gchar *status, gint percent);
+static void search_result (EAddressbookView *view,
+ const GError *error);
+static void folder_bar_message (EAddressbookView *view,
+ const gchar *status);
+static void stop_state_changed (GObject *object,
+ EAddressbookView *view);
+static void command_state_change (EAddressbookView *view);
-#define d(x)
+struct _EAddressbookViewPrivate {
+ gpointer shell_view; /* weak pointer */
+
+ EAddressbookModel *model;
+ EActivity *activity;
+
+ ESource *source;
+
+ GObject *object;
+
+ GalViewInstance *view_instance;
+
+ /* stored search setup for this view */
+ gint filter_id;
+ gchar *search_text;
+ gint search_id;
+ EFilterRule *advanced_search;
+
+ GtkTargetList *copy_target_list;
+ GtkTargetList *paste_target_list;
+};
-static void e_addressbook_view_init (EAddressbookView *card);
-static void e_addressbook_view_class_init (EAddressbookViewClass *klass);
-static void e_addressbook_view_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_addressbook_view_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_addressbook_view_destroy (GtkObject *object);
-static void change_view_type (EAddressbookView *view, EAddressbookViewType 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 selection_clear_event (GtkWidget *invisible, GdkEventSelection *event,
- EAddressbookView *view);
-static void selection_received (GtkWidget *invisible, GtkSelectionData *selection_data,
- guint time, EAddressbookView *view);
-static void selection_get (GtkWidget *invisible, GtkSelectionData *selection_data,
- guint info, guint time_stamp, EAddressbookView *view);
-static void invisible_destroyed (GtkWidget *invisible, EAddressbookView *view);
-
-static GtkTableClass *parent_class = NULL;
-
-/* The arguments we take */
enum {
- ARG_0,
- ARG_BOOK,
- ARG_QUERY,
- ARG_TYPE,
+ PROP_0,
+ PROP_COPY_TARGET_LIST,
+ PROP_MODEL,
+ PROP_PASTE_TARGET_LIST,
+ PROP_SHELL_VIEW,
+ PROP_SOURCE
};
enum {
- STATUS_MESSAGE,
- SEARCH_RESULT,
- FOLDER_BAR_MESSAGE,
+ OPEN_CONTACT,
+ POPUP_EVENT,
COMMAND_STATE_CHANGE,
- ALPHABET_STATE_CHANGE,
+ SELECTION_CHANGE,
LAST_SIGNAL
};
-enum DndTargetType {
- DND_TARGET_TYPE_VCARD,
+enum {
+ DND_TARGET_TYPE_SOURCE_VCARD,
+ DND_TARGET_TYPE_VCARD
};
-#define VCARD_TYPE "text/x-vcard"
+
static GtkTargetEntry drag_types[] = {
- { VCARD_TYPE, 0, DND_TARGET_TYPE_VCARD },
+ { (gchar *) "text/x-source-vcard", 0, DND_TARGET_TYPE_SOURCE_VCARD },
+ { (gchar *) "text/x-vcard", 0, DND_TARGET_TYPE_VCARD }
};
-static const int num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]);
-static guint e_addressbook_view_signals [LAST_SIGNAL] = {0, };
+static guint signals[LAST_SIGNAL];
-static GdkAtom clipboard_atom = GDK_NONE;
+/* Forward Declarations */
+static void e_addressbook_view_selectable_init
+ (ESelectableInterface *interface);
-static GalViewCollection *collection = NULL;
+G_DEFINE_TYPE_WITH_CODE (
+ EAddressbookView,
+ e_addressbook_view,
+ GTK_TYPE_SCROLLED_WINDOW,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_SELECTABLE,
+ e_addressbook_view_selectable_init))
-GtkType
-e_addressbook_view_get_type (void)
+static void
+addressbook_view_emit_open_contact (EAddressbookView *view,
+ EContact *contact,
+ gboolean is_new_contact)
{
- static GtkType type = 0;
-
- if (!type) {
- static const GtkTypeInfo info =
- {
- "EAddressbookView",
- sizeof (EAddressbookView),
- sizeof (EAddressbookViewClass),
- (GtkClassInitFunc) e_addressbook_view_class_init,
- (GtkObjectInitFunc) e_addressbook_view_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- type = gtk_type_unique (gtk_table_get_type (), &info);
- }
-
- return type;
+ g_signal_emit (view, signals[OPEN_CONTACT], 0, contact, is_new_contact);
}
static void
-e_addressbook_view_class_init (EAddressbookViewClass *klass)
+addressbook_view_emit_popup_event (EAddressbookView *view,
+ GdkEvent *event)
{
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
-
- object_class = GTK_OBJECT_CLASS(klass);
- widget_class = GTK_WIDGET_CLASS(klass);
-
- parent_class = gtk_type_class (gtk_table_get_type ());
-
- object_class->set_arg = e_addressbook_view_set_arg;
- object_class->get_arg = e_addressbook_view_get_arg;
- object_class->destroy = e_addressbook_view_destroy;
-
- gtk_object_add_arg_type ("EAddressbookView::book", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_BOOK);
- gtk_object_add_arg_type ("EAddressbookView::query", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_QUERY);
- gtk_object_add_arg_type ("EAddressbookView::type", GTK_TYPE_ENUM,
- GTK_ARG_READWRITE, ARG_TYPE);
-
- e_addressbook_view_signals [STATUS_MESSAGE] =
- gtk_signal_new ("status_message",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookViewClass, status_message),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
-
- e_addressbook_view_signals [SEARCH_RESULT] =
- gtk_signal_new ("search_result",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookViewClass, search_result),
- gtk_marshal_NONE__ENUM,
- GTK_TYPE_NONE, 1, GTK_TYPE_ENUM);
-
- e_addressbook_view_signals [FOLDER_BAR_MESSAGE] =
- gtk_signal_new ("folder_bar_message",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookViewClass, folder_bar_message),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
-
- e_addressbook_view_signals [COMMAND_STATE_CHANGE] =
- gtk_signal_new ("command_state_change",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookViewClass, command_state_change),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- e_addressbook_view_signals [ALPHABET_STATE_CHANGE] =
- gtk_signal_new ("alphabet_state_change",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookViewClass, alphabet_state_change),
- gtk_marshal_NONE__UINT,
- GTK_TYPE_NONE, 1, GTK_TYPE_UINT);
-
- gtk_object_class_add_signals (object_class, e_addressbook_view_signals, LAST_SIGNAL);
-
- if (!clipboard_atom)
- clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
+ /* Grab focus so that EFocusTracker asks us to update the
+ * selection-related actions before showing the popup menu.
+ * Apparently ETable doesn't automatically grab focus on
+ * right-clicks (is that a bug?). */
+ gtk_widget_grab_focus (GTK_WIDGET (view));
+
+ g_signal_emit (view, signals[POPUP_EVENT], 0, event);
}
static void
-e_addressbook_view_init (EAddressbookView *eav)
+addressbook_view_emit_selection_change (EAddressbookView *view)
{
- eav->view_type = E_ADDRESSBOOK_VIEW_NONE;
-
- eav->model = e_addressbook_model_new ();
-
- gtk_signal_connect (GTK_OBJECT(eav->model),
- "status_message",
- GTK_SIGNAL_FUNC (status_message),
- eav);
-
- gtk_signal_connect (GTK_OBJECT(eav->model),
- "search_result",
- GTK_SIGNAL_FUNC (search_result),
- eav);
-
- gtk_signal_connect (GTK_OBJECT(eav->model),
- "folder_bar_message",
- GTK_SIGNAL_FUNC (folder_bar_message),
- eav);
-
- gtk_signal_connect (GTK_OBJECT(eav->model),
- "stop_state_changed",
- GTK_SIGNAL_FUNC (stop_state_changed),
- eav);
-
- gtk_signal_connect (GTK_OBJECT(eav->model),
- "writable_status",
- GTK_SIGNAL_FUNC (writable_status),
- eav);
-
- gtk_signal_connect (GTK_OBJECT(eav->model),
- "backend_died",
- GTK_SIGNAL_FUNC (backend_died),
- eav);
-
- eav->editable = FALSE;
- eav->book = NULL;
- eav->query = g_strdup (SHOW_ALL_SEARCH);
-
- eav->object = NULL;
- eav->widget = NULL;
-
- eav->view_instance = NULL;
- eav->view_menus = NULL;
- eav->uic = NULL;
- eav->current_alphabet_widget = NULL;
-
- eav->invisible = gtk_invisible_new ();
-
- gtk_selection_add_target (eav->invisible,
- clipboard_atom,
- GDK_SELECTION_TYPE_STRING,
- 0);
-
- gtk_signal_connect (GTK_OBJECT(eav->invisible), "selection_get",
- GTK_SIGNAL_FUNC (selection_get),
- eav);
- gtk_signal_connect (GTK_OBJECT(eav->invisible), "selection_clear_event",
- GTK_SIGNAL_FUNC (selection_clear_event),
- eav);
- gtk_signal_connect (GTK_OBJECT(eav->invisible), "selection_received",
- GTK_SIGNAL_FUNC (selection_received),
- eav);
- gtk_signal_connect (GTK_OBJECT(eav->invisible), "destroy",
- GTK_SIGNAL_FUNC (invisible_destroyed),
- eav);
+ g_signal_emit (view, signals[SELECTION_CHANGE], 0);
}
static void
-e_addressbook_view_destroy (GtkObject *object)
+addressbook_view_open_contact (EAddressbookView *view,
+ EContact *contact)
{
- EAddressbookView *eav = E_ADDRESSBOOK_VIEW(object);
-
- if (eav->model) {
- gtk_object_unref(GTK_OBJECT(eav->model));
- eav->model = NULL;
- }
+ addressbook_view_emit_open_contact (view, contact, FALSE);
+}
- if (eav->book) {
- gtk_object_unref(GTK_OBJECT(eav->book));
- eav->book = NULL;
- }
+static void
+addressbook_view_create_contact (EAddressbookView *view)
+{
+ EContact *contact;
- g_free(eav->query);
- eav->query = NULL;
+ contact = e_contact_new ();
+ addressbook_view_emit_open_contact (view, contact, TRUE);
+ g_object_unref (contact);
+}
- eav->uic = NULL;
+static void
+addressbook_view_create_contact_list (EAddressbookView *view)
+{
+ EContact *contact;
- if (eav->view_instance) {
- gtk_object_unref (GTK_OBJECT (eav->view_instance));
- eav->view_instance = NULL;
- }
+ contact = e_contact_new ();
+ e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (TRUE));
+ addressbook_view_emit_open_contact (view, contact, TRUE);
+ g_object_unref (contact);
+}
- if (eav->view_menus) {
- gtk_object_unref (GTK_OBJECT (eav->view_menus));
- eav->view_menus = NULL;
- }
+static void
+table_double_click (ETable *table,
+ gint row,
+ gint col,
+ GdkEvent *event,
+ EAddressbookView *view)
+{
+ EAddressbookModel *model;
+ EContact *contact;
- if (eav->clipboard_cards) {
- g_list_foreach (eav->clipboard_cards, (GFunc)gtk_object_unref, NULL);
- g_list_free (eav->clipboard_cards);
- eav->clipboard_cards = NULL;
- }
-
- if (eav->invisible) {
- gtk_widget_destroy (eav->invisible);
- eav->invisible = NULL;
- }
+ if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER (view->priv->object))
+ return;
- if (GTK_OBJECT_CLASS(parent_class)->destroy)
- GTK_OBJECT_CLASS(parent_class)->destroy(object);
+ model = e_addressbook_view_get_model (view);
+ contact = e_addressbook_model_get_contact (model, row);
+ addressbook_view_emit_open_contact (view, contact, FALSE);
+ g_object_unref (contact);
}
-GtkWidget*
-e_addressbook_view_new (void)
+static gint
+table_right_click (ETable *table,
+ gint row,
+ gint col,
+ GdkEvent *event,
+ EAddressbookView *view)
{
- GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_addressbook_view_get_type ()));
- return widget;
+ addressbook_view_emit_popup_event (view, event);
+
+ return TRUE;
}
-static void
-writable_status (GtkObject *object, gboolean writable, EAddressbookView *eav)
+static gint
+table_white_space_event (ETable *table,
+ GdkEvent *event,
+ EAddressbookView *view)
{
- eav->editable = writable;
- command_state_change (eav);
+ guint event_button = 0;
+
+ gdk_event_get_button (event, &event_button);
+
+ if (event->type == GDK_BUTTON_PRESS && event_button == 3) {
+ addressbook_view_emit_popup_event (view, event);
+ return TRUE;
+ }
+
+ return FALSE;
}
static void
-init_collection (void)
+table_drag_data_get (ETable *table,
+ gint row,
+ gint col,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer user_data)
{
- GalViewFactory *factory;
- ETableSpecification *spec;
- char *galview;
+ EAddressbookView *view = user_data;
+ EAddressbookModel *model;
+ EBookClient *book_client;
+ GSList *contact_list;
+ GdkAtom target;
+ gchar *value;
- if (collection == NULL) {
- collection = gal_view_collection_new();
+ if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER (view->priv->object))
+ return;
- gal_view_collection_set_title (collection, _("Addressbook"));
+ model = e_addressbook_view_get_model (view);
+ book_client = e_addressbook_model_get_client (model);
- galview = gnome_util_prepend_user_home("/evolution/views/addressbook/");
- gal_view_collection_set_storage_directories
- (collection,
- EVOLUTION_DATADIR "/evolution/views/addressbook/",
- galview);
- g_free(galview);
+ contact_list = e_addressbook_view_get_selected (view);
+ target = gtk_selection_data_get_target (selection_data);
- spec = e_table_specification_new();
- e_table_specification_load_from_file (spec, EVOLUTION_ETSPECDIR "/e-addressbook-view.etspec");
+ switch (info) {
+ case DND_TARGET_TYPE_VCARD:
+ value = eab_contact_list_to_string (contact_list);
- factory = gal_view_factory_etable_new (spec);
- gtk_object_unref (GTK_OBJECT (spec));
- gal_view_collection_add_factory (collection, factory);
- gtk_object_unref (GTK_OBJECT (factory));
+ gtk_selection_data_set (
+ selection_data, target, 8,
+ (guchar *) value, strlen (value));
- factory = gal_view_factory_minicard_new ();
- gal_view_collection_add_factory (collection, factory);
- gtk_object_unref (GTK_OBJECT (factory));
+ g_free (value);
+ break;
- gal_view_collection_load(collection);
- }
-}
+ case DND_TARGET_TYPE_SOURCE_VCARD:
+ value = eab_book_and_contact_list_to_string (
+ book_client, contact_list);
-static void
-display_view(GalViewInstance *instance,
- GalView *view,
- gpointer data)
-{
- EAddressbookView *address_view = data;
- if (GAL_IS_VIEW_ETABLE(view)) {
- change_view_type (address_view, E_ADDRESSBOOK_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));
+ gtk_selection_data_set (
+ selection_data, target, 8,
+ (guchar *) value, strlen (value));
+
+ g_free (value);
+ break;
}
- address_view->current_view = view;
+
+ g_slist_free_full (contact_list, (GDestroyNotify) g_object_unref);
}
static void
-setup_menus (EAddressbookView *view)
+addressbook_view_create_table_view (EAddressbookView *view,
+ GalViewEtable *gal_view)
{
- if (view->book && view->view_instance == NULL) {
- init_collection ();
- view->view_instance = gal_view_instance_new (collection, e_book_get_uri (view->book));
- }
+ ETableModel *adapter;
+ ETableExtras *extras;
+ ETableSpecification *specification;
+ ECell *cell;
+ GtkWidget *widget;
+ gchar *etspecfile;
+ GError *local_error = NULL;
- if (view->view_instance && view->uic) {
- view->view_menus = gal_view_menus_new(view->view_instance);
- gal_view_menus_apply(view->view_menus, view->uic, NULL);
+ adapter = e_addressbook_table_adapter_new (view->priv->model);
- display_view (view->view_instance, gal_view_instance_get_current_view (view->view_instance), view);
+ extras = e_table_extras_new ();
- gtk_signal_connect(GTK_OBJECT(view->view_instance), "display_view",
- display_view, view);
+ /* Set proper format component for a default 'date' cell renderer. */
+ cell = e_table_extras_get_cell (extras, "date");
+ e_cell_date_set_format_component (E_CELL_DATE (cell), "addressbook");
+
+ etspecfile = g_build_filename (
+ EVOLUTION_ETSPECDIR, "e-addressbook-view.etspec", NULL);
+ specification = e_table_specification_new (etspecfile, &local_error);
+
+ /* Failure here is fatal. */
+ if (local_error != NULL) {
+ g_error ("%s: %s", etspecfile, local_error->message);
+ g_assert_not_reached ();
}
-}
-static void
-e_addressbook_view_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- EAddressbookView *eav = E_ADDRESSBOOK_VIEW(object);
+ /* Here we create the table. We give it the three pieces of
+ * the table we've created, the header, the model, and the
+ * initial layout. It does the rest. */
+ widget = e_table_new (adapter, extras, specification);
+ gtk_container_add (GTK_CONTAINER (view), widget);
- switch (arg_id){
- case ARG_BOOK:
- if (eav->book) {
- gtk_object_unref(GTK_OBJECT(eav->book));
- }
- if (GTK_VALUE_OBJECT(*arg)) {
- eav->book = E_BOOK(GTK_VALUE_OBJECT(*arg));
- gtk_object_ref(GTK_OBJECT(eav->book));
- }
- else
- eav->book = NULL;
+ g_object_unref (specification);
+ g_free (etspecfile);
- if (eav->view_instance) {
- gtk_object_unref (GTK_OBJECT (eav->view_instance));
- eav->view_instance = NULL;
- }
+ view->priv->object = G_OBJECT (adapter);
- gtk_object_set(GTK_OBJECT(eav->model),
- "book", eav->book,
- NULL);
+ g_signal_connect (
+ widget, "double_click",
+ G_CALLBACK (table_double_click), view);
+ g_signal_connect (
+ widget, "right_click",
+ G_CALLBACK (table_right_click), view);
+ g_signal_connect (
+ widget, "white_space_event",
+ G_CALLBACK (table_white_space_event), view);
+ g_signal_connect_swapped (
+ widget, "selection_change",
+ G_CALLBACK (addressbook_view_emit_selection_change), view);
- setup_menus (eav);
+ e_table_drag_source_set (
+ E_TABLE (widget), GDK_BUTTON1_MASK,
+ drag_types, G_N_ELEMENTS (drag_types),
+ GDK_ACTION_MOVE | GDK_ACTION_COPY);
- break;
- case ARG_QUERY:
-#if 0 /* This code will mess up ldap a bit. We need to think about the ramifications of this more. */
- if ((GTK_VALUE_STRING (*arg) == NULL && !strcmp (eav->query, SHOW_ALL_SEARCH)) ||
- (GTK_VALUE_STRING (*arg) != NULL && !strcmp (eav->query, GTK_VALUE_STRING (*arg))))
- break;
-#endif
- g_free(eav->query);
- eav->query = g_strdup(GTK_VALUE_STRING(*arg));
- if (!eav->query)
- eav->query = g_strdup (SHOW_ALL_SEARCH);
- gtk_object_set(GTK_OBJECT(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 ARG_TYPE:
- change_view_type(eav, GTK_VALUE_ENUM(*arg));
- break;
- default:
- break;
- }
+ g_signal_connect (
+ E_TABLE (widget), "table_drag_data_get",
+ G_CALLBACK (table_drag_data_get), view);
+
+ gtk_widget_show (widget);
+
+ gal_view_etable_attach_table (gal_view, E_TABLE (widget));
}
static void
-e_addressbook_view_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+addressbook_view_create_minicard_view (EAddressbookView *view,
+ GalViewMinicard *gal_view)
{
- EAddressbookView *eav = E_ADDRESSBOOK_VIEW(object);
+ GtkWidget *minicard_view;
+ EAddressbookReflowAdapter *adapter;
- switch (arg_id) {
- case ARG_BOOK:
- if (eav->book)
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(eav->book);
- else
- GTK_VALUE_OBJECT (*arg) = NULL;
- break;
- case ARG_QUERY:
- GTK_VALUE_STRING (*arg) = eav->query;
- break;
- case ARG_TYPE:
- GTK_VALUE_ENUM (*arg) = eav->view_type;
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
-}
+ adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (
+ e_addressbook_reflow_adapter_new (view->priv->model));
+ minicard_view = e_minicard_view_widget_new (adapter);
-static ESelectionModel*
-get_selection_model (EAddressbookView *view)
-{
- if (view->view_type == E_ADDRESSBOOK_VIEW_MINICARD)
- return e_minicard_view_widget_get_selection_model (E_MINICARD_VIEW_WIDGET(view->object));
- else
- return e_table_get_selection_model (e_table_scrolled_get_table (E_TABLE_SCROLLED(view->widget)));
-}
+ g_signal_connect_swapped (
+ adapter, "open-contact",
+ G_CALLBACK (addressbook_view_open_contact), view);
-/* Popup menu stuff */
-typedef struct {
- EAddressbookView *view;
- EPopupMenu *submenu;
- gpointer closure;
-} CardAndBook;
+ g_signal_connect_swapped (
+ minicard_view, "create-contact",
+ G_CALLBACK (addressbook_view_create_contact), view);
-static ESelectionModel*
-card_and_book_get_selection_model (CardAndBook *card_and_book)
-{
- return get_selection_model (card_and_book->view);
+ g_signal_connect_swapped (
+ minicard_view, "create-contact-list",
+ G_CALLBACK (addressbook_view_create_contact_list), view);
+
+ g_signal_connect_swapped (
+ minicard_view, "selection_change",
+ G_CALLBACK (addressbook_view_emit_selection_change), view);
+
+ g_signal_connect_swapped (
+ minicard_view, "right_click",
+ G_CALLBACK (addressbook_view_emit_popup_event), view);
+
+ view->priv->object = G_OBJECT (minicard_view);
+
+ gtk_container_add (GTK_CONTAINER (view), minicard_view);
+ gtk_widget_show (minicard_view);
+
+ e_reflow_model_changed (E_REFLOW_MODEL (adapter));
+
+ gal_view_minicard_attach (gal_view, view);
}
static void
-card_and_book_free (CardAndBook *card_and_book)
+addressbook_view_display_view_cb (GalViewInstance *view_instance,
+ GalView *gal_view,
+ EAddressbookView *view)
{
- EAddressbookView *view = card_and_book->view;
- ESelectionModel *selection;
+ EShellView *shell_view;
+ GtkWidget *child;
- if (card_and_book->submenu)
- gal_view_instance_free_popup_menu (view->view_instance,
- card_and_book->submenu);
+ child = gtk_bin_get_child (GTK_BIN (view));
+ if (child != NULL)
+ gtk_container_remove (GTK_CONTAINER (view), child);
+ view->priv->object = NULL;
- selection = card_and_book_get_selection_model (card_and_book);
- if (selection)
- e_selection_model_right_click_up(selection);
+ if (GAL_IS_VIEW_ETABLE (gal_view))
+ addressbook_view_create_table_view (
+ view, GAL_VIEW_ETABLE (gal_view));
+ else if (GAL_IS_VIEW_MINICARD (gal_view))
+ addressbook_view_create_minicard_view (
+ view, GAL_VIEW_MINICARD (gal_view));
- gtk_object_unref(GTK_OBJECT(view));
+ shell_view = e_addressbook_view_get_shell_view (view);
+ e_shell_view_set_view_instance (shell_view, view_instance);
+
+ command_state_change (view);
}
static void
-get_card_list_1(gint model_row,
- gpointer closure)
+addressbook_view_set_shell_view (EAddressbookView *view,
+ EShellView *shell_view)
{
- CardAndBook *card_and_book;
- GList **list;
- EAddressbookView *view;
- ECard *card;
+ g_return_if_fail (view->priv->shell_view == NULL);
- card_and_book = closure;
- list = card_and_book->closure;
- view = card_and_book->view;
+ view->priv->shell_view = shell_view;
- card = e_addressbook_model_get_card(view->model, model_row);
- *list = g_list_prepend(*list, card);
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_view),
+ &view->priv->shell_view);
}
-static GList *
-get_card_list (CardAndBook *card_and_book)
+static void
+addressbook_view_set_source (EAddressbookView *view,
+ ESource *source)
{
- GList *list = NULL;
- ESelectionModel *selection;
+ g_return_if_fail (view->priv->source == NULL);
- selection = card_and_book_get_selection_model (card_and_book);
+ view->priv->source = g_object_ref (source);
+}
+
+static void
+addressbook_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_VIEW:
+ addressbook_view_set_shell_view (
+ E_ADDRESSBOOK_VIEW (object),
+ g_value_get_object (value));
+ return;
- if (selection) {
- card_and_book->closure = &list;
- e_selection_model_foreach (selection, get_card_list_1, card_and_book);
+ case PROP_SOURCE:
+ addressbook_view_set_source (
+ E_ADDRESSBOOK_VIEW (object),
+ g_value_get_object (value));
+ return;
}
- return list;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-has_email_address_1(gint model_row,
- gpointer closure)
-{
- CardAndBook *card_and_book;
- gboolean *has_email;
- EAddressbookView *view;
- const ECard *card;
- EList *email;
+addressbook_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_COPY_TARGET_LIST:
+ g_value_set_boxed (
+ value,
+ e_addressbook_view_get_copy_target_list (
+ E_ADDRESSBOOK_VIEW (object)));
+ return;
- card_and_book = closure;
- has_email = card_and_book->closure;
- view = card_and_book->view;
+ case PROP_MODEL:
+ g_value_set_object (
+ value,
+ e_addressbook_view_get_model (
+ E_ADDRESSBOOK_VIEW (object)));
+ return;
- if (*has_email)
- return;
+ case PROP_PASTE_TARGET_LIST:
+ g_value_set_boxed (
+ value,
+ e_addressbook_view_get_paste_target_list (
+ E_ADDRESSBOOK_VIEW (object)));
+ return;
- card = e_addressbook_model_peek_card(view->model, model_row);
+ case PROP_SHELL_VIEW:
+ g_value_set_object (
+ value,
+ e_addressbook_view_get_shell_view (
+ E_ADDRESSBOOK_VIEW (object)));
+ return;
- gtk_object_get (GTK_OBJECT (card),
- "email", &email,
- NULL);
+ case PROP_SOURCE:
+ g_value_set_object (
+ value,
+ e_addressbook_view_get_source (
+ E_ADDRESSBOOK_VIEW (object)));
+ return;
+ }
- if (e_list_length (email) > 0)
- *has_email = TRUE;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
-static gboolean
-get_has_email_address (CardAndBook *card_and_book)
+static void
+addressbook_view_dispose (GObject *object)
{
- ESelectionModel *selection;
- gboolean has_email = FALSE;
+ EAddressbookViewPrivate *priv;
- selection = card_and_book_get_selection_model (card_and_book);
+ priv = E_ADDRESSBOOK_VIEW_GET_PRIVATE (object);
- if (selection) {
- card_and_book->closure = &has_email;
- e_selection_model_foreach (selection, has_email_address_1, card_and_book);
+ if (priv->shell_view != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell_view),
+ &priv->shell_view);
+ priv->shell_view = NULL;
}
- return has_email;
-}
+ if (priv->model != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->model, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->model);
+ priv->model = NULL;
+ }
-static void
-save_as (GtkWidget *widget, CardAndBook *card_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);
+ if (priv->activity != NULL) {
+ /* XXX Activity is not cancellable. */
+ e_activity_set_state (priv->activity, E_ACTIVITY_COMPLETED);
+ g_object_unref (priv->activity);
+ priv->activity = NULL;
}
-}
-static void
-send_as (GtkWidget *widget, CardAndBook *card_and_book)
-{
- GList *cards = get_card_list (card_and_book);
- if (cards) {
- e_card_list_send(cards, E_CARD_DISPOSITION_AS_ATTACHMENT);
- e_free_object_list(cards);
+ if (priv->source != NULL) {
+ g_object_unref (priv->source);
+ priv->source = NULL;
}
-}
-static void
-send_to (GtkWidget *widget, CardAndBook *card_and_book)
+ if (priv->view_instance != NULL) {
+ g_object_unref (priv->view_instance);
+ priv->view_instance = NULL;
+ }
-{
- GList *cards = get_card_list (card_and_book);
+ priv->filter_id = 0;
+ priv->search_id = 0;
- if (cards) {
- e_card_list_send(cards, E_CARD_DISPOSITION_AS_TO);
- e_free_object_list(cards);
+ if (priv->search_text) {
+ g_free (priv->search_text);
+ priv->search_text = NULL;
}
-}
-static void
-print (GtkWidget *widget, CardAndBook *card_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));
- else
- gtk_widget_show(e_contact_print_card_dialog_new(cards->data));
- e_free_object_list(cards);
+ if (priv->advanced_search) {
+ g_object_unref (priv->advanced_search);
+ priv->advanced_search = NULL;
}
-}
-#if 0 /* Envelope printing is disabled for Evolution 1.0. */
-static void
-print_envelope (GtkWidget *widget, CardAndBook *card_and_book)
-{
- GList *cards = get_card_list (card_and_book);
- if (cards) {
- gtk_widget_show(e_contact_list_print_envelope_dialog_new(card_and_book->card));
- e_free_object_list(cards);
+ if (priv->copy_target_list != NULL) {
+ gtk_target_list_unref (priv->copy_target_list);
+ priv->copy_target_list = NULL;
}
-}
-#endif
-static void
-copy (GtkWidget *widget, CardAndBook *card_and_book)
-{
- e_addressbook_view_copy (card_and_book->view);
-}
+ if (priv->paste_target_list != NULL) {
+ gtk_target_list_unref (priv->paste_target_list);
+ priv->paste_target_list = NULL;
+ }
-static void
-paste (GtkWidget *widget, CardAndBook *card_and_book)
-{
- e_addressbook_view_paste (card_and_book->view);
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_addressbook_view_parent_class)->dispose (object);
}
static void
-cut (GtkWidget *widget, CardAndBook *card_and_book)
+addressbook_view_constructed (GObject *object)
{
- e_addressbook_view_cut (card_and_book->view);
-}
+ EAddressbookView *view = E_ADDRESSBOOK_VIEW (object);
+ GalViewInstance *view_instance;
+ EShell *shell;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EClientCache *client_cache;
+ ESource *source;
+ const gchar *uid;
-static void
-delete (GtkWidget *widget, CardAndBook *card_and_book)
-{
- if (e_contact_editor_confirm_delete(GTK_WINDOW(gtk_widget_get_toplevel(card_and_book->view->widget)))) {
- EBook *book;
+ shell_view = e_addressbook_view_get_shell_view (view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell = e_shell_backend_get_shell (shell_backend);
+ client_cache = e_shell_get_client_cache (shell);
- GList *list = get_card_list(card_and_book);
- GList *iterator;
+ source = e_addressbook_view_get_source (view);
+ uid = e_source_get_uid (source);
- gtk_object_get(GTK_OBJECT(card_and_book->view->model),
- "book", &book,
- NULL);
+ view->priv->model = e_addressbook_model_new (client_cache);
- for (iterator = list; iterator; iterator = iterator->next) {
- ECard *card = iterator->data;
- /* Remove the card. */
- e_book_remove_card (book,
- card,
- NULL,
- NULL);
- }
- e_free_object_list(list);
- }
-}
+ view_instance = e_shell_view_new_view_instance (shell_view, uid);
+ g_signal_connect (
+ view_instance, "display-view",
+ G_CALLBACK (addressbook_view_display_view_cb), view);
+ view->priv->view_instance = view_instance;
-static void
-copy_to_folder (GtkWidget *widget, CardAndBook *card_and_book)
-{
- e_addressbook_view_copy_to_folder (card_and_book->view);
-}
+ /* Do not call gal_view_instance_load() here. EBookShellContent
+ * must first obtain a reference to this EAddressbookView so that
+ * e_book_shell_content_get_current_view() returns the correct
+ * view in GalViewInstance::loaded signal handlers. */
-static void
-move_to_folder (GtkWidget *widget, CardAndBook *card_and_book)
-{
- e_addressbook_view_move_to_folder (card_and_book->view);
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_addressbook_view_parent_class)->constructed (object);
}
static void
-free_popup_info (GtkWidget *w, CardAndBook *card_and_book)
+addressbook_view_update_actions (ESelectable *selectable,
+ EFocusTracker *focus_tracker,
+ GdkAtom *clipboard_targets,
+ gint n_clipboard_targets)
{
- card_and_book_free (card_and_book);
+ EAddressbookView *view;
+ EAddressbookModel *model;
+ ESelectionModel *selection_model;
+ GtkAction *action;
+ GtkTargetList *target_list;
+ gboolean can_paste = FALSE;
+ gboolean source_is_editable;
+ gboolean sensitive;
+ const gchar *tooltip;
+ gint n_contacts;
+ gint n_selected;
+ gint ii;
+
+ view = E_ADDRESSBOOK_VIEW (selectable);
+ model = e_addressbook_view_get_model (view);
+ selection_model = e_addressbook_view_get_selection_model (view);
+
+ source_is_editable = e_addressbook_model_get_editable (model);
+ n_contacts = (selection_model != NULL) ?
+ e_selection_model_row_count (selection_model) : 0;
+ n_selected = (selection_model != NULL) ?
+ e_selection_model_selected_count (selection_model) : 0;
+
+ target_list = e_selectable_get_paste_target_list (selectable);
+ for (ii = 0; ii < n_clipboard_targets && !can_paste; ii++)
+ can_paste = gtk_target_list_find (
+ target_list, clipboard_targets[ii], NULL);
+
+ action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
+ sensitive = source_is_editable && (n_selected > 0);
+ tooltip = _("Cut selected contacts to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_copy_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0);
+ tooltip = _("Copy selected contacts to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
+ sensitive = source_is_editable && can_paste;
+ tooltip = _("Paste contacts from the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_delete_selection_action (focus_tracker);
+ sensitive = source_is_editable && (n_selected > 0);
+ tooltip = _("Delete selected contacts");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_select_all_action (focus_tracker);
+ sensitive = (n_contacts > 0);
+ tooltip = _("Select all visible contacts");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
}
static void
-new_card (GtkWidget *widget, CardAndBook *card_and_book)
+addressbook_view_cut_clipboard (ESelectable *selectable)
{
- EBook *book;
-
- gtk_object_get(GTK_OBJECT(card_and_book->view->model),
- "book", &book,
- NULL);
- e_addressbook_show_contact_editor (book, e_card_new(""), TRUE, TRUE);
-}
+ EAddressbookView *view;
-static void
-new_list (GtkWidget *widget, CardAndBook *card_and_book)
-{
- EBook *book;
+ view = E_ADDRESSBOOK_VIEW (selectable);
- gtk_object_get(GTK_OBJECT(card_and_book->view->model),
- "book", &book,
- NULL);
- e_addressbook_show_contact_list_editor (book, e_card_new(""), TRUE, TRUE);
+ e_selectable_copy_clipboard (selectable);
+ e_addressbook_view_delete_selection (view, FALSE);
}
-#if 0
static void
-sources (GtkWidget *widget, CardAndBook *card_and_book)
+addressbook_view_copy_clipboard (ESelectable *selectable)
{
- BonoboControl *control;
- GNOME_Evolution_ShellView shell_view;
- CORBA_Environment ev;
+ EAddressbookView *view;
+ GtkClipboard *clipboard;
+ GSList *contact_list;
+ gchar *string;
- control = gtk_object_get_data (GTK_OBJECT (gcal), "control");
- if (control == NULL)
- return;
+ view = E_ADDRESSBOOK_VIEW (selectable);
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- shell_view = get_shell_view_interface (control);
- if (shell_view == CORBA_OBJECT_NIL)
- return;
+ contact_list = e_addressbook_view_get_selected (view);
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_ShellView_showSettings (shell_view, &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("control_util_show_settings(): Could not show settings");
+ string = eab_contact_list_to_string (contact_list);
+ e_clipboard_set_directory (clipboard, string, -1);
+ g_free (string);
- CORBA_exception_free (&ev);
+ g_slist_free_full (contact_list, (GDestroyNotify) g_object_unref);
}
-#endif
-
-#define POPUP_READONLY_MASK 0x1
-#define POPUP_NOSELECTION_MASK 0x2
-#define POPUP_NOEMAIL_MASK 0x4
static void
-do_popup_menu(EAddressbookView *view, GdkEvent *event)
+addressbook_view_paste_clipboard (ESelectable *selectable)
{
- CardAndBook *card_and_book;
- GtkMenu *popup;
- EPopupMenu *submenu = NULL;
- ESelectionModel *selection_model;
- gboolean selection = FALSE;
-
- EPopupMenu menu[] = {
- E_POPUP_ITEM (N_("New Contact..."), GTK_SIGNAL_FUNC(new_card), POPUP_READONLY_MASK),
- E_POPUP_ITEM (N_("New Contact List..."), GTK_SIGNAL_FUNC(new_list), POPUP_READONLY_MASK),
- E_POPUP_SEPARATOR,
-#if 0
- E_POPUP_ITEM (N_("Go to Folder..."), GTK_SIGNAL_FUNC (goto_folder), 0),
- E_POPUP_ITEM (N_("Import..."), GTK_SIGNAL_FUNC (import), POPUP_READONLY_MASK),
- E_POPUP_SEPARATOR,
- E_POPUP_ITEM (N_("Search for Contacts..."), GTK_SIGNAL_FUNC (search), 0),
- E_POPUP_ITEM (N_("Addressbook Sources..."), GTK_SIGNAL_FUNC (sources), 0),
- E_POPUP_SEPARATOR,
- E_POPUP_ITEM (N_("Pilot Settings..."), GTK_SIGNAL_FUNC (pilot_settings), 0),
-#endif
- E_POPUP_SEPARATOR,
- E_POPUP_ITEM (N_("Save as VCard"), GTK_SIGNAL_FUNC(save_as), POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Forward Contact"), GTK_SIGNAL_FUNC(send_as), POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Send Message to Contact"), GTK_SIGNAL_FUNC(send_to), POPUP_NOSELECTION_MASK | POPUP_NOEMAIL_MASK),
- E_POPUP_ITEM (N_("Print"), GTK_SIGNAL_FUNC(print), POPUP_NOSELECTION_MASK),
-#if 0 /* Envelope printing is disabled for Evolution 1.0. */
- E_POPUP_ITEM (N_("Print Envelope"), GTK_SIGNAL_FUNC(print_envelope), POPUP_NOSELECTION_MASK),
-#endif
- E_POPUP_SEPARATOR,
+ EBookClient *book_client;
+ EAddressbookView *view;
+ EAddressbookModel *model;
+ EClientCache *client_cache;
+ ESourceRegistry *registry;
+ GtkClipboard *clipboard;
+ GSList *contact_list, *iter;
+ gchar *string;
- E_POPUP_ITEM (N_("Copy to folder..."), GTK_SIGNAL_FUNC(copy_to_folder), POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Move to folder..."), GTK_SIGNAL_FUNC(move_to_folder), POPUP_READONLY_MASK | POPUP_NOSELECTION_MASK),
- E_POPUP_SEPARATOR,
+ view = E_ADDRESSBOOK_VIEW (selectable);
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- E_POPUP_ITEM (N_("Cut"), GTK_SIGNAL_FUNC (cut), POPUP_READONLY_MASK | POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Copy"), GTK_SIGNAL_FUNC (copy), POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Paste"), GTK_SIGNAL_FUNC (paste), POPUP_READONLY_MASK),
- E_POPUP_ITEM (N_("Delete"), GTK_SIGNAL_FUNC(delete), POPUP_READONLY_MASK | POPUP_NOSELECTION_MASK),
- E_POPUP_SEPARATOR,
+ if (!e_clipboard_wait_is_directory_available (clipboard))
+ return;
-#if 0
- E_POPUP_SUBMENU (N_("Current View"), submenu = gal_view_instance_get_popup_menu (view->view_instance), 0),
-#endif
- E_POPUP_TERMINATOR
- };
+ model = e_addressbook_view_get_model (view);
+ client_cache = e_addressbook_model_get_client_cache (model);
+ book_client = e_addressbook_model_get_client (model);
- card_and_book = g_new(CardAndBook, 1);
- card_and_book->view = view;
- card_and_book->submenu = submenu;
+ string = e_clipboard_wait_for_directory (clipboard);
+ contact_list = eab_contact_list_from_string (string);
+ g_free (string);
- gtk_object_ref(GTK_OBJECT(card_and_book->view));
+ registry = e_client_cache_ref_registry (client_cache);
- selection_model = card_and_book_get_selection_model (card_and_book);
- if (selection_model)
- selection = e_selection_model_selected_count (selection_model) > 0;
+ for (iter = contact_list; iter != NULL; iter = iter->next) {
+ EContact *contact = iter->data;
- popup = e_popup_menu_create (menu,
- 0,
- (e_addressbook_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);
+ eab_merging_book_add_contact (
+ registry, book_client, contact, NULL, NULL);
+ }
- gtk_signal_connect (GTK_OBJECT (popup), "selection-done",
- GTK_SIGNAL_FUNC (free_popup_info), card_and_book);
- e_popup_menu (popup, event);
+ g_object_unref (registry);
+ g_slist_free_full (contact_list, (GDestroyNotify) g_object_unref);
}
+static void
+addressbook_view_delete_selection (ESelectable *selectable)
+{
+ EAddressbookView *view;
-/* 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");
+ view = E_ADDRESSBOOK_VIEW (selectable);
-typedef struct {
- EAddressbookView *view;
- GtkWidget *button;
- GtkWidget *vbox;
- gunichar letter;
-} LetterClosure;
+ e_addressbook_view_delete_selection (view, TRUE);
+}
-static char **
-e_utf8_split (const char *utf8_str, gunichar delim)
+static void
+addressbook_view_select_all (ESelectable *selectable)
{
- 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;
- }
- }
+ EAddressbookView *view;
+ ESelectionModel *selection_model;
- 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);
+ view = E_ADDRESSBOOK_VIEW (selectable);
+ selection_model = e_addressbook_view_get_selection_model (view);
- return str_array;
+ if (selection_model != NULL)
+ e_selection_model_select_all (selection_model);
}
static void
-jump_to_letter(EAddressbookView *view, gunichar letter)
-{
- char *query;
-
- if (g_unichar_isdigit (letter)) {
- const char *letters = U_(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++) {
- g_string_sprintfa (gstr, "(beginswith \"file_as\" \"%s\")", *p);
- }
- g_string_append (gstr, "))");
- query = gstr->str;
- g_strfreev (letter_v);
- g_string_free (gstr, FALSE);
- } else {
- char s[6 + 1];
-
- s [g_unichar_to_utf8 (letter, s)] = '\0';
- query = g_strdup_printf ("(beginswith \"file_as\" \"%s\")", s);
- }
- gtk_object_set (GTK_OBJECT (view),
- "query", query,
- NULL);
- g_free (query);
+e_addressbook_view_class_init (EAddressbookViewClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EAddressbookViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = addressbook_view_set_property;
+ object_class->get_property = addressbook_view_get_property;
+ object_class->dispose = addressbook_view_dispose;
+ object_class->constructed = addressbook_view_constructed;
+
+ /* Inherited from ESelectableInterface */
+ g_object_class_override_property (
+ object_class,
+ PROP_COPY_TARGET_LIST,
+ "copy-target-list");
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MODEL,
+ g_param_spec_object (
+ "model",
+ "Model",
+ NULL,
+ E_TYPE_ADDRESSBOOK_MODEL,
+ G_PARAM_READABLE));
+
+ /* Inherited from ESelectableInterface */
+ g_object_class_override_property (
+ object_class,
+ PROP_PASTE_TARGET_LIST,
+ "paste-target-list");
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_VIEW,
+ g_param_spec_object (
+ "shell-view",
+ "Shell View",
+ NULL,
+ E_TYPE_SHELL_VIEW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SOURCE,
+ g_param_spec_object (
+ "source",
+ "Source",
+ NULL,
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ signals[OPEN_CONTACT] = g_signal_new (
+ "open-contact",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookViewClass, open_contact),
+ NULL, NULL,
+ e_marshal_VOID__OBJECT_BOOLEAN,
+ G_TYPE_NONE, 2,
+ E_TYPE_CONTACT,
+ G_TYPE_BOOLEAN);
+
+ signals[POPUP_EVENT] = g_signal_new (
+ "popup-event",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookViewClass, popup_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ signals[COMMAND_STATE_CHANGE] = g_signal_new (
+ "command-state-change",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookViewClass, command_state_change),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[SELECTION_CHANGE] = g_signal_new (
+ "selection-change",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookViewClass, selection_change),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /* init the accessibility support for e_addressbook_view */
+ eab_view_a11y_init ();
}
static void
-button_toggled(GtkWidget *button, LetterClosure *closure)
+e_addressbook_view_init (EAddressbookView *view)
{
- EAddressbookView *view = closure->view;
+ GtkTargetList *target_list;
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
- GtkWidget *current = view->current_alphabet_widget;
+ view->priv = E_ADDRESSBOOK_VIEW_GET_PRIVATE (view);
- view->current_alphabet_widget = NULL;
- if (current && current != button)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (current), FALSE);
- jump_to_letter (view, closure->letter);
- view->current_alphabet_widget = button;
- alphabet_state_change (view, closure->letter);
- } else {
- if (view->current_alphabet_widget != NULL &&
- view->current_alphabet_widget == button) {
- view->current_alphabet_widget = NULL;
- gtk_object_set (GTK_OBJECT (view),
- "query", NULL,
- NULL);
- alphabet_state_change (view, 0);
- }
- }
+ target_list = gtk_target_list_new (NULL, 0);
+ e_target_list_add_directory_targets (target_list, 0);
+ view->priv->copy_target_list = target_list;
+
+ target_list = gtk_target_list_new (NULL, 0);
+ e_target_list_add_directory_targets (target_list, 0);
+ view->priv->paste_target_list = target_list;
+
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (view),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (view), GTK_SHADOW_IN);
}
static void
-free_closure(GtkWidget *button, LetterClosure *closure)
+e_addressbook_view_selectable_init (ESelectableInterface *interface)
{
- if (button != NULL &&
- button == closure->view->current_alphabet_widget) {
- closure->view->current_alphabet_widget = NULL;
- }
- g_free(closure);
+ interface->update_actions = addressbook_view_update_actions;
+ interface->cut_clipboard = addressbook_view_cut_clipboard;
+ interface->copy_clipboard = addressbook_view_copy_clipboard;
+ interface->paste_clipboard = addressbook_view_paste_clipboard;
+ interface->delete_selection = addressbook_view_delete_selection;
+ interface->select_all = addressbook_view_select_all;
}
-static GtkWidget *
-create_alphabet (EAddressbookView *view)
+GtkWidget *
+e_addressbook_view_new (EShellView *shell_view,
+ ESource *source)
{
- 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);
- gtk_widget_set_usize (vbox, 27, 0);
-
- labels = U_(button_labels);
- sep = g_utf8_get_char (labels);
- label_v = e_utf8_split (g_utf8_next_char (labels), sep);
- letters = U_(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 = e_utf8_to_locale_string (*pl);
- button = gtk_toggle_button_new_with_label (label);
- g_free (label);
- gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
- closure = g_new (LetterClosure, 1);
- closure->view = view;
- closure->letter = g_utf8_get_char (*pc);
- closure->button = button;
- closure->vbox = vbox;
- gtk_signal_connect(GTK_OBJECT(button), "toggled",
- GTK_SIGNAL_FUNC (button_toggled), closure);
- gtk_signal_connect(GTK_OBJECT(button), "destroy",
- GTK_SIGNAL_FUNC (free_closure), closure);
-
- }
- g_strfreev (label_v);
- g_strfreev (letter_v);
+ GtkWidget *widget;
+ EAddressbookView *view;
- gtk_widget_show_all (widget);
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ widget = g_object_new (
+ E_TYPE_ADDRESSBOOK_VIEW, "shell-view",
+ shell_view, "source", source, NULL);
+
+ view = E_ADDRESSBOOK_VIEW (widget);
+
+ g_signal_connect_swapped (
+ view->priv->model, "status_message",
+ G_CALLBACK (status_message), view);
+ g_signal_connect_swapped (
+ view->priv->model, "search_result",
+ G_CALLBACK (search_result), view);
+ g_signal_connect_swapped (
+ view->priv->model, "folder_bar_message",
+ G_CALLBACK (folder_bar_message), view);
+ g_signal_connect (
+ view->priv->model, "stop_state_changed",
+ G_CALLBACK (stop_state_changed), view);
+ g_signal_connect_swapped (
+ view->priv->model, "writable-status",
+ G_CALLBACK (command_state_change), view);
return widget;
}
-static void
-minicard_selection_change (EMinicardViewWidget *widget, EAddressbookView *view)
+EAddressbookModel *
+e_addressbook_view_get_model (EAddressbookView *view)
{
- command_state_change (view);
-}
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
-static void
-minicard_button_press (GtkWidget *widget, GdkEventButton *event, EAddressbookView *view)
-{
- d(g_print ("Button %d pressed with event type %d\n", event->button, event->type));
+ return view->priv->model;
}
-static void
-minicard_right_click (EMinicardView *minicard_view_item, GdkEvent *event, EAddressbookView *view)
+GalViewInstance *
+e_addressbook_view_get_view_instance (EAddressbookView *view)
{
- do_popup_menu(view, event);
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
+
+ return view->priv->view_instance;
}
-static void
-create_minicard_view (EAddressbookView *view)
+GObject *
+e_addressbook_view_get_view_object (EAddressbookView *view)
{
- GtkWidget *scrollframe;
- GtkWidget *alphabet;
- GtkWidget *minicard_view;
- GtkWidget *minicard_hbox;
- EAddressbookReflowAdapter *adapter;
+ /* XXX Find a more descriptive name for this. */
- gtk_widget_push_visual (gdk_rgb_get_visual ());
- gtk_widget_push_colormap (gdk_rgb_get_cmap ());
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
- minicard_hbox = gtk_hbox_new(FALSE, 0);
+ return view->priv->object;
+}
- adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(e_addressbook_reflow_adapter_new (view->model));
- minicard_view = e_minicard_view_widget_new(adapter);
+/* Helper for e_addressbook_view_get_selected() */
+static void
+add_to_list (gint model_row,
+ gpointer closure)
+{
+ GSList **list = closure;
+ *list = g_slist_prepend (*list, GINT_TO_POINTER (model_row));
+}
- /* A hack */
- gtk_object_set_data (GTK_OBJECT (adapter), "view", view);
+GSList *
+e_addressbook_view_get_selected (EAddressbookView *view)
+{
+ GSList *list, *iter;
+ ESelectionModel *selection;
- gtk_signal_connect(GTK_OBJECT(minicard_view), "selection_change",
- GTK_SIGNAL_FUNC(minicard_selection_change), view);
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
- gtk_signal_connect(GTK_OBJECT(minicard_view), "button_press_event",
- GTK_SIGNAL_FUNC(minicard_button_press), view);
+ list = NULL;
+ selection = e_addressbook_view_get_selection_model (view);
+ e_selection_model_foreach (selection, add_to_list, &list);
- gtk_signal_connect(GTK_OBJECT(minicard_view), "right_click",
- GTK_SIGNAL_FUNC(minicard_right_click), view);
+ for (iter = list; iter != NULL; iter = iter->next)
+ iter->data = e_addressbook_model_get_contact (
+ view->priv->model, GPOINTER_TO_INT (iter->data));
+ return g_slist_reverse (list);
+}
+ESelectionModel *
+e_addressbook_view_get_selection_model (EAddressbookView *view)
+{
+ GalView *gal_view;
+ GalViewInstance *view_instance;
+ ESelectionModel *model = NULL;
- view->object = GTK_OBJECT(minicard_view);
- view->widget = minicard_hbox;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
- scrollframe = e_scroll_frame_new (NULL, NULL);
- e_scroll_frame_set_policy (E_SCROLL_FRAME (scrollframe),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
+ view_instance = e_addressbook_view_get_view_instance (view);
+ gal_view = gal_view_instance_get_current_view (view_instance);
- gtk_container_add (GTK_CONTAINER (scrollframe), minicard_view);
+ if (GAL_IS_VIEW_ETABLE (gal_view)) {
+ GtkWidget *child;
+ child = gtk_bin_get_child (GTK_BIN (view));
+ model = e_table_get_selection_model (E_TABLE (child));
- gtk_box_pack_start(GTK_BOX(minicard_hbox), scrollframe, TRUE, TRUE, 0);
+ } else if (GAL_IS_VIEW_MINICARD (gal_view)) {
+ EMinicardViewWidget *widget;
- alphabet = create_alphabet(view);
- if (alphabet) {
- gtk_object_ref(GTK_OBJECT(alphabet));
- gtk_widget_unparent(alphabet);
- gtk_box_pack_start(GTK_BOX(minicard_hbox), alphabet, FALSE, FALSE, 0);
- gtk_object_unref(GTK_OBJECT(alphabet));
+ widget = E_MINICARD_VIEW_WIDGET (view->priv->object);
+ model = e_minicard_view_widget_get_selection_model (widget);
}
- 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_visual ();
- gtk_widget_pop_colormap ();
-
- e_reflow_model_changed (E_REFLOW_MODEL (adapter));
-
- gtk_object_unref (GTK_OBJECT (adapter));
+ return model;
}
-static void
-table_double_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EAddressbookView *view)
+EShellView *
+e_addressbook_view_get_shell_view (EAddressbookView *view)
{
- if (E_IS_ADDRESSBOOK_TABLE_ADAPTER(view->object)) {
- EAddressbookModel *model = view->model;
- ECard *card = e_addressbook_model_get_card(model, row);
- EBook *book;
-
- gtk_object_get(GTK_OBJECT(model),
- "book", &book,
- NULL);
-
- g_assert (E_IS_BOOK (book));
-
- if (e_card_evolution_list (card))
- e_addressbook_show_contact_list_editor (book, card, FALSE, view->editable);
- else
- e_addressbook_show_contact_editor (book, card, FALSE, view->editable);
- }
-}
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
-static gint
-table_right_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EAddressbookView *view)
-{
- do_popup_menu(view, event);
- return TRUE;
+ return view->priv->shell_view;
}
-static gint
-table_white_space_event(ETableScrolled *table, GdkEvent *event, EAddressbookView *view)
+ESource *
+e_addressbook_view_get_source (EAddressbookView *view)
{
- if (event->type == GDK_BUTTON_PRESS && ((GdkEventButton *)event)->button == 3) {
- do_popup_menu(view, event);
- return TRUE;
- } else {
- return FALSE;
- }
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
+
+ return view->priv->source;
}
-static void
-table_selection_change(ETableScrolled *table, EAddressbookView *view)
+GtkTargetList *
+e_addressbook_view_get_copy_target_list (EAddressbookView *view)
{
- command_state_change (view);
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
+
+ return view->priv->copy_target_list;
}
-static void
-table_drag_data_get (ETable *table,
- int row,
- int col,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- gpointer user_data)
+GtkTargetList *
+e_addressbook_view_get_paste_target_list (EAddressbookView *view)
{
- EAddressbookView *view = user_data;
-
- if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER(view->object))
- return;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
- switch (info) {
- case DND_TARGET_TYPE_VCARD: {
- char *value;
+ return view->priv->paste_target_list;
+}
- row = e_table_view_to_model_row (table, row);
- value = e_card_get_vcard(view->model->data[row]);
+static void
+status_message (EAddressbookView *view,
+ const gchar *status,
+ gint percent)
+{
+ EActivity *activity;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+
+ activity = view->priv->activity;
+ shell_view = e_addressbook_view_get_shell_view (view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ if (status == NULL || *status == '\0') {
+ if (activity != NULL) {
+ view->priv->activity = NULL;
+ e_activity_set_state (activity, E_ACTIVITY_COMPLETED);
+ g_object_unref (activity);
+ }
- gtk_selection_data_set (selection_data,
- selection_data->target,
- 8,
- value, strlen (value));
- break;
- }
+ } else if (activity == NULL) {
+ activity = e_activity_new ();
+ view->priv->activity = activity;
+ e_activity_set_text (activity, status);
+ if (percent >= 0)
+ e_activity_set_percent (activity, percent);
+ e_shell_backend_add_activity (shell_backend, activity);
+ } else {
+ e_activity_set_text (activity, status);
+ if (percent >= 0)
+ e_activity_set_percent (activity, percent);
}
}
static void
-emit_status_message (EAddressbookView *eav, const gchar *status)
+search_result (EAddressbookView *view,
+ const GError *error)
{
- gtk_signal_emit (GTK_OBJECT (eav),
- e_addressbook_view_signals [STATUS_MESSAGE],
- status);
-}
+ EShellView *shell_view;
+ EAlertSink *alert_sink;
-static void
-emit_search_result (EAddressbookView *eav, EBookViewStatus status)
-{
- gtk_signal_emit (GTK_OBJECT (eav),
- e_addressbook_view_signals [SEARCH_RESULT],
- status);
-}
+ shell_view = e_addressbook_view_get_shell_view (view);
+ alert_sink = E_ALERT_SINK (e_shell_view_get_shell_content (shell_view));
-static void
-emit_folder_bar_message (EAddressbookView *eav, const gchar *message)
-{
- gtk_signal_emit (GTK_OBJECT (eav),
- e_addressbook_view_signals [FOLDER_BAR_MESSAGE],
- message);
+ eab_search_result_dialog (alert_sink, error);
}
static void
-status_message (GtkObject *object, const gchar *status, EAddressbookView *eav)
+folder_bar_message (EAddressbookView *view,
+ const gchar *message)
{
- emit_status_message (eav, status);
-}
+ EShellView *shell_view;
+ EShellSidebar *shell_sidebar;
+ const gchar *display_name;
-static void
-search_result (GtkObject *object, EBookViewStatus status, EAddressbookView *eav)
-{
- emit_search_result (eav, status);
-}
+ shell_view = e_addressbook_view_get_shell_view (view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
-static void
-folder_bar_message (GtkObject *object, const gchar *status, EAddressbookView *eav)
-{
- emit_folder_bar_message (eav, status);
-}
+ if (view->priv->source == NULL)
+ return;
-static void
-stop_state_changed (GtkObject *object, EAddressbookView *eav)
-{
- command_state_change (eav);
+ display_name = e_source_get_display_name (view->priv->source);
+ e_shell_sidebar_set_primary_text (shell_sidebar, display_name);
+ e_shell_sidebar_set_secondary_text (shell_sidebar, message);
}
static void
-command_state_change (EAddressbookView *eav)
+stop_state_changed (GObject *object,
+ EAddressbookView *view)
{
- /* Reffing during emission is unnecessary. Gtk automatically refs during an emission. */
- gtk_signal_emit (GTK_OBJECT (eav), e_addressbook_view_signals [COMMAND_STATE_CHANGE]);
+ command_state_change (view);
}
static void
-alphabet_state_change (EAddressbookView *eav, gunichar letter)
+command_state_change (EAddressbookView *view)
{
- gtk_signal_emit (GTK_OBJECT (eav), e_addressbook_view_signals [ALPHABET_STATE_CHANGE], letter);
+ g_signal_emit (view, signals[COMMAND_STATE_CHANGE], 0);
}
static void
-backend_died (GtkObject *object, EAddressbookView *eav)
+contact_print_button_draw_page (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr,
+ EPrintable *printable)
{
- char *message = g_strdup_printf (_("The addressbook backend for\n%s\nhas crashed. "
- "You will have to restart Evolution in order "
- "to use it again"),
- e_book_get_uri (eav->book));
- gnome_error_dialog_parented (message, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (eav))));
- g_free (message);
-}
+ GtkPageSetup *setup;
+ gdouble top_margin, page_width;
+ cairo_t *cr;
-static void
-create_table_view (EAddressbookView *view)
-{
- ETableModel *adapter;
- ECardSimple *simple;
- GtkWidget *table;
-
- simple = e_card_simple_new(NULL);
+ setup = gtk_print_context_get_page_setup (context);
+ top_margin = gtk_page_setup_get_top_margin (setup, GTK_UNIT_POINTS);
+ page_width = gtk_page_setup_get_page_width (setup, GTK_UNIT_POINTS);
- adapter = e_addressbook_table_adapter_new(view->model);
+ cr = gtk_print_context_get_cairo_context (context);
- /* Here we create the table. We give it the three pieces of
- the table we've created, the header, the model, and the
- initial layout. It does the rest. */
- table = e_table_scrolled_new_from_spec_file (adapter, NULL, EVOLUTION_ETSPECDIR "/e-addressbook-view.etspec", NULL);
-
- view->object = GTK_OBJECT(adapter);
- view->widget = table;
-
- gtk_signal_connect(GTK_OBJECT(e_table_scrolled_get_table(E_TABLE_SCROLLED(table))), "double_click",
- GTK_SIGNAL_FUNC(table_double_click), view);
- gtk_signal_connect(GTK_OBJECT(e_table_scrolled_get_table(E_TABLE_SCROLLED(table))), "right_click",
- GTK_SIGNAL_FUNC(table_right_click), view);
- gtk_signal_connect(GTK_OBJECT(e_table_scrolled_get_table(E_TABLE_SCROLLED(table))), "white_space_event",
- GTK_SIGNAL_FUNC(table_white_space_event), view);
- gtk_signal_connect(GTK_OBJECT(e_table_scrolled_get_table(E_TABLE_SCROLLED(table))), "selection_change",
- GTK_SIGNAL_FUNC(table_selection_change), view);
-
- /* drag & drop signals */
- e_table_drag_source_set (E_TABLE(E_TABLE_SCROLLED(table)->table), GDK_BUTTON1_MASK,
- drag_types, num_drag_types, GDK_ACTION_MOVE);
-
- gtk_signal_connect (GTK_OBJECT (E_TABLE_SCROLLED(table)->table),
- "table_drag_data_get",
- GTK_SIGNAL_FUNC (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_widget_show( GTK_WIDGET(table) );
-
- gtk_object_unref(GTK_OBJECT(simple));
-}
+ e_printable_reset (printable);
+ while (e_printable_data_left (printable)) {
+ cairo_save (cr);
+ contact_page_draw_footer (operation,context,page_nr++);
+ e_printable_print_page (
+ printable, context, page_width - 16, top_margin + 10, TRUE);
+ cairo_restore (cr);
+ }
+}
static void
-change_view_type (EAddressbookView *view, EAddressbookViewType view_type)
+e_contact_print_button (EPrintable *printable,
+ GtkPrintOperationAction action)
{
- if (view_type == view->view_type)
- return;
+ GtkPrintOperation *operation;
- if (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:
- create_table_view (view);
- break;
- default:
- g_warning ("view_type must be either TABLE or MINICARD\n");
- return;
- }
+ operation = e_print_operation_new ();
+ gtk_print_operation_set_n_pages (operation, 1);
- view->view_type = view_type;
+ g_signal_connect (
+ operation, "draw_page",
+ G_CALLBACK (contact_print_button_draw_page), printable);
- command_state_change (view);
-}
+ gtk_print_operation_run (operation, action, NULL, NULL);
-static void
-e_contact_print_destroy(GnomeDialog *dialog, gpointer data)
-{
- ETableScrolled *table = gtk_object_get_data(GTK_OBJECT(dialog), "table");
- EPrintable *printable = gtk_object_get_data(GTK_OBJECT(dialog), "printable");
- gtk_object_unref(GTK_OBJECT(printable));
- gtk_object_unref(GTK_OBJECT(table));
-}
-
-static void
-e_contact_print_button(GnomeDialog *dialog, gint button, gpointer data)
-{
- GnomePrintMaster *master;
- GnomePrintContext *pc;
- EPrintable *printable = gtk_object_get_data(GTK_OBJECT(dialog), "printable");
- GtkWidget *preview;
- switch( button ) {
- case GNOME_PRINT_PRINT:
- master = gnome_print_master_new_from_dialog( GNOME_PRINT_DIALOG(dialog) );
- pc = gnome_print_master_get_context( master );
- e_printable_reset(printable);
- while (e_printable_data_left(printable)) {
- if (gnome_print_gsave(pc) == -1)
- /* FIXME */;
- if (gnome_print_translate(pc, 72, 72) == -1)
- /* FIXME */;
- e_printable_print_page(printable,
- pc,
- 6.5 * 72,
- 5 * 72,
- TRUE);
- if (gnome_print_grestore(pc) == -1)
- /* FIXME */;
- if (gnome_print_showpage(pc) == -1)
- /* FIXME */;
- }
- gnome_print_master_close(master);
- gnome_print_master_print(master);
- gtk_object_unref(GTK_OBJECT(master));
- gnome_dialog_close(dialog);
- break;
- case GNOME_PRINT_PREVIEW:
- master = gnome_print_master_new_from_dialog( GNOME_PRINT_DIALOG(dialog) );
- pc = gnome_print_master_get_context( master );
- e_printable_reset(printable);
- while (e_printable_data_left(printable)) {
- if (gnome_print_gsave(pc) == -1)
- /* FIXME */;
- if (gnome_print_translate(pc, 72, 72) == -1)
- /* FIXME */;
- e_printable_print_page(printable,
- pc,
- 6.5 * 72,
- 9 * 72,
- TRUE);
- if (gnome_print_grestore(pc) == -1)
- /* FIXME */;
- if (gnome_print_showpage(pc) == -1)
- /* FIXME */;
- }
- gnome_print_master_close(master);
- preview = GTK_WIDGET(gnome_print_master_preview_new(master, "Print Preview"));
- gtk_widget_show_all(preview);
- gtk_object_unref(GTK_OBJECT(master));
- break;
- case GNOME_PRINT_CANCEL:
- gnome_dialog_close(dialog);
- break;
- }
+ g_object_unref (operation);
}
void
-e_addressbook_view_setup_menus (EAddressbookView *view,
- BonoboUIComponent *uic)
+e_addressbook_view_print (EAddressbookView *view,
+ gboolean selection_only,
+ GtkPrintOperationAction action)
{
+ GalView *gal_view;
+ GalViewInstance *view_instance;
- g_return_if_fail (view != NULL);
g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
- g_return_if_fail (uic != NULL);
- g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic));
- init_collection ();
+ view_instance = e_addressbook_view_get_view_instance (view);
+ gal_view = gal_view_instance_get_current_view (view_instance);
- view->uic = uic;
+ /* Print the selected contacts. */
+ if (GAL_IS_VIEW_MINICARD (gal_view) && selection_only) {
+ GSList *contact_list;
- setup_menus (view);
-}
+ contact_list = e_addressbook_view_get_selected (view);
+ e_contact_print (NULL, NULL, contact_list, action);
+ g_slist_free_full (
+ contact_list,
+ (GDestroyNotify) g_object_unref);
-/**
- * e_addressbook_view_discard_menus:
- * @view: An addressbook view.
- *
- * Makes an addressbook view discard its GAL view menus and its views instance
- * objects. This should be called when the corresponding Bonobo component is
- * deactivated.
- **/
-void
-e_addressbook_view_discard_menus (EAddressbookView *view)
-{
- g_return_if_fail (view != NULL);
- g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
- g_return_if_fail (view->view_instance);
+ /* Print the latest query results. */
+ } else if (GAL_IS_VIEW_MINICARD (gal_view)) {
+ EAddressbookModel *model;
+ EBookClient *book_client;
+ EBookQuery *query;
+ const gchar *query_string;
- if (view->view_menus) {
- gal_view_menus_unmerge (view->view_menus, NULL);
+ model = e_addressbook_view_get_model (view);
+ book_client = e_addressbook_model_get_client (model);
+ query_string = e_addressbook_model_get_query (model);
- gtk_object_unref (GTK_OBJECT (view->view_menus));
- view->view_menus = NULL;
- }
+ if (query_string != NULL)
+ query = e_book_query_from_string (query_string);
+ else
+ query = NULL;
- if (view->view_instance) {
- gtk_object_unref (GTK_OBJECT (view->view_instance));
- view->view_instance = NULL;
- }
+ e_contact_print (book_client, query, NULL, action);
- view->uic = NULL;
-}
+ if (query != NULL)
+ e_book_query_unref (query);
-void
-e_addressbook_view_print(EAddressbookView *view)
-{
- if (view->view_type == E_ADDRESSBOOK_VIEW_MINICARD) {
- char *query;
- EBook *book;
- GtkWidget *print;
-
- gtk_object_get (GTK_OBJECT(view->model),
- "query", &query,
- "book", &book,
- NULL);
- print = e_contact_print_dialog_new(book, query);
- g_free(query);
- gtk_widget_show_all(print);
- } else if (view->view_type == E_ADDRESSBOOK_VIEW_TABLE) {
- GtkWidget *dialog;
+ /* XXX Does this print the entire table or just selected? */
+ } else if (GAL_IS_VIEW_ETABLE (gal_view)) {
EPrintable *printable;
- ETable *etable;
-
- dialog = gnome_print_dialog_new("Print cards", 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);
+ GtkWidget *widget;
- gtk_object_get(GTK_OBJECT(view->widget), "table", &etable, NULL);
- printable = e_table_get_printable(etable);
+ widget = gtk_bin_get_child (GTK_BIN (view));
+ printable = e_table_get_printable (E_TABLE (widget));
+ g_object_ref_sink (printable);
- gtk_object_ref(GTK_OBJECT(view->widget));
-
- gtk_object_set_data(GTK_OBJECT(dialog), "table", view->widget);
- gtk_object_set_data(GTK_OBJECT(dialog), "printable", printable);
-
- gtk_signal_connect(GTK_OBJECT(dialog),
- "clicked", GTK_SIGNAL_FUNC(e_contact_print_button), NULL);
- gtk_signal_connect(GTK_OBJECT(dialog),
- "destroy", GTK_SIGNAL_FUNC(e_contact_print_destroy), NULL);
- gtk_widget_show(dialog);
- }
-}
-
-void
-e_addressbook_view_print_preview(EAddressbookView *view)
-{
- if (view->view_type == E_ADDRESSBOOK_VIEW_MINICARD) {
- char *query;
- EBook *book;
-
- gtk_object_get (GTK_OBJECT(view->model),
- "query", &query,
- "book", &book,
- NULL);
- e_contact_print_preview(book, query);
- g_free(query);
- } else if (view->view_type == E_ADDRESSBOOK_VIEW_TABLE) {
- EPrintable *printable;
- ETable *etable;
- GnomePrintMaster *master;
- GnomePrintContext *pc;
- GtkWidget *preview;
-
- gtk_object_get(GTK_OBJECT(view->widget), "table", &etable, NULL);
- printable = e_table_get_printable(etable);
-
- master = gnome_print_master_new();
- gnome_print_master_set_copies (master, 1, FALSE);
- pc = gnome_print_master_get_context( master );
- e_printable_reset(printable);
- while (e_printable_data_left(printable)) {
- if (gnome_print_gsave(pc) == -1)
- /* FIXME */;
- if (gnome_print_translate(pc, 72, 72) == -1)
- /* FIXME */;
- e_printable_print_page(printable,
- pc,
- 6.5 * 72,
- 9 * 72,
- TRUE);
- if (gnome_print_grestore(pc) == -1)
- /* FIXME */;
- if (gnome_print_showpage(pc) == -1)
- /* FIXME */;
- }
- gnome_print_master_close(master);
- preview = GTK_WIDGET(gnome_print_master_preview_new(master, "Print Preview"));
- gtk_widget_show_all(preview);
- gtk_object_unref(GTK_OBJECT(master));
- gtk_object_unref(GTK_OBJECT(printable));
- }
-}
+ e_contact_print_button (printable, action);
-static void
-card_deleted_cb (EBook* book, EBookStatus status, gpointer user_data)
-{
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (_("Error removing card"), status);
+ g_object_unref (printable);
}
}
static void
-do_remove (int i, gpointer user_data)
+report_and_free_error_if_any (GError *error)
{
- EBook *book;
- ECard *card;
- EAddressbookView *view = user_data;
-
- gtk_object_get (GTK_OBJECT(view->model),
- "book", &book,
- NULL);
+ if (!error)
+ return;
- card = e_addressbook_model_get_card (view->model, i);
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (error);
+ return;
+ }
- e_book_remove_card(book, card, card_deleted_cb, view);
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_PERMISSION_DENIED)) {
+ e_alert_run_dialog_for_args (
+ e_shell_get_active_window (NULL),
+ "addressbook:contact-delete-error-perm", NULL);
+ } else {
+ eab_error_dialog (NULL, NULL, _("Failed to delete contact"), error);
+ }
- gtk_object_unref (GTK_OBJECT (card));
+ g_error_free (error);
}
-void
-e_addressbook_view_delete_selection(EAddressbookView *view)
+/* callback function to handle removal of contacts for
+ * which a user doesnt have write permission
+ */
+static void
+remove_contacts_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- ESelectionModel *model = get_selection_model (view);
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ GError *error = NULL;
- g_return_if_fail (model);
+ e_book_client_remove_contacts_finish (book_client, result, &error);
- e_selection_model_foreach (model,
- do_remove,
- view);
-}
-
-static void
-invisible_destroyed (GtkWidget *invisible, EAddressbookView *view)
-{
- view->invisible = NULL;
+ report_and_free_error_if_any (error);
}
static void
-selection_get (GtkWidget *invisible,
- GtkSelectionData *selection_data,
- guint info,
- guint time_stamp,
- EAddressbookView *view)
+remove_contact_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- char *value;
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ GError *error = NULL;
- value = e_card_list_get_vcard(view->clipboard_cards);
+ e_book_client_remove_contact_finish (book_client, result, &error);
- gtk_selection_data_set (selection_data, GDK_SELECTION_TYPE_STRING,
- 8, value, strlen (value));
-
+ report_and_free_error_if_any (error);
}
-static void
-selection_clear_event (GtkWidget *invisible,
- GdkEventSelection *event,
- EAddressbookView *view)
-{
- if (view->clipboard_cards) {
- g_list_foreach (view->clipboard_cards, (GFunc)gtk_object_unref, NULL);
- g_list_free (view->clipboard_cards);
- view->clipboard_cards = NULL;
- }
-}
-
-static void
-selection_received (GtkWidget *invisible,
- GtkSelectionData *selection_data,
- guint time,
- EAddressbookView *view)
-{
- if (selection_data->length < 0 || selection_data->type != GDK_SELECTION_TYPE_STRING) {
- return;
+static gboolean
+addressbook_view_confirm_delete (GtkWindow *parent,
+ gboolean plural,
+ gboolean is_list,
+ const gchar *name)
+{
+ GtkWidget *dialog;
+ gchar *message;
+ gint response;
+
+ if (is_list) {
+ if (plural) {
+ message = g_strdup (
+ _("Are you sure you want to "
+ "delete these contact lists?"));
+ } else if (name == NULL) {
+ message = g_strdup (
+ _("Are you sure you want to "
+ "delete this contact list?"));
+ } else {
+ message = g_strdup_printf (
+ _("Are you sure you want to delete "
+ "this contact list (%s)?"), name);
+ }
+ } else {
+ if (plural) {
+ message = g_strdup (
+ _("Are you sure you want to "
+ "delete these contacts?"));
+ } else if (name == NULL) {
+ message = g_strdup (
+ _("Are you sure you want to "
+ "delete this contact?"));
+ } else {
+ message = g_strdup_printf (
+ _("Are you sure you want to delete "
+ "this contact (%s)?"), name);
+ }
}
- 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 *l;
-
- if (!card_list /* it wasn't a vcard list */)
- return;
- for (l = card_list; l; l = l->next) {
- ECard *card = l->data;
+ dialog = gtk_message_dialog_new (
+ parent, 0, GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_NONE, "%s", message);
+ gtk_dialog_add_buttons (
+ GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
- e_card_merging_book_add_card (view->book, card, NULL /* XXX */, NULL);
- }
+ g_free (message);
- g_list_foreach (card_list, (GFunc)gtk_object_unref, NULL);
- g_list_free (card_list);
- }
+ return (response == GTK_RESPONSE_ACCEPT);
}
-static void
-add_to_list (int model_row, gpointer closure)
-{
- GList **list = closure;
- *list = g_list_prepend (*list, GINT_TO_POINTER (model_row));
-}
+void
+e_addressbook_view_delete_selection (EAddressbookView *view,
+ gboolean is_delete)
+{
+ GSList *list, *l;
+ gboolean plural = FALSE, is_list = FALSE;
+ EContact *contact;
+ ETable *etable = NULL;
+ EAddressbookModel *model;
+ EBookClient *book_client;
+ ESelectionModel *selection_model = NULL;
+ GalViewInstance *view_instance;
+ GalView *gal_view;
+ GtkWidget *widget;
+ gchar *name = NULL;
+ gint row = 0, select;
+
+ model = e_addressbook_view_get_model (view);
+ book_client = e_addressbook_model_get_client (model);
+
+ view_instance = e_addressbook_view_get_view_instance (view);
+ gal_view = gal_view_instance_get_current_view (view_instance);
+
+ list = e_addressbook_view_get_selected (view);
+ contact = list->data;
+
+ if (g_slist_next (list))
+ plural = TRUE;
+ else
+ name = e_contact_get (contact, E_CONTACT_FILE_AS);
-static GList *
-get_selected_cards (EAddressbookView *view)
-{
- GList *list;
- GList *iterator;
- ESelectionModel *selection = get_selection_model (view);
+ if (e_contact_get (contact, E_CONTACT_IS_LIST))
+ is_list = TRUE;
- list = NULL;
- e_selection_model_foreach (selection, add_to_list, &list);
+ widget = gtk_bin_get_child (GTK_BIN (view));
- for (iterator = list; iterator; iterator = iterator->next) {
- iterator->data = e_addressbook_model_card_at (view->model, GPOINTER_TO_INT (iterator->data));
- if (iterator->data)
- gtk_object_ref (iterator->data);
+ if (GAL_IS_VIEW_MINICARD (gal_view)) {
+ selection_model = e_addressbook_view_get_selection_model (view);
+ row = e_selection_model_cursor_row (selection_model);
}
- list = g_list_reverse (list);
- return list;
-}
-#if 0
-void
-e_addressbook_view_save_state (EAddressbookView *view, const char *filename)
-{
- xmlDoc *doc;
- xmlNode *node;
-
- doc = xmlNewDoc ("1.0");
- node = xmlNewDocNode (doc, NULL, "addressbook-view", NULL);
- xmlDocSetRootElement (doc, node);
-
- switch (view->view_type) {
- case E_ADDRESSBOOK_VIEW_MINICARD: {
- int column_width;
- e_xml_set_string_prop_by_name (node, "style", "minicard");
- gtk_object_get (GTK_OBJECT (view->object),
- "column_width", &column_width,
- NULL);
- e_xml_set_integer_prop_by_name (node, "column-width", column_width);
- break;
- }
- case E_ADDRESSBOOK_VIEW_TABLE: {
- ETableState *state;
- state = e_table_get_state_object (E_TABLE (view->widget));
-
- e_xml_set_string_prop_by_name (node, "style", "table");
- e_table_state_save_to_node (state, node);
- gtk_object_unref (GTK_OBJECT (state));
- break;
+ else if (GAL_IS_VIEW_ETABLE (gal_view)) {
+ etable = E_TABLE (widget);
+ row = e_table_get_cursor_row (E_TABLE (etable));
}
- default:
- xmlFreeDoc(doc);
+
+ /* confirm delete */
+ if (is_delete && !addressbook_view_confirm_delete (
+ GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view))),
+ plural, is_list, name)) {
+ g_free (name);
+ g_slist_free_full (list, (GDestroyNotify) g_object_unref);
return;
}
- xmlSaveFile (filename, doc);
- xmlFreeDoc(doc);
-}
-void
-e_addressbook_view_load_state (EAddressbookView *view, const char *filename)
-{
- xmlDoc *doc;
+ if (e_client_check_capability (E_CLIENT (book_client), "bulk-remove")) {
+ GSList *ids = NULL;
- doc = xmlParseFile (filename);
- if (doc) {
- xmlNode *node;
- char *type;
+ for (l = list; l; l = g_slist_next (l)) {
+ const gchar *uid;
- node = xmlDocGetRootElement (doc);
- type = e_xml_get_string_prop_by_name (node, "style");
+ contact = l->data;
- if (!strcmp (type, "minicard")) {
- int column_width;
-
- change_view_type (view, E_ADDRESSBOOK_VIEW_MINICARD);
+ uid = e_contact_get_const (contact, E_CONTACT_UID);
+ ids = g_slist_prepend (ids, (gpointer) uid);
+ }
- column_width = e_xml_get_integer_prop_by_name (node, "column-width");
- gtk_object_set (GTK_OBJECT (view->object),
- "column_width", column_width,
- NULL);
- } else if (!strcmp (type, "table")) {
- ETableState *state;
+ /* Remove the cards all at once. */
+ e_book_client_remove_contacts (
+ book_client, ids, NULL, remove_contacts_cb, NULL);
- change_view_type (view, E_ADDRESSBOOK_VIEW_TABLE);
+ g_slist_free (ids);
+ } else {
+ for (l = list; l; l = g_slist_next (l)) {
+ contact = l->data;
- state = e_table_state_new();
- e_table_state_load_from_node (state, node->xmlChildrenNode);
- e_table_set_state_object (E_TABLE (view->widget), state);
- gtk_object_unref (GTK_OBJECT (state));
+ /* Remove the card. */
+ e_book_client_remove_contact (
+ book_client, contact, NULL,
+ remove_contact_cb, NULL);
}
- xmlFreeDoc(doc);
}
-}
-#endif
-void
-e_addressbook_view_save_as (EAddressbookView *view)
-{
- GList *list = get_selected_cards (view);
- if (list)
- e_contact_list_save_as (_("Save as VCard"), list, NULL);
- e_free_object_list(list);
-}
+ /* Sets the cursor, at the row after the deleted row */
+ if (GAL_IS_VIEW_MINICARD (gal_view) && row != 0 && selection_model) {
+ select = e_sorter_model_to_sorted (selection_model->sorter, row);
-void
-e_addressbook_view_view (EAddressbookView *view)
-{
- GList *list = get_selected_cards (view);
- e_addressbook_show_multiple_cards (view->book, list, view->editable);
- e_free_object_list(list);
-}
+ /* Sets the cursor, before the deleted row if its the last row */
+ if (select == e_selection_model_row_count (selection_model) - 1)
+ select = select - 1;
+ else
+ select = select + 1;
-void
-e_addressbook_view_send (EAddressbookView *view)
-{
- GList *list = get_selected_cards (view);
- if (list)
- e_card_list_send (list, E_CARD_DISPOSITION_AS_ATTACHMENT);
- e_free_object_list(list);
-}
+ row = e_sorter_sorted_to_model (selection_model->sorter, select);
+ e_selection_model_cursor_changed (selection_model, row, 0);
+ }
-void
-e_addressbook_view_send_to (EAddressbookView *view)
-{
- GList *list = get_selected_cards (view);
- if (list)
- e_card_list_send (list, E_CARD_DISPOSITION_AS_TO);
- e_free_object_list(list);
-}
+ /* Sets the cursor, at the row after the deleted row */
+ else if (GAL_IS_VIEW_ETABLE (gal_view) && row != 0) {
+ select = e_table_model_to_view_row (E_TABLE (etable), row);
-void
-e_addressbook_view_cut (EAddressbookView *view)
-{
- e_addressbook_view_copy (view);
- e_addressbook_view_delete_selection (view);
+ /* Sets the cursor, before the deleted row if its the last row */
+ if (select == e_table_model_row_count (E_TABLE (etable)->model) - 1)
+ select = select - 1;
+ else
+ select = select + 1;
+
+ row = e_table_view_to_model_row (E_TABLE (etable), select);
+ e_table_set_cursor_row (E_TABLE (etable), row);
+ }
+ g_slist_free_full (list, (GDestroyNotify) g_object_unref);
}
void
-e_addressbook_view_copy (EAddressbookView *view)
+e_addressbook_view_view (EAddressbookView *view)
{
- view->clipboard_cards = get_selected_cards (view);
+ GSList *list, *iter;
+ gint response;
+ guint length;
- gtk_selection_owner_set (view->invisible, clipboard_atom, GDK_CURRENT_TIME);
-}
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
-void
-e_addressbook_view_paste (EAddressbookView *view)
-{
- gtk_selection_convert (view->invisible, clipboard_atom,
- GDK_SELECTION_TYPE_STRING,
- GDK_CURRENT_TIME);
-}
+ list = e_addressbook_view_get_selected (view);
+ length = g_slist_length (list);
+ response = GTK_RESPONSE_YES;
-void
-e_addressbook_view_select_all (EAddressbookView *view)
-{
- ESelectionModel *model = get_selection_model (view);
+ if (length > 5) {
+ GtkWidget *dialog;
+
+ /* XXX Use e_alert_new(). */
+ /* XXX Provide a parent window. */
+ dialog = gtk_message_dialog_new (
+ NULL, 0,
+ GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, ngettext (
+ /* Translators: This is shown for > 5 contacts. */
+ "Opening %d contacts will open %d new windows "
+ "as well.\nDo you really want to display all of "
+ "these contacts?",
+ "Opening %d contacts will open %d new windows "
+ "as well.\nDo you really want to display all of "
+ "these contacts?", length), length, length);
+ gtk_dialog_add_buttons (
+ GTK_DIALOG (dialog),
+ _("_Don't Display"), GTK_RESPONSE_NO,
+ _("Display _All Contacts"), GTK_RESPONSE_YES,
+ NULL);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ }
- g_return_if_fail (model);
+ if (response == GTK_RESPONSE_YES)
+ for (iter = list; iter != NULL; iter = iter->next)
+ addressbook_view_emit_open_contact (
+ view, iter->data, FALSE);
- e_selection_model_select_all (model);
+ g_slist_free_full (list, (GDestroyNotify) g_object_unref);
}
void
-e_addressbook_view_show_all(EAddressbookView *view)
+e_addressbook_view_show_all (EAddressbookView *view)
{
- gtk_object_set(GTK_OBJECT(view),
- "query", NULL,
- NULL);
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
+
+ e_addressbook_model_set_query (view->priv->model, "");
}
void
-e_addressbook_view_stop(EAddressbookView *view)
+e_addressbook_view_stop (EAddressbookView *view)
{
- if (view)
- e_addressbook_model_stop (view->model);
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
+
+ e_addressbook_model_stop (view->priv->model);
}
-static void
-view_transfer_cards (EAddressbookView *view, gboolean delete_from_source)
+struct TransferContactsData
{
- EBook *book;
- GList *cards;
- GtkWindow *parent_window;
-
- gtk_object_get(GTK_OBJECT(view->model),
- "book", &book,
- NULL);
- cards = get_selected_cards (view);
- parent_window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view)));
+ gboolean delete_from_source;
+ EAddressbookView *view;
+};
- e_addressbook_transfer_cards (book, cards, delete_from_source, parent_window);
-}
+static void
+all_contacts_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ struct TransferContactsData *tcd = user_data;
+ EAddressbookModel *model;
+ EClientCache *client_cache;
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ EAlertSink *alert_sink;
+ GSList *contacts = NULL;
+ GError *error = NULL;
+
+ g_return_if_fail (book_client != NULL);
+ g_return_if_fail (tcd != NULL);
+
+ if (!e_book_client_get_contacts_finish (book_client, result, &contacts, &error))
+ contacts = NULL;
+
+ shell_view = e_addressbook_view_get_shell_view (tcd->view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ alert_sink = E_ALERT_SINK (shell_content);
+
+ model = e_addressbook_view_get_model (tcd->view);
+ client_cache = e_addressbook_model_get_client_cache (model);
+
+ if (error) {
+ e_alert_submit (
+ alert_sink, "addressbook:search-error",
+ error->message, NULL);
+ g_error_free (error);
+ } else if (contacts) {
+ ESourceRegistry *registry;
+
+ registry = e_client_cache_ref_registry (client_cache);
+
+ eab_transfer_contacts (
+ registry, book_client, contacts,
+ tcd->delete_from_source, alert_sink);
+
+ g_object_unref (registry);
+ }
-void
-e_addressbook_view_copy_to_folder (EAddressbookView *view)
-{
- view_transfer_cards (view, FALSE);
+ g_object_unref (tcd->view);
+ g_free (tcd);
}
-void
-e_addressbook_view_move_to_folder (EAddressbookView *view)
-{
- view_transfer_cards (view, TRUE);
-}
+static void
+view_transfer_contacts (EAddressbookView *view,
+ gboolean delete_from_source,
+ gboolean all)
+{
+ EAddressbookModel *model;
+ EBookClient *book_client;
+ EClientCache *client_cache;
+
+ model = e_addressbook_view_get_model (view);
+ book_client = e_addressbook_model_get_client (model);
+ client_cache = e_addressbook_model_get_client_cache (model);
+
+ if (all) {
+ EBookQuery *query;
+ gchar *query_str;
+ struct TransferContactsData *tcd;
+
+ query = e_book_query_any_field_contains ("");
+ query_str = e_book_query_to_string (query);
+ e_book_query_unref (query);
+
+ tcd = g_new0 (struct TransferContactsData, 1);
+ tcd->delete_from_source = delete_from_source;
+ tcd->view = g_object_ref (view);
+
+ e_book_client_get_contacts (
+ book_client, query_str, NULL,
+ all_contacts_ready_cb, tcd);
+ } else {
+ GSList *contacts = NULL;
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ EAlertSink *alert_sink;
+ ESourceRegistry *registry;
+ shell_view = e_addressbook_view_get_shell_view (view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ alert_sink = E_ALERT_SINK (shell_content);
-static gboolean
-e_addressbook_view_selection_nonempty (EAddressbookView *view)
-{
- ESelectionModel *selection_model;
+ contacts = e_addressbook_view_get_selected (view);
- selection_model = get_selection_model (view);
- if (selection_model == NULL)
- return FALSE;
+ registry = e_client_cache_ref_registry (client_cache);
- return e_selection_model_selected_count (selection_model) != 0;
-}
+ eab_transfer_contacts (
+ registry, book_client, contacts,
+ delete_from_source, alert_sink);
-gboolean
-e_addressbook_view_can_create (EAddressbookView *view)
-{
- return view ? e_addressbook_model_editable (view->model) : FALSE;
+ g_object_unref (registry);
+ }
}
-gboolean
-e_addressbook_view_can_print (EAddressbookView *view)
+void
+e_addressbook_view_copy_to_folder (EAddressbookView *view,
+ gboolean all)
{
- return view && view->model ? e_addressbook_model_card_count (view->model) : FALSE;
+ view_transfer_contacts (view, FALSE, all);
}
-gboolean
-e_addressbook_view_can_save_as (EAddressbookView *view)
+void
+e_addressbook_view_move_to_folder (EAddressbookView *view,
+ gboolean all)
{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
+ view_transfer_contacts (view, TRUE, all);
}
-gboolean
-e_addressbook_view_can_view (EAddressbookView *view)
+void
+e_addressbook_view_set_search (EAddressbookView *view,
+ gint filter_id,
+ gint search_id,
+ const gchar *search_text,
+ EFilterRule *advanced_search)
{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
-}
+ EAddressbookViewPrivate *priv;
-gboolean
-e_addressbook_view_can_send (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
-}
+ g_return_if_fail (view != NULL);
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
-gboolean
-e_addressbook_view_can_send_to (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
-}
+ priv = view->priv;
-gboolean
-e_addressbook_view_can_delete (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) && e_addressbook_model_editable (view->model) : FALSE;
-}
+ if (priv->search_text)
+ g_free (priv->search_text);
+ if (priv->advanced_search)
+ g_object_unref (priv->advanced_search);
-gboolean
-e_addressbook_view_can_cut (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) && e_addressbook_model_editable (view->model) : FALSE;
-}
+ priv->filter_id = filter_id;
+ priv->search_id = search_id;
+ priv->search_text = g_strdup (search_text);
-gboolean
-e_addressbook_view_can_copy (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
+ if (advanced_search != NULL)
+ priv->advanced_search = e_filter_rule_clone (advanced_search);
+ else
+ priv->advanced_search = NULL;
}
-gboolean
-e_addressbook_view_can_paste (EAddressbookView *view)
+/* Free returned values for search_text and advanced_search,
+ * if not NULL, as these are new copies. */
+void
+e_addressbook_view_get_search (EAddressbookView *view,
+ gint *filter_id,
+ gint *search_id,
+ gchar **search_text,
+ EFilterRule **advanced_search)
{
- return view ? e_addressbook_model_editable (view->model) : FALSE;
-}
+ EAddressbookViewPrivate *priv;
-gboolean
-e_addressbook_view_can_select_all (EAddressbookView *view)
-{
- return view ? e_addressbook_model_card_count (view->model) != 0 : FALSE;
-}
+ g_return_if_fail (view != NULL);
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
+ g_return_if_fail (filter_id != NULL);
+ g_return_if_fail (search_id != NULL);
+ g_return_if_fail (search_text != NULL);
+ g_return_if_fail (advanced_search != NULL);
-gboolean
-e_addressbook_view_can_stop (EAddressbookView *view)
-{
- return view ? e_addressbook_model_can_stop (view->model) : FALSE;
-}
+ priv = view->priv;
-gboolean
-e_addressbook_view_can_copy_to_folder (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
-}
+ *filter_id = priv->filter_id;
+ *search_id = priv->search_id;
+ *search_text = g_strdup (priv->search_text);
-gboolean
-e_addressbook_view_can_move_to_folder (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) && e_addressbook_model_editable (view->model) : FALSE;
+ if (priv->advanced_search != NULL)
+ *advanced_search = e_filter_rule_clone (priv->advanced_search);
+ else
+ *advanced_search = NULL;
}
diff --git a/addressbook/gui/widgets/e-addressbook-view.etspec b/addressbook/gui/widgets/e-addressbook-view.etspec
index a0a0015d75..45eaea1df3 100644
--- a/addressbook/gui/widgets/e-addressbook-view.etspec
+++ b/addressbook/gui/widgets/e-addressbook-view.etspec
@@ -1,51 +1,65 @@
-<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= "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="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"/>
- <ETableColumn model_col="13" _title="Car Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="14" _title="Business Fax" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="15" _title="Home Fax" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="16" _title="Business Phone 2" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="17" _title="Home Phone 2" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="18" _title="ISDN" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="19" _title="Other Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="20" _title="Other Fax" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="21" _title="Pager" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="22" _title="Radio" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <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="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="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"/>
+<ETableSpecification draw-grid="true" cursor-mode="line">
+ <ETableColumn model_col= "2" _title="File As" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "4" _title="Full Name" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "5" _title="Given Name" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "6" _title="Family Name" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "7" _title="Nickname" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+ <ETableColumn model_col= "8" _title="Email" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "9" _title="Email 2" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "10" _title="Email 3" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+ <ETableColumn model_col= "16" _title="Assistant Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "17" _title="Business Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "18" _title="Business Phone 2" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="19" _title="Business Fax" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="20" _title="Callback Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="21" _title="Car Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="22" _title="Company Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="23" _title="Home Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="24" _title="Home Phone 2" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="25" _title="Home Fax" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="26" _title="ISDN Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="27" _title="Mobile Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="28" _title="Other Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="29" _title="Other Fax" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="30" _title="Pager" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="31" _title="Primary Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="32" _title="Radio" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="33" _title="Telex" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+<!-- Translators: This is a vcard standard and stands for the type of
+ phone used by the hearing impaired. TTY stands for "teletype"
+ (familiar from Unix device names), and TDD is "Telecommunications
+ Device for Deaf". However, you probably want to leave this
+ abbreviation unchanged unless you know that there is actually a
+ different and established translation for this in your language. -->
+ <ETableColumn model_col="34" _title="TTYTDD" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+ <ETableColumn model_col="35" _title="Company" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="stringcase"/>
+ <ETableColumn model_col="36" _title="Unit" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="37" _title="Office" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="38" _title="Title" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="39" _title="Role" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="40" _title="Manager" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="41" _title="Assistant" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+ <ETableColumn model_col="42" _title="Web Site" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="43" _title="Journal" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+ <ETableColumn model_col="44" _title="Categories" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+ <ETableColumn model_col="49" _title="Spouse" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="50" _title="Note" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
<ETableState>
<column source="0"/>
<column source="1"/>
<column source="5"/>
- <column source="2"/>
- <column source="3"/>
+ <column source="23"/>
+ <column source="36"/>
<grouping>
- <leaf column="0" ascending="true"/>
+ <leaf column="2" ascending="true"/>
</grouping>
</ETableState>
</ETableSpecification>
diff --git a/addressbook/gui/widgets/e-addressbook-view.h b/addressbook/gui/widgets/e-addressbook-view.h
index 897c37d420..94668d6ace 100644
--- a/addressbook/gui/widgets/e-addressbook-view.h
+++ b/addressbook/gui/widgets/e-addressbook-view.h
@@ -1,147 +1,129 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-addressbook-view.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser 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_VIEW_H__
-#define __E_ADDRESSBOOK_VIEW_H__
-
-#include <gtk/gtktable.h>
-#include <bonobo/bonobo-ui-component.h>
-#include <gal/menus/gal-view-instance.h>
-#include "e-addressbook-model.h"
-#include "widgets/menus/gal-view-menus.h"
-#include "addressbook/backend/ebook/e-book.h"
-#include <gal/unicode/gunicode.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* EAddressbookView - A card displaying information about a contact.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
*
- * The following arguments are available:
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * name type read/write description
- * --------------------------------------------------------------------------------
*/
-#define E_ADDRESSBOOK_VIEW_TYPE (e_addressbook_view_get_type ())
-#define E_ADDRESSBOOK_VIEW(obj) (GTK_CHECK_CAST ((obj), E_ADDRESSBOOK_VIEW_TYPE, EAddressbookView))
-#define E_ADDRESSBOOK_VIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_ADDRESSBOOK_VIEW_TYPE, EAddressbookViewClass))
-#define E_IS_ADDRESSBOOK_VIEW(obj) (GTK_CHECK_TYPE ((obj), E_ADDRESSBOOK_VIEW_TYPE))
-#define E_IS_ADDRESSBOOK_VIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_ADDRESSBOOK_VIEW_TYPE))
+#ifndef E_ADDRESSBOOK_VIEW_H
+#define E_ADDRESSBOOK_VIEW_H
-typedef enum {
- E_ADDRESSBOOK_VIEW_NONE, /* initialized to this */
- E_ADDRESSBOOK_VIEW_TABLE,
- E_ADDRESSBOOK_VIEW_MINICARD
-} EAddressbookViewType;
+#include <libebook/libebook.h>
+#include <shell/e-shell-view.h>
-typedef struct _EAddressbookView EAddressbookView;
-typedef struct _EAddressbookViewClass EAddressbookViewClass;
-
-struct _EAddressbookView
-{
- GtkTable parent;
-
- /* item specific fields */
- EAddressbookViewType view_type;
-
- EAddressbookModel *model;
-
- GtkWidget *invisible;
- GList *clipboard_cards;
-
- EBook *book;
- char *query;
- guint editable : 1;
-
- GtkObject *object;
- GtkWidget *widget;
- GtkWidget *current_alphabet_widget;
-
- GtkWidget *vbox;
-
- /* Menus handler and the view instance */
- GalViewInstance *view_instance;
- GalViewMenus *view_menus;
- GalView *current_view;
- BonoboUIComponent *uic;
+#include "e-addressbook-model.h"
+#include "eab-contact-display.h"
+
+/* Standard GObject macros */
+#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(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), 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(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_ADDRESSBOOK_VIEW))
+#define E_ADDRESSBOOK_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EAddressbookView EAddressbookView;
+typedef struct _EAddressbookViewClass EAddressbookViewClass;
+typedef struct _EAddressbookViewPrivate EAddressbookViewPrivate;
+
+struct _EAddressbookView {
+ GtkScrolledWindow parent;
+ EAddressbookViewPrivate *priv;
};
-struct _EAddressbookViewClass
-{
- GtkTableClass 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);
+struct _EAddressbookViewClass {
+ GtkScrolledWindowClass parent_class;
+
+ /* Signals */
+ void (*open_contact) (EAddressbookView *view,
+ EContact *contact,
+ gboolean is_new_contact);
+ void (*popup_event) (EAddressbookView *view,
+ GdkEvent *event);
+ void (*command_state_change) (EAddressbookView *view);
+ void (*selection_change) (EAddressbookView *view);
};
-GtkWidget *e_addressbook_view_new (void);
-GtkType 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__ */
+GType e_addressbook_view_get_type (void);
+GtkWidget * e_addressbook_view_new (EShellView *shell_view,
+ ESource *source);
+EAddressbookModel *
+ e_addressbook_view_get_model (EAddressbookView *view);
+GalViewInstance *
+ e_addressbook_view_get_view_instance
+ (EAddressbookView *view);
+GObject * e_addressbook_view_get_view_object
+ (EAddressbookView *view);
+GSList * e_addressbook_view_get_selected (EAddressbookView *view);
+ESelectionModel *
+ e_addressbook_view_get_selection_model
+ (EAddressbookView *view);
+EShellView * e_addressbook_view_get_shell_view
+ (EAddressbookView *view);
+ESource * e_addressbook_view_get_source (EAddressbookView *view);
+GtkTargetList * e_addressbook_view_get_copy_target_list
+ (EAddressbookView *view);
+GtkTargetList * e_addressbook_view_get_paste_target_list
+ (EAddressbookView *view);
+void e_addressbook_view_view (EAddressbookView *view);
+void e_addressbook_view_print (EAddressbookView *view,
+ gboolean selection_only,
+ GtkPrintOperationAction action);
+void e_addressbook_view_delete_selection
+ (EAddressbookView *view,
+ gboolean is_delete);
+void e_addressbook_view_show_all (EAddressbookView *view);
+void e_addressbook_view_stop (EAddressbookView *view);
+void e_addressbook_view_copy_to_folder
+ (EAddressbookView *view,
+ gboolean all);
+void e_addressbook_view_move_to_folder
+ (EAddressbookView *view,
+ gboolean all);
+
+gboolean e_addressbook_view_can_create (EAddressbookView *view);
+
+void e_addressbook_view_set_search (EAddressbookView *view,
+ gint filter_id,
+ gint search_id,
+ const gchar *search_text,
+ EFilterRule *advanced_search);
+
+void e_addressbook_view_get_search (EAddressbookView *view,
+ gint *filter_id,
+ gint *search_id,
+ gchar **search_text,
+ EFilterRule **advanced_search);
+
+G_END_DECLS
+
+#endif /* E_ADDRESSBOOK_VIEW_H */
diff --git a/addressbook/gui/widgets/e-contact-map-window.c b/addressbook/gui/widgets/e-contact-map-window.c
new file mode 100644
index 0000000000..1dbe694d50
--- /dev/null
+++ b/addressbook/gui/widgets/e-contact-map-window.c
@@ -0,0 +1,500 @@
+/*
+ * e-contact-map-window.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WITH_CONTACT_MAPS
+
+#include "e-contact-map.h"
+#include "e-contact-map-window.h"
+#include "e-contact-marker.h"
+
+#include <champlain/champlain.h>
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+#include <glib-object.h>
+
+#define E_CONTACT_MAP_WINDOW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindowPrivate))
+
+G_DEFINE_TYPE (EContactMapWindow, e_contact_map_window, GTK_TYPE_WINDOW)
+
+struct _EContactMapWindowPrivate {
+ EContactMap *map;
+
+ GtkWidget *zoom_in_btn;
+ GtkWidget *zoom_out_btn;
+
+ GtkWidget *search_entry;
+ GtkListStore *completion_model;
+
+ GHashTable *hash_table; /* Hash table contact-name -> marker */
+
+ GtkWidget *spinner;
+ gint tasks_cnt;
+};
+
+enum {
+ SHOW_CONTACT_EDITOR,
+ LAST_SIGNAL
+};
+
+static gint signals[LAST_SIGNAL] = {0};
+
+static void
+marker_doubleclick_cb (ClutterActor *actor,
+ gpointer user_data)
+{
+ EContactMapWindow *window = user_data;
+ EContactMarker *marker;
+ const gchar *contact_uid;
+
+ marker = E_CONTACT_MARKER (actor);
+ contact_uid = e_contact_marker_get_contact_uid (marker);
+
+ g_signal_emit (window, signals[SHOW_CONTACT_EDITOR], 0, contact_uid);
+}
+
+static void
+book_contacts_received_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EContactMapWindow *window = user_data;
+ EBookClient *client = E_BOOK_CLIENT (source_object);
+ GSList *contacts = NULL, *p;
+ GError *error = NULL;
+
+ if (!e_book_client_get_contacts_finish (client, result, &contacts, &error))
+ contacts = NULL;
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to get contacts: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ for (p = contacts; p; p = p->next)
+ e_contact_map_add_contact (
+ window->priv->map, (EContact *) p->data);
+
+ g_slist_free_full (contacts, (GDestroyNotify) g_object_unref);
+ g_object_unref (client);
+}
+
+static void
+contact_map_window_zoom_in_cb (GtkButton *button,
+ gpointer user_data)
+{
+ EContactMapWindow *window = user_data;
+ ChamplainView *view;
+
+ view = e_contact_map_get_view (window->priv->map);
+
+ champlain_view_zoom_in (view);
+}
+
+static void
+contact_map_window_zoom_out_cb (GtkButton *button,
+ gpointer user_data)
+{
+ EContactMapWindow *window = user_data;
+ ChamplainView *view;
+
+ view = e_contact_map_get_view (window->priv->map);
+
+ champlain_view_zoom_out (view);
+}
+static void
+zoom_level_changed_cb (ChamplainView *view,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ EContactMapWindow *window = user_data;
+ gint zoom_level = champlain_view_get_zoom_level (view);
+
+ gtk_widget_set_sensitive (
+ window->priv->zoom_in_btn,
+ (zoom_level < champlain_view_get_max_zoom_level (view)));
+
+ gtk_widget_set_sensitive (
+ window->priv->zoom_out_btn,
+ (zoom_level > champlain_view_get_min_zoom_level (view)));
+}
+
+/**
+ * Add contact to hash_table only when EContactMap tells us
+ * that the contact has really been added to map.
+ */
+static void
+map_contact_added_cb (EContactMap *map,
+ ClutterActor *marker,
+ gpointer user_data)
+{
+ EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
+ const gchar *name;
+ GtkTreeIter iter;
+
+ name = champlain_label_get_text (CHAMPLAIN_LABEL (marker));
+
+ g_hash_table_insert (
+ priv->hash_table,
+ g_strdup (name), marker);
+
+ gtk_list_store_append (priv->completion_model, &iter);
+ gtk_list_store_set (
+ priv->completion_model, &iter,
+ 0, name, -1);
+
+ g_signal_connect (
+ marker, "double-clicked",
+ G_CALLBACK (marker_doubleclick_cb), user_data);
+
+ priv->tasks_cnt--;
+ if (priv->tasks_cnt == 0) {
+ gtk_spinner_stop (GTK_SPINNER (priv->spinner));
+ gtk_widget_hide (priv->spinner);
+ }
+}
+
+static void
+map_contact_removed_cb (EContactMap *map,
+ const gchar *name,
+ gpointer user_data)
+{
+ EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
+ GtkTreeIter iter;
+ GtkTreeModel *model = GTK_TREE_MODEL (priv->completion_model);
+
+ g_hash_table_remove (priv->hash_table, name);
+
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ do {
+ gchar *name_str;
+ gtk_tree_model_get (model, &iter, 0, &name_str, -1);
+ if (g_ascii_strcasecmp (name_str, name) == 0) {
+ g_free (name_str);
+ gtk_list_store_remove (priv->completion_model, &iter);
+ break;
+ }
+ g_free (name_str);
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
+}
+
+static void
+map_contact_geocoding_started_cb (EContactMap *map,
+ ClutterActor *marker,
+ gpointer user_data)
+{
+ EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
+
+ gtk_spinner_start (GTK_SPINNER (priv->spinner));
+ gtk_widget_show (priv->spinner);
+
+ priv->tasks_cnt++;
+}
+
+static void
+map_contact_geocoding_failed_cb (EContactMap *map,
+ const gchar *name,
+ gpointer user_data)
+{
+ EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
+
+ priv->tasks_cnt--;
+
+ if (priv->tasks_cnt == 0) {
+ gtk_spinner_stop (GTK_SPINNER (priv->spinner));
+ gtk_widget_hide (priv->spinner);
+ }
+}
+
+static void
+contact_map_window_find_contact_cb (GtkButton *button,
+ gpointer user_data)
+{
+ EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
+ ClutterActor *marker;
+
+ marker = g_hash_table_lookup (
+ priv->hash_table,
+ gtk_entry_get_text (GTK_ENTRY (priv->search_entry)));
+
+ if (marker)
+ e_contact_map_zoom_on_marker (priv->map, marker);
+}
+
+static gboolean
+contact_map_window_entry_key_pressed_cb (GtkWidget *entry,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+ if (event->keyval == GDK_KEY_Return)
+ contact_map_window_find_contact_cb (NULL, user_data);
+
+ return FALSE;
+}
+
+static gboolean
+entry_completion_match_selected_cb (GtkEntryCompletion *widget,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ GValue name_val = {0};
+ EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
+ const gchar *name;
+
+ gtk_tree_model_get_value (model, iter, 0, &name_val);
+ g_return_val_if_fail (G_VALUE_HOLDS_STRING (&name_val), FALSE);
+
+ name = g_value_get_string (&name_val);
+ gtk_entry_set_text (GTK_ENTRY (priv->search_entry), name);
+
+ contact_map_window_find_contact_cb (NULL, user_data);
+
+ return TRUE;
+}
+
+static void
+contact_map_window_finalize (GObject *object)
+{
+ EContactMapWindowPrivate *priv;
+
+ priv = E_CONTACT_MAP_WINDOW (object)->priv;
+
+ if (priv->hash_table) {
+ g_hash_table_destroy (priv->hash_table);
+ priv->hash_table = NULL;
+ }
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_contact_map_window_parent_class)->finalize (object);
+}
+
+static void
+contact_map_window_dispose (GObject *object)
+{
+ EContactMapWindowPrivate *priv;
+
+ priv = E_CONTACT_MAP_WINDOW (object)->priv;
+
+ if (priv->map) {
+ gtk_widget_destroy (GTK_WIDGET (priv->map));
+ priv->map = NULL;
+ }
+
+ if (priv->completion_model) {
+ g_object_unref (priv->completion_model);
+ priv->completion_model = NULL;
+ }
+
+ G_OBJECT_CLASS (e_contact_map_window_parent_class)->dispose (object);
+}
+
+static void
+e_contact_map_window_class_init (EContactMapWindowClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EContactMapWindowPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = contact_map_window_finalize;
+ object_class->dispose = contact_map_window_dispose;
+
+ signals[SHOW_CONTACT_EDITOR] = g_signal_new (
+ "show-contact-editor",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EContactMapWindowClass, show_contact_editor),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+}
+
+static void
+e_contact_map_window_init (EContactMapWindow *window)
+{
+ EContactMapWindowPrivate *priv;
+ GtkWidget *map;
+ GtkWidget *button, *entry;
+ GtkWidget *hbox, *vbox, *viewport;
+ GtkEntryCompletion *entry_completion;
+ GtkListStore *completion_model;
+ ChamplainView *view;
+ GHashTable *hash_table;
+
+ priv = E_CONTACT_MAP_WINDOW_GET_PRIVATE (window);
+ window->priv = priv;
+
+ priv->tasks_cnt = 0;
+
+ hash_table = g_hash_table_new_full (
+ (GHashFunc) g_str_hash,
+ (GEqualFunc) g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) NULL);
+ priv->hash_table = hash_table;
+
+ gtk_window_set_title (GTK_WINDOW (window), _("Contacts Map"));
+ gtk_container_set_border_width (GTK_CONTAINER (window), 12);
+ gtk_widget_set_size_request (GTK_WIDGET (window), 800, 600);
+
+ /* The map view itself */
+ map = e_contact_map_new ();
+ view = e_contact_map_get_view (E_CONTACT_MAP (map));
+ champlain_view_set_zoom_level (view, 2);
+ priv->map = E_CONTACT_MAP (map);
+ g_signal_connect (
+ view, "notify::zoom-level",
+ G_CALLBACK (zoom_level_changed_cb), window);
+ g_signal_connect (
+ map, "contact-added",
+ G_CALLBACK (map_contact_added_cb), window);
+ g_signal_connect (
+ map, "contact-removed",
+ G_CALLBACK (map_contact_removed_cb), window);
+ g_signal_connect (
+ map, "geocoding-started",
+ G_CALLBACK (map_contact_geocoding_started_cb), window);
+ g_signal_connect (
+ map, "geocoding-failed",
+ G_CALLBACK (map_contact_geocoding_failed_cb), window);
+
+ /* HBox container */
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 7);
+
+ /* Spinner */
+ button = gtk_spinner_new ();
+ gtk_container_add (GTK_CONTAINER (hbox), button);
+ gtk_widget_hide (button);
+ priv->spinner = button;
+
+ /* Zoom-in button */
+ button = gtk_button_new_from_stock (GTK_STOCK_ZOOM_IN);
+ g_signal_connect (
+ button, "clicked",
+ G_CALLBACK (contact_map_window_zoom_in_cb), window);
+ priv->zoom_in_btn = button;
+ gtk_container_add (GTK_CONTAINER (hbox), button);
+
+ /* Zoom-out button */
+ button = gtk_button_new_from_stock (GTK_STOCK_ZOOM_OUT);
+ g_signal_connect (
+ button, "clicked",
+ G_CALLBACK (contact_map_window_zoom_out_cb), window);
+ priv->zoom_out_btn = button;
+ gtk_container_add (GTK_CONTAINER (hbox), button);
+
+ /* Completion model */
+ completion_model = gtk_list_store_new (1, G_TYPE_STRING);
+ priv->completion_model = completion_model;
+
+ /* Entry completion */
+ entry_completion = gtk_entry_completion_new ();
+ gtk_entry_completion_set_model (
+ entry_completion, GTK_TREE_MODEL (completion_model));
+ gtk_entry_completion_set_text_column (entry_completion, 0);
+ g_signal_connect (
+ entry_completion, "match-selected",
+ G_CALLBACK (entry_completion_match_selected_cb), window);
+
+ /* Search entry */
+ entry = gtk_entry_new ();
+ gtk_entry_set_completion (GTK_ENTRY (entry), entry_completion);
+ g_signal_connect (
+ entry, "key-press-event",
+ G_CALLBACK (contact_map_window_entry_key_pressed_cb), window);
+ window->priv->search_entry = entry;
+ gtk_container_add (GTK_CONTAINER (hbox), entry);
+
+ /* Search button */
+ button = gtk_button_new_from_stock (GTK_STOCK_FIND);
+ g_signal_connect (
+ button, "clicked",
+ G_CALLBACK (contact_map_window_find_contact_cb), window);
+ gtk_container_add (GTK_CONTAINER (hbox), button);
+
+ viewport = gtk_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (viewport), map);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_container_add (GTK_CONTAINER (vbox), viewport);
+ gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ gtk_widget_show_all (vbox);
+ gtk_widget_hide (priv->spinner);
+}
+
+EContactMapWindow *
+e_contact_map_window_new (void)
+{
+ return g_object_new (
+ E_TYPE_CONTACT_MAP_WINDOW, NULL);
+}
+
+/**
+ * Gets all contacts from @book and puts them
+ * on the map view
+ */
+void
+e_contact_map_window_load_addressbook (EContactMapWindow *map,
+ EBookClient *book_client)
+{
+ EBookQuery *book_query;
+ gchar *query_string;
+
+ g_return_if_fail (E_IS_CONTACT_MAP_WINDOW (map));
+ g_return_if_fail (E_IS_BOOK_CLIENT (book_client));
+
+ /* Reference book, so that it does not get deleted before the callback is
+ * involved. The book is unrefed in the callback */
+ g_object_ref (book_client);
+
+ book_query = e_book_query_field_exists (E_CONTACT_ADDRESS);
+ query_string = e_book_query_to_string (book_query);
+ e_book_query_unref (book_query);
+
+ e_book_client_get_contacts (
+ book_client, query_string, NULL,
+ book_contacts_received_cb, map);
+
+ g_free (query_string);
+}
+
+EContactMap *
+e_contact_map_window_get_map (EContactMapWindow *window)
+{
+ g_return_val_if_fail (E_IS_CONTACT_MAP_WINDOW (window), NULL);
+
+ return window->priv->map;
+}
+
+#endif /* WITH_CONTACT_MAPS */
diff --git a/addressbook/gui/widgets/e-contact-map-window.h b/addressbook/gui/widgets/e-contact-map-window.h
new file mode 100644
index 0000000000..aa7bff4208
--- /dev/null
+++ b/addressbook/gui/widgets/e-contact-map-window.h
@@ -0,0 +1,81 @@
+/*
+ * e-contact-map-window.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com>
+ *
+ */
+
+#ifndef E_CONTACT_MAP_WINDOW_H
+#define E_CONTACT_MAP_WINDOW_H
+
+#ifdef WITH_CONTACT_MAPS
+
+#include <gtk/gtk.h>
+
+#include <libebook/libebook.h>
+
+#include "e-contact-map.h"
+
+/* Standard GObject macros */
+#define E_TYPE_CONTACT_MAP_WINDOW \
+ (e_contact_map_window_get_type ())
+#define E_CONTACT_MAP_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindow))
+#define E_CONTACT_MAP_WINDOW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindowClass))
+#define E_IS_CONTACT_MAP_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CONTACT_MAP_WINDOW))
+#define E_IS_CONTACT_MAP_WINDOW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CONTACT_MAP_WINDOW))
+#define E_CONTACT_MAP_WINDOW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindowClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EContactMapWindow EContactMapWindow;
+typedef struct _EContactMapWindowClass EContactMapWindowClass;
+typedef struct _EContactMapWindowPrivate EContactMapWindowPrivate;
+
+struct _EContactMapWindow {
+ GtkWindow parent;
+ EContactMapWindowPrivate *priv;
+};
+
+struct _EContactMapWindowClass {
+ GtkWindowClass parent_class;
+
+ void (*show_contact_editor) (EContactMapWindow *window,
+ const gchar *contact_uid);
+};
+
+GType e_contact_map_window_get_type (void) G_GNUC_CONST;
+EContactMapWindow * e_contact_map_window_new (void);
+
+void e_contact_map_window_load_addressbook (EContactMapWindow *window,
+ EBookClient *book);
+
+EContactMap * e_contact_map_window_get_map (EContactMapWindow *window);
+
+G_END_DECLS
+
+#endif /* WITH_CONTACT_MAPS */
+
+#endif /* E_CONTACT_MAP_WINDOW_H */
diff --git a/addressbook/gui/widgets/e-contact-map.c b/addressbook/gui/widgets/e-contact-map.c
new file mode 100644
index 0000000000..57e7e55b97
--- /dev/null
+++ b/addressbook/gui/widgets/e-contact-map.c
@@ -0,0 +1,408 @@
+/*
+ * e-contact-map.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WITH_CONTACT_MAPS
+
+#include "e-contact-map.h"
+
+#include <champlain/champlain.h>
+#include <champlain-gtk/champlain-gtk.h>
+#include <geoclue/geoclue-address.h>
+#include <geoclue/geoclue-position.h>
+#include <geocode-glib.h>
+
+#include <clutter/clutter.h>
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <math.h>
+
+#include "e-util/e-util.h"
+
+#include "e-contact-marker.h"
+
+#define E_CONTACT_MAP_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CONTACT_MAP, EContactMapPrivate))
+
+typedef struct _AsyncContext AsyncContext;
+
+struct _EContactMapPrivate {
+ GHashTable *markers; /* Hash table contact-name -> marker */
+
+ ChamplainMarkerLayer *marker_layer;
+};
+
+struct _AsyncContext {
+ EContactMap *map;
+ EContactMarker *marker;
+};
+
+enum {
+ CONTACT_ADDED,
+ CONTACT_REMOVED,
+ GEOCODING_STARTED,
+ GEOCODING_FAILED,
+ LAST_SIGNAL
+};
+
+static gint signals[LAST_SIGNAL] = {0};
+
+G_DEFINE_TYPE (EContactMap, e_contact_map, GTK_CHAMPLAIN_TYPE_EMBED)
+
+static void
+async_context_free (AsyncContext *async_context)
+{
+ if (async_context->map != NULL)
+ g_object_unref (async_context->map);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
+static void
+contact_map_address_resolved_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GHashTable *resolved = NULL;
+ gpointer marker_ptr;
+ const gchar *name;
+ gdouble latitude, longitude;
+ AsyncContext *async_context = user_data;
+ ChamplainMarkerLayer *marker_layer;
+ ChamplainMarker *marker;
+ GError *error = NULL;
+
+ g_return_if_fail (async_context != NULL);
+ g_return_if_fail (E_IS_CONTACT_MAP (async_context->map));
+ g_return_if_fail (E_IS_CONTACT_MARKER (async_context->marker));
+
+ marker = CHAMPLAIN_MARKER (async_context->marker);
+ marker_layer = async_context->map->priv->marker_layer;
+
+ /* If the marker_layer does not exist anymore, the map has
+ * probably been destroyed before this callback was launched.
+ * It's not a failure, just silently clean up what was left
+ * behind and pretend nothing happened. */
+
+ if (!CHAMPLAIN_IS_MARKER_LAYER (marker_layer))
+ goto exit;
+
+ resolved = geocode_object_resolve_finish (
+ GEOCODE_OBJECT (source), result, &error);
+
+ if (resolved == NULL ||
+ !geocode_object_get_coords (resolved, &longitude, &latitude)) {
+ const gchar *name;
+ if (error)
+ g_error_free (error);
+ name = champlain_label_get_text (CHAMPLAIN_LABEL (marker));
+ g_signal_emit (
+ async_context->map,
+ signals[GEOCODING_FAILED], 0, name);
+ goto exit;
+ }
+
+ /* Move the marker to resolved position */
+ champlain_location_set_location (
+ CHAMPLAIN_LOCATION (marker), latitude, longitude);
+ champlain_marker_layer_add_marker (marker_layer, marker);
+ champlain_marker_set_selected (marker, FALSE);
+
+ /* Store the marker in the hash table. Use it's label as key */
+ name = champlain_label_get_text (CHAMPLAIN_LABEL (marker));
+ marker_ptr = g_hash_table_lookup (
+ async_context->map->priv->markers, name);
+ if (marker_ptr != NULL) {
+ g_hash_table_remove (async_context->map->priv->markers, name);
+ champlain_marker_layer_remove_marker (marker_layer, marker_ptr);
+ }
+ g_hash_table_insert (
+ async_context->map->priv->markers,
+ g_strdup (name), marker);
+
+ g_signal_emit (
+ async_context->map,
+ signals[CONTACT_ADDED], 0, marker);
+
+exit:
+ async_context_free (async_context);
+
+ if (resolved != NULL)
+ g_hash_table_unref (resolved);
+}
+
+static void
+resolve_marker_position (EContactMap *map,
+ EContactMarker *marker,
+ EContactAddress *address)
+{
+ GeocodeObject *geocoder;
+ AsyncContext *async_context;
+ const gchar *key;
+
+ g_return_if_fail (E_IS_CONTACT_MAP (map));
+ g_return_if_fail (address != NULL);
+
+ geocoder = geocode_object_new ();
+
+ key = GEOCODE_OBJECT_FIELD_POSTAL;
+ geocode_object_add (geocoder, key, address->code);
+
+ key = GEOCODE_OBJECT_FIELD_COUNTRY;
+ geocode_object_add (geocoder, key, address->country);
+
+ key = GEOCODE_OBJECT_FIELD_STATE;
+ geocode_object_add (geocoder, key, address->region);
+
+ key = GEOCODE_OBJECT_FIELD_CITY;
+ geocode_object_add (geocoder, key, address->locality);
+
+ key = GEOCODE_OBJECT_FIELD_STREET;
+ geocode_object_add (geocoder, key, address->street);
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->map = g_object_ref (map);
+ async_context->marker = marker;
+
+ geocode_object_resolve_async (
+ geocoder, NULL,
+ contact_map_address_resolved_cb,
+ async_context);
+
+ g_object_unref (geocoder);
+
+ g_signal_emit (map, signals[GEOCODING_STARTED], 0, marker);
+}
+
+static void
+contact_map_finalize (GObject *object)
+{
+ EContactMapPrivate *priv;
+
+ priv = E_CONTACT_MAP (object)->priv;
+
+ if (priv->markers) {
+ g_hash_table_destroy (priv->markers);
+ priv->markers = NULL;
+ }
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_contact_map_parent_class)->finalize (object);
+}
+
+static void
+e_contact_map_class_init (EContactMapClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EContactMapPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = contact_map_finalize;
+
+ signals[CONTACT_ADDED] = g_signal_new (
+ "contact-added",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EContactMapClass, contact_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
+ signals[CONTACT_REMOVED] = g_signal_new (
+ "contact-removed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EContactMapClass, contact_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ signals[GEOCODING_STARTED] = g_signal_new (
+ "geocoding-started",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EContactMapClass, geocoding_started),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
+ signals[GEOCODING_FAILED] = g_signal_new (
+ "geocoding-failed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EContactMapClass, geocoding_failed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+}
+
+static void
+e_contact_map_init (EContactMap *map)
+{
+ GHashTable *hash_table;
+ ChamplainMarkerLayer *layer;
+ ChamplainView *view;
+
+ map->priv = E_CONTACT_MAP_GET_PRIVATE (map);
+
+ hash_table = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free, NULL);
+
+ map->priv->markers = hash_table;
+
+ view = gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (map));
+ /* This feature is somehow broken sometimes, so disable it for now */
+ champlain_view_set_zoom_on_double_click (view, FALSE);
+ layer = champlain_marker_layer_new_full (CHAMPLAIN_SELECTION_SINGLE);
+ champlain_view_add_layer (view, CHAMPLAIN_LAYER (layer));
+ map->priv->marker_layer = layer;
+}
+
+GtkWidget *
+e_contact_map_new (void)
+{
+ return g_object_new (
+ E_TYPE_CONTACT_MAP,NULL);
+}
+
+void
+e_contact_map_add_contact (EContactMap *map,
+ EContact *contact)
+{
+ EContactAddress *address;
+ EContactPhoto *photo;
+ const gchar *contact_uid;
+ gchar *name;
+
+ g_return_if_fail (map && E_IS_CONTACT_MAP (map));
+ g_return_if_fail (contact && E_IS_CONTACT (contact));
+
+ photo = e_contact_get (contact, E_CONTACT_PHOTO);
+ contact_uid = e_contact_get_const (contact, E_CONTACT_UID);
+
+ address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME);
+ if (address) {
+ name = g_strconcat (e_contact_get_const (contact, E_CONTACT_FILE_AS), " (", _("Home"), ")", NULL);
+ e_contact_map_add_marker (map, name, contact_uid, address, photo);
+ g_free (name);
+ e_contact_address_free (address);
+ }
+
+ address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK);
+ if (address) {
+ name = g_strconcat (e_contact_get_const (contact, E_CONTACT_FILE_AS), " (", _("Work"), ")", NULL);
+ e_contact_map_add_marker (map, name, contact_uid, address, photo);
+ g_free (name);
+ e_contact_address_free (address);
+ }
+
+ if (photo)
+ e_contact_photo_free (photo);
+}
+
+void
+e_contact_map_add_marker (EContactMap *map,
+ const gchar *name,
+ const gchar *contact_uid,
+ EContactAddress *address,
+ EContactPhoto *photo)
+{
+ EContactMarker *marker;
+
+ g_return_if_fail (map && E_IS_CONTACT_MAP (map));
+ g_return_if_fail (name && *name);
+ g_return_if_fail (contact_uid && *contact_uid);
+ g_return_if_fail (address);
+
+ marker = E_CONTACT_MARKER (e_contact_marker_new (name, contact_uid, photo));
+
+ resolve_marker_position (map, marker, address);
+}
+
+/**
+ * The \name parameter must match the label of the
+ * marker (for example "John Smith (work)")
+ */
+void
+e_contact_map_remove_contact (EContactMap *map,
+ const gchar *name)
+{
+ ChamplainMarker *marker;
+
+ g_return_if_fail (map && E_IS_CONTACT_MAP (map));
+ g_return_if_fail (name && *name);
+
+ marker = g_hash_table_lookup (map->priv->markers, name);
+
+ champlain_marker_layer_remove_marker (map->priv->marker_layer, marker);
+
+ g_hash_table_remove (map->priv->markers, name);
+
+ g_signal_emit (map, signals[CONTACT_REMOVED], 0, name);
+}
+
+void
+e_contact_map_remove_marker (EContactMap *map,
+ ClutterActor *marker)
+{
+ const gchar *name;
+
+ g_return_if_fail (map && E_IS_CONTACT_MAP (map));
+ g_return_if_fail (marker && CLUTTER_IS_ACTOR (marker));
+
+ name = champlain_label_get_text (CHAMPLAIN_LABEL (marker));
+
+ e_contact_map_remove_contact (map, name);
+}
+
+void
+e_contact_map_zoom_on_marker (EContactMap *map,
+ ClutterActor *marker)
+{
+ ChamplainView *view;
+ gdouble lat, lng;
+
+ g_return_if_fail (map && E_IS_CONTACT_MAP (map));
+ g_return_if_fail (marker && CLUTTER_IS_ACTOR (marker));
+
+ lat = champlain_location_get_latitude (CHAMPLAIN_LOCATION (marker));
+ lng = champlain_location_get_longitude (CHAMPLAIN_LOCATION (marker));
+
+ view = gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (map));
+
+ champlain_view_center_on (view, lat, lng);
+ champlain_view_set_zoom_level (view, 15);
+}
+
+ChamplainView *
+e_contact_map_get_view (EContactMap *map)
+{
+ g_return_val_if_fail (E_IS_CONTACT_MAP (map), NULL);
+
+ return gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (map));
+}
+
+#endif /* WITH_CONTACT_MAPS */
diff --git a/addressbook/gui/widgets/e-contact-map.h b/addressbook/gui/widgets/e-contact-map.h
new file mode 100644
index 0000000000..d9503e2c9b
--- /dev/null
+++ b/addressbook/gui/widgets/e-contact-map.h
@@ -0,0 +1,106 @@
+/*
+ * e-contact-map.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com>
+ *
+ */
+
+#ifndef E_CONTACT_MAP_H
+#define E_CONTACT_MAP_H
+
+#ifdef WITH_CONTACT_MAPS
+
+#include <gtk/gtk.h>
+
+#include <champlain/champlain.h>
+#include <champlain-gtk/champlain-gtk.h>
+
+#include <libebook/libebook.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CONTACT_MAP \
+ (e_contact_map_get_type ())
+#define E_CONTACT_MAP(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CONTACT_MAP, EContactMap))
+#define E_CONTACT_MAP_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CONTACT_MAP, EContactMapClass))
+#define E_IS_CONTACT_MAP(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CONTACT_MAP))
+#define E_IS_CONTACT_MAP_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CONTACT_MAP))
+#define E_CONTACT_MAP_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CONTACT_MAP, EContactMapClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EContactMap EContactMap;
+typedef struct _EContactMapClass EContactMapClass;
+typedef struct _EContactMapPrivate EContactMapPrivate;
+
+struct _EContactMap {
+ GtkChamplainEmbed parent;
+ EContactMapPrivate *priv;
+};
+
+struct _EContactMapClass {
+ GtkWindowClass parent_class;
+
+ void (*contact_added) (EContactMap *map,
+ ClutterActor *marker);
+
+ void (*contact_removed) (EContactMap *map,
+ const gchar *name);
+
+ void (*geocoding_started) (EContactMap *map,
+ ClutterActor *marker);
+
+ void (*geocoding_failed) (EContactMap *map,
+ const gchar *name);
+};
+
+GType e_contact_map_get_type (void) G_GNUC_CONST;
+GtkWidget * e_contact_map_new (void);
+
+void e_contact_map_add_contact (EContactMap *map,
+ EContact *contact);
+
+void e_contact_map_add_marker (EContactMap *map,
+ const gchar *name,
+ const gchar *contact_uid,
+ EContactAddress *address,
+ EContactPhoto *photo);
+
+void e_contact_map_remove_contact (EContactMap *map,
+ const gchar *name);
+
+void e_contact_map_remove_marker (EContactMap *map,
+ ClutterActor *marker);
+
+void e_contact_map_zoom_on_marker (EContactMap *map,
+ ClutterActor *marker);
+
+ChamplainView * e_contact_map_get_view (EContactMap *map);
+
+G_END_DECLS
+
+#endif /* WITH_CONTACT_MAPS */
+
+#endif
diff --git a/addressbook/gui/widgets/e-contact-marker.c b/addressbook/gui/widgets/e-contact-marker.c
new file mode 100644
index 0000000000..9ac9417c9f
--- /dev/null
+++ b/addressbook/gui/widgets/e-contact-marker.c
@@ -0,0 +1,624 @@
+/*
+ * e-contact-marker.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
+ * Copyright (C) 2011 Jiri Techet <techet@gmail.com>
+ * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WITH_CONTACT_MAPS
+
+#include "e-contact-marker.h"
+
+#include <champlain/champlain.h>
+#include <gtk/gtk.h>
+#include <clutter/clutter.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <cairo.h>
+#include <math.h>
+#include <string.h>
+
+#define E_CONTACT_MARKER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CONTACT_MARKER, EContactMarkerPrivate))
+
+G_DEFINE_TYPE (EContactMarker, e_contact_marker, CHAMPLAIN_TYPE_LABEL);
+
+struct _EContactMarkerPrivate
+{
+ gchar *contact_uid;
+
+ ClutterActor *image;
+ ClutterActor *text_actor;
+
+ ClutterActor *shadow;
+ ClutterActor *background;
+
+ guint total_width;
+ guint total_height;
+
+ ClutterGroup *content_group;
+
+ guint redraw_id;
+};
+
+enum {
+ DOUBLE_CLICKED,
+ LAST_SIGNAL
+};
+
+static gint signals[LAST_SIGNAL] = {0};
+
+#define DEFAULT_FONT_NAME "Serif 9"
+
+static ClutterColor DEFAULT_COLOR = { 0x33, 0x33, 0x33, 0xff };
+
+#define RADIUS 10
+#define PADDING (RADIUS / 2)
+
+static gboolean
+contact_marker_clicked_cb (ClutterActor *actor,
+ ClutterEvent *event,
+ gpointer user_data)
+{
+ gint click_count = clutter_event_get_click_count (event);
+
+ if (click_count == 2)
+ g_signal_emit (E_CONTACT_MARKER (actor), signals[DOUBLE_CLICKED], 0);
+
+ return TRUE;
+}
+
+static ClutterActor *
+texture_new_from_pixbuf (GdkPixbuf *pixbuf,
+ GError **error)
+{
+ ClutterActor *texture = NULL;
+ const guchar *data;
+ gboolean has_alpha, success;
+ gint width, height, rowstride;
+ ClutterTextureFlags flags = 0;
+
+ data = gdk_pixbuf_get_pixels (pixbuf);
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ texture = clutter_texture_new ();
+ success = clutter_texture_set_from_rgb_data (
+ CLUTTER_TEXTURE (texture),
+ data, has_alpha, width, height, rowstride,
+ (has_alpha ? 4: 3), flags, NULL);
+
+ if (!success) {
+ clutter_actor_destroy (CLUTTER_ACTOR (texture));
+ texture = NULL;
+ }
+
+ return texture;
+}
+
+static ClutterActor *
+contact_photo_to_texture (EContactPhoto *photo)
+{
+ GdkPixbuf *pixbuf;
+
+ if (photo->type == E_CONTACT_PHOTO_TYPE_INLINED) {
+ GError *error = NULL;
+
+ GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
+ gdk_pixbuf_loader_write (
+ loader, photo->data.inlined.data,
+ photo->data.inlined.length, NULL);
+ gdk_pixbuf_loader_close (loader, NULL);
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+ if (pixbuf)
+ g_object_ref (pixbuf);
+ g_object_unref (loader);
+
+ if (error) {
+ g_error_free (error);
+ return NULL;
+ }
+ } else if (photo->type == E_CONTACT_PHOTO_TYPE_URI) {
+ GError *error = NULL;
+
+ pixbuf = gdk_pixbuf_new_from_file (photo->data.uri, &error);
+
+ if (error) {
+ g_error_free (error);
+ return NULL;
+ }
+ } else
+ return NULL;
+
+ if (pixbuf) {
+ ClutterActor *texture;
+ GError *error = NULL;
+
+ texture = texture_new_from_pixbuf (pixbuf, &error);
+ if (error) {
+ g_error_free (error);
+ g_object_unref (pixbuf);
+ return NULL;
+ }
+
+ g_object_unref (pixbuf);
+ return texture;
+ }
+
+ return NULL;
+}
+
+static void
+draw_box (cairo_t *cr,
+ gint width,
+ gint height,
+ gint point)
+{
+ cairo_move_to (cr, RADIUS, 0);
+ cairo_line_to (cr, width - RADIUS, 0);
+ cairo_arc (cr, width - RADIUS, RADIUS, RADIUS - 1, 3 * M_PI / 2.0, 0);
+ cairo_line_to (cr, width, height - RADIUS);
+ cairo_arc (cr, width - RADIUS, height - RADIUS, RADIUS - 1, 0, M_PI / 2.0);
+ cairo_line_to (cr, point, height);
+ cairo_line_to (cr, 0, height + point);
+ cairo_arc (cr, RADIUS, RADIUS, RADIUS - 1, M_PI, 3 * M_PI / 2.0);
+ cairo_close_path (cr);
+}
+
+static void
+draw_shadow (EContactMarker *marker,
+ gint width,
+ gint height,
+ gint point)
+{
+ EContactMarkerPrivate *priv = marker->priv;
+ ClutterActor *shadow = NULL;
+ cairo_t *cr;
+ gdouble slope;
+ gdouble scaling;
+ gint x;
+ cairo_matrix_t matrix;
+
+ slope = -0.3;
+ scaling = 0.65;
+ x = -40 * slope;
+
+ shadow = clutter_cairo_texture_new (width + x, (height + point));
+ cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (shadow));
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ cairo_matrix_init (&matrix, 1, 0, slope, scaling, x, 0);
+ cairo_set_matrix (cr, &matrix);
+
+ draw_box (cr, width, height, point);
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 0.15);
+ cairo_fill (cr);
+
+ cairo_destroy (cr);
+
+ clutter_actor_set_position (shadow, 0, height / 2.0);
+
+ clutter_container_add_actor (CLUTTER_CONTAINER (priv->content_group), shadow);
+
+ if (priv->shadow != NULL) {
+ clutter_container_remove_actor (
+ CLUTTER_CONTAINER (priv->content_group),
+ priv->shadow);
+ }
+
+ priv->shadow = shadow;
+}
+
+static void
+draw_background (EContactMarker *marker,
+ gint width,
+ gint height,
+ gint point)
+{
+ EContactMarkerPrivate *priv = marker->priv;
+ ClutterActor *bg = NULL;
+ const ClutterColor *color;
+ ClutterColor darker_color;
+ cairo_t *cr;
+
+ bg = clutter_cairo_texture_new (width, height + point);
+ cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (bg));
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ /* If selected, add the selection color to the marker's color */
+ if (champlain_marker_get_selected (CHAMPLAIN_MARKER (marker)))
+ color = champlain_marker_get_selection_color ();
+ else
+ color = &DEFAULT_COLOR;
+
+ draw_box (cr, width, height, point);
+
+ clutter_color_darken (color, &darker_color);
+
+ cairo_set_source_rgba (
+ cr,
+ color->red / 255.0,
+ color->green / 255.0,
+ color->blue / 255.0,
+ color->alpha / 255.0);
+ cairo_fill_preserve (cr);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_source_rgba (
+ cr,
+ darker_color.red / 255.0,
+ darker_color.green / 255.0,
+ darker_color.blue / 255.0,
+ darker_color.alpha / 255.0);
+ cairo_stroke (cr);
+ cairo_destroy (cr);
+
+ clutter_container_add_actor (CLUTTER_CONTAINER (priv->content_group), bg);
+
+ if (priv->background != NULL) {
+ clutter_container_remove_actor (
+ CLUTTER_CONTAINER (priv->content_group),
+ priv->background);
+ }
+
+ priv->background = bg;
+}
+
+static void
+draw_marker (EContactMarker *marker)
+{
+ EContactMarkerPrivate *priv = marker->priv;
+ ChamplainLabel *label = CHAMPLAIN_LABEL (marker);
+ guint height = 0, point = 0;
+ guint total_width = 0, total_height = 0;
+ ClutterText *text;
+
+ if (priv->image) {
+ clutter_actor_set_position (priv->image, 2 *PADDING, 2 *PADDING);
+ if (clutter_actor_get_parent (priv->image) == NULL)
+ clutter_container_add_actor (
+ CLUTTER_CONTAINER (priv->content_group),
+ priv->image);
+ }
+
+ if (priv->text_actor == NULL) {
+ priv->text_actor = clutter_text_new_with_text (
+ "Serif 8",
+ champlain_label_get_text (label));
+ champlain_label_set_font_name (label, "Serif 8");
+ }
+
+ text = CLUTTER_TEXT (priv->text_actor);
+ clutter_text_set_text (
+ text,
+ champlain_label_get_text (label));
+ clutter_text_set_font_name (
+ text,
+ champlain_label_get_font_name (label));
+ clutter_text_set_line_alignment (text, PANGO_ALIGN_CENTER);
+ clutter_text_set_line_wrap (text, TRUE);
+ clutter_text_set_line_wrap_mode (text, PANGO_WRAP_WORD);
+ clutter_text_set_ellipsize (
+ text,
+ champlain_label_get_ellipsize (label));
+ clutter_text_set_attributes (
+ text,
+ champlain_label_get_attributes (label));
+ clutter_text_set_use_markup (
+ text,
+ champlain_label_get_use_markup (label));
+
+ if (priv->image) {
+ clutter_actor_set_width (
+ priv->text_actor,
+ clutter_actor_get_width (priv->image));
+ total_height = clutter_actor_get_height (priv->image) + 2 *PADDING +
+ clutter_actor_get_height (priv->text_actor) + 2 *PADDING;
+ total_width = clutter_actor_get_width (priv->image) + 4 *PADDING;
+ clutter_actor_set_position (
+ priv->text_actor, PADDING,
+ clutter_actor_get_height (priv->image) + 2 *PADDING + 3);
+ } else {
+ total_height = clutter_actor_get_height (priv->text_actor) + 2 *PADDING;
+ total_width = clutter_actor_get_width (priv->text_actor) + 4 *PADDING;
+ clutter_actor_set_position (priv->text_actor, 2 * PADDING, PADDING);
+ }
+
+ height += 2 * PADDING;
+ if (height > total_height)
+ total_height = height;
+
+ clutter_text_set_color (
+ CLUTTER_TEXT (priv->text_actor),
+ (champlain_marker_get_selected (CHAMPLAIN_MARKER (marker)) ?
+ champlain_marker_get_selection_text_color () :
+ champlain_label_get_text_color (CHAMPLAIN_LABEL (marker))));
+ if (clutter_actor_get_parent (priv->text_actor) == NULL)
+ clutter_container_add_actor (
+ CLUTTER_CONTAINER (priv->content_group),
+ priv->text_actor);
+
+ if (priv->text_actor == NULL && priv->image == NULL) {
+ total_width = 6 * PADDING;
+ total_height = 6 * PADDING;
+ }
+
+ point = (total_height + 2 * PADDING) / 4.0;
+ priv->total_width = total_width;
+ priv->total_height = total_height;
+
+ draw_shadow (marker, total_width, total_height, point);
+ draw_background (marker, total_width, total_height, point);
+
+ if (priv->text_actor != NULL && priv->background != NULL)
+ clutter_actor_raise (priv->text_actor, priv->background);
+ if (priv->image != NULL && priv->background != NULL)
+ clutter_actor_raise (priv->image, priv->background);
+
+ clutter_actor_set_anchor_point (CLUTTER_ACTOR (marker), 0, total_height + point);
+}
+
+static gboolean
+redraw_on_idle (gpointer gobject)
+{
+ EContactMarker *marker = E_CONTACT_MARKER (gobject);
+
+ draw_marker (marker);
+ marker->priv->redraw_id = 0;
+ return FALSE;
+}
+
+static void
+queue_redraw (EContactMarker *marker)
+{
+ EContactMarkerPrivate *priv = marker->priv;
+
+ if (!priv->redraw_id) {
+ priv->redraw_id = g_idle_add_full (
+ G_PRIORITY_DEFAULT,
+ (GSourceFunc) redraw_on_idle,
+ g_object_ref (marker),
+ (GDestroyNotify) g_object_unref);
+ }
+}
+
+static void
+allocate (ClutterActor *self,
+ const ClutterActorBox *box,
+ ClutterAllocationFlags flags)
+{
+ ClutterActorBox child_box;
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
+
+ CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->allocate (self, box, flags);
+
+ child_box.x1 = 0;
+ child_box.x2 = box->x2 - box->x1;
+ child_box.y1 = 0;
+ child_box.y2 = box->y2 - box->y1;
+ clutter_actor_allocate (CLUTTER_ACTOR (priv->content_group), &child_box, flags);
+}
+
+static void
+paint (ClutterActor *self)
+{
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
+
+ clutter_actor_paint (CLUTTER_ACTOR (priv->content_group));
+}
+
+static void
+map (ClutterActor *self)
+{
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
+
+ CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->map (self);
+
+ clutter_actor_map (CLUTTER_ACTOR (priv->content_group));
+}
+
+static void
+unmap (ClutterActor *self)
+{
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
+
+ CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->unmap (self);
+
+ clutter_actor_unmap (CLUTTER_ACTOR (priv->content_group));
+}
+
+static void
+pick (ClutterActor *self,
+ const ClutterColor *color)
+{
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
+ gfloat width, height;
+
+ if (!clutter_actor_should_pick_paint (self))
+ return;
+
+ width = priv->total_width;
+ height = priv->total_height;
+
+ cogl_path_new ();
+
+ cogl_set_source_color4ub (
+ color->red,
+ color->green,
+ color->blue,
+ color->alpha);
+
+ cogl_path_move_to (RADIUS, 0);
+ cogl_path_line_to (width - RADIUS, 0);
+ cogl_path_arc (width - RADIUS, RADIUS, RADIUS, RADIUS, -90, 0);
+ cogl_path_line_to (width, height - RADIUS);
+ cogl_path_arc (width - RADIUS, height - RADIUS, RADIUS, RADIUS, 0, 90);
+ cogl_path_line_to (RADIUS, height);
+ cogl_path_arc (RADIUS, height - RADIUS, RADIUS, RADIUS, 90, 180);
+ cogl_path_line_to (0, RADIUS);
+ cogl_path_arc (RADIUS, RADIUS, RADIUS, RADIUS, 180, 270);
+ cogl_path_close ();
+ cogl_path_fill ();
+}
+
+static void
+notify_selected (GObject *gobject,
+ G_GNUC_UNUSED GParamSpec *pspec,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ queue_redraw (E_CONTACT_MARKER (gobject));
+}
+
+static void
+e_contact_marker_finalize (GObject *object)
+{
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (object)->priv;
+
+ if (priv->contact_uid) {
+ g_free (priv->contact_uid);
+ priv->contact_uid = NULL;
+ }
+
+ if (priv->redraw_id) {
+ g_source_remove (priv->redraw_id);
+ priv->redraw_id = 0;
+ }
+
+ G_OBJECT_CLASS (e_contact_marker_parent_class)->finalize (object);
+}
+
+static void
+e_contact_marker_dispose (GObject *object)
+{
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (object)->priv;
+
+ priv->background = NULL;
+ priv->shadow = NULL;
+ priv->text_actor = NULL;
+
+ if (priv->content_group) {
+ clutter_actor_unparent (CLUTTER_ACTOR (priv->content_group));
+ priv->content_group = NULL;
+ }
+
+ G_OBJECT_CLASS (e_contact_marker_parent_class)->dispose (object);
+}
+
+static void
+e_contact_marker_class_init (EContactMarkerClass *class)
+{
+ ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (class);
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ g_type_class_add_private (class, sizeof (EContactMarkerPrivate));
+
+ object_class->dispose = e_contact_marker_dispose;
+ object_class->finalize = e_contact_marker_finalize;
+
+ actor_class->paint = paint;
+ actor_class->allocate = allocate;
+ actor_class->map = map;
+ actor_class->unmap = unmap;
+ actor_class->pick = pick;
+
+ signals[DOUBLE_CLICKED] = g_signal_new (
+ "double-clicked",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EContactMarkerClass, double_clicked),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+e_contact_marker_init (EContactMarker *marker)
+{
+ EContactMarkerPrivate *priv;
+
+ priv = E_CONTACT_MARKER_GET_PRIVATE (marker);
+
+ marker->priv = priv;
+ priv->contact_uid = NULL;
+ priv->image = NULL;
+ priv->background = NULL;
+ priv->shadow = NULL;
+ priv->text_actor = NULL;
+ priv->content_group = CLUTTER_GROUP (clutter_group_new ());
+ priv->redraw_id = 0;
+
+ clutter_actor_set_parent (
+ CLUTTER_ACTOR (priv->content_group), CLUTTER_ACTOR (marker));
+ clutter_actor_queue_relayout (CLUTTER_ACTOR (marker));
+
+ priv->total_width = 0;
+ priv->total_height = 0;
+
+ g_signal_connect (
+ marker, "notify::selected",
+ G_CALLBACK (notify_selected), NULL);
+ g_signal_connect (
+ marker, "button-release-event",
+ G_CALLBACK (contact_marker_clicked_cb), NULL);
+}
+
+ClutterActor *
+e_contact_marker_new (const gchar *name,
+ const gchar *contact_uid,
+ EContactPhoto *photo)
+{
+ ClutterActor *marker = CLUTTER_ACTOR (g_object_new (E_TYPE_CONTACT_MARKER, NULL));
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (marker)->priv;
+
+ g_return_val_if_fail (name && *name, NULL);
+ g_return_val_if_fail (contact_uid && *contact_uid, NULL);
+
+ champlain_label_set_text (CHAMPLAIN_LABEL (marker), name);
+ priv->contact_uid = g_strdup (contact_uid);
+ if (photo)
+ priv->image = contact_photo_to_texture (photo);
+
+ queue_redraw (E_CONTACT_MARKER (marker));
+
+ return marker;
+}
+
+const gchar *
+e_contact_marker_get_contact_uid (EContactMarker *marker)
+{
+ g_return_val_if_fail (marker && E_IS_CONTACT_MARKER (marker), NULL);
+
+ return marker->priv->contact_uid;
+}
+
+#endif /* WITH_CONTACT_MAPS */
diff --git a/addressbook/gui/widgets/e-contact-marker.h b/addressbook/gui/widgets/e-contact-marker.h
new file mode 100644
index 0000000000..791a9c46b5
--- /dev/null
+++ b/addressbook/gui/widgets/e-contact-marker.h
@@ -0,0 +1,84 @@
+/*
+ * e-contact-marker.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
+ * Copyright (C) 2011 Jiri Techet <techet@gmail.com>
+ * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com>
+ *
+ */
+
+#ifndef E_CONTACT_MARKER_H
+#define E_CONTACT_MARKER_H
+
+#ifdef WITH_CONTACT_MAPS
+
+#include <libebook/libebook.h>
+
+#include <champlain/champlain.h>
+
+#include <glib-object.h>
+#include <clutter/clutter.h>
+
+G_BEGIN_DECLS
+
+#define E_TYPE_CONTACT_MARKER e_contact_marker_get_type ()
+
+#define E_CONTACT_MARKER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CONTACT_MARKER, EContactMarker))
+
+#define E_CONTACT_MARKER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CONTACT_MARKER, EContactMarkerClass))
+
+#define E_IS_CONTACT_MARKER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CONTACT_MARKER))
+
+#define E_IS_CONTACT_MARKER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CONTACT_MARKER))
+
+#define E_CONTACT_MARKER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CONTACT_MARKER, EContactMarkerClass))
+
+typedef struct _EContactMarkerPrivate EContactMarkerPrivate;
+
+typedef struct _EContactMarker EContactMarker;
+typedef struct _EContactMarkerClass EContactMarkerClass;
+
+struct _EContactMarker
+{
+ ChamplainLabel parent;
+ EContactMarkerPrivate *priv;
+};
+
+struct _EContactMarkerClass
+{
+ ChamplainLabelClass parent_class;
+
+ void (*double_clicked) (ClutterActor *actor);
+};
+
+GType e_contact_marker_get_type (void);
+
+ClutterActor * e_contact_marker_new (const gchar *name,
+ const gchar *contact_uid,
+ EContactPhoto *photo);
+
+const gchar * e_contact_marker_get_contact_uid (EContactMarker *marker);
+
+G_END_DECLS
+
+#endif /* WITH_CONTACT_MAPS */
+
+#endif
diff --git a/addressbook/gui/widgets/e-minicard-control.c b/addressbook/gui/widgets/e-minicard-control.c
deleted file mode 100644
index 73417af78c..0000000000
--- a/addressbook/gui/widgets/e-minicard-control.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-minicard-control.c
- *
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * Copyright 1999, 2000, Ximian, Inc.
- */
-
-#include <config.h>
-
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-persist.h>
-#include <bonobo/bonobo-persist-stream.h>
-#include <bonobo/bonobo-stream-client.h>
-#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-book-util.h>
-#include <addressbook/backend/ebook/e-card.h>
-#include <gal/util/e-util.h>
-
-#include <addressbook/gui/component/addressbook.h>
-
-#include "e-minicard-control.h"
-#include "e-minicard-widget.h"
-#include "e-card-merging.h"
-
-typedef struct {
- EMinicardWidget *minicard;
- GList *card_list;
- GtkWidget *label;
-} EMinicardControl;
-
-#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)
-{
- GtkObject *clock = user_data;
-
- switch (arg_id) {
-
- case PROP_RUNNING:
- {
- gboolean b = GPOINTER_TO_UINT (gtk_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);
-
- gtk_object_set_data (GTK_OBJECT (clock), RUNNING_KEY,
- GUINT_TO_POINTER (i));
- break;
- }
-
- default:
- g_warning ("Unhandled arg %d", arg_id);
- break;
- }
-}
-#endif
-
-/*
- * Bonobo::PersistStream
- *
- * These two functions implement the Bonobo::PersistStream load and
- * save methods which allow data to be loaded into and out of the
- * BonoboObject.
- */
-static char *
-stream_read (Bonobo_Stream stream)
-{
- Bonobo_Stream_iobuf *buffer;
- CORBA_Environment ev;
- char *data = NULL;
- gint length = 0;
-
- CORBA_exception_init (&ev);
- do {
-#define READ_CHUNK_SIZE 65536
- Bonobo_Stream_read (stream, READ_CHUNK_SIZE,
- &buffer, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- if (buffer->_length <= 0)
- break;
-
- data = g_realloc (data, length + buffer->_length + 1);
-
- memcpy (data + length, buffer->_buffer, buffer->_length);
-
- length += buffer->_length;
-
- CORBA_free (buffer);
- } while (1);
-
- CORBA_free (buffer);
- CORBA_exception_free (&ev);
-
- if (data)
- data[length] = '\0';
- else
- data = g_strdup("");
-
- return data;
-} /* stream_read */
-
-/*
- * This function implements the Bonobo::PersistStream:load method.
- */
-static void
-pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream,
- Bonobo_Persist_ContentType type, void *data,
- CORBA_Environment *ev)
-{
- GList *list;
- char *vcard;
- EMinicardControl *minicard_control = data;
-
- if (type && g_strcasecmp (type, "text/vCard") != 0 &&
- g_strcasecmp (type, "text/x-vCard") != 0) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_Bonobo_Persist_WrongDataType, NULL);
- return;
- }
-
- if ((vcard = stream_read (stream)) == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_Bonobo_Persist_FileNotFound, NULL);
- return;
- }
-
- e_free_object_list (minicard_control->card_list);
- list = e_card_load_cards_from_string_with_default_charset(vcard, "ISO-8859-1");
- g_free(vcard);
- minicard_control->card_list = list;
- if (list)
- gtk_object_set(GTK_OBJECT(minicard_control->minicard),
- "card", list->data,
- NULL);
- 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);
- } else {
- message = g_strdup_printf (_("and one other card."));
- }
- gtk_label_set_text (GTK_LABEL (minicard_control->label), message);
- g_free (message);
- gtk_widget_show (minicard_control->label);
- } else {
- gtk_widget_hide (minicard_control->label);
- }
-} /* pstream_load */
-
-/*
- * This function implements the Bonobo::PersistStream:save method.
- */
-static void
-pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream,
- Bonobo_Persist_ContentType type, void *data,
- CORBA_Environment *ev)
-{
- EMinicardControl *minicard_control = data;
- char *vcard;
- int length;
-
- if (type && g_strcasecmp (type, "text/vCard") != 0 &&
- g_strcasecmp (type, "text/x-vCard") != 0) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_Bonobo_Persist_WrongDataType, NULL);
- return;
- }
-
- vcard = e_card_list_get_vcard(minicard_control->card_list);
- length = strlen (vcard);
- bonobo_stream_client_write (stream, vcard, length, ev);
- g_free (vcard);
-} /* pstream_save */
-
-static CORBA_long
-pstream_get_max_size (BonoboPersistStream *ps, void *data,
- CORBA_Environment *ev)
-{
- EMinicardControl *minicard_control = data;
- char *vcard;
- gint length;
-
- vcard = e_card_list_get_vcard(minicard_control->card_list);
- length = strlen (vcard);
- g_free (vcard);
-
- return length;
-}
-
-static Bonobo_Persist_ContentTypeList *
-pstream_get_content_types (BonoboPersistStream *ps, void *closure,
- CORBA_Environment *ev)
-{
- return bonobo_persist_generate_content_types (2, "text/vCard", "text/x-vCard");
-}
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- GList *list = closure;
- if (book) {
- GList *p;
- for (p = list; p; p = p->next) {
- e_card_merging_book_add_card(book, p->data, NULL, NULL);
- }
- gtk_object_unref (GTK_OBJECT (book));
- }
- e_free_object_list (list);
-}
-
-static void
-save_in_addressbook(GtkWidget *button, gpointer data)
-{
- EMinicardControl *minicard_control = data;
- GList *list, *p;
- EBook *book;
-
- book = e_book_new ();
-
- list = g_list_copy (minicard_control->card_list);
-
- for (p = list; p; p = p->next)
- gtk_object_ref (GTK_OBJECT (p->data));
-
- if (!addressbook_load_default_book (book, book_open_cb, list)) {
- gtk_object_unref (GTK_OBJECT (book));
- book_open_cb (NULL, E_BOOK_STATUS_OTHER_ERROR, list);
- }
-}
-
-static void
-free_struct (GtkWidget *control, gpointer data)
-{
- EMinicardControl *minicard_control = data;
- e_free_object_list (minicard_control->card_list);
- g_free (minicard_control);
-}
-
-static BonoboObject *
-e_minicard_control_factory (BonoboGenericFactory *Factory, void *closure)
-{
-#if 0
- BonoboPropertyBag *pb;
-#endif
- BonoboControl *control;
- BonoboPersistStream *stream;
- GtkWidget *minicard;
- GtkWidget *button;
- GtkWidget *label;
- GtkWidget *vbox;
-
- EMinicardControl *minicard_control = g_new (EMinicardControl, 1);
-
-
- minicard_control->card_list = NULL;
- minicard_control->minicard = NULL;
- minicard_control->label = NULL;
-
- /* Create the control. */
-
- minicard = e_minicard_widget_new ();
- gtk_widget_show (minicard);
- minicard_control->minicard = E_MINICARD_WIDGET (minicard);
-
- /* This is intentionally not shown. */
- label = gtk_label_new ("");
- minicard_control->label = label;
-
- button = gtk_button_new_with_label(_("Save in addressbook"));
- gtk_signal_connect(GTK_OBJECT(button), "clicked",
- save_in_addressbook, minicard_control);
- gtk_widget_show (button);
-
- 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);
-
- control = bonobo_control_new (vbox);
-
- gtk_signal_connect (GTK_OBJECT (control), "destroy",
- free_struct, minicard_control);
-
- stream = bonobo_persist_stream_new (pstream_load, pstream_save,
- pstream_get_max_size,
- pstream_get_content_types,
- 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
-
- if (stream == NULL) {
- bonobo_object_unref (BONOBO_OBJECT (control));
- return NULL;
- }
-
- bonobo_object_add_interface (BONOBO_OBJECT (control),
- BONOBO_OBJECT (stream));
-
- return BONOBO_OBJECT (control);
-}
-
-void
-e_minicard_control_factory_init (void)
-{
- static BonoboGenericFactory *factory = NULL;
-
- if (factory != NULL)
- return;
-
- factory =
- bonobo_generic_factory_new (
- "OAFIID:GNOME_Evolution_Addressbook_MiniCard_ControlFactory",
- e_minicard_control_factory, NULL);
-
- if (factory == NULL)
- g_error ("I could not register a EMinicard control factory.");
-}
diff --git a/addressbook/gui/widgets/e-minicard-control.h b/addressbook/gui/widgets/e-minicard-control.h
deleted file mode 100644
index 4a0da88435..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>
-
-void e_minicard_control_factory_init (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 b59ff46ae3..0e75917b80 100644
--- a/addressbook/gui/widgets/e-minicard-label.c
+++ b/addressbook/gui/widgets/e-minicard-label.c
@@ -1,216 +1,286 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-minicard-label.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
#include "e-minicard-label.h"
-#include <gtk/gtksignal.h>
-#include <libgnomeui/gnome-canvas-rect-ellipse.h>
-#include <gal/util/e-util.h>
-#include <gal/e-text/e-text.h>
-#include <gal/widgets/e-canvas.h>
-#include <gal/widgets/e-canvas-utils.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
#include <gdk/gdkkeysyms.h>
-static void e_minicard_label_init (EMinicardLabel *card);
-static void e_minicard_label_class_init (EMinicardLabelClass *klass);
-static void e_minicard_label_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_minicard_label_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+#include <libgnomecanvas/libgnomecanvas.h>
+
+#include "e-util/e-util.h"
+
+static void e_minicard_label_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+static void e_minicard_label_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static gboolean e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event);
static void e_minicard_label_realize (GnomeCanvasItem *item);
-static void e_minicard_label_unrealize (GnomeCanvasItem *item);
-static void e_minicard_label_reflow(GnomeCanvasItem *item, int flags);
+static void e_minicard_label_reflow (GnomeCanvasItem *item, gint flags);
+static void e_minicard_label_style_set (EMinicardLabel *label, GtkStyle *previous_style);
-static void e_minicard_label_resize_children( EMinicardLabel *e_minicard_label );
+static void e_minicard_label_resize_children (EMinicardLabel *e_minicard_label);
-static GnomeCanvasGroupClass *parent_class = NULL;
+static void set_colors (EMinicardLabel *label);
-/* The arguments we take */
enum {
- ARG_0,
- ARG_WIDTH,
- ARG_HEIGHT,
- ARG_HAS_FOCUS,
- ARG_FIELD,
- ARG_FIELDNAME,
- ARG_TEXT_MODEL,
- ARG_MAX_FIELD_NAME_WIDTH,
- ARG_EDITABLE
+ PROP_0,
+ PROP_WIDTH,
+ PROP_HEIGHT,
+ PROP_HAS_FOCUS,
+ PROP_FIELD,
+ PROP_FIELDNAME,
+ PROP_TEXT_MODEL,
+ PROP_MAX_FIELD_NAME_WIDTH,
+ PROP_EDITABLE
};
-GtkType
-e_minicard_label_get_type (void)
-{
- static GtkType minicard_label_type = 0;
-
- if (!minicard_label_type)
- {
- static const GtkTypeInfo minicard_label_info =
- {
- "EMinicardLabel",
- sizeof (EMinicardLabel),
- sizeof (EMinicardLabelClass),
- (GtkClassInitFunc) e_minicard_label_class_init,
- (GtkObjectInitFunc) e_minicard_label_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- minicard_label_type = gtk_type_unique (gnome_canvas_group_get_type (), &minicard_label_info);
- }
-
- return minicard_label_type;
-}
+enum {
+ STYLE_SET,
+ LAST_SIGNAL
+};
+
+static guint e_minicard_label_signals[LAST_SIGNAL] = {0, };
+
+G_DEFINE_TYPE (
+ EMinicardLabel,
+ e_minicard_label,
+ GNOME_TYPE_CANVAS_GROUP)
static void
-e_minicard_label_class_init (EMinicardLabelClass *klass)
+e_minicard_label_class_init (EMinicardLabelClass *class)
{
- GtkObjectClass *object_class;
- GnomeCanvasItemClass *item_class;
-
- object_class = (GtkObjectClass*) klass;
- item_class = (GnomeCanvasItemClass *) klass;
-
- parent_class = gtk_type_class (gnome_canvas_group_get_type ());
-
- gtk_object_add_arg_type ("EMinicardLabel::width", GTK_TYPE_DOUBLE,
- GTK_ARG_READWRITE, ARG_WIDTH);
- gtk_object_add_arg_type ("EMinicardLabel::height", GTK_TYPE_DOUBLE,
- GTK_ARG_READABLE, ARG_HEIGHT);
- gtk_object_add_arg_type ("EMinicardLabel::has_focus", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_HAS_FOCUS);
- gtk_object_add_arg_type ("EMinicardLabel::field", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_FIELD);
- gtk_object_add_arg_type ("EMinicardLabel::fieldname", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_FIELDNAME);
- gtk_object_add_arg_type ("EMinicardLabel::text_model", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_TEXT_MODEL);
- gtk_object_add_arg_type ("EMinicardLabel::max_field_name_length", GTK_TYPE_DOUBLE,
- GTK_ARG_READWRITE, ARG_MAX_FIELD_NAME_WIDTH);
- gtk_object_add_arg_type ("EMinicardLabel::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
-
- object_class->set_arg = e_minicard_label_set_arg;
- object_class->get_arg = e_minicard_label_get_arg;
- /* object_class->destroy = e_minicard_label_destroy; */
-
- /* GnomeCanvasItem method overrides */
- item_class->realize = e_minicard_label_realize;
- item_class->unrealize = e_minicard_label_unrealize;
- item_class->event = e_minicard_label_event;
+ GObjectClass *object_class;
+ GnomeCanvasItemClass *item_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ item_class = (GnomeCanvasItemClass *) class;
+
+ class->style_set = e_minicard_label_style_set;
+
+ object_class->set_property = e_minicard_label_set_property;
+ object_class->get_property = e_minicard_label_get_property;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WIDTH,
+ g_param_spec_double (
+ "width",
+ "Width",
+ NULL,
+ 0.0, G_MAXDOUBLE, 10.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HEIGHT,
+ g_param_spec_double (
+ "height",
+ "Height",
+ NULL,
+ 0.0, G_MAXDOUBLE, 10.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HAS_FOCUS,
+ g_param_spec_boolean (
+ "has_focus",
+ "Has Focus",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FIELD,
+ g_param_spec_string (
+ "field",
+ "Field",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FIELDNAME,
+ g_param_spec_string (
+ "fieldname",
+ "Field Name",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TEXT_MODEL,
+ g_param_spec_object (
+ "text_model",
+ "Text Model",
+ NULL,
+ E_TYPE_TEXT_MODEL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MAX_FIELD_NAME_WIDTH,
+ g_param_spec_double (
+ "max_field_name_length",
+ "Max field name length",
+ NULL,
+ -1.0, G_MAXDOUBLE, -1.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ "Editable",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ e_minicard_label_signals[STYLE_SET] = g_signal_new (
+ "style_set",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMinicardLabelClass, style_set),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_STYLE);
+
+ /* GnomeCanvasItem method overrides */
+ item_class->realize = e_minicard_label_realize;
+ item_class->event = e_minicard_label_event;
}
static void
e_minicard_label_init (EMinicardLabel *minicard_label)
{
- minicard_label->width = 10;
- minicard_label->height = 10;
- minicard_label->rect = NULL;
- minicard_label->fieldname = NULL;
- minicard_label->field = NULL;
+ minicard_label->width = 10;
+ minicard_label->height = 10;
+ minicard_label->rect = NULL;
+ minicard_label->fieldname = NULL;
+ minicard_label->field = NULL;
- minicard_label->max_field_name_length = -1;
+ minicard_label->max_field_name_length = -1;
- e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(minicard_label), e_minicard_label_reflow);
+ e_canvas_item_set_reflow_callback (
+ GNOME_CANVAS_ITEM (minicard_label),
+ e_minicard_label_reflow);
}
static void
-e_minicard_label_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+e_minicard_label_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GnomeCanvasItem *item;
EMinicardLabel *e_minicard_label;
+ GnomeCanvasItem *item;
+
+ e_minicard_label = E_MINICARD_LABEL (object);
+ item = GNOME_CANVAS_ITEM (object);
- item = GNOME_CANVAS_ITEM (o);
- e_minicard_label = E_MINICARD_LABEL (o);
-
- switch (arg_id){
- case ARG_WIDTH:
- e_minicard_label->width = GTK_VALUE_DOUBLE (*arg);
- e_minicard_label_resize_children(e_minicard_label);
+ switch (property_id) {
+ case PROP_WIDTH:
+ e_minicard_label->width = g_value_get_double (value);
+ e_minicard_label_resize_children (e_minicard_label);
e_canvas_item_request_reflow (item);
break;
- case ARG_HAS_FOCUS:
- if (e_minicard_label->field && (GTK_VALUE_ENUM(*arg) != E_FOCUS_NONE))
- e_canvas_item_grab_focus(e_minicard_label->field, FALSE);
+ case PROP_HAS_FOCUS:
+ if (e_minicard_label->field && (g_value_get_boolean (value) != E_FOCUS_NONE))
+ e_canvas_item_grab_focus (e_minicard_label->field, FALSE);
break;
- case ARG_FIELD:
- gnome_canvas_item_set( e_minicard_label->field, "text", GTK_VALUE_STRING (*arg), NULL );
+ case PROP_FIELD:
+ gnome_canvas_item_set (e_minicard_label->field, "text", g_value_get_string (value), NULL);
break;
- case ARG_FIELDNAME:
- gnome_canvas_item_set( e_minicard_label->fieldname, "text", GTK_VALUE_STRING (*arg), NULL );
+ case PROP_FIELDNAME:
+ gnome_canvas_item_set (e_minicard_label->fieldname, "text", g_value_get_string (value), NULL);
break;
- case ARG_TEXT_MODEL:
- gnome_canvas_item_set( e_minicard_label->field, "model", GTK_VALUE_OBJECT (*arg), NULL);
+ case PROP_TEXT_MODEL:
+ gnome_canvas_item_set (e_minicard_label->field, "model", g_value_get_object (value), NULL);
break;
- case ARG_MAX_FIELD_NAME_WIDTH:
- e_minicard_label->max_field_name_length = GTK_VALUE_DOUBLE (*arg);
+ case PROP_MAX_FIELD_NAME_WIDTH:
+ e_minicard_label->max_field_name_length = g_value_get_double (value);
break;
- case ARG_EDITABLE:
- e_minicard_label->editable = GTK_VALUE_BOOL (*arg);
- gtk_object_set (GTK_OBJECT (e_minicard_label->field), "editable", e_minicard_label->editable, NULL);
+ case PROP_EDITABLE:
+ e_minicard_label->editable = g_value_get_boolean (value);
+ g_object_set (e_minicard_label->field, "editable", FALSE /* e_minicard_label->editable */, NULL);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
-e_minicard_label_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+e_minicard_label_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
EMinicardLabel *e_minicard_label;
- char *temp;
- ETextModel *tempmodel;
e_minicard_label = E_MINICARD_LABEL (object);
- switch (arg_id) {
- case ARG_WIDTH:
- GTK_VALUE_DOUBLE (*arg) = e_minicard_label->width;
+ switch (property_id) {
+ case PROP_WIDTH:
+ g_value_set_double (value, e_minicard_label->width);
break;
- case ARG_HEIGHT:
- GTK_VALUE_DOUBLE (*arg) = e_minicard_label->height;
+ case PROP_HEIGHT:
+ g_value_set_double (value, e_minicard_label->height);
break;
- case ARG_HAS_FOCUS:
- GTK_VALUE_ENUM (*arg) = e_minicard_label->has_focus ? E_FOCUS_CURRENT : E_FOCUS_NONE;
+ case PROP_HAS_FOCUS:
+ g_value_set_boolean (value, e_minicard_label->has_focus ? E_FOCUS_CURRENT : E_FOCUS_NONE);
break;
- case ARG_FIELD:
- gtk_object_get( GTK_OBJECT( e_minicard_label->field ), "text", &temp, NULL );
- GTK_VALUE_STRING (*arg) = temp;
+ case PROP_FIELD:
+ g_object_get_property (
+ G_OBJECT (e_minicard_label->field),
+ "text", value);
break;
- case ARG_FIELDNAME:
- gtk_object_get( GTK_OBJECT( e_minicard_label->fieldname ), "text", &temp, NULL );
- GTK_VALUE_STRING (*arg) = temp;
+ case PROP_FIELDNAME:
+ g_object_get_property (
+ G_OBJECT (e_minicard_label->fieldname),
+ "text", value);
break;
- case ARG_TEXT_MODEL:
- gtk_object_get( GTK_OBJECT( e_minicard_label->field ), "model", &tempmodel, NULL );
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(tempmodel);
+ case PROP_TEXT_MODEL:
+ g_object_get_property (
+ G_OBJECT (e_minicard_label->field),
+ "model", value);
break;
- case ARG_MAX_FIELD_NAME_WIDTH:
- GTK_VALUE_DOUBLE (*arg) = e_minicard_label->max_field_name_length;
+ case PROP_MAX_FIELD_NAME_WIDTH:
+ g_value_set_double (value, e_minicard_label->max_field_name_length);
break;
- case ARG_EDITABLE:
- GTK_VALUE_BOOL (*arg) = e_minicard_label->editable;
+ case PROP_EDITABLE:
+ g_value_set_boolean (value, e_minicard_label->editable);
break;
default:
- arg->type = GTK_TYPE_INVALID;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
@@ -218,253 +288,241 @@ e_minicard_label_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
static void
e_minicard_label_realize (GnomeCanvasItem *item)
{
- if (GNOME_CANVAS_ITEM_CLASS( parent_class )->realize)
- (* GNOME_CANVAS_ITEM_CLASS( parent_class )->realize) (item);
-
- e_canvas_item_request_reflow(item);
-
- if (!item->canvas->aa)
- {
- }
-}
-
-void
-e_minicard_label_construct (GnomeCanvasItem *item)
-{
EMinicardLabel *e_minicard_label;
GnomeCanvasGroup *group;
- GdkFont *font;
-
- font = ((GtkWidget *) item->canvas)->style->font;
e_minicard_label = E_MINICARD_LABEL (item);
- group = GNOME_CANVAS_GROUP( item );
-
- e_minicard_label->rect =
- gnome_canvas_item_new( group,
- gnome_canvas_rect_get_type(),
- "x1", (double) 0,
- "y1", (double) 0,
- "x2", (double) e_minicard_label->width - 1,
- "y2", (double) e_minicard_label->height - 1,
- "outline_color", NULL,
- NULL );
- e_minicard_label->fieldname =
- gnome_canvas_item_new( group,
- e_text_get_type(),
- "anchor", GTK_ANCHOR_NW,
- "clip_width", (double) ( e_minicard_label->width / 2 - 4 ),
- "clip", TRUE,
- "use_ellipsis", TRUE,
- "font_gdk", font,
- "fill_color", "black",
- "draw_background", FALSE,
- NULL );
- e_canvas_item_move_absolute(e_minicard_label->fieldname, 2, 1);
-
- e_minicard_label->field =
- gnome_canvas_item_new( group,
- e_text_get_type(),
- "anchor", GTK_ANCHOR_NW,
- "clip_width", (double) ( ( e_minicard_label->width + 1 ) / 2 - 4 ),
- "clip", TRUE,
- "use_ellipsis", TRUE,
- "font_gdk", font,
- "fill_color", "black",
- "editable", e_minicard_label->editable,
- "draw_background", FALSE,
- NULL );
- e_canvas_item_move_absolute(e_minicard_label->field, ( e_minicard_label->width / 2 + 2), 1);
-
- e_canvas_item_request_reflow(item);
+ group = GNOME_CANVAS_GROUP (item);
+
+ GNOME_CANVAS_ITEM_CLASS (e_minicard_label_parent_class)->realize (item);
+
+ e_canvas_item_request_reflow (item);
+
+ e_minicard_label->rect = gnome_canvas_item_new (
+ group,
+ gnome_canvas_rect_get_type (),
+ "x1", (gdouble) 0,
+ "y1", (gdouble) 0,
+ "x2", (gdouble) e_minicard_label->width - 1,
+ "y2", (gdouble) e_minicard_label->height - 1,
+ "outline_color", NULL,
+ NULL);
+
+ e_minicard_label->fieldname = gnome_canvas_item_new (
+ group,
+ e_text_get_type (),
+ "clip_width", (gdouble) (e_minicard_label->width / 2 - 4),
+ "clip", TRUE,
+ "use_ellipsis", TRUE,
+ "fill_color", "black",
+ "im_context", E_CANVAS (item->canvas)->im_context,
+ NULL);
+
+ e_canvas_item_move_absolute (e_minicard_label->fieldname, 2, 1);
+
+ e_minicard_label->field = gnome_canvas_item_new (
+ group,
+ e_text_get_type (),
+ "clip_width", (gdouble) ((e_minicard_label->width + 1) / 2 - 4),
+ "clip", TRUE,
+ "use_ellipsis", TRUE,
+ "fill_color", "black",
+ "editable", FALSE, /* e_minicard_label->editable, */
+ "im_context", E_CANVAS (item->canvas)->im_context,
+ NULL);
+
+ e_canvas_item_move_absolute (
+ e_minicard_label->field,
+ (e_minicard_label->width / 2 + 2), 1);
+
+ set_colors (e_minicard_label);
+
+ e_canvas_item_request_reflow (item);
}
-static void
-e_minicard_label_unrealize (GnomeCanvasItem *item)
+static gboolean
+e_minicard_label_event (GnomeCanvasItem *item,
+ GdkEvent *event)
{
- EMinicardLabel *e_minicard_label;
+ EMinicardLabel *e_minicard_label;
+
+ e_minicard_label = E_MINICARD_LABEL (item);
- e_minicard_label = E_MINICARD_LABEL (item);
+ switch (event->type) {
+ case GDK_KEY_PRESS:
+ if (event->key.keyval == GDK_KEY_Escape) {
+ GnomeCanvasItem *parent;
- if (!item->canvas->aa)
- {
- }
+ e_text_cancel_editing (E_TEXT (e_minicard_label->field));
- if (GNOME_CANVAS_ITEM_CLASS( parent_class )->unrealize)
- (* GNOME_CANVAS_ITEM_CLASS( parent_class )->unrealize) (item);
-}
+ parent = GNOME_CANVAS_ITEM (e_minicard_label)->parent;
+ if (parent)
+ e_canvas_item_grab_focus (parent, FALSE);
+ }
+ break;
+ case GDK_FOCUS_CHANGE: {
+ GdkEventFocus *focus_event = (GdkEventFocus *) event;
-static gboolean
-e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event)
-{
- EMinicardLabel *e_minicard_label;
-
- e_minicard_label = E_MINICARD_LABEL (item);
-
- switch( event->type )
- {
- case GDK_KEY_PRESS:
- if (event->key.keyval == GDK_Escape) {
- GnomeCanvasItem *parent;
-
- e_text_cancel_editing (E_TEXT (e_minicard_label->field));
-
- parent = GNOME_CANVAS_ITEM (e_minicard_label)->parent;
- if (parent)
- e_canvas_item_grab_focus(parent, FALSE);
- }
- break;
- case GDK_FOCUS_CHANGE:
- {
- GdkEventFocus *focus_event = (GdkEventFocus *) event;
- if ( focus_event->in )
- {
- gnome_canvas_item_set( e_minicard_label->rect,
- "outline_color", "grey50",
- "fill_color", "grey90",
- NULL );
- e_minicard_label->has_focus = TRUE;
- }
- else
- {
- gnome_canvas_item_set( e_minicard_label->rect,
- "outline_color", NULL,
- "fill_color", NULL,
- NULL );
- e_minicard_label->has_focus = FALSE;
- }
- }
- break;
- case GDK_BUTTON_PRESS:
- case GDK_BUTTON_RELEASE:
- case GDK_MOTION_NOTIFY:
- case GDK_ENTER_NOTIFY:
- case GDK_LEAVE_NOTIFY: {
- gboolean return_val;
-#if 0
- GnomeCanvasItem *field;
- ArtPoint p;
- double inv[6], affine[6];
-
- field = e_minicard_label->field;
- art_affine_identity (affine);
-
- if (field->xform != NULL) {
- if (field->object.flags & GNOME_CANVAS_ITEM_AFFINE_FULL) {
- art_affine_multiply (affine, affine, field->xform);
- } else {
- affine[4] += field->xform[0];
- affine[5] += field->xform[1];
- }
- }
-
- art_affine_invert (inv, affine);
- switch(event->type) {
- case GDK_MOTION_NOTIFY:
- p.x = event->motion.x;
- p.y = event->motion.y;
- art_affine_point (&p, &p, inv);
- event->motion.x = p.x;
- event->motion.y = p.y;
- break;
- case GDK_BUTTON_PRESS:
- case GDK_BUTTON_RELEASE:
- p.x = event->button.x;
- p.y = event->button.y;
- art_affine_point (&p, &p, inv);
- event->button.x = p.x;
- event->button.y = p.y;
- break;
- case GDK_ENTER_NOTIFY:
- case GDK_LEAVE_NOTIFY:
- p.x = event->crossing.x;
- p.y = event->crossing.y;
- art_affine_point (&p, &p, inv);
- event->crossing.x = p.x;
- event->crossing.y = p.y;
- break;
- default:
- break;
- }
-#endif
- gtk_signal_emit_by_name(GTK_OBJECT(e_minicard_label->field), "event", event, &return_val);
- return return_val;
- break;
- }
- default:
- break;
- }
-
- if (GNOME_CANVAS_ITEM_CLASS( parent_class )->event)
- return (* GNOME_CANVAS_ITEM_CLASS( parent_class )->event) (item, event);
- else
- return 0;
+ e_minicard_label->has_focus = focus_event->in;
+ set_colors (e_minicard_label);
+
+ g_object_set (
+ e_minicard_label->field,
+ "handle_popup", e_minicard_label->has_focus,
+ NULL);
+ break;
+ }
+ case GDK_BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ case GDK_MOTION_NOTIFY:
+ case GDK_ENTER_NOTIFY:
+ case GDK_LEAVE_NOTIFY: {
+ gboolean return_val;
+ g_signal_emit_by_name (e_minicard_label->field, "event", event, &return_val);
+ return return_val;
+ }
+ default:
+ break;
+ }
+
+ return GNOME_CANVAS_ITEM_CLASS (e_minicard_label_parent_class)->
+ event (item, event);
}
static void
-e_minicard_label_resize_children(EMinicardLabel *e_minicard_label)
+e_minicard_label_resize_children (EMinicardLabel *e_minicard_label)
{
- double left_width;
+ gdouble left_width;
+ gdouble fieldnamewidth;
+ gdouble fieldwidth;
+ gboolean is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
if (e_minicard_label->max_field_name_length != -1 && ((e_minicard_label->width / 2) - 4 > e_minicard_label->max_field_name_length))
left_width = e_minicard_label->max_field_name_length;
else
left_width = e_minicard_label->width / 2 - 4;
- gnome_canvas_item_set( e_minicard_label->fieldname,
- "clip_width", (double) ( left_width ),
- NULL );
- gnome_canvas_item_set( e_minicard_label->field,
- "clip_width", (double) ( e_minicard_label->width - 8 - left_width ),
- NULL );
+ fieldnamewidth = (gdouble) MAX (left_width, 0);
+ fieldwidth = (gdouble) MAX (e_minicard_label->width - 8 - left_width, 0);
+ gnome_canvas_item_set (
+ e_minicard_label->fieldname,
+ "clip_width", is_rtl ? fieldwidth : fieldnamewidth,
+ NULL);
+ gnome_canvas_item_set (
+ e_minicard_label->field,
+ "clip_width", is_rtl ? fieldnamewidth : fieldwidth,
+ NULL);
}
static void
-e_minicard_label_reflow(GnomeCanvasItem *item, int flags)
+set_colors (EMinicardLabel *label)
{
- EMinicardLabel *e_minicard_label = E_MINICARD_LABEL(item);
-
+ GnomeCanvasItem *item = GNOME_CANVAS_ITEM (label);
+
+ if ((item->flags & GNOME_CANVAS_ITEM_REALIZED)) {
+ GnomeCanvas *canvas;
+ GtkStyle *style;
+
+ canvas = GNOME_CANVAS_ITEM (label)->canvas;
+ style = gtk_widget_get_style (GTK_WIDGET (canvas));
+
+ if (label->has_focus) {
+ gnome_canvas_item_set (
+ label->rect,
+ "outline_color_gdk", &style->mid[GTK_STATE_SELECTED],
+ "fill_color_gdk", &style->bg[GTK_STATE_NORMAL],
+ NULL);
+
+ gnome_canvas_item_set (
+ label->field,
+ "fill_color_gdk", &style->text[GTK_STATE_NORMAL],
+ NULL);
+
+ gnome_canvas_item_set (
+ label->fieldname,
+ "fill_color_gdk", &style->text[GTK_STATE_NORMAL],
+ NULL);
+ }
+ else {
+ gnome_canvas_item_set (
+ label->rect,
+ "outline_color_gdk", NULL,
+ "fill_color_gdk", NULL,
+ NULL);
+
+ gnome_canvas_item_set (
+ label->field,
+ "fill_color_gdk", &style->text[GTK_STATE_NORMAL],
+ NULL);
+
+ gnome_canvas_item_set (
+ label->fieldname,
+ "fill_color_gdk", &style->text[GTK_STATE_NORMAL],
+ NULL);
+ }
+ }
+}
+
+static void
+e_minicard_label_style_set (EMinicardLabel *label,
+ GtkStyle *previous_style)
+{
+ set_colors (label);
+}
+
+static void
+e_minicard_label_reflow (GnomeCanvasItem *item,
+ gint flags)
+{
+ EMinicardLabel *e_minicard_label = E_MINICARD_LABEL (item);
+
gint old_height;
gdouble text_height;
gdouble left_width;
old_height = e_minicard_label->height;
- gtk_object_get(GTK_OBJECT(e_minicard_label->fieldname),
- "text_height", &text_height,
- NULL);
+ g_object_get (
+ e_minicard_label->fieldname,
+ "text_height", &text_height,
+ NULL);
e_minicard_label->height = text_height;
-
- gtk_object_get(GTK_OBJECT(e_minicard_label->field),
- "text_height", &text_height,
- NULL);
+ g_object_get (
+ e_minicard_label->field,
+ "text_height", &text_height,
+ NULL);
if (e_minicard_label->height < text_height)
e_minicard_label->height = text_height;
e_minicard_label->height += 3;
- gnome_canvas_item_set( e_minicard_label->rect,
- "x2", (double) e_minicard_label->width - 1,
- "y2", (double) e_minicard_label->height - 1,
- NULL );
+ gnome_canvas_item_set (
+ e_minicard_label->rect,
+ "x2", (gdouble) e_minicard_label->width - 1,
+ "y2", (gdouble) e_minicard_label->height - 1,
+ NULL);
+
+ gnome_canvas_item_set (
+ e_minicard_label->fieldname,
+ "clip_height", (gdouble) e_minicard_label->height - 3,
+ NULL);
if (e_minicard_label->max_field_name_length != -1 && ((e_minicard_label->width / 2) - 4 > e_minicard_label->max_field_name_length))
left_width = e_minicard_label->max_field_name_length;
else
left_width = e_minicard_label->width / 2 - 4;
- e_canvas_item_move_absolute(e_minicard_label->field, left_width + 6, 1);
+ e_canvas_item_move_absolute (e_minicard_label->field, left_width + 6, 1);
if (old_height != e_minicard_label->height)
- e_canvas_item_request_parent_reflow(item);
+ e_canvas_item_request_parent_reflow (item);
}
GnomeCanvasItem *
-e_minicard_label_new(GnomeCanvasGroup *parent)
+e_minicard_label_new (GnomeCanvasGroup *parent)
{
- GnomeCanvasItem *item = gnome_canvas_item_new(parent, e_minicard_label_get_type(), NULL);
- e_minicard_label_construct(item);
- return item;
+ return gnome_canvas_item_new (
+ parent, e_minicard_label_get_type (), NULL);
}
diff --git a/addressbook/gui/widgets/e-minicard-label.h b/addressbook/gui/widgets/e-minicard-label.h
index 32792991a7..0cd9183e5f 100644
--- a/addressbook/gui/widgets/e-minicard-label.h
+++ b/addressbook/gui/widgets/e-minicard-label.h
@@ -1,32 +1,31 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-minicard-label.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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_LABEL_H__
#define __E_MINICARD_LABEL_H__
-#include <glib.h>
-#include <libgnomeui/gnome-canvas.h>
+#include <libgnomecanvas/libgnomecanvas.h>
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
+G_BEGIN_DECLS
/* EMinicardLabel - A label doing focus with non-marching ants.
*
@@ -40,12 +39,11 @@ extern "C" {
* fieldname string RW text in the fieldname label
*/
-#define E_MINICARD_LABEL_TYPE (e_minicard_label_get_type ())
-#define E_MINICARD_LABEL(obj) (GTK_CHECK_CAST ((obj), E_MINICARD_LABEL_TYPE, EMinicardLabel))
-#define E_MINICARD_LABEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_MINICARD_LABEL_TYPE, EMiniCardLabelClass))
-#define E_IS_MINICARD_LABEL(obj) (GTK_CHECK_TYPE ((obj), E_MINICARD_LABEL_TYPE))
-#define E_IS_MINICARD_LABEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_MINICARD_LABEL_TYPE))
-
+#define E_TYPE_MINICARD_LABEL (e_minicard_label_get_type ())
+#define E_MINICARD_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MINICARD_LABEL, EMinicardLabel))
+#define E_MINICARD_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MINICARD_LABEL, EMiniCardLabelClass))
+#define E_IS_MINICARD_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MINICARD_LABEL))
+#define E_IS_MINICARD_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_MINICARD_LABEL))
typedef struct _EMinicardLabel EMinicardLabel;
typedef struct _EMinicardLabelClass EMinicardLabelClass;
@@ -53,11 +51,11 @@ typedef struct _EMinicardLabelClass EMinicardLabelClass;
struct _EMinicardLabel
{
GnomeCanvasGroup parent;
-
+
/* item specific fields */
- double width;
- double height;
- double max_field_name_length;
+ gdouble width;
+ gdouble height;
+ gdouble max_field_name_length;
guint editable : 1;
GnomeCanvasItem *fieldname;
GnomeCanvasItem *field;
@@ -69,16 +67,14 @@ struct _EMinicardLabel
struct _EMinicardLabelClass
{
GnomeCanvasGroupClass parent_class;
-};
+ void (* style_set) (EMinicardLabel *label, GtkStyle *previous_style);
+};
-GtkType e_minicard_label_get_type (void);
-GnomeCanvasItem *e_minicard_label_new(GnomeCanvasGroup *parent);
+GType e_minicard_label_get_type (void);
+GnomeCanvasItem *e_minicard_label_new (GnomeCanvasGroup *parent);
void e_minicard_label_construct (GnomeCanvasItem *item);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
+G_END_DECLS
#endif /* __E_MINICARD_LABEL_H__ */
diff --git a/addressbook/gui/widgets/e-minicard-view-widget.c b/addressbook/gui/widgets/e-minicard-view-widget.c
index 1f6e1bd26b..7ff63a1bd9 100644
--- a/addressbook/gui/widgets/e-minicard-view-widget.c
+++ b/addressbook/gui/widgets/e-minicard-view-widget.c
@@ -1,146 +1,194 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-minicard-view-widget.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
-#include <gtk/gtksignal.h>
-#include <gal/widgets/e-canvas-background.h>
-#include <gal/widgets/e-canvas.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
-#include "e-minicard-view-widget.h"
+#include <e-util/e-util.h>
-static void e_minicard_view_widget_init (EMinicardViewWidget *widget);
-static void e_minicard_view_widget_class_init (EMinicardViewWidgetClass *klass);
-static void e_minicard_view_widget_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_minicard_view_widget_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_minicard_view_widget_destroy (GtkObject *object);
-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_realize (GtkWidget *widget);
+#include "e-minicard-view-widget.h"
-static ECanvasClass *parent_class = NULL;
+static void e_minicard_view_widget_set_property
+ (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void e_minicard_view_widget_get_property
+ (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void e_minicard_view_widget_dispose (GObject *object);
+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);
-/* The arguments we take */
enum {
- ARG_0,
- ARG_BOOK,
- ARG_QUERY,
- ARG_EDITABLE,
- ARG_COLUMN_WIDTH
+ PROP_0,
+ PROP_CLIENT,
+ PROP_QUERY,
+ PROP_EDITABLE,
+ PROP_COLUMN_WIDTH
};
enum {
+ CREATE_CONTACT,
+ CREATE_CONTACT_LIST,
SELECTION_CHANGE,
COLUMN_WIDTH_CHANGED,
RIGHT_CLICK,
LAST_SIGNAL
};
-static guint signals [LAST_SIGNAL] = {0, };
+static guint signals[LAST_SIGNAL] = {0, };
-GtkType
-e_minicard_view_widget_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type)
- {
- static const GtkTypeInfo info =
- {
- "EMinicardViewWidget",
- sizeof (EMinicardViewWidget),
- sizeof (EMinicardViewWidgetClass),
- (GtkClassInitFunc) e_minicard_view_widget_class_init,
- (GtkObjectInitFunc) e_minicard_view_widget_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- type = gtk_type_unique (e_canvas_get_type (), &info);
- }
-
- return type;
-}
+G_DEFINE_TYPE (
+ EMinicardViewWidget,
+ e_minicard_view_widget,
+ E_TYPE_CANVAS)
static void
-e_minicard_view_widget_class_init (EMinicardViewWidgetClass *klass)
+e_minicard_view_widget_class_init (EMinicardViewWidgetClass *class)
{
- GtkObjectClass *object_class;
+ GObjectClass *object_class;
GtkWidgetClass *widget_class;
ECanvasClass *canvas_class;
- object_class = (GtkObjectClass*) klass;
- widget_class = GTK_WIDGET_CLASS (klass);
- canvas_class = E_CANVAS_CLASS (klass);
-
- parent_class = gtk_type_class (e_canvas_get_type ());
-
- gtk_object_add_arg_type ("EMinicardViewWidget::book", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_BOOK);
- gtk_object_add_arg_type ("EMinicardViewWidget::query", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_QUERY);
- gtk_object_add_arg_type ("EMinicardViewWidget::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
- gtk_object_add_arg_type ("EMinicardViewWidget::column_width", GTK_TYPE_INT,
- GTK_ARG_READWRITE, ARG_COLUMN_WIDTH);
-
- signals [SELECTION_CHANGE] =
- gtk_signal_new ("selection_change",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardViewWidgetClass, selection_change),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- signals [COLUMN_WIDTH_CHANGED] =
- gtk_signal_new ("column_width_changed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardViewWidgetClass, column_width_changed),
- e_marshal_NONE__DOUBLE,
- GTK_TYPE_NONE, 1, GTK_TYPE_DOUBLE);
-
- signals [RIGHT_CLICK] =
- gtk_signal_new ("right_click",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardViewWidgetClass, right_click),
- gtk_marshal_INT__POINTER,
- GTK_TYPE_INT, 1, GTK_TYPE_GDK_EVENT);
-
- gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
-
- object_class->set_arg = e_minicard_view_widget_set_arg;
- object_class->get_arg = e_minicard_view_widget_get_arg;
- object_class->destroy = e_minicard_view_widget_destroy;
-
- widget_class->realize = e_minicard_view_widget_realize;
- widget_class->size_allocate = e_minicard_view_widget_size_allocate;
-
- canvas_class->reflow = e_minicard_view_widget_reflow;
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = e_minicard_view_widget_set_property;
+ object_class->get_property = e_minicard_view_widget_get_property;
+ object_class->dispose = e_minicard_view_widget_dispose;
- klass->selection_change = NULL;
- klass->column_width_changed = NULL;
- klass->right_click = NULL;
+ widget_class = GTK_WIDGET_CLASS (class);
+ 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 = E_CANVAS_CLASS (class);
+ canvas_class->reflow = e_minicard_view_widget_reflow;
+
+ class->selection_change = NULL;
+ class->column_width_changed = NULL;
+ class->right_click = NULL;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLIENT,
+ g_param_spec_object (
+ "client",
+ "EBookClient",
+ NULL,
+ E_TYPE_BOOK_CLIENT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_QUERY,
+ g_param_spec_string (
+ "query",
+ "Query",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ "Editable",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_COLUMN_WIDTH,
+ g_param_spec_double (
+ "column_width",
+ "Column Width",
+ NULL,
+ 0.0, G_MAXDOUBLE, 225.0,
+ G_PARAM_READWRITE));
+
+ signals[CREATE_CONTACT] = g_signal_new (
+ "create-contact",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewWidgetClass, create_contact),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[CREATE_CONTACT_LIST] = g_signal_new (
+ "create-contact-list",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewWidgetClass, create_contact_list),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[SELECTION_CHANGE] = g_signal_new (
+ "selection_change",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewWidgetClass, selection_change),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[COLUMN_WIDTH_CHANGED] = g_signal_new (
+ "column_width_changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewWidgetClass, column_width_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__DOUBLE,
+ G_TYPE_NONE, 1,
+ G_TYPE_DOUBLE);
+
+ signals[RIGHT_CLICK] = g_signal_new (
+ "right_click",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewWidgetClass, right_click),
+ NULL, NULL,
+ e_marshal_INT__POINTER,
+ G_TYPE_INT, 1,
+ G_TYPE_POINTER);
}
static void
@@ -148,205 +196,287 @@ e_minicard_view_widget_init (EMinicardViewWidget *view)
{
view->emv = NULL;
- view->book = NULL;
+ view->book_client = NULL;
view->query = NULL;
view->editable = FALSE;
- view->column_width = 150;
+ view->column_width = 225;
}
GtkWidget *
e_minicard_view_widget_new (EAddressbookReflowAdapter *adapter)
{
- EMinicardViewWidget *widget = E_MINICARD_VIEW_WIDGET (gtk_type_new (e_minicard_view_widget_get_type ()));
+ EMinicardViewWidget *widget;
+
+ widget = g_object_new (E_TYPE_MINICARD_VIEW_WIDGET, NULL);
- widget->adapter = adapter;
- gtk_object_ref (GTK_OBJECT (widget->adapter));
+ widget->adapter = g_object_ref (adapter);
return GTK_WIDGET (widget);
}
static void
-e_minicard_view_widget_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+e_minicard_view_widget_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
EMinicardViewWidget *emvw;
- emvw = E_MINICARD_VIEW_WIDGET (o);
+ emvw = E_MINICARD_VIEW_WIDGET (object);
- switch (arg_id){
- case ARG_BOOK:
- if (emvw->book)
- gtk_object_unref(GTK_OBJECT(emvw->book));
- if (GTK_VALUE_OBJECT (*arg)) {
- emvw->book = E_BOOK(GTK_VALUE_OBJECT (*arg));
- if (emvw->book)
- gtk_object_ref(GTK_OBJECT(emvw->book));
+ switch (property_id) {
+ case PROP_CLIENT:
+ if (emvw->book_client)
+ g_object_unref (emvw->book_client);
+ if (g_value_get_object (value)) {
+ emvw->book_client = E_BOOK_CLIENT (g_value_get_object (value));
+ if (emvw->book_client)
+ g_object_ref (emvw->book_client);
} else
- emvw->book = NULL;
+ emvw->book_client = NULL;
if (emvw->emv)
- gtk_object_set(GTK_OBJECT(emvw->emv),
- "book", emvw->book,
- NULL);
+ g_object_set (
+ emvw->emv,
+ "client", emvw->book_client,
+ NULL);
break;
- case ARG_QUERY:
- emvw->query = g_strdup(GTK_VALUE_STRING (*arg));
+ case PROP_QUERY:
+ emvw->query = g_strdup (g_value_get_string (value));
if (emvw->emv)
- gtk_object_set(GTK_OBJECT(emvw->emv),
- "query", emvw->query,
- NULL);
+ g_object_set (
+ emvw->emv,
+ "query", emvw->query,
+ NULL);
break;
- case ARG_EDITABLE:
- emvw->editable = GTK_VALUE_BOOL(*arg);
+ case PROP_EDITABLE:
+ emvw->editable = g_value_get_boolean (value);
if (emvw->emv)
- gtk_object_set (GTK_OBJECT(emvw->emv),
- "editable", emvw->editable,
- NULL);
+ g_object_set (
+ emvw->emv,
+ "editable", emvw->editable,
+ NULL);
break;
- case ARG_COLUMN_WIDTH:
- emvw->column_width = GTK_VALUE_INT (*arg);
+ case PROP_COLUMN_WIDTH:
+ emvw->column_width = g_value_get_double (value);
if (emvw->emv) {
- gtk_object_set (GTK_OBJECT(emvw->emv),
- "column_width", (int) emvw->column_width,
- NULL);
+ g_object_set (
+ emvw->emv,
+ "column_width", emvw->column_width,
+ NULL);
}
break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
static void
-e_minicard_view_widget_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+e_minicard_view_widget_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
EMinicardViewWidget *emvw;
emvw = E_MINICARD_VIEW_WIDGET (object);
- switch (arg_id) {
- case ARG_BOOK:
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(emvw->book);
+ switch (property_id) {
+ case PROP_CLIENT:
+ g_value_set_object (value, emvw->book_client);
break;
- case ARG_QUERY:
- GTK_VALUE_STRING (*arg) = g_strdup(emvw->query);
+ case PROP_QUERY:
+ g_value_set_string (value, emvw->query);
break;
- case ARG_EDITABLE:
- GTK_VALUE_BOOL (*arg) = emvw->editable;
+ case PROP_EDITABLE:
+ g_value_set_boolean (value, emvw->editable);
break;
- case ARG_COLUMN_WIDTH:
- GTK_VALUE_INT (*arg) = emvw->column_width;
+ case PROP_COLUMN_WIDTH:
+ g_value_set_double (value, emvw->column_width);
break;
default:
- arg->type = GTK_TYPE_INVALID;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
-e_minicard_view_widget_destroy (GtkObject *object)
+e_minicard_view_widget_dispose (GObject *object)
{
- EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET(object);
+ EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET (object);
- if (view->book)
- gtk_object_unref(GTK_OBJECT(view->book));
- g_free(view->query);
+ if (view->book_client) {
+ g_object_unref (view->book_client);
+ view->book_client = NULL;
+ }
+ if (view->query) {
+ g_free (view->query);
+ view->query = NULL;
+ }
- gtk_object_unref (GTK_OBJECT (view->adapter));
+ if (view->adapter) {
+ g_object_unref (view->adapter);
+ view->adapter = NULL;
+ }
- GTK_OBJECT_CLASS(parent_class)->destroy (object);
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_minicard_view_widget_parent_class)->dispose (object);
}
static void
-selection_change (ESelectionModel *esm, EMinicardViewWidget *widget)
+selection_change (ESelectionModel *esm,
+ EMinicardViewWidget *widget)
{
- gtk_signal_emit (GTK_OBJECT(widget),
- signals [SELECTION_CHANGE]);
+ g_signal_emit (widget, signals[SELECTION_CHANGE], 0);
}
static void
-column_width_changed (ESelectionModel *esm, double width, EMinicardViewWidget *widget)
+selection_row_change (ESelectionModel *esm,
+ gint row,
+ EMinicardViewWidget *widget)
{
- gtk_signal_emit (GTK_OBJECT(widget),
- signals [COLUMN_WIDTH_CHANGED], width);
+ selection_change (esm, widget);
+}
+
+static void
+column_width_changed (ESelectionModel *esm,
+ gdouble width,
+ EMinicardViewWidget *widget)
+{
+ g_signal_emit (widget, signals[COLUMN_WIDTH_CHANGED], 0, width);
+}
+
+static void
+create_contact (EMinicardView *view,
+ EMinicardViewWidget *widget)
+{
+ g_signal_emit (widget, signals[CREATE_CONTACT], 0);
+}
+
+static void
+create_contact_list (EMinicardView *view,
+ EMinicardViewWidget *widget)
+{
+ g_signal_emit (widget, signals[CREATE_CONTACT_LIST], 0);
}
static guint
-right_click (EMinicardView *view, GdkEvent *event, EMinicardViewWidget *widget)
+right_click (EMinicardView *view,
+ GdkEvent *event,
+ EMinicardViewWidget *widget)
{
guint ret_val;
- gtk_signal_emit (GTK_OBJECT(widget),
- signals [RIGHT_CLICK],
- event, &ret_val);
+
+ g_signal_emit (widget, signals[RIGHT_CLICK], 0, event, &ret_val);
+
return ret_val;
}
static void
+e_minicard_view_widget_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+ EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET (widget);
+ GtkStyle *style;
+
+ style = gtk_widget_get_style (widget);
+
+ if (view->background)
+ gnome_canvas_item_set (
+ view->background, "fill_color_gdk",
+ &style->base[GTK_STATE_NORMAL], NULL);
+
+ GTK_WIDGET_CLASS (e_minicard_view_widget_parent_class)->
+ style_set (widget, previous_style);
+}
+
+static void
e_minicard_view_widget_realize (GtkWidget *widget)
{
- EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET(widget);
-
- gnome_canvas_item_new(gnome_canvas_root( GNOME_CANVAS(view) ),
- e_canvas_background_get_type(),
- "fill_color", "white",
- NULL );
-
- view->emv = gnome_canvas_item_new(
- gnome_canvas_root( GNOME_CANVAS(view) ),
- e_minicard_view_get_type(),
- "height", (double) 100,
- "minimum_width", (double) 100,
+ EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET (widget);
+ GtkStyle *style = gtk_widget_get_style (widget);
+
+ view->background = gnome_canvas_item_new (
+ gnome_canvas_root (GNOME_CANVAS (view)),
+ e_canvas_background_get_type (),
+ "fill_color_gdk", &style->base[GTK_STATE_NORMAL],
+ NULL);
+
+ view->emv = gnome_canvas_item_new (
+ gnome_canvas_root (GNOME_CANVAS (view)),
+ e_minicard_view_get_type (),
+ "height", (gdouble) 100,
+ "minimum_width", (gdouble) 100,
"adapter", view->adapter,
- "column_width", (int) view->column_width,
- NULL );
-
- gtk_signal_connect (GTK_OBJECT (E_REFLOW(view->emv)->selection),
- "selection_changed",
- selection_change, view);
- gtk_signal_connect (GTK_OBJECT (view->emv),
- "column_width_changed",
- column_width_changed, view);
- gtk_signal_connect (GTK_OBJECT (view->emv),
- "right_click",
- GTK_SIGNAL_FUNC (right_click), view);
-
- if (GTK_WIDGET_CLASS(parent_class)->realize)
- GTK_WIDGET_CLASS(parent_class)->realize (widget);
+ "column_width", view->column_width,
+ NULL);
+
+ 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);
+ g_signal_connect (
+ view->emv, "create-contact",
+ G_CALLBACK (create_contact), view);
+ g_signal_connect (
+ view->emv, "create-contact-list",
+ G_CALLBACK (create_contact_list), view);
+ g_signal_connect (
+ view->emv, "right_click",
+ G_CALLBACK (right_click), view);
+
+ GTK_WIDGET_CLASS (e_minicard_view_widget_parent_class)->
+ realize (widget);
}
static void
-e_minicard_view_widget_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
+e_minicard_view_widget_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
{
- if (GTK_WIDGET_CLASS(parent_class)->size_allocate)
- GTK_WIDGET_CLASS(parent_class)->size_allocate (widget, allocation);
-
- if (GTK_WIDGET_REALIZED(widget)) {
- double width;
- EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET(widget);
-
- gnome_canvas_item_set( view->emv,
- "height", (double) allocation->height,
- NULL );
- gnome_canvas_item_set( view->emv,
- "minimum_width", (double) allocation->width,
- NULL );
- gtk_object_get(GTK_OBJECT(view->emv),
- "width", &width,
- NULL);
- width = MAX(width, allocation->width);
- gnome_canvas_set_scroll_region (GNOME_CANVAS (view), 0, 0, width - 1, allocation->height - 1);
+ GTK_WIDGET_CLASS (e_minicard_view_widget_parent_class)->
+ size_allocate (widget, allocation);
+
+ if (gtk_widget_get_realized (widget)) {
+ gdouble width;
+ EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET (widget);
+
+ gnome_canvas_item_set (
+ view->emv, "height",
+ (gdouble) allocation->height, NULL);
+ gnome_canvas_item_set (
+ view->emv, "minimum_width",
+ (gdouble) allocation->width, NULL);
+ g_object_get (view->emv, "width", &width, NULL);
+ width = MAX (width, allocation->width);
+ gnome_canvas_set_scroll_region (
+ GNOME_CANVAS (view), 0, 0,
+ width - 1, allocation->height - 1);
}
}
static void
-e_minicard_view_widget_reflow(ECanvas *canvas)
+e_minicard_view_widget_reflow (ECanvas *canvas)
{
- double width;
- EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET(canvas);
+ gdouble width;
+ EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET (canvas);
+ GtkAllocation allocation;
+
+ E_CANVAS_CLASS (e_minicard_view_widget_parent_class)->reflow (canvas);
- if (E_CANVAS_CLASS(parent_class)->reflow)
- E_CANVAS_CLASS(parent_class)->reflow (canvas);
+ g_object_get (view->emv, "width", &width, NULL);
+ gtk_widget_get_allocation (GTK_WIDGET (canvas), &allocation);
- gtk_object_get(GTK_OBJECT(view->emv),
- "width", &width,
- NULL);
- width = MAX(width, GTK_WIDGET(canvas)->allocation.width);
- gnome_canvas_set_scroll_region(GNOME_CANVAS(canvas), 0, 0, width - 1, GTK_WIDGET(canvas)->allocation.height - 1);
+ gnome_canvas_set_scroll_region (
+ GNOME_CANVAS (canvas), 0, 0,
+ MAX (width, allocation.width) - 1,
+ allocation.height - 1);
}
ESelectionModel *
@@ -359,10 +489,35 @@ e_minicard_view_widget_get_selection_model (EMinicardViewWidget *view)
}
EMinicardView *
-e_minicard_view_widget_get_view (EMinicardViewWidget *view)
+e_minicard_view_widget_get_view (EMinicardViewWidget *view)
{
if (view->emv)
return E_MINICARD_VIEW (view->emv);
else
return 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) {
+ gint unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), 0);
+
+ if (unsorted != -1)
+ canvas->focused_item = reflow->items[unsorted];
+ }
+ }
+
+ return GTK_WIDGET_CLASS (e_minicard_view_widget_parent_class)->
+ focus_in_event (widget, event);
+}
+
diff --git a/addressbook/gui/widgets/e-minicard-view-widget.h b/addressbook/gui/widgets/e-minicard-view-widget.h
index c55bb6e636..71fe00a497 100644
--- a/addressbook/gui/widgets/e-minicard-view-widget.h
+++ b/addressbook/gui/widgets/e-minicard-view-widget.h
@@ -1,41 +1,41 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-minicard-view-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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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_VIEW_WIDGET_H__
#define __E_MINICARD_VIEW_WIDGET_H__
-#include <gal/widgets/e-canvas.h>
-#include <gal/unicode/gunicode.h>
-#include "addressbook/backend/ebook/e-book.h"
-#include "e-minicard-view.h"
+#include <libebook/libebook.h>
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
+#include <e-util/e-util.h>
-#define E_MINICARD_VIEW_WIDGET_TYPE (e_minicard_view_widget_get_type ())
-#define E_MINICARD_VIEW_WIDGET(obj) (GTK_CHECK_CAST ((obj), E_MINICARD_VIEW_WIDGET_TYPE, EMinicardViewWidget))
-#define E_MINICARD_VIEW_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_MINICARD_VIEW_WIDGET_TYPE, EMinicardViewWidgetClass))
-#define E_IS_MINICARD_VIEW_WIDGET(obj) (GTK_CHECK_TYPE ((obj), E_MINICARD_VIEW_WIDGET_TYPE))
-#define E_IS_MINICARD_VIEW_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_MINICARD_VIEW_WIDGET_TYPE))
+#include "e-minicard-view.h"
+G_BEGIN_DECLS
+
+#define E_TYPE_MINICARD_VIEW_WIDGET (e_minicard_view_widget_get_type ())
+#define E_MINICARD_VIEW_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MINICARD_VIEW_WIDGET, EMinicardViewWidget))
+#define E_MINICARD_VIEW_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MINICARD_VIEW_WIDGET, EMinicardViewWidgetClass))
+#define E_IS_MINICARD_VIEW_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MINICARD_VIEW_WIDGET))
+#define E_IS_MINICARD_VIEW_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_MINICARD_VIEW_WIDGET))
typedef struct _EMinicardViewWidget EMinicardViewWidget;
typedef struct _EMinicardViewWidgetClass EMinicardViewWidgetClass;
@@ -44,35 +44,35 @@ struct _EMinicardViewWidget
{
ECanvas parent;
+ GnomeCanvasItem *background;
GnomeCanvasItem *emv;
EAddressbookReflowAdapter *adapter;
- EBook *book;
- char *query;
+ EBookClient *book_client;
+ gchar *query;
guint editable : 1;
- double column_width;
+ gdouble column_width;
};
struct _EMinicardViewWidgetClass
{
ECanvasClass parent_class;
+ void (*create_contact) (EMinicardViewWidget *emvw);
+ void (*create_contact_list) (EMinicardViewWidget *emvw);
void (*selection_change) (EMinicardViewWidget *emvw);
void (*column_width_changed) (EMinicardViewWidget *emvw, double width);
guint (*right_click) (EMinicardViewWidget *emvw);
};
-
-GtkType e_minicard_view_widget_get_type (void);
+GType e_minicard_view_widget_get_type (void);
GtkWidget *e_minicard_view_widget_new (EAddressbookReflowAdapter *adapter);
/* Get parts of the view widget. */
ESelectionModel *e_minicard_view_widget_get_selection_model (EMinicardViewWidget *view);
EMinicardView *e_minicard_view_widget_get_view (EMinicardViewWidget *view);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+G_END_DECLS
#endif /* __E_MINICARD_VIEW_WIDGET_H__ */
diff --git a/addressbook/gui/widgets/e-minicard-view.c b/addressbook/gui/widgets/e-minicard-view.c
index 6b596bb754..1a35f3aa09 100644
--- a/addressbook/gui/widgets/e-minicard-view.c
+++ b/addressbook/gui/widgets/e-minicard-view.c
@@ -1,123 +1,158 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-minicard-view.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
#include "e-minicard-view.h"
-#include "e-addressbook-util.h"
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
-#include <gtk/gtkselection.h>
-#include <gtk/gtkdnd.h>
-#include <gal/widgets/e-canvas.h>
-#include <gal/widgets/e-unicode.h>
-#include <libgnome/gnome-i18n.h>
+#include "e-util/e-util.h"
-static void e_minicard_view_drag_data_get(GtkWidget *widget,
+#include "eab-gui-util.h"
+#include "util/eab-book-util.h"
+
+#include "ea-addressbook.h"
+
+static void e_minicard_view_drag_data_get (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint time,
EMinicardView *view);
-static EReflowClass *parent_class = NULL;
-#define PARENT_TYPE (E_REFLOW_TYPE)
-
-/* The arguments we take */
enum {
- ARG_0,
- ARG_ADAPTER,
- ARG_BOOK,
- ARG_QUERY,
- ARG_EDITABLE
+ PROP_0,
+ PROP_ADAPTER,
+ PROP_CLIENT,
+ PROP_QUERY,
+ PROP_EDITABLE
};
-
enum {
+ CREATE_CONTACT,
+ CREATE_CONTACT_LIST,
RIGHT_CLICK,
LAST_SIGNAL
};
-static guint signals [LAST_SIGNAL] = {0, };
+static guint signals[LAST_SIGNAL] = {0, };
enum DndTargetType {
DND_TARGET_TYPE_VCARD_LIST,
+ DND_TARGET_TYPE_SOURCE_VCARD_LIST
};
#define VCARD_LIST_TYPE "text/x-vcard"
+#define SOURCE_VCARD_LIST_TYPE "text/x-source-vcard"
static GtkTargetEntry drag_types[] = {
- { VCARD_LIST_TYPE, 0, DND_TARGET_TYPE_VCARD_LIST }
+ { (gchar *) SOURCE_VCARD_LIST_TYPE, 0, DND_TARGET_TYPE_SOURCE_VCARD_LIST },
+ { (gchar *) VCARD_LIST_TYPE, 0, DND_TARGET_TYPE_VCARD_LIST }
};
-static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]);
+
+G_DEFINE_TYPE (EMinicardView, e_minicard_view, E_TYPE_REFLOW)
static void
-e_minicard_view_drag_data_get(GtkWidget *widget,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- EMinicardView *view)
+e_minicard_view_drag_data_get (GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ EMinicardView *view)
{
- if (!E_IS_MINICARD_VIEW(view))
+ GdkAtom target;
+
+ if (!E_IS_MINICARD_VIEW (view))
return;
+ target = gtk_selection_data_get_target (selection_data);
+
switch (info) {
case DND_TARGET_TYPE_VCARD_LIST: {
- char *value;
-
- value = e_card_list_get_vcard(view->drag_list);
-
- gtk_selection_data_set (selection_data,
- selection_data->target,
- 8,
- value, strlen (value));
+ gchar *value;
+
+ value = eab_contact_list_to_string (view->drag_list);
+
+ gtk_selection_data_set (
+ selection_data, target, 8,
+ (guchar *) value, strlen (value));
+ g_free (value);
+ break;
+ }
+ case DND_TARGET_TYPE_SOURCE_VCARD_LIST: {
+ EBookClient *book_client = NULL;
+ gchar *value;
+
+ g_object_get (view->adapter, "book_client", &book_client, NULL);
+ value = eab_book_and_contact_list_to_string (book_client, view->drag_list);
+
+ gtk_selection_data_set (
+ selection_data, target, 8,
+ (guchar *) value, strlen (value));
+
+ g_object_unref (book_client);
+ g_free (value);
break;
}
}
+}
- g_list_foreach (view->drag_list, (GFunc)gtk_object_unref, NULL);
- g_list_free (view->drag_list);
+static void
+clear_drag_data (EMinicardView *view)
+{
+ g_slist_free_full (view->drag_list, (GDestroyNotify) g_object_unref);
view->drag_list = NULL;
}
-static int
-e_minicard_view_drag_begin (EAddressbookReflowAdapter *adapter, GdkEvent *event, EMinicardView *view)
+static gint
+e_minicard_view_drag_begin (EAddressbookReflowAdapter *adapter,
+ GdkEvent *event,
+ EMinicardView *view)
{
GdkDragContext *context;
GtkTargetList *target_list;
GdkDragAction actions = GDK_ACTION_MOVE | GDK_ACTION_COPY;
-
+
+ clear_drag_data (view);
+
view->drag_list = e_minicard_view_get_card_list (view);
- g_print ("dragging %d card(s)\n", g_list_length (view->drag_list));
+ g_print ("dragging %d card(s)\n", g_slist_length (view->drag_list));
- target_list = gtk_target_list_new (drag_types, num_drag_types);
+ target_list = gtk_target_list_new (drag_types, G_N_ELEMENTS (drag_types));
- context = gtk_drag_begin (GTK_WIDGET (GNOME_CANVAS_ITEM (view)->canvas),
- target_list, actions, 1/*XXX*/, event);
+ context = gtk_drag_begin (
+ GTK_WIDGET (GNOME_CANVAS_ITEM (view)->canvas),
+ target_list, actions, 1/*XXX */, event);
if (!view->canvas_drag_data_get_id)
- view->canvas_drag_data_get_id = gtk_signal_connect (GTK_OBJECT (GNOME_CANVAS_ITEM (view)->canvas),
- "drag_data_get",
- GTK_SIGNAL_FUNC (e_minicard_view_drag_data_get),
- view);
+ view->canvas_drag_data_get_id = g_signal_connect (
+ GNOME_CANVAS_ITEM (view)->canvas, "drag_data_get",
+ G_CALLBACK (e_minicard_view_drag_data_get), view);
gtk_drag_set_icon_default (context);
@@ -127,30 +162,64 @@ e_minicard_view_drag_begin (EAddressbookReflowAdapter *adapter, GdkEvent *event,
static void
set_empty_message (EMinicardView *view)
{
- char *empty_message;
- gboolean editable = FALSE;
+ gchar *empty_message;
+ gboolean editable = FALSE, perform_initial_query = FALSE, searching = FALSE;
if (view->adapter) {
- gtk_object_get (GTK_OBJECT (view->adapter),
- "editable", &editable,
- NULL);
+ EAddressbookModel *model = NULL;
+ EBookClient *book_client = NULL;
+
+ g_object_get (
+ view->adapter,
+ "editable", &editable,
+ "model", &model,
+ "client", &book_client,
+ NULL);
+
+ if (book_client && !e_client_check_capability (E_CLIENT (book_client), "do-initial-query"))
+ perform_initial_query = TRUE;
+
+ searching = model && e_addressbook_model_can_stop (model);
+
+ if (book_client)
+ g_object_unref (book_client);
+ if (model)
+ g_object_unref (model);
}
- if (editable)
- empty_message = e_utf8_from_locale_string(_("\n\nThere are no items to show in this view.\n\n"
- "Double-click here to create a new Contact."));
- else
- empty_message = e_utf8_from_locale_string(_("\n\nThere are no items to show in this view."));
+ if (searching) {
+ empty_message = _("\n\nSearching for the Contacts...");
+ } else if (editable) {
+ if (perform_initial_query)
+ empty_message = _("\n\nSearch for the Contact\n\n"
+ "or double-click here to create a new Contact.");
+ else
+ empty_message = _("\n\nThere are no items to show in this view.\n\n"
+ "Double-click here to create a new Contact.");
+ } else {
+ if (perform_initial_query)
+ empty_message = _("\n\nSearch for the Contact.");
+ else
+ empty_message = _("\n\nThere are no items to show in this view.");
+ }
- gtk_object_set (GTK_OBJECT(view),
- "empty_message", empty_message,
- NULL);
+ g_object_set (
+ view,
+ "empty_message", empty_message,
+ NULL);
+}
- g_free (empty_message);
+static void
+writable_status_change (EAddressbookModel *model,
+ gboolean writable,
+ EMinicardView *view)
+{
+ set_empty_message (view);
}
static void
-writable_status_change (EAddressbookModel *model, gboolean writable, EMinicardView *view)
+stop_state_changed (EAddressbookModel *model,
+ EMinicardView *view)
{
set_empty_message (view);
}
@@ -160,169 +229,206 @@ adapter_changed (EMinicardView *view)
{
set_empty_message (view);
- gtk_signal_connect (GTK_OBJECT (view->adapter), "drag_begin",
- GTK_SIGNAL_FUNC (e_minicard_view_drag_begin), view);
+ g_signal_connect (
+ view->adapter, "drag_begin",
+ G_CALLBACK (e_minicard_view_drag_begin), view);
}
static void
-e_minicard_view_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+e_minicard_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GnomeCanvasItem *item;
EMinicardView *view;
- item = GNOME_CANVAS_ITEM (o);
- view = E_MINICARD_VIEW (o);
-
- switch (arg_id){
- case ARG_ADAPTER:
+ view = E_MINICARD_VIEW (object);
+
+ switch (property_id) {
+ case PROP_ADAPTER:
if (view->adapter) {
- if (view->writable_status_id) {
+ if (view->writable_status_id || view->stop_state_id) {
EAddressbookModel *model;
- gtk_object_get (GTK_OBJECT (view->adapter),
- "model", &model,
- NULL);
+ g_object_get (
+ view->adapter,
+ "model", &model,
+ NULL);
if (model) {
- gtk_signal_disconnect (GTK_OBJECT (model), view->writable_status_id);
+ if (view->writable_status_id)
+ g_signal_handler_disconnect (model, view->writable_status_id);
+ if (view->stop_state_id)
+ g_signal_handler_disconnect (model, view->stop_state_id);
}
}
- gtk_object_unref (GTK_OBJECT(view->adapter));
+ g_object_unref (view->adapter);
}
view->writable_status_id = 0;
- view->adapter = GTK_VALUE_POINTER (*arg);
- gtk_object_ref (GTK_OBJECT (view->adapter));
+ view->stop_state_id = 0;
+ view->adapter = g_value_get_object (value);
+ g_object_ref (view->adapter);
adapter_changed (view);
- gtk_object_set (GTK_OBJECT (view),
- "model", view->adapter,
- NULL);
+ g_object_set (
+ view,
+ "model", view->adapter,
+ NULL);
if (view->adapter) {
EAddressbookModel *model;
- gtk_object_get (GTK_OBJECT (view->adapter),
- "model", &model,
- NULL);
+ g_object_get (
+ view->adapter,
+ "model", &model,
+ NULL);
if (model) {
- view->writable_status_id =
- gtk_signal_connect (GTK_OBJECT (model), "writable_status",
- GTK_SIGNAL_FUNC (writable_status_change), view);
+ view->writable_status_id = g_signal_connect (
+ model, "writable_status",
+ G_CALLBACK (writable_status_change), view);
+ view->stop_state_id = g_signal_connect (
+ model, "stop_state_changed",
+ G_CALLBACK (stop_state_changed), view);
}
-
+
}
break;
- case ARG_BOOK:
- gtk_object_set (GTK_OBJECT (view->adapter),
- "book", GTK_VALUE_OBJECT (*arg),
- NULL);
+ case PROP_CLIENT:
+ g_object_set (
+ view->adapter,
+ "client", g_value_get_object (value),
+ NULL);
set_empty_message (view);
break;
- case ARG_QUERY:
- gtk_object_set (GTK_OBJECT (view->adapter),
- "query", GTK_VALUE_STRING (*arg),
- NULL);
+ case PROP_QUERY:
+ g_object_set (
+ view->adapter,
+ "query", g_value_get_string (value),
+ NULL);
break;
- case ARG_EDITABLE:
- gtk_object_set (GTK_OBJECT (view->adapter),
- "editable", GTK_VALUE_BOOL (*arg),
- NULL);
+ case PROP_EDITABLE:
+ g_object_set (
+ view->adapter,
+ "editable", g_value_get_boolean (value),
+ NULL);
set_empty_message (view);
break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
static void
-e_minicard_view_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+e_minicard_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
EMinicardView *view;
view = E_MINICARD_VIEW (object);
- switch (arg_id) {
- case ARG_ADAPTER:
- GTK_VALUE_POINTER (*arg) = view->adapter;
+ switch (property_id) {
+ case PROP_ADAPTER:
+ g_value_set_object (value, view->adapter);
break;
- case ARG_BOOK:
- gtk_object_get (GTK_OBJECT (view->adapter),
- "book", &GTK_VALUE_OBJECT (*arg),
- NULL);
+ case PROP_CLIENT:
+ g_object_get_property (
+ G_OBJECT (view->adapter),
+ "client", value);
break;
- case ARG_QUERY:
- gtk_object_get (GTK_OBJECT (view->adapter),
- "query", &GTK_VALUE_STRING (*arg),
- NULL);
+ case PROP_QUERY:
+ g_object_get_property (
+ G_OBJECT (view->adapter),
+ "query", value);
break;
- case ARG_EDITABLE:
- gtk_object_get (GTK_OBJECT (view->adapter),
- "editable", &GTK_VALUE_BOOL (*arg),
- NULL);
+ case PROP_EDITABLE:
+ g_object_get_property (
+ G_OBJECT (view->adapter),
+ "editable", value);
break;
default:
- arg->type = GTK_TYPE_INVALID;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
-e_minicard_view_destroy (GtkObject *object)
+e_minicard_view_dispose (GObject *object)
{
- EMinicardView *view = E_MINICARD_VIEW(object);
+ EMinicardView *view = E_MINICARD_VIEW (object);
+
+ clear_drag_data (view);
if (view->canvas_drag_data_get_id) {
- gtk_signal_disconnect (GTK_OBJECT (GNOME_CANVAS_ITEM (view)->canvas),
- view->canvas_drag_data_get_id);
+ g_signal_handler_disconnect (
+ GNOME_CANVAS_ITEM (view)->canvas,
+ view->canvas_drag_data_get_id);
+ view->canvas_drag_data_get_id = 0;
}
if (view->adapter) {
- if (view->writable_status_id) {
+ if (view->writable_status_id || view->stop_state_id) {
EAddressbookModel *model;
- gtk_object_get (GTK_OBJECT (view->adapter),
- "model", &model,
- NULL);
+ g_object_get (
+ view->adapter,
+ "model", &model,
+ NULL);
if (model) {
- gtk_signal_disconnect (GTK_OBJECT (model), view->writable_status_id);
+ if (view->writable_status_id)
+ g_signal_handler_disconnect (model, view->writable_status_id);
+ if (view->stop_state_id)
+ g_signal_handler_disconnect (model, view->stop_state_id);
}
}
- gtk_object_unref (GTK_OBJECT(view->adapter));
+ g_object_unref (view->adapter);
}
view->writable_status_id = 0;
+ view->stop_state_id = 0;
view->adapter = NULL;
- GTK_OBJECT_CLASS(parent_class)->destroy (object);
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_minicard_view_parent_class)->dispose (object);
}
static guint
-e_minicard_view_right_click (EMinicardView *view, GdkEvent *event)
+e_minicard_view_right_click (EMinicardView *view,
+ GdkEvent *event)
{
guint ret_val = 0;
- gtk_signal_emit (GTK_OBJECT (view), signals[RIGHT_CLICK],
- event, &ret_val);
+ g_signal_emit (
+ view, signals[RIGHT_CLICK], 0,
+ event, &ret_val);
return ret_val;
}
static gboolean
-e_minicard_view_event (GnomeCanvasItem *item, GdkEvent *event)
+e_minicard_view_event (GnomeCanvasItem *item,
+ GdkEvent *event)
{
EMinicardView *view;
-
+ guint event_button = 0;
+
view = E_MINICARD_VIEW (item);
- switch( event->type ) {
+ switch (event->type) {
case GDK_2BUTTON_PRESS:
- if (((GdkEventButton *)event)->button == 1) {
+ gdk_event_get_button (event, &event_button);
+ if (event_button == 1) {
gboolean editable;
- gtk_object_get(GTK_OBJECT(view->adapter), "editable", &editable, NULL);
-
- if (editable) {
- EBook *book;
- gtk_object_get(GTK_OBJECT(view), "book", &book, NULL);
-
- if (book && E_IS_BOOK (book))
- e_addressbook_show_contact_editor (book, e_card_new(""), TRUE, editable);
- }
+ g_object_get (view->adapter, "editable", &editable, NULL);
+
+ if (editable)
+ e_minicard_view_create_contact (view);
return TRUE;
}
case GDK_BUTTON_PRESS:
- if (event->button.button == 3) {
+ gdk_event_get_button (event, &event_button);
+ if (event_button == 3)
+ e_minicard_view_right_click (view, event);
+ break;
+ case GDK_KEY_PRESS:
+ if (event->key.keyval & GDK_SHIFT_MASK &&
+ event->key.keyval == GDK_KEY_F10) {
e_minicard_view_right_click (view, event);
}
break;
@@ -330,30 +436,29 @@ e_minicard_view_event (GnomeCanvasItem *item, GdkEvent *event)
break;
}
- if (GNOME_CANVAS_ITEM_CLASS(parent_class)->event)
- return GNOME_CANVAS_ITEM_CLASS(parent_class)->event(item, event);
- else
- return FALSE;
+ return GNOME_CANVAS_ITEM_CLASS (e_minicard_view_parent_class)->
+ event (item, event);
}
static gint
-e_minicard_view_selection_event (EReflow *reflow, GnomeCanvasItem *item, GdkEvent *event)
+e_minicard_view_selection_event (EReflow *reflow,
+ GnomeCanvasItem *item,
+ GdkEvent *event)
{
EMinicardView *view;
- int return_val = FALSE;
+ gint return_val = FALSE;
view = E_MINICARD_VIEW (reflow);
- if (parent_class->selection_event) {
- return_val = parent_class->selection_event (reflow, item, event);
- }
+ return_val = E_REFLOW_CLASS (e_minicard_view_parent_class)->
+ selection_event (reflow, item, event);
switch (event->type) {
case GDK_FOCUS_CHANGE:
if (event->focus_change.in) {
- int i;
+ gint i;
for (i = 0; i < reflow->count; i++) {
if (reflow->items[i] == item) {
- e_selection_model_maybe_do_something(reflow->selection, i, 0, 0);
+ e_selection_model_maybe_do_something (reflow->selection, i, 0, 0);
break;
}
}
@@ -363,7 +468,7 @@ e_minicard_view_selection_event (EReflow *reflow, GnomeCanvasItem *item, GdkEven
if (event->button.button == 3) {
return_val = e_minicard_view_right_click (view, event);
if (!return_val)
- e_selection_model_right_click_up(reflow->selection);
+ e_selection_model_right_click_up (reflow->selection);
}
break;
default:
@@ -372,176 +477,139 @@ e_minicard_view_selection_event (EReflow *reflow, GnomeCanvasItem *item, GdkEven
return return_val;
}
-typedef struct {
- EMinicardView *view;
- EBookCallback cb;
- gpointer closure;
-} ViewCbClosure;
-
-static void
-do_remove (int i, gpointer user_data)
-{
- EBook *book;
- ECard *card;
- ViewCbClosure *viewcbclosure = user_data;
- EMinicardView *view = viewcbclosure->view;
- EBookCallback cb = viewcbclosure->cb;
- gpointer closure = viewcbclosure->closure;
-
- gtk_object_get (GTK_OBJECT(view->adapter),
- "book", &book,
- NULL);
-
- card = e_addressbook_reflow_adapter_get_card (view->adapter, i);
-
- e_book_remove_card(book, card, cb, closure);
-
- gtk_object_unref (GTK_OBJECT (card));
-}
-
-#if 0
-static int
-compare_to_utf_str (EMinicard *card, const char *utf_str)
-{
- g_return_val_if_fail(card != NULL, 0);
- g_return_val_if_fail(E_IS_MINICARD(card), 0);
-
- if (g_unichar_isdigit (g_utf8_get_char (utf_str))) {
- return 1;
- }
-
- if (card->card) {
- char *file_as;
- gtk_object_get(GTK_OBJECT(card->card),
- "file_as", &file_as,
- NULL);
- if (file_as)
- return g_utf8_strcasecmp (file_as, utf_str);
- else
- return 0;
- } else {
- return 0;
- }
-}
-#endif
-
static void
-e_minicard_view_class_init (EMinicardViewClass *klass)
+e_minicard_view_class_init (EMinicardViewClass *class)
{
- GtkObjectClass *object_class;
+ GObjectClass *object_class;
GnomeCanvasItemClass *item_class;
EReflowClass *reflow_class;
-
- object_class = (GtkObjectClass*) klass;
- item_class = (GnomeCanvasItemClass *) klass;
- reflow_class = (EReflowClass *) klass;
-
- parent_class = gtk_type_class (PARENT_TYPE);
-
- gtk_object_add_arg_type ("EMinicardView::adapter", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_ADAPTER);
- gtk_object_add_arg_type ("EMinicardView::book", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_BOOK);
- gtk_object_add_arg_type ("EMinicardView::query", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_QUERY);
- gtk_object_add_arg_type ("EMinicardView::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
-
- signals [RIGHT_CLICK] =
- gtk_signal_new ("right_click",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardViewClass, right_click),
- gtk_marshal_INT__POINTER,
- GTK_TYPE_INT, 1, GTK_TYPE_GDK_EVENT);
-
- gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
-
- object_class->set_arg = e_minicard_view_set_arg;
- object_class->get_arg = e_minicard_view_get_arg;
- object_class->destroy = e_minicard_view_destroy;
+
+ object_class = G_OBJECT_CLASS (class);
+ item_class = (GnomeCanvasItemClass *) class;
+ reflow_class = (EReflowClass *) class;
+
+ object_class->set_property = e_minicard_view_set_property;
+ object_class->get_property = e_minicard_view_get_property;
+ object_class->dispose = e_minicard_view_dispose;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ADAPTER,
+ g_param_spec_object (
+ "adapter",
+ "Adapter",
+ NULL,
+ E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLIENT,
+ g_param_spec_object (
+ "client",
+ "EBookClient",
+ NULL,
+ E_TYPE_BOOK_CLIENT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_QUERY,
+ g_param_spec_string (
+ "query",
+ "Query",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ "Editable",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ signals[CREATE_CONTACT] = g_signal_new (
+ "create-contact",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[CREATE_CONTACT_LIST] = g_signal_new (
+ "create-contact-list",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[RIGHT_CLICK] = g_signal_new (
+ "right_click",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewClass, right_click),
+ NULL, NULL,
+ e_marshal_INT__POINTER,
+ G_TYPE_INT, 1,
+ G_TYPE_POINTER);
item_class->event = e_minicard_view_event;
reflow_class->selection_event = e_minicard_view_selection_event;
/* GnomeCanvasItem method overrides */
+
+ /* init the accessibility support for e_minicard_view */
+ e_minicard_view_a11y_init ();
}
static void
e_minicard_view_init (EMinicardView *view)
{
+ view->drag_list = NULL;
view->adapter = NULL;
view->canvas_drag_data_get_id = 0;
view->writable_status_id = 0;
+ view->stop_state_id = 0;
set_empty_message (view);
}
-GtkType
-e_minicard_view_get_type (void)
-{
- static GtkType reflow_type = 0;
-
- if (!reflow_type) {
- static const GtkTypeInfo reflow_info = {
- "EMinicardView",
- sizeof (EMinicardView),
- sizeof (EMinicardViewClass),
- (GtkClassInitFunc) e_minicard_view_class_init,
- (GtkObjectInitFunc) e_minicard_view_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- reflow_type = gtk_type_unique (PARENT_TYPE, &reflow_info);
- }
-
- return reflow_type;
-}
-
-void
-e_minicard_view_remove_selection(EMinicardView *view,
- EBookCallback cb,
- gpointer closure)
-{
- ViewCbClosure viewcbclosure;
- viewcbclosure.view = view;
- viewcbclosure.cb = cb;
- viewcbclosure.closure = closure;
-
- e_selection_model_foreach (E_REFLOW (view)->selection,
- do_remove,
- &viewcbclosure);
-}
-
void
e_minicard_view_jump_to_letter (EMinicardView *view,
gunichar letter)
{
#if 0
- char uft_str[6 + 1];
+ gchar uft_str[6 + 1];
- utf_str [g_unichar_to_utf8 (letter, utf_str)] = '\0';
- e_reflow_sorted_jump (E_REFLOW_SORTED (view),
- (GCompareFunc) compare_to_utf_str,
- utf_str);
+ utf_str[g_unichar_to_utf8 (letter, utf_str)] = '\0';
+ e_reflow_sorted_jump (
+ E_REFLOW_SORTED (view),
+ (GCompareFunc) compare_to_utf_str,
+ utf_str);
#endif
}
typedef struct {
- GList *list;
+ GSList *list;
EAddressbookReflowAdapter *adapter;
} ModelAndList;
static void
-add_to_list (int index, gpointer closure)
+add_to_list (gint 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_slist_prepend (
+ mal->list, e_addressbook_reflow_adapter_get_contact (
+ mal->adapter, index));
}
-GList *
+GSList *
e_minicard_view_get_card_list (EMinicardView *view)
{
ModelAndList mal;
@@ -551,6 +619,21 @@ e_minicard_view_get_card_list (EMinicardView *view)
e_selection_model_foreach (E_REFLOW (view)->selection, add_to_list, &mal);
- mal.list = g_list_reverse (mal.list);
- return mal.list;
+ return g_slist_reverse (mal.list);
+}
+
+void
+e_minicard_view_create_contact (EMinicardView *view)
+{
+ g_return_if_fail (E_IS_MINICARD_VIEW (view));
+
+ g_signal_emit (view, signals[CREATE_CONTACT], 0);
+}
+
+void
+e_minicard_view_create_contact_list (EMinicardView *view)
+{
+ g_return_if_fail (E_IS_MINICARD_VIEW (view));
+
+ g_signal_emit (view, signals[CREATE_CONTACT_LIST], 0);
}
diff --git a/addressbook/gui/widgets/e-minicard-view.h b/addressbook/gui/widgets/e-minicard-view.h
index 1f23c62754..bf116e4513 100644
--- a/addressbook/gui/widgets/e-minicard-view.h
+++ b/addressbook/gui/widgets/e-minicard-view.h
@@ -1,37 +1,36 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-minicard-view.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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_VIEW_H__
#define __E_MINICARD_VIEW_H__
#include "e-minicard.h"
-#include <gal/widgets/e-reflow.h>
-#include <gal/widgets/e-selection-model-simple.h>
-#include <gal/unicode/gunicode.h>
-#include "addressbook/backend/ebook/e-book.h"
+#include <e-util/e-util.h>
+
#include "e-addressbook-reflow-adapter.h"
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
+G_BEGIN_DECLS
/* EMinicardView - A canvas item container.
*
@@ -52,12 +51,11 @@ extern "C" {
* height double RW height of the reflow
*/
-#define E_MINICARD_VIEW_TYPE (e_minicard_view_get_type ())
-#define E_MINICARD_VIEW(obj) (GTK_CHECK_CAST ((obj), E_MINICARD_VIEW_TYPE, EMinicardView))
-#define E_MINICARD_VIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_MINICARD_VIEW_TYPE, EMinicardViewClass))
-#define E_IS_MINICARD_VIEW(obj) (GTK_CHECK_TYPE ((obj), E_MINICARD_VIEW_TYPE))
-#define E_IS_MINICARD_VIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_MINICARD_VIEW_TYPE))
-
+#define E_TYPE_MINICARD_VIEW (e_minicard_view_get_type ())
+#define E_MINICARD_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MINICARD_VIEW, EMinicardView))
+#define E_MINICARD_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MINICARD_VIEW, EMinicardViewClass))
+#define E_IS_MINICARD_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MINICARD_VIEW))
+#define E_IS_MINICARD_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_MINICARD_VIEW))
typedef struct _EMinicardView EMinicardView;
typedef struct _EMinicardViewClass EMinicardViewClass;
@@ -67,14 +65,14 @@ struct _EMinicardView
EReflow parent;
EAddressbookReflowAdapter *adapter;
-
+
/* item specific fields */
- GList *drag_list;
+ GSList *drag_list;
guint canvas_drag_data_get_id;
-
guint writable_status_id;
+ guint stop_state_id;
};
struct _EMinicardViewClass
@@ -84,17 +82,13 @@ struct _EMinicardViewClass
void (*right_click) (EMinicardView *view, GdkEvent *event);
};
-GtkType e_minicard_view_get_type (void);
-void e_minicard_view_remove_selection (EMinicardView *view,
- EBookCallback cb,
- gpointer closure);
+GType e_minicard_view_get_type (void);
void e_minicard_view_jump_to_letter (EMinicardView *view,
gunichar letter);
-GList *e_minicard_view_get_card_list (EMinicardView *view);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+GSList *e_minicard_view_get_card_list (EMinicardView *view);
+void e_minicard_view_create_contact (EMinicardView *view);
+void e_minicard_view_create_contact_list (EMinicardView *view);
+G_END_DECLS
#endif /* __E_MINICARD_VIEW_H__ */
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 04ef2f0823..0000000000
--- a/addressbook/gui/widgets/e-minicard-widget-test.c
+++ /dev/null
@@ -1,119 +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(GtkWidget *app, gpointer data)
-{
- 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);
- gtk_object_set(GTK_OBJECT(minicard),
- "card", card,
- NULL);
-
- gnome_app_set_contents( GNOME_APP( app ), minicard );
-
- /* Connect the signals */
- gtk_signal_connect( GTK_OBJECT( app ), "destroy",
- GTK_SIGNAL_FUNC( destroy_callback ),
- ( gpointer ) 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 566a43b087..0000000000
--- a/addressbook/gui/widgets/e-minicard-widget.c
+++ /dev/null
@@ -1,249 +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 <libgnomeui/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_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_minicard_widget_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_minicard_widget_destroy (GtkObject *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 {
- ARG_0,
- ARG_CARD,
-};
-
-GtkType
-e_minicard_widget_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type)
- {
- static const GtkTypeInfo info =
- {
- "EMinicardWidget",
- sizeof (EMinicardWidget),
- sizeof (EMinicardWidgetClass),
- (GtkClassInitFunc) e_minicard_widget_class_init,
- (GtkObjectInitFunc) e_minicard_widget_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- type = gtk_type_unique (e_canvas_get_type (), &info);
- }
-
- return type;
-}
-
-static void
-e_minicard_widget_class_init (EMinicardWidgetClass *klass)
-{
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
- ECanvasClass *ecanvas_class;
-
- object_class = GTK_OBJECT_CLASS(klass);
- widget_class = GTK_WIDGET_CLASS(klass);
- ecanvas_class = E_CANVAS_CLASS(klass);
-
- parent_class = gtk_type_class (e_canvas_get_type ());
-
- object_class->set_arg = e_minicard_widget_set_arg;
- object_class->get_arg = e_minicard_widget_get_arg;
- object_class->destroy = e_minicard_widget_destroy;
-
- 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;
-
- gtk_object_add_arg_type ("EMinicardWidget::card", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_CARD);
-}
-
-static void
-e_minicard_widget_size_request(GtkWidget *widget, GtkRequisition *requisition)
-{
- double height;
- EMinicardWidget *emw = E_MINICARD_WIDGET(widget);
- gtk_object_get(GTK_OBJECT(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 );
- gtk_object_get(GTK_OBJECT(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);
- gtk_object_get(GTK_OBJECT(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 );
-
- gnome_canvas_set_scroll_region ( GNOME_CANVAS( emw ),
- 0, 0,
- 100, 100 );
-
- emw->card = NULL;
-}
-
-static void
-e_minicard_widget_destroy (GtkObject *object)
-{
- EMinicardWidget *emw = E_MINICARD_WIDGET(object);
-
- if (emw->card)
- gtk_object_unref(GTK_OBJECT(emw->card));
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy)
- GTK_OBJECT_CLASS(parent_class)->destroy(object);
-}
-
-GtkWidget*
-e_minicard_widget_new (void)
-{
- GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_minicard_widget_get_type ()));
- return widget;
-}
-
-static void
-e_minicard_widget_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- EMinicardWidget *emw = E_MINICARD_WIDGET(object);
- gpointer ptr;
-
- switch (arg_id){
- case ARG_CARD:
- ptr = GTK_VALUE_POINTER (*arg);
- e_minicard_widget_set_card (emw, ptr ? E_CARD (ptr) : NULL);
- break;
- default:
- break;
- }
-}
-
-static void
-e_minicard_widget_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- EMinicardWidget *emw = E_MINICARD_WIDGET(object);
-
- switch (arg_id) {
- case ARG_CARD:
- if (emw->card)
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(emw->card);
- else
- GTK_VALUE_OBJECT (*arg) = NULL;
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- 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)
- gtk_object_unref (GTK_OBJECT (emw->card));
-
- emw->card = card;
-
- if (emw->card)
- gtk_object_ref (GTK_OBJECT (emw->card));
-
- if (emw->item)
- gtk_object_set (GTK_OBJECT (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 eaf0f8edb6..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_MINICARD_WIDGET_TYPE (e_minicard_widget_get_type ())
-#define E_MINICARD_WIDGET(obj) (GTK_CHECK_CAST ((obj), E_MINICARD_WIDGET_TYPE, EMinicardWidget))
-#define E_MINICARD_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_MINICARD_WIDGET_TYPE, EMinicardWidgetClass))
-#define E_IS_MINICARD_WIDGET(obj) (GTK_CHECK_TYPE ((obj), E_MINICARD_WIDGET_TYPE))
-#define E_IS_MINICARD_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_MINICARD_WIDGET_TYPE))
-
-
-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);
-GtkType 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 99e1d524fa..d5a1a3ce99 100644
--- a/addressbook/gui/widgets/e-minicard.c
+++ b/addressbook/gui/widgets/e-minicard.c
@@ -1,189 +1,243 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-minicard.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
-#include <glib.h>
-#include <gtk/gtkdnd.h>
-#include <gdk/gdkkeysyms.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-canvas-rect-ellipse.h>
-#include <gdk-pixbuf/gnome-canvas-pixbuf.h>
-#include <gal/e-text/e-text.h>
-#include <gal/util/e-util.h>
-#include <gal/widgets/e-canvas-utils.h>
-#include <gal/widgets/e-canvas.h>
-#include <gal/unicode/gunicode.h>
-#include "addressbook/backend/ebook/e-book.h"
-#include "e-addressbook-util.h"
+#endif
+
#include "e-minicard.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <libgnomecanvas/libgnomecanvas.h>
+
+#include "e-util/e-util.h"
+
+#include "eab-book-util.h"
+#include "eab-gui-util.h"
#include "e-minicard-label.h"
#include "e-minicard-view.h"
-#include "e-contact-editor.h"
-#include "e-card-merging.h"
-
-static void e_minicard_init (EMinicard *card);
-static void e_minicard_class_init (EMinicardClass *klass);
-static void e_minicard_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_minicard_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_minicard_destroy (GtkObject *object);
-static void e_minicard_finalize (GtkObject *object);
+#include "ea-addressbook.h"
+
+static void e_minicard_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+static void e_minicard_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void e_minicard_dispose (GObject *object);
+static void e_minicard_finalize (GObject *object);
static gboolean e_minicard_event (GnomeCanvasItem *item, GdkEvent *event);
static void e_minicard_realize (GnomeCanvasItem *item);
-static void e_minicard_unrealize (GnomeCanvasItem *item);
-static void e_minicard_reflow ( GnomeCanvasItem *item, int flags );
+static void e_minicard_reflow (GnomeCanvasItem *item, gint flags);
+static void e_minicard_style_set (EMinicard *minicard, GtkStyle *previous_style);
-static void e_minicard_resize_children( EMinicard *e_minicard );
-static void remodel( EMinicard *e_minicard );
+static void e_minicard_resize_children (EMinicard *e_minicard);
+static void remodel (EMinicard *e_minicard);
static gint e_minicard_drag_begin (EMinicard *minicard, GdkEvent *event);
-static GnomeCanvasGroupClass *parent_class = NULL;
-
-typedef struct _EMinicardField EMinicardField;
-
-struct _EMinicardField {
- ECardSimpleField field;
- GnomeCanvasItem *label;
-};
-
#define d(x)
-#define LIST_ICON_FILENAME "contact-list-16.png"
-
-#define E_MINICARD_FIELD(field) ((EMinicardField *)(field))
+#define LIST_ICON_NAME "stock_contact-list"
static void
-e_minicard_field_destroy(EMinicardField *field)
+e_minicard_field_destroy (EMinicardField *field)
{
- gtk_object_destroy(GTK_OBJECT(field->label));
- g_free(field);
+ g_object_run_dispose (G_OBJECT (field->label));
+ g_free (field);
}
-/* The arguments we take */
enum {
- ARG_0,
- ARG_WIDTH,
- ARG_HEIGHT,
- ARG_HAS_FOCUS,
- ARG_SELECTED,
- ARG_HAS_CURSOR,
- ARG_EDITABLE,
- ARG_CARD
+ PROP_0,
+ PROP_WIDTH,
+ PROP_HEIGHT,
+ PROP_HAS_FOCUS,
+ PROP_SELECTED,
+ PROP_HAS_CURSOR,
+ PROP_EDITABLE,
+ PROP_CONTACT
};
enum {
SELECTED,
DRAG_BEGIN,
+ OPEN_CONTACT,
+ STYLE_SET,
LAST_SIGNAL
};
-static guint e_minicard_signals [LAST_SIGNAL] = {0, };
-
-GtkType
-e_minicard_get_type (void)
-{
- static GtkType minicard_type = 0;
-
- if (!minicard_type)
- {
- static const GtkTypeInfo minicard_info =
- {
- "EMinicard",
- sizeof (EMinicard),
- sizeof (EMinicardClass),
- (GtkClassInitFunc) e_minicard_class_init,
- (GtkObjectInitFunc) e_minicard_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- minicard_type = gtk_type_unique (gnome_canvas_group_get_type (), &minicard_info);
- }
-
- return minicard_type;
+static struct {
+ const gchar *name;
+ const gchar *pretty_name;
}
+common_location[] =
+{
+ { "WORK", N_ ("Work Email") },
+ { "HOME", N_ ("Home Email") },
+ { "OTHER", N_ ("Other Email") }
+};
+
+static guint signals[LAST_SIGNAL] = {0, };
+
+G_DEFINE_TYPE (EMinicard, e_minicard, GNOME_TYPE_CANVAS_GROUP)
static void
-e_minicard_class_init (EMinicardClass *klass)
+e_minicard_class_init (EMinicardClass *class)
{
- GtkObjectClass *object_class;
+ GObjectClass *object_class;
GnomeCanvasItemClass *item_class;
- object_class = (GtkObjectClass*) klass;
- item_class = (GnomeCanvasItemClass *) klass;
-
- parent_class = gtk_type_class (gnome_canvas_group_get_type ());
-
- gtk_object_add_arg_type ("EMinicard::width", GTK_TYPE_DOUBLE,
- GTK_ARG_READWRITE, ARG_WIDTH);
- gtk_object_add_arg_type ("EMinicard::height", GTK_TYPE_DOUBLE,
- GTK_ARG_READABLE, ARG_HEIGHT);
- gtk_object_add_arg_type ("EMinicard::has_focus", GTK_TYPE_ENUM,
- GTK_ARG_READWRITE, ARG_HAS_FOCUS);
- gtk_object_add_arg_type ("EMinicard::selected", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_SELECTED);
- gtk_object_add_arg_type ("EMinicard::has_cursor", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_HAS_CURSOR);
- gtk_object_add_arg_type ("EMinicard::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
- gtk_object_add_arg_type ("EMinicard::card", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_CARD);
-
- e_minicard_signals [SELECTED] =
- gtk_signal_new ("selected",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardClass, selected),
- gtk_marshal_INT__POINTER,
- GTK_TYPE_INT, 1, GTK_TYPE_POINTER);
-
- e_minicard_signals [DRAG_BEGIN] =
- gtk_signal_new ("drag_begin",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardClass, drag_begin),
- gtk_marshal_INT__POINTER,
- GTK_TYPE_INT, 1, GTK_TYPE_POINTER);
-
- gtk_object_class_add_signals (object_class, e_minicard_signals, LAST_SIGNAL);
-
- object_class->set_arg = e_minicard_set_arg;
- object_class->get_arg = e_minicard_get_arg;
- object_class->destroy = e_minicard_destroy;
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = e_minicard_set_property;
+ object_class->get_property = e_minicard_get_property;
+ object_class->dispose = e_minicard_dispose;
object_class->finalize = e_minicard_finalize;
-
- /* GnomeCanvasItem method overrides */
- item_class->realize = e_minicard_realize;
- item_class->unrealize = e_minicard_unrealize;
- item_class->event = e_minicard_event;
- klass->selected = NULL;
+ item_class = GNOME_CANVAS_ITEM_CLASS (class);
+ item_class->realize = e_minicard_realize;
+ item_class->event = e_minicard_event;
+
+ class->style_set = e_minicard_style_set;
+ class->selected = NULL;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WIDTH,
+ g_param_spec_double (
+ "width",
+ "Width",
+ NULL,
+ 0.0, G_MAXDOUBLE, 10.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HEIGHT,
+ g_param_spec_double (
+ "height",
+ "Height",
+ NULL,
+ 0.0, G_MAXDOUBLE, 10.0,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HAS_FOCUS,
+ /* XXX should be _enum */
+ g_param_spec_int (
+ "has_focus",
+ "Has Focus",
+ NULL,
+ E_MINICARD_FOCUS_TYPE_START,
+ E_MINICARD_FOCUS_TYPE_END,
+ E_MINICARD_FOCUS_TYPE_START,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTED,
+ g_param_spec_boolean (
+ "selected",
+ "Selected",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HAS_CURSOR,
+ g_param_spec_boolean (
+ "has_cursor",
+ "Has Cursor",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ "Editable",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CONTACT,
+ g_param_spec_object (
+ "contact",
+ "Contact",
+ NULL,
+ E_TYPE_CONTACT,
+ G_PARAM_READWRITE));
+
+ signals[SELECTED] = g_signal_new (
+ "selected",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardClass, selected),
+ NULL, NULL,
+ e_marshal_INT__POINTER,
+ G_TYPE_INT, 1,
+ G_TYPE_POINTER);
+
+ signals[DRAG_BEGIN] = g_signal_new (
+ "drag_begin",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardClass, drag_begin),
+ NULL, NULL,
+ e_marshal_INT__POINTER,
+ G_TYPE_INT, 1,
+ G_TYPE_POINTER);
+
+ signals[OPEN_CONTACT] = g_signal_new (
+ "open-contact",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardClass, open_contact),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CONTACT);
+
+ signals[STYLE_SET] = g_signal_new (
+ "style_set",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMinicardClass, style_set),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_STYLE);
+
+ /* init the accessibility support for e_minicard */
+ e_minicard_a11y_init ();
}
static void
e_minicard_init (EMinicard *minicard)
{
- /* minicard->card = NULL;*/
minicard->rect = NULL;
minicard->fields = NULL;
minicard->width = 10;
@@ -193,163 +247,186 @@ 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);
+ minicard->list_icon_pixbuf = e_icon_factory_get_icon (LIST_ICON_NAME, GTK_ICON_SIZE_MENU);
minicard->list_icon_size = gdk_pixbuf_get_height (minicard->list_icon_pixbuf);
- minicard->editor = NULL;
-
minicard->changed = FALSE;
- e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(minicard), e_minicard_reflow);
+ e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (minicard), e_minicard_reflow);
}
static void
-set_selected (EMinicard *minicard, gboolean selected)
+set_selected (EMinicard *minicard,
+ gboolean selected)
{
- GtkWidget *canvas = GTK_WIDGET(GNOME_CANVAS_ITEM(minicard)->canvas);
+ GnomeCanvas *canvas;
+ GtkStyle *style;
+
+ canvas = GNOME_CANVAS_ITEM (minicard)->canvas;
+ style = gtk_widget_get_style (GTK_WIDGET (canvas));
+
if (selected) {
- gnome_canvas_item_set (minicard->rect,
- "outline_color_gdk", &canvas->style->bg[GTK_STATE_NORMAL],
- NULL);
- gnome_canvas_item_set (minicard->header_rect,
- "fill_color_gdk", &canvas->style->bg[GTK_STATE_SELECTED],
- NULL);
- gnome_canvas_item_set (minicard->header_text,
- "fill_color_gdk", &canvas->style->text[GTK_STATE_SELECTED],
- NULL);
+ gnome_canvas_item_set (
+ minicard->rect,
+ "outline_color_gdk", &style->bg[GTK_STATE_ACTIVE],
+ NULL);
+ gnome_canvas_item_set (
+ minicard->header_rect,
+ "fill_color_gdk", &style->bg[GTK_STATE_SELECTED],
+ NULL);
+ gnome_canvas_item_set (
+ minicard->header_text,
+ "fill_color_gdk", &style->text[GTK_STATE_SELECTED],
+ NULL);
} else {
- gnome_canvas_item_set (minicard->rect,
- "outline_color", NULL,
- NULL);
- gnome_canvas_item_set (minicard->header_rect,
- "fill_color_gdk", &canvas->style->bg[GTK_STATE_NORMAL],
- NULL);
- gnome_canvas_item_set (minicard->header_text,
- "fill_color_gdk", &canvas->style->fg[GTK_STATE_NORMAL],
- NULL);
+ gnome_canvas_item_set (
+ minicard->rect,
+ "outline_color", NULL,
+ NULL);
+ gnome_canvas_item_set (
+ minicard->header_rect,
+ "fill_color_gdk", &style->bg[GTK_STATE_NORMAL],
+ NULL);
+ gnome_canvas_item_set (
+ minicard->header_text,
+ "fill_color_gdk", &style->text[GTK_STATE_NORMAL],
+ NULL);
}
minicard->selected = selected;
}
static void
-set_has_cursor (EMinicard *minicard, gboolean has_cursor)
+set_has_cursor (EMinicard *minicard,
+ gboolean has_cursor)
{
if (!minicard->has_focus && has_cursor)
- e_canvas_item_grab_focus(GNOME_CANVAS_ITEM (minicard), FALSE);
+ e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (minicard), FALSE);
minicard->has_cursor = has_cursor;
}
-
static void
-e_minicard_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+e_minicard_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
GnomeCanvasItem *item;
EMinicard *e_minicard;
+ EContact *contact;
GList *l;
- item = GNOME_CANVAS_ITEM (o);
- e_minicard = E_MINICARD (o);
-
- switch (arg_id){
- case ARG_WIDTH:
- if (e_minicard->width != GTK_VALUE_DOUBLE (*arg)) {
- e_minicard->width = GTK_VALUE_DOUBLE (*arg);
- e_minicard_resize_children(e_minicard);
- if ( GTK_OBJECT_FLAGS( e_minicard ) & GNOME_CANVAS_ITEM_REALIZED )
- e_canvas_item_request_reflow(item);
+ item = GNOME_CANVAS_ITEM (object);
+ e_minicard = E_MINICARD (object);
+
+ switch (property_id) {
+ case PROP_WIDTH:
+ if (e_minicard->width != g_value_get_double (value)) {
+ e_minicard->width = g_value_get_double (value);
+ e_minicard_resize_children (e_minicard);
+ if (item->flags & GNOME_CANVAS_ITEM_REALIZED)
+ e_canvas_item_request_reflow (item);
}
break;
- case ARG_HAS_FOCUS:
+ case PROP_HAS_FOCUS:
if (e_minicard->fields) {
- if ( GTK_VALUE_ENUM(*arg) == E_FOCUS_START ||
- GTK_VALUE_ENUM(*arg) == E_FOCUS_CURRENT) {
- gnome_canvas_item_set(E_MINICARD_FIELD(e_minicard->fields->data)->label,
- "has_focus", GTK_VALUE_ENUM(*arg),
- NULL);
- } else if ( GTK_VALUE_ENUM(*arg) == E_FOCUS_END ) {
- gnome_canvas_item_set(E_MINICARD_FIELD(g_list_last(e_minicard->fields)->data)->label,
- "has_focus", GTK_VALUE_ENUM(*arg),
- NULL);
+ if (g_value_get_int (value) == E_FOCUS_START ||
+ g_value_get_int (value) == E_FOCUS_CURRENT) {
+ gnome_canvas_item_set (
+ E_MINICARD_FIELD (e_minicard->fields->data)->label,
+ "has_focus", g_value_get_int (value),
+ NULL);
+ } else if (g_value_get_int (value) == E_FOCUS_END) {
+ gnome_canvas_item_set (
+ E_MINICARD_FIELD (g_list_last (e_minicard->fields)->data)->label,
+ "has_focus", g_value_get_int (value),
+ NULL);
}
}
else {
if (!e_minicard->has_focus)
- e_canvas_item_grab_focus(item, FALSE);
+ e_canvas_item_grab_focus (item, FALSE);
}
break;
- case ARG_SELECTED:
- if (e_minicard->selected != GTK_VALUE_BOOL(*arg))
- set_selected (e_minicard, GTK_VALUE_BOOL(*arg));
+ case PROP_SELECTED:
+ if (e_minicard->selected != g_value_get_boolean (value))
+ set_selected (e_minicard, g_value_get_boolean (value));
break;
- case ARG_EDITABLE:
- e_minicard->editable = GTK_VALUE_BOOL(*arg);
- for (l = e_minicard->fields; l; l = l->next)
- gtk_object_set (GTK_OBJECT (E_MINICARD_FIELD (l->data)->label),
- "editable", e_minicard->editable,
- NULL);
+ case PROP_EDITABLE:
+ e_minicard->editable = g_value_get_boolean (value);
+ for (l = e_minicard->fields; l; l = l->next) {
+ g_object_set (
+ E_MINICARD_FIELD (l->data)->label,
+ "editable", FALSE /* e_minicard->editable */,
+ NULL);
+ }
break;
- case ARG_HAS_CURSOR:
- d(g_print("%s: ARG_HAS_CURSOR\n", __FUNCTION__));
- if (e_minicard->has_cursor != GTK_VALUE_BOOL(*arg))
- set_has_cursor (e_minicard, GTK_VALUE_BOOL(*arg));
+ case PROP_HAS_CURSOR:
+ d (g_print ("%s: PROP_HAS_CURSOR\n", G_STRFUNC));
+ if (e_minicard->has_cursor != g_value_get_boolean (value))
+ set_has_cursor (e_minicard, g_value_get_boolean (value));
break;
- case ARG_CARD:
- if (e_minicard->card)
- gtk_object_unref (GTK_OBJECT(e_minicard->card));
- e_minicard->card = E_CARD(GTK_VALUE_OBJECT (*arg));
- if (e_minicard->card)
- gtk_object_ref (GTK_OBJECT(e_minicard->card));
- gtk_object_set(GTK_OBJECT(e_minicard->simple),
- "card", e_minicard->card,
- NULL);
- remodel(e_minicard);
- e_canvas_item_request_reflow(item);
+ case PROP_CONTACT:
+ contact = E_CONTACT (g_value_get_object (value));
+ if (contact)
+ g_object_ref (contact);
+
+ if (e_minicard->contact)
+ g_object_unref (e_minicard->contact);
+
+ e_minicard->contact = contact;
+
+ remodel (e_minicard);
+ e_canvas_item_request_reflow (item);
e_minicard->changed = FALSE;
break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
static void
-e_minicard_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+e_minicard_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
EMinicard *e_minicard;
e_minicard = E_MINICARD (object);
- switch (arg_id) {
- case ARG_WIDTH:
- GTK_VALUE_DOUBLE (*arg) = e_minicard->width;
- break;
- case ARG_HEIGHT:
- GTK_VALUE_DOUBLE (*arg) = e_minicard->height;
- break;
- case ARG_HAS_FOCUS:
- GTK_VALUE_ENUM (*arg) = e_minicard->has_focus ? E_FOCUS_CURRENT : E_FOCUS_NONE;
+ switch (property_id) {
+ case PROP_WIDTH:
+ g_value_set_double (value, e_minicard->width);
+ break;
+ case PROP_HEIGHT:
+ g_value_set_double (value, e_minicard->height);
+ break;
+ case PROP_HAS_FOCUS:
+ g_value_set_int (value, e_minicard->has_focus ? E_FOCUS_CURRENT : E_FOCUS_NONE);
break;
- case ARG_SELECTED:
- GTK_VALUE_BOOL (*arg) = e_minicard->selected;
+ case PROP_SELECTED:
+ g_value_set_boolean (value, e_minicard->selected);
break;
- case ARG_HAS_CURSOR:
- GTK_VALUE_BOOL (*arg) = e_minicard->has_cursor;
+ case PROP_HAS_CURSOR:
+ g_value_set_boolean (value, e_minicard->has_cursor);
break;
- case ARG_EDITABLE:
- GTK_VALUE_BOOL (*arg) = e_minicard->editable;
+ case PROP_EDITABLE:
+ g_value_set_boolean (value, e_minicard->editable);
break;
- case ARG_CARD:
- e_card_simple_sync_card(e_minicard->simple);
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(e_minicard->card);
+ case PROP_CONTACT:
+ g_value_set_object (value, e_minicard->contact);
break;
default:
- arg->type = GTK_TYPE_INVALID;
- break;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
static void
-e_minicard_destroy (GtkObject *object)
+e_minicard_dispose (GObject *object)
{
EMinicard *e_minicard;
@@ -357,20 +434,24 @@ e_minicard_destroy (GtkObject *object)
g_return_if_fail (E_IS_MINICARD (object));
e_minicard = E_MINICARD (object);
-
- g_list_foreach(e_minicard->fields, (GFunc) e_minicard_field_destroy, NULL);
- g_list_free(e_minicard->fields);
-
- gdk_pixbuf_unref (e_minicard->list_icon_pixbuf);
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
+ if (e_minicard->fields) {
+ g_list_foreach (e_minicard->fields, (GFunc) e_minicard_field_destroy, NULL);
+ g_list_free (e_minicard->fields);
+ e_minicard->fields = NULL;
+ }
+ if (e_minicard->list_icon_pixbuf) {
+ g_object_unref (e_minicard->list_icon_pixbuf);
+ e_minicard->list_icon_pixbuf = NULL;
+ }
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_minicard_parent_class)->dispose (object);
+}
static void
-e_minicard_finalize (GtkObject *object)
+e_minicard_finalize (GObject *object)
{
EMinicard *e_minicard;
@@ -378,178 +459,149 @@ e_minicard_finalize (GtkObject *object)
g_return_if_fail (E_IS_MINICARD (object));
e_minicard = E_MINICARD (object);
-
- if (e_minicard->card)
- gtk_object_unref (GTK_OBJECT(e_minicard->card));
- if (e_minicard->simple)
- gtk_object_unref (GTK_OBJECT(e_minicard->simple));
-
- if (GTK_OBJECT_CLASS (parent_class)->finalize)
- (* GTK_OBJECT_CLASS (parent_class)->finalize) (object);
-}
-
-static void
-e_minicard_realize (GnomeCanvasItem *item)
-{
- EMinicard *e_minicard;
- GnomeCanvasGroup *group;
- GtkWidget *canvas;
- e_minicard = E_MINICARD (item);
- group = GNOME_CANVAS_GROUP( item );
- canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (item)->canvas);
-
- if (GNOME_CANVAS_ITEM_CLASS(parent_class)->realize)
- (* GNOME_CANVAS_ITEM_CLASS(parent_class)->realize) (item);
-
- e_minicard->rect =
- gnome_canvas_item_new( group,
- gnome_canvas_rect_get_type(),
- "x1", (double) 0,
- "y1", (double) 0,
- "x2", (double) e_minicard->width - 1,
- "y2", (double) e_minicard->height - 1,
- "outline_color", NULL,
- NULL );
-
- e_minicard->header_rect =
- gnome_canvas_item_new( group,
- gnome_canvas_rect_get_type(),
- "x1", (double) 2,
- "y1", (double) 2,
- "x2", (double) e_minicard->width - 3,
- "y2", (double) e_minicard->height - 3,
- "fill_color_gdk", &canvas->style->bg[GTK_STATE_NORMAL],
- NULL );
-
- e_minicard->header_text =
- gnome_canvas_item_new( group,
- e_text_get_type(),
- "anchor", GTK_ANCHOR_NW,
- "width", (double) ( e_minicard->width - 12 ),
- "clip", TRUE,
- "use_ellipsis", TRUE,
-#if 0
- "font", "fixed-bold-10",
-#endif
- "fill_color_gdk", &canvas->style->fg[GTK_STATE_NORMAL],
- "text", "",
- "draw_background", FALSE,
- NULL );
-
- e_canvas_item_move_absolute(e_minicard->header_text, 6, 6);
-
- e_minicard->list_icon =
- gnome_canvas_item_new ( group,
- gnome_canvas_pixbuf_get_type(),
- "pixbuf", e_minicard->list_icon_pixbuf,
- NULL);
-
- remodel(e_minicard);
- e_canvas_item_request_reflow(item);
+ if (e_minicard->contact) {
+ g_object_unref (e_minicard->contact);
+ e_minicard->contact = NULL;
+ }
- if (!item->canvas->aa) {
+ if (e_minicard->list_icon_pixbuf) {
+ g_object_unref (e_minicard->list_icon_pixbuf);
+ e_minicard->list_icon_pixbuf = NULL;
}
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_minicard_parent_class)->finalize (object);
}
static void
-e_minicard_unrealize (GnomeCanvasItem *item)
+e_minicard_style_set (EMinicard *minicard,
+ GtkStyle *previous_style)
{
- EMinicard *e_minicard;
-
- e_minicard = E_MINICARD (item);
-
- if (!item->canvas->aa)
- {
- }
+ GnomeCanvasItem *item = GNOME_CANVAS_ITEM (minicard);
- if (GNOME_CANVAS_ITEM_CLASS(parent_class)->unrealize)
- (* GNOME_CANVAS_ITEM_CLASS(parent_class)->unrealize) (item);
+ if ((item->flags & GNOME_CANVAS_ITEM_REALIZED))
+ set_selected (minicard, minicard->selected);
}
static void
-card_modified_cb (EBook* book, EBookStatus status, gpointer user_data)
+e_minicard_realize (GnomeCanvasItem *item)
{
- d(g_print ("%s: %s(): a card was modified\n", __FILE__, __FUNCTION__));
- if (status != E_BOOK_STATUS_SUCCESS)
- e_addressbook_error_dialog (_("Error modifying card"), status);
+ EMinicard *e_minicard;
+ GnomeCanvasGroup *group;
+ GnomeCanvas *canvas;
+ GtkStyle *style;
+
+ e_minicard = E_MINICARD (item);
+ group = GNOME_CANVAS_GROUP (item);
+
+ canvas = GNOME_CANVAS_ITEM (item)->canvas;
+ style = gtk_widget_get_style (GTK_WIDGET (canvas));
+
+ GNOME_CANVAS_ITEM_CLASS (e_minicard_parent_class)->realize (item);
+
+ e_minicard->rect = gnome_canvas_item_new (
+ group,
+ gnome_canvas_rect_get_type (),
+ "x1", (gdouble) 0,
+ "y1", (gdouble) 0,
+ "x2", (gdouble) MAX (e_minicard->width - 1, 0),
+ "y2", (gdouble) MAX (e_minicard->height - 1, 0),
+ "outline_color", NULL,
+ NULL);
+
+ e_minicard->header_rect = gnome_canvas_item_new (
+ group,
+ gnome_canvas_rect_get_type (),
+ "x1", (gdouble) 2,
+ "y1", (gdouble) 2,
+ "x2", (gdouble) MAX (e_minicard->width - 3, 0),
+ "y2", (gdouble) MAX (e_minicard->height - 3, 0),
+ "fill_color_gdk", &style->bg[GTK_STATE_NORMAL],
+ NULL);
+
+ e_minicard->header_text = gnome_canvas_item_new (
+ group,
+ e_text_get_type (),
+ "width", (gdouble) MAX (e_minicard->width - 12, 0),
+ "clip", TRUE,
+ "use_ellipsis", TRUE,
+ "fill_color_gdk", &style->fg[GTK_STATE_NORMAL],
+ "text", "",
+ NULL);
+
+ e_canvas_item_move_absolute (e_minicard->header_text, 6, 6);
+
+ e_minicard->list_icon = gnome_canvas_item_new (
+ group,
+ gnome_canvas_pixbuf_get_type (),
+ "pixbuf", e_minicard->list_icon_pixbuf,
+ NULL);
+
+ set_selected (e_minicard, e_minicard->selected);
+
+ remodel (e_minicard);
+ e_canvas_item_request_reflow (item);
}
-/* Callback used when the contact editor is closed */
-static void
-editor_closed_cb (GtkObject *editor, gpointer data)
+void
+e_minicard_activate_editor (EMinicard *minicard)
{
- EMinicard *minicard = data;
- gtk_object_unref (GTK_OBJECT (editor));
- minicard->editor = NULL;
+ g_return_if_fail (E_IS_MINICARD (minicard));
+
+ g_signal_emit (minicard, signals[OPEN_CONTACT], 0, minicard->contact);
}
static gboolean
-e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
+e_minicard_event (GnomeCanvasItem *item,
+ GdkEvent *event)
{
EMinicard *e_minicard;
- GtkWidget *canvas;
-
+
e_minicard = E_MINICARD (item);
- canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (item)->canvas);
-
- switch( event->type ) {
+
+ switch (event->type) {
case GDK_FOCUS_CHANGE:
{
GdkEventFocus *focus_event = (GdkEventFocus *) event;
- d(g_print("%s: GDK_FOCUS_CHANGE: %s\n", __FUNCTION__, focus_event->in?"in":"out"));
+ d (g_print ("%s: GDK_FOCUS_CHANGE: %s\n", G_STRFUNC, focus_event->in?"in":"out"));
if (focus_event->in) {
/* Chris: When EMinicard gets the cursor, if it doesn't have the focus, it should take it. */
e_minicard->has_focus = TRUE;
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)) {
-
- gtk_object_get(GTK_OBJECT(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);
- } else {
- remodel(e_minicard);
- e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(e_minicard));
- }
- e_minicard->changed = FALSE;
+ e_minicard_selected (e_minicard, event);
}
+ }
+ else {
e_minicard->has_focus = FALSE;
}
}
break;
case GDK_BUTTON_PRESS: {
if (1 <= event->button.button && event->button.button <= 2) {
- int ret_val = e_minicard_selected(e_minicard, event);
- GdkEventMask mask = ((1 << (4 + event->button.button)) |
- GDK_POINTER_MOTION_MASK |
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK);
-
- e_canvas_item_grab_focus(item, TRUE);
-
- if (gnome_canvas_item_grab (GNOME_CANVAS_ITEM (e_minicard),
- mask, NULL, event->button.time)) {
+ gint ret_val = e_minicard_selected (e_minicard, event);
+ GdkGrabStatus grab_status;
+ GdkDevice *event_device;
+ guint32 event_time;
+
+ e_canvas_item_grab_focus (item, TRUE);
+
+ event_device = gdk_event_get_device (event);
+ event_time = gdk_event_get_time (event);
+
+ grab_status = gnome_canvas_item_grab (
+ GNOME_CANVAS_ITEM (e_minicard),
+ (1 << (4 + event->button.button)) |
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK,
+ NULL,
+ event_device,
+ event_time);
+
+ if (grab_status != GDK_GRAB_SUCCESS)
return FALSE;
- }
+
gtk_grab_add (GTK_WIDGET (GNOME_CANVAS_ITEM (e_minicard)->canvas));
e_minicard->button_x = event->button.x;
e_minicard->button_y = event->button.y;
@@ -557,21 +609,21 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
e_minicard->drag_button_down = TRUE;
return ret_val;
} else if (event->button.button == 3) {
- int ret_val = e_minicard_selected(e_minicard, event);
+ gint ret_val = e_minicard_selected (e_minicard, event);
if (ret_val != 0)
return ret_val;
}
break;
}
case GDK_BUTTON_RELEASE:
- e_minicard_selected(e_minicard, event);
+ e_minicard_selected (e_minicard, event);
if (e_minicard->drag_button == event->button.button) {
e_minicard->drag_button = 0;
e_minicard->drag_button_down = FALSE;
e_minicard->button_x = -1;
e_minicard->button_y = -1;
- if (GTK_WIDGET_HAS_GRAB (GNOME_CANVAS_ITEM (e_minicard)->canvas)) {
+ if (gtk_widget_has_grab (GTK_WIDGET (GNOME_CANVAS_ITEM (e_minicard)->canvas))) {
gtk_grab_remove (GTK_WIDGET (GNOME_CANVAS_ITEM (e_minicard)->canvas));
gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (e_minicard), event->button.time);
}
@@ -583,7 +635,7 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
abs (e_minicard->button_y - event->motion.y)) > 3) {
gint ret_val;
- ret_val = e_minicard_drag_begin(e_minicard, event);
+ ret_val = e_minicard_drag_begin (e_minicard, event);
e_minicard->drag_button_down = FALSE;
@@ -592,408 +644,555 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
}
break;
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))
- e_contact_list_editor_raise (E_CONTACT_LIST_EDITOR(e_minicard->editor));
- else
- e_contact_editor_raise(E_CONTACT_EDITOR(e_minicard->editor));
- } else {
- EBook *book = NULL;
- if (E_IS_MINICARD_VIEW(item->parent)) {
- gtk_object_get(GTK_OBJECT(item->parent),
- "book", &book,
- NULL);
+ if (event->button.button == 1 && E_IS_MINICARD_VIEW (item->parent)) {
+ e_minicard_activate_editor (e_minicard);
+ return TRUE;
+ }
+ break;
+ case GDK_KEY_PRESS:
+ if (event->key.keyval == GDK_KEY_Tab ||
+ event->key.keyval == GDK_KEY_KP_Tab ||
+ event->key.keyval == GDK_KEY_ISO_Left_Tab) {
+
+ EMinicardView *view = E_MINICARD_VIEW (item->parent);
+ EReflow *reflow = E_REFLOW (view);
+
+ if (reflow == NULL) {
+ return FALSE;
+ }
+
+ if (event->key.state & GDK_SHIFT_MASK) {
+ if (event->key.state & GDK_CONTROL_MASK) {
+ return FALSE;
}
+ else {
+ gint row_count = e_selection_model_row_count (reflow->selection);
+ gint model_index = e_selection_model_cursor_row (reflow->selection);
+ gint view_index = e_sorter_model_to_sorted (reflow->selection->sorter, model_index);
- 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);
- e_minicard->editor = GTK_OBJECT (editor);
- }
- else {
- EContactEditor *editor = e_addressbook_show_contact_editor (book, e_minicard->card,
- FALSE, e_minicard->editable);
- e_minicard->editor = GTK_OBJECT (editor);
- }
- gtk_object_ref (e_minicard->editor);
+ if (view_index == 0)
+ view_index = row_count - 1;
+ else
+ view_index--;
- gtk_signal_connect (e_minicard->editor, "editor_closed",
- GTK_SIGNAL_FUNC (editor_closed_cb), e_minicard);
+ model_index = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), view_index);
+ if (reflow->items[model_index] == NULL) {
+ reflow->items[model_index] = e_reflow_model_incarnate (reflow->model, model_index, GNOME_CANVAS_GROUP (reflow));
+ g_object_set (
+ reflow->items[model_index],
+ "width", (gdouble) reflow->column_width,
+ NULL);
+ }
+ e_canvas_item_grab_focus (reflow->items[model_index], FALSE);
+ return TRUE;
}
}
- 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;
- gtk_object_get(GTK_OBJECT(item),
- "has_focus", &has_focus,
- NULL);
- if (has_focus != E_FOCUS_NONE) {
- if (event->key.state & GDK_SHIFT_MASK)
- list = list->prev;
+ else {
+ if (event->key.state & GDK_CONTROL_MASK) {
+ return FALSE;
+ }
+ else {
+ gint row_count = e_selection_model_row_count (reflow->selection);
+ gint model_index = e_selection_model_cursor_row (reflow->selection);
+ gint view_index = e_sorter_model_to_sorted (reflow->selection->sorter, model_index);
+
+ if (view_index == row_count - 1)
+ view_index = 0;
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;
+ view_index++;
+
+ model_index = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), view_index);
+ if (reflow->items[model_index] == NULL) {
+ reflow->items[model_index] = e_reflow_model_incarnate (reflow->model, model_index, GNOME_CANVAS_GROUP (reflow));
+ g_object_set (
+ reflow->items[model_index],
+ "width", (gdouble) reflow->column_width,
+ NULL);
+
}
+ e_canvas_item_grab_focus (reflow->items[model_index], FALSE);
+ return TRUE;
}
}
}
+ else if (event->key.keyval == GDK_KEY_Return ||
+ event->key.keyval == GDK_KEY_KP_Enter) {
+ e_minicard_activate_editor (e_minicard);
+ return TRUE;
+ }
+ break;
default:
break;
}
-
- if (GNOME_CANVAS_ITEM_CLASS( parent_class )->event)
- return (* GNOME_CANVAS_ITEM_CLASS( parent_class )->event) (item, event);
- else
- return 0;
+
+ return FALSE;
}
static void
-e_minicard_resize_children( EMinicard *e_minicard )
+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)),
- NULL );
+ gnome_canvas_item_set (
+ e_minicard->header_text,
+ "width", ((gdouble) e_minicard->width - 12
+ - (is_list ? e_minicard->list_icon_size : 0.0)),
+ NULL);
}
if (e_minicard->list_icon) {
- e_canvas_item_move_absolute(e_minicard->list_icon,
- e_minicard->width - e_minicard->list_icon_size - 3,
- 3);
+ e_canvas_item_move_absolute (
+ e_minicard->list_icon,
+ e_minicard->width - e_minicard->list_icon_size - 3,
+ 3);
}
- for ( list = e_minicard->fields; list; list = g_list_next( list ) ) {
- gnome_canvas_item_set( E_MINICARD_FIELD( list->data )->label,
- "width", (double) e_minicard->width - 4.0,
- NULL );
+ for (list = e_minicard->fields; list; list = g_list_next (list)) {
+ gnome_canvas_item_set (
+ E_MINICARD_FIELD (list->data)->label,
+ "width", (gdouble) e_minicard->width - 4.0,
+ NULL);
}
}
static void
-field_changed (EText *text, EMinicard *e_minicard)
+add_field (EMinicard *e_minicard,
+ EContactField field,
+ gdouble left_width)
{
- ECardSimpleType type;
- char *string;
-
- type = GPOINTER_TO_INT
- (gtk_object_get_data(GTK_OBJECT(text),
- "EMinicard:field"));
- gtk_object_get(GTK_OBJECT(text),
- "text", &string,
- NULL);
- e_card_simple_set(e_minicard->simple,
- type,
- string);
- g_free(string);
- e_minicard->changed = TRUE;
+ GnomeCanvasItem *new_item;
+ GnomeCanvasGroup *group;
+ EMinicardField *minicard_field;
+ gchar *name;
+ gchar *string;
+ gboolean is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
+
+ group = GNOME_CANVAS_GROUP (e_minicard);
+
+ name = g_strdup_printf ("%s:", e_contact_pretty_name (field));
+ string = e_contact_get (e_minicard->contact, field);
+
+ new_item = e_minicard_label_new (group);
+
+ if (e_minicard->contact && e_contact_get (e_minicard->contact, E_CONTACT_IS_LIST))
+ gnome_canvas_item_set (
+ new_item,
+ "fieldname", is_rtl ? "" : string,
+ "field", is_rtl ? string : "",
+ "max_field_name_length", left_width,
+ "editable", FALSE /* e_minicard->editable */,
+ "width", e_minicard->width - 4.0,
+ NULL);
+ else
+ gnome_canvas_item_set (
+ new_item,
+ "fieldname", is_rtl ? string : name,
+ "field", is_rtl ? name : string,
+ "max_field_name_length", left_width,
+ "editable", FALSE /* e_minicard->editable */,
+ "width", e_minicard->width - 4.0,
+ NULL);
+
+#ifdef notyet
+ g_object_set (
+ E_MINICARD_LABEL (new_item)->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));
+
+ minicard_field = g_new (EMinicardField, 1);
+ minicard_field->field = field;
+ minicard_field->label = new_item;
+
+ e_minicard->fields = g_list_append (e_minicard->fields, minicard_field);
+ e_canvas_item_move_absolute (new_item, 2, e_minicard->height);
+ g_free (name);
+ g_free (string);
}
-static void
-field_activated (EText *text, EMinicard *e_minicard)
+static const gchar *
+get_email_location (EVCardAttribute *attr)
{
- e_text_stop_editing (text);
- e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (e_minicard), FALSE);
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (common_location); i++) {
+ if (e_vcard_attribute_has_type (attr, common_location[i].name))
+ return _(common_location[i].pretty_name);
+ }
+
+ return _("Other Email");
}
static void
-add_field (EMinicard *e_minicard, ECardSimpleField field, gdouble left_width)
+add_email_field (EMinicard *e_minicard,
+ GList *email_list,
+ gdouble left_width,
+ gint limit,
+ gboolean is_list)
{
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);
-
- /* Magically convert embedded XML into an address. */
- if (!strncmp (string, "<?xml", 5)) {
- EDestination *dest = e_destination_import (string);
- if (dest != NULL) {
- gchar *new_string = g_strdup (e_destination_get_address (dest));
- g_free (string);
- string = new_string;
- gtk_object_unref (GTK_OBJECT (dest));
+ gchar *name;
+ GList *l, *le;
+ gint count =0;
+ gboolean is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
+ GList *emails = e_contact_get (e_minicard->contact, E_CONTACT_EMAIL);
+ group = GNOME_CANVAS_GROUP (e_minicard);
+
+ for (l = email_list, le = emails; l != NULL && count < limit && le != NULL; l = l->next, le = le->next) {
+ const gchar *tmp;
+ gchar *email = NULL;
+ gchar *string = NULL;
+ gchar *parsed_name = NULL;
+ gboolean parser_check;
+
+ /* do not use name for fields in the contact list */
+ if (is_list) {
+ name = (gchar *)"";
+ } else {
+ tmp = get_email_location ((EVCardAttribute *) l->data);
+ name = g_strdup_printf ("%s:", tmp);
}
- }
- new_item = e_minicard_label_new(group);
- gnome_canvas_item_set( new_item,
- "width", e_minicard->width - 4.0,
- "fieldname", name,
- "field", string,
- "max_field_name_length", left_width,
- "editable", e_minicard->editable,
- NULL );
- gtk_signal_connect(GTK_OBJECT(E_MINICARD_LABEL(new_item)->field),
- "changed", GTK_SIGNAL_FUNC(field_changed), e_minicard);
- gtk_signal_connect(GTK_OBJECT(E_MINICARD_LABEL(new_item)->field),
- "activate", GTK_SIGNAL_FUNC(field_activated), e_minicard);
- gtk_object_set(GTK_OBJECT(E_MINICARD_LABEL(new_item)->field),
- "allow_newlines", e_card_simple_get_allow_newlines (e_minicard->simple, field),
- NULL);
- gtk_object_set_data(GTK_OBJECT(E_MINICARD_LABEL(new_item)->field),
- "EMinicard:field",
- GINT_TO_POINTER(field));
-
- minicard_field = g_new(EMinicardField, 1);
- minicard_field->field = field;
- minicard_field->label = new_item;
+ parser_check = eab_parse_qp_email ((const gchar *) le->data, &parsed_name, &email);
+ if (parser_check) {
+ /* if true, we had a quoted printable mail address */
+ string = g_strdup_printf ("%s <%s>", parsed_name, email);
+ } else {
+ /* we got a NON-quoted printable string */
+ string = g_strdup (le->data);
+ }
- e_minicard->fields = g_list_append( e_minicard->fields, minicard_field);
- e_canvas_item_move_absolute(new_item, 2, e_minicard->height);
- g_free(name);
- g_free(string);
+ new_item = e_minicard_label_new (group);
+
+ gnome_canvas_item_set (
+ new_item,
+ "fieldname", is_rtl ? string : name,
+ "field", is_rtl ? name : string,
+ "max_field_name_length", left_width,
+ "editable", FALSE /* e_minicard->editable */,
+ "width", e_minicard->width - 4.0,
+ NULL);
+
+#ifdef notyet
+ g_object_set (
+ E_MINICARD_LABEL (new_item)->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 (E_CONTACT_EMAIL));
+
+ minicard_field = g_new (EMinicardField, 1);
+ minicard_field->field = E_CONTACT_EMAIL;
+ minicard_field->label = new_item;
+
+ e_minicard->fields = g_list_append (e_minicard->fields, minicard_field);
+ e_canvas_item_move_absolute (new_item, 2, e_minicard->height);
+ count++;
+ if (!is_list)
+ g_free (name);
+ g_free (string);
+ g_free (parsed_name);
+ g_free (email);
+ }
+ g_list_foreach (emails, (GFunc) g_free, NULL);
+ g_list_free (emails);
}
-static gdouble
-get_left_width(EMinicard *e_minicard)
+static gint
+get_left_width (EMinicard *e_minicard,
+ gboolean is_list)
{
gchar *name;
- ECardSimpleField field;
- gdouble width = -1;
- GdkFont *font;
+ EContactField field;
+ gint width = -1;
+ PangoLayout *layout;
+
+ if (is_list)
+ return 0;
+
+ layout = gtk_widget_create_pango_layout (GTK_WIDGET (GNOME_CANVAS_ITEM (e_minicard)->canvas), "");
+ for (field = E_CONTACT_FULL_NAME; field != E_CONTACT_LAST_SIMPLE_STRING; field++) {
+ gint this_width;
- font = ((GtkWidget *) ((GnomeCanvasItem *) e_minicard)->canvas)->style->font;
+ if (field == E_CONTACT_FAMILY_NAME || field == E_CONTACT_GIVEN_NAME)
+ continue;
- for(field = E_CARD_SIMPLE_FIELD_FULL_NAME; field != E_CARD_SIMPLE_FIELD_LAST; field++) {
- gdouble this_width;
- name = g_strdup_printf("%s:", e_card_simple_get_name(e_minicard->simple, field));
- this_width = gdk_text_width(font, name, strlen(name));
+ 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)
width = this_width;
- g_free(name);
+ g_free (name);
}
+ g_object_unref (layout);
return width;
}
static void
-remodel( EMinicard *e_minicard )
+remodel (EMinicard *e_minicard)
{
- int count = 0;
- if ( !(GTK_OBJECT_FLAGS( e_minicard ) & GNOME_CANVAS_ITEM_REALIZED) )
+ GnomeCanvasItem *item = GNOME_CANVAS_ITEM (e_minicard);
+ gint count = 0;
+
+ if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED))
return;
- if (e_minicard->simple) {
- ECardSimpleField field;
+
+ if (e_minicard->contact) {
+ EContactField field;
GList *list;
- char *file_as;
- gdouble left_width = -1;
+ gchar *file_as;
+ gint left_width = -1;
+ gboolean is_list = FALSE;
+ gboolean email_rendered = FALSE;
+ gboolean has_voice = FALSE, has_fax = FALSE;
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,
- "text", file_as ? file_as : "",
- NULL );
- g_free(file_as);
+ 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))
+ is_list = TRUE;
+
+ if (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 -1) && count < 5; field++) {
EMinicardField *minicard_field = NULL;
+ gboolean is_email = FALSE;
+
+ if (field == E_CONTACT_FAMILY_NAME || field == E_CONTACT_GIVEN_NAME ||
+ (has_voice && field == E_CONTACT_PHONE_OTHER) ||
+ (has_fax && field == E_CONTACT_PHONE_OTHER_FAX))
+ continue;
+
+ if (field == E_CONTACT_FULL_NAME && is_list)
+ continue;
+
+ if (field == E_CONTACT_EMAIL_1 || field == E_CONTACT_EMAIL_2 || field == E_CONTACT_EMAIL_3 || field == E_CONTACT_EMAIL_4) {
+ if (email_rendered)
+ continue;
+ email_rendered = TRUE;
+ is_email = TRUE;
+ }
if (list)
minicard_field = list->data;
if (minicard_field && minicard_field->field == field) {
GList *this_list = list;
- char *string;
+ gchar *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);
- if (dest != NULL) {
- gchar *new_string = g_strdup (e_destination_get_address (dest));
- g_free (string);
- string = new_string;
- gtk_object_unref (GTK_OBJECT (dest));
- }
- }
-
- e_minicard->fields = g_list_append(e_minicard->fields, minicard_field);
- gtk_object_set(GTK_OBJECT(minicard_field->label),
- "field", string,
- NULL);
- count ++;
+ e_minicard->fields = g_list_append (e_minicard->fields, minicard_field);
+ g_object_set (
+ minicard_field->label,
+ "field", string,
+ NULL);
+ count++;
} else {
- e_minicard_field_destroy(minicard_field);
+ e_minicard_field_destroy (minicard_field);
}
- list = g_list_remove_link(list, this_list);
- g_list_free_1(this_list);
- g_free(string);
+ list = g_list_delete_link (list, this_list);
+ g_free (string);
} else {
- char *string;
+ gchar *string;
if (left_width == -1) {
- left_width = get_left_width(e_minicard);
+ left_width = get_left_width (e_minicard, is_list);
}
- string = e_card_simple_get(e_minicard->simple, field);
- if (string && *string) {
- add_field(e_minicard, field, left_width);
- count++;
+ if (is_email) {
+ GList *email;
+ gint limit;
+
+ limit = 5 - count;
+ email = e_contact_get_attributes (e_minicard->contact, E_CONTACT_EMAIL);
+ add_email_field (e_minicard, email, left_width, limit, is_list);
+ if (count + limit >5)
+ count = 5;
+ else
+ count = count + g_list_length (email);
+ g_list_free_full (email, (GDestroyNotify) e_vcard_attribute_free);
+ } else {
+ string = e_contact_get (e_minicard->contact, field);
+ if (string && *string) {
+ add_field (e_minicard, field, left_width);
+ count++;
+
+ has_voice = has_voice ||
+ field == E_CONTACT_PHONE_BUSINESS ||
+ field == E_CONTACT_PHONE_BUSINESS_2 ||
+ field == E_CONTACT_PHONE_HOME ||
+ field == E_CONTACT_PHONE_HOME_2;
+ has_fax = has_fax ||
+ field == E_CONTACT_PHONE_BUSINESS_FAX ||
+ field == E_CONTACT_PHONE_HOME_FAX;
+ }
+ g_free (string);
}
- g_free(string);
}
}
- g_list_foreach(list, (GFunc) e_minicard_field_destroy, NULL);
- g_list_free(list);
+ g_list_foreach (list, (GFunc) e_minicard_field_destroy, NULL);
+ g_list_free (list);
}
}
static void
-e_minicard_reflow( GnomeCanvasItem *item, int flags )
+e_minicard_reflow (GnomeCanvasItem *item,
+ gint flags)
{
- EMinicard *e_minicard = E_MINICARD(item);
- if ( GTK_OBJECT_FLAGS( e_minicard ) & GNOME_CANVAS_ITEM_REALIZED ) {
+ EMinicard *e_minicard = E_MINICARD (item);
+
+ if (item->flags & GNOME_CANVAS_ITEM_REALIZED) {
GList *list;
gdouble text_height;
gint old_height;
-
+
old_height = e_minicard->height;
- gtk_object_get( GTK_OBJECT( e_minicard->header_text ),
- "text_height", &text_height,
- NULL );
-
+ g_object_get (
+ e_minicard->header_text,
+ "text_height", &text_height,
+ NULL);
+
e_minicard->height = text_height + 10.0;
-
- gnome_canvas_item_set( e_minicard->header_rect,
- "y2", text_height + 9.0,
- NULL );
-
- for(list = e_minicard->fields; list; list = g_list_next(list)) {
- EMinicardField *field = E_MINICARD_FIELD(list->data);
+
+ gnome_canvas_item_set (
+ e_minicard->header_rect,
+ "y2", text_height + 9.0,
+ NULL);
+
+ for (list = e_minicard->fields; list; list = g_list_next (list)) {
+ EMinicardField *field = E_MINICARD_FIELD (list->data);
+ /* Why not use the item that is passed in? */
GnomeCanvasItem *item = field->label;
- gtk_object_get (GTK_OBJECT(item),
- "height", &text_height,
- NULL);
- e_canvas_item_move_absolute(item, 2, e_minicard->height);
+ g_object_get (
+ item,
+ "height", &text_height,
+ NULL);
+ e_canvas_item_move_absolute (item, 2, e_minicard->height);
e_minicard->height += text_height;
}
e_minicard->height += 2;
-
- gnome_canvas_item_set( e_minicard->rect,
- "y2", (double) e_minicard->height - 1,
- NULL );
-
- gnome_canvas_item_set( e_minicard->rect,
- "x2", (double) e_minicard->width - 1.0,
- "y2", (double) e_minicard->height - 1.0,
- NULL );
- gnome_canvas_item_set( e_minicard->header_rect,
- "x2", (double) e_minicard->width - 3.0,
- NULL );
+
+ gnome_canvas_item_set (
+ e_minicard->rect,
+ "x2", (gdouble) e_minicard->width - 1.0,
+ "y2", (gdouble) e_minicard->height - 1.0,
+ NULL);
+ gnome_canvas_item_set (
+ e_minicard->header_rect,
+ "x2", (gdouble) e_minicard->width - 3.0,
+ NULL);
if (old_height != e_minicard->height)
- e_canvas_item_request_parent_reflow(item);
+ e_canvas_item_request_parent_reflow (item);
}
}
-const char *
+const gchar *
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);
+ 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 "";
}
}
-int
-e_minicard_compare (EMinicard *minicard1, EMinicard *minicard2)
+gint
+e_minicard_compare (EMinicard *minicard1,
+ EMinicard *minicard2)
{
- g_return_val_if_fail(minicard1 != NULL, 0);
- g_return_val_if_fail(E_IS_MINICARD(minicard1), 0);
- g_return_val_if_fail(minicard2 != NULL, 0);
- g_return_val_if_fail(E_IS_MINICARD(minicard2), 0);
-
- if (minicard1->card && minicard2->card) {
- char *file_as1, *file_as2;
- gtk_object_get(GTK_OBJECT(minicard1->card),
- "file_as", &file_as1,
- NULL);
- gtk_object_get(GTK_OBJECT(minicard2->card),
- "file_as", &file_as2,
- NULL);
+ gint cmp = 0;
+
+ g_return_val_if_fail (minicard1 != NULL, 0);
+ g_return_val_if_fail (E_IS_MINICARD (minicard1), 0);
+ g_return_val_if_fail (minicard2 != NULL, 0);
+ g_return_val_if_fail (E_IS_MINICARD (minicard2), 0);
+
+ if (minicard1->contact && minicard2->contact) {
+ gchar *file_as1, *file_as2;
+ g_object_get (
+ minicard1->contact,
+ "file_as", &file_as1,
+ NULL);
+ g_object_get (
+ minicard2->contact,
+ "file_as", &file_as2,
+ NULL);
+
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_minicard_get_card_id(minicard1), e_minicard_get_card_id(minicard2));
- } else {
- return 0;
+ cmp = g_utf8_collate (file_as1, file_as2);
+ else if (file_as1)
+ cmp = -1;
+ else if (file_as2)
+ cmp = 1;
+ else
+ cmp = strcmp (e_minicard_get_card_id (minicard1), e_minicard_get_card_id (minicard2));
+
+ g_free (file_as1);
+ g_free (file_as2);
}
+
+ return cmp;
}
-int
-e_minicard_selected (EMinicard *minicard, GdkEvent *event)
+gint
+e_minicard_selected (EMinicard *minicard,
+ GdkEvent *event)
{
gint ret_val = 0;
GnomeCanvasItem *item = GNOME_CANVAS_ITEM (minicard);
if (item->parent) {
- guint signal_id = gtk_signal_lookup ("selection_event", GTK_OBJECT_TYPE (item->parent));
+ guint signal_id = g_signal_lookup ("selection_event", G_OBJECT_TYPE (item->parent));
/* We should probably check the signature here, but I
* don't think it's worth the time required to code
* it.
*/
if (signal_id != 0) {
- gtk_signal_emit(GTK_OBJECT(item->parent),
- signal_id,
- item, event, &ret_val);
+ g_signal_emit (
+ item->parent,
+ signal_id, 0,
+ item, event, &ret_val);
}
}
return ret_val;
}
static gint
-e_minicard_drag_begin (EMinicard *minicard, GdkEvent *event)
+e_minicard_drag_begin (EMinicard *minicard,
+ GdkEvent *event)
{
gint ret_val = 0;
GnomeCanvasItem *parent;
- gtk_signal_emit (GTK_OBJECT(minicard),
- e_minicard_signals[DRAG_BEGIN],
- event, &ret_val);
+ g_signal_emit (
+ minicard,
+ signals[DRAG_BEGIN], 0,
+ event, &ret_val);
parent = GNOME_CANVAS_ITEM (minicard)->parent;
if (parent && E_IS_REFLOW (parent)) {
diff --git a/addressbook/gui/widgets/e-minicard.h b/addressbook/gui/widgets/e-minicard.h
index bb6a3c072e..986f47194a 100644
--- a/addressbook/gui/widgets/e-minicard.h
+++ b/addressbook/gui/widgets/e-minicard.h
@@ -1,56 +1,56 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-minicard.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser 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_H__
-#define __E_MINICARD_H__
-
-#include <libgnomeui/gnome-canvas.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include "addressbook/gui/contact-editor/e-contact-editor.h"
-#include "addressbook/backend/ebook/e-card.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* EMinicard - A small card displaying information about a contact.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
*
- * The following arguments are available:
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * name type read/write description
- * --------------------------------------------------------------------------------
- * width double RW width of the card
- * height double R height of the card
- * card ECard* RW Pointer to the ECard
*/
-#define E_MINICARD_TYPE (e_minicard_get_type ())
-#define E_MINICARD(obj) (GTK_CHECK_CAST ((obj), E_MINICARD_TYPE, EMinicard))
-#define E_MINICARD_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_MINICARD_TYPE, EMinicardClass))
-#define E_IS_MINICARD(obj) (GTK_CHECK_TYPE ((obj), E_MINICARD_TYPE))
-#define E_IS_MINICARD_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_MINICARD_TYPE))
+#ifndef E_MINICARD_H
+#define E_MINICARD_H
+
+#include <gtk/gtk.h>
+#include <libebook/libebook.h>
+#include <libgnomecanvas/libgnomecanvas.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MINICARD \
+ (e_minicard_get_type ())
+#define E_MINICARD(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MINICARD, EMinicard))
+#define E_MINICARD_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MINICARD, EMinicardClass))
+#define E_IS_MINICARD(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MINICARD))
+#define E_IS_MINICARD_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_MINICARD))
+#define E_MINICARD_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MINICARD, EMinicardClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMinicard EMinicard;
+typedef struct _EMinicardClass EMinicardClass;
-
-typedef struct _EMinicard EMinicard;
-typedef struct _EMinicardClass EMinicardClass;
typedef enum _EMinicardFocusType EMinicardFocusType;
enum _EMinicardFocusType {
@@ -61,20 +61,17 @@ enum _EMinicardFocusType {
struct _EMinicard
{
GnomeCanvasGroup parent;
-
+
/* item specific fields */
- ECard *card;
- ECardSimple *simple;
-
+ EContact *contact;
+
GnomeCanvasItem *rect;
GnomeCanvasItem *header_rect;
GnomeCanvasItem *header_text;
GnomeCanvasItem *list_icon;
GdkPixbuf *list_icon_pixbuf;
- double list_icon_size;
-
- GtkObject *editor;
+ gdouble list_icon_size;
GList *fields; /* Of type EMinicardField */
guint needs_remodeling : 1;
@@ -94,8 +91,8 @@ struct _EMinicard
gint button_x;
gint button_y;
- double width;
- double height;
+ gdouble width;
+ gdouble height;
};
struct _EMinicardClass
@@ -104,20 +101,28 @@ struct _EMinicardClass
gint (* selected) (EMinicard *minicard, GdkEvent *event);
gint (* drag_begin) (EMinicard *minicard, GdkEvent *event);
+ void (* open_contact) (EMinicard *minicard, EContact *contact);
+
+ void (* style_set) (EMinicard *minicard, GtkStyle *previous_style);
};
+typedef struct _EMinicardField EMinicardField;
-GtkType e_minicard_get_type (void);
-const char *e_minicard_get_card_id (EMinicard *minicard);
-int e_minicard_compare (EMinicard *minicard1,
- EMinicard *minicard2);
+struct _EMinicardField {
+ EContactField field;
+ GnomeCanvasItem *label;
+};
-int e_minicard_selected (EMinicard *minicard,
- GdkEvent *event);
+#define E_MINICARD_FIELD(field) ((EMinicardField *)(field))
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+GType e_minicard_get_type (void);
+const gchar * e_minicard_get_card_id (EMinicard *minicard);
+gint e_minicard_compare (EMinicard *minicard1,
+ EMinicard *minicard2);
+gint e_minicard_selected (EMinicard *minicard,
+ GdkEvent *event);
+void e_minicard_activate_editor (EMinicard *minicard);
+G_END_DECLS
-#endif /* __E_MINICARD_H__ */
+#endif /* E_MINICARD_H */
diff --git a/addressbook/gui/widgets/ea-addressbook-view.c b/addressbook/gui/widgets/ea-addressbook-view.c
new file mode 100644
index 0000000000..f1c21d1001
--- /dev/null
+++ b/addressbook/gui/widgets/ea-addressbook-view.c
@@ -0,0 +1,123 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+#include "ea-addressbook-view.h"
+
+static const gchar * ea_ab_view_get_name (AtkObject *accessible);
+static const gchar * ea_ab_view_get_description (AtkObject *accessible);
+
+static void ea_ab_view_class_init (EAddressbookViewClass *class);
+
+GType
+ea_ab_view_get_type (void)
+{
+ static GType type = 0;
+ AtkObjectFactory *factory;
+ GTypeQuery query;
+ GType derived_atk_type;
+
+ if (!type) {
+ static GTypeInfo tinfo = {
+ sizeof (EAddressbookViewClass),
+ (GBaseInitFunc) NULL, /* base_init */
+ (GBaseFinalizeFunc) NULL, /* base_finalize */
+ (GClassInitFunc) ea_ab_view_class_init,
+ (GClassFinalizeFunc) NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EAddressbookView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL, /* instance init */
+ NULL /* value table */
+ };
+
+ /*
+ * Figure out the size of the class and instance
+ * we are run-time deriving from (GailWidget, in this case) */
+
+ factory = atk_registry_get_factory (
+ atk_get_default_registry (),
+ GTK_TYPE_EVENT_BOX);
+ derived_atk_type = atk_object_factory_get_accessible_type (factory);
+ g_type_query (derived_atk_type, &query);
+
+ tinfo.class_size = query.class_size;
+ tinfo.instance_size = query.instance_size;
+
+ type = g_type_register_static (
+ derived_atk_type,
+ "EaABView", &tinfo, 0);
+ }
+
+ return type;
+}
+
+static void
+ea_ab_view_class_init (EAddressbookViewClass *class)
+{
+ AtkObjectClass *atk_object_class;
+
+ atk_object_class = ATK_OBJECT_CLASS (class);
+ atk_object_class->get_name = ea_ab_view_get_name;
+ atk_object_class->get_description = ea_ab_view_get_description;
+}
+
+static const gchar *
+ea_ab_view_get_name (AtkObject *accessible)
+{
+ g_return_val_if_fail (EA_IS_AB_VIEW (accessible), NULL);
+ if (accessible->name)
+ return accessible->name;
+
+ return _("evolution address book");
+}
+
+static const gchar *
+ea_ab_view_get_description (AtkObject *accessible)
+{
+ if (accessible->description)
+ return accessible->description;
+
+ return _("evolution address book");
+}
+
+AtkObject *
+ea_ab_view_new (GObject *obj)
+{
+ GObject *object;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (obj != NULL, NULL);
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (obj), NULL);
+
+ object = g_object_new (EA_TYPE_AB_VIEW, NULL);
+
+ accessible = ATK_OBJECT (object);
+ atk_object_initialize (accessible, obj);
+ accessible->role = ATK_ROLE_CANVAS;
+
+ return accessible;
+}
diff --git a/addressbook/gui/widgets/ea-addressbook-view.h b/addressbook/gui/widgets/ea-addressbook-view.h
new file mode 100644
index 0000000000..55da1d5e37
--- /dev/null
+++ b/addressbook/gui/widgets/ea-addressbook-view.h
@@ -0,0 +1,55 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EA_ADDRESSBOOK_VIEW_H__
+#define __EA_ADDRESSBOOK_VIEW_H__
+
+#include <gtk/gtk.h>
+#include "e-addressbook-view.h"
+
+G_BEGIN_DECLS
+
+#define EA_TYPE_AB_VIEW (ea_ab_view_get_type ())
+#define EA_AB_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_AB_VIEW, EaABView))
+#define EA_AB_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_AB_VIEW, EaABViewClass))
+#define EA_IS_AB_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_AB_VIEW))
+#define EA_IS_AB_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EA_TYPE_AB_VIEW))
+
+typedef struct _EaABView EaABView;
+typedef struct _EaABViewClass EaABViewClass;
+
+struct _EaABView
+{
+ GtkAccessible parent;
+};
+
+struct _EaABViewClass
+{
+ GtkAccessibleClass parent_class;
+};
+
+GType ea_ab_view_get_type (void);
+AtkObject * ea_ab_view_new (GObject *obj);
+
+G_END_DECLS
+
+#endif /* __EA_ADDRESSBOOK_VIEW_H__ */
diff --git a/addressbook/gui/widgets/ea-addressbook.c b/addressbook/gui/widgets/ea-addressbook.c
new file mode 100644
index 0000000000..51af22d0d4
--- /dev/null
+++ b/addressbook/gui/widgets/ea-addressbook.c
@@ -0,0 +1,90 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-util/e-util.h"
+
+#include "ea-addressbook.h"
+#include "ea-minicard.h"
+#include "ea-minicard-view.h"
+#include "ea-addressbook-view.h"
+
+EA_FACTORY_GOBJECT (EA_TYPE_MINICARD, ea_minicard, ea_minicard_new)
+EA_FACTORY_GOBJECT (EA_TYPE_MINICARD_VIEW, ea_minicard_view, ea_minicard_view_new)
+EA_FACTORY_GOBJECT (EA_TYPE_AB_VIEW, ea_ab_view, ea_ab_view_new)
+
+static gboolean ea_addressbook_focus_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+
+void e_minicard_a11y_init (void)
+{
+ EA_SET_FACTORY (e_minicard_get_type (), ea_minicard);
+}
+
+void e_minicard_view_a11y_init (void)
+{
+ EA_SET_FACTORY (e_minicard_view_get_type (), ea_minicard_view);
+
+ if (atk_get_root ()) {
+ g_signal_add_emission_hook (
+ g_signal_lookup ("event",
+ e_minicard_get_type ()),
+ 0, ea_addressbook_focus_watcher,
+ NULL, (GDestroyNotify) NULL);
+ }
+}
+
+void eab_view_a11y_init (void)
+{
+ EA_SET_FACTORY (E_TYPE_ADDRESSBOOK_VIEW, ea_ab_view);
+}
+
+static gboolean
+ea_addressbook_focus_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ GdkEvent *event;
+ AtkObject *ea_event = NULL;
+
+ object = g_value_get_object (param_values + 0);
+ event = g_value_get_boxed (param_values + 1);
+
+ if (E_IS_MINICARD (object)) {
+ GnomeCanvasItem *item = GNOME_CANVAS_ITEM (object);
+ ea_event = atk_gobject_accessible_for_object (object);
+ if (event->type == GDK_FOCUS_CHANGE) {
+ if ((event->focus_change.in) &&
+ (E_IS_MINICARD (item->canvas->focused_item)))
+ atk_focus_tracker_notify (ea_event);
+ }
+ }
+
+ return TRUE;
+}
diff --git a/addressbook/gui/widgets/ea-addressbook.h b/addressbook/gui/widgets/ea-addressbook.h
new file mode 100644
index 0000000000..97b691dc18
--- /dev/null
+++ b/addressbook/gui/widgets/ea-addressbook.h
@@ -0,0 +1,33 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* Evolution Accessibility
+*/
+
+#ifndef _EA_ADDRESSBOOK_H__
+#define _EA_ADDRESSBOOK_H__
+
+void eab_view_a11y_init (void);
+void e_minicard_view_a11y_init (void);
+void e_minicard_a11y_init (void);
+
+#endif /* _EA_ADDRESSBOOK_H__ */
diff --git a/addressbook/gui/widgets/ea-minicard-view.c b/addressbook/gui/widgets/ea-minicard-view.c
new file mode 100644
index 0000000000..d1592df69e
--- /dev/null
+++ b/addressbook/gui/widgets/ea-minicard-view.c
@@ -0,0 +1,446 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Leon Zhang < leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include "ea-minicard.h"
+#include "ea-minicard-view.h"
+#include "eab-gui-util.h"
+#include "e-addressbook-view.h"
+
+static const gchar * action_name[] = {
+ N_("New Contact"),
+ N_("New Contact List")
+};
+
+static const gchar * ea_minicard_view_get_name (AtkObject *accessible);
+static const gchar * ea_minicard_view_get_description (AtkObject *accessible);
+
+static void ea_minicard_view_class_init (EaMinicardViewClass *klass);
+
+static gint ea_minicard_view_get_n_children (AtkObject *obj);
+static AtkObject *ea_minicard_view_ref_child (AtkObject *obj, gint i);
+
+static AtkStateSet *ea_minicard_view_ref_state_set (AtkObject *obj);
+
+static void atk_selection_interface_init (AtkSelectionIface *iface);
+static gboolean selection_interface_add_selection (AtkSelection *selection,
+ gint i);
+static gboolean selection_interface_clear_selection (AtkSelection *selection);
+static AtkObject * selection_interface_ref_selection (AtkSelection *selection,
+ gint i);
+static gint selection_interface_get_selection_count (AtkSelection *selection);
+static gboolean selection_interface_is_child_selected (AtkSelection *selection,
+ gint i);
+
+static void atk_action_interface_init (AtkActionIface *iface);
+static gboolean atk_action_interface_do_action (AtkAction *iface, gint i);
+static gint atk_action_interface_get_n_action (AtkAction *iface);
+static const gchar *
+ atk_action_interface_get_description
+ (AtkAction *iface,
+ gint i);
+static const gchar *
+ atk_action_interface_get_name (AtkAction *iface,
+ gint i);
+
+static gpointer parent_class = NULL;
+
+GType
+ea_minicard_view_get_type (void)
+{
+ static GType type = 0;
+ AtkObjectFactory *factory;
+ GTypeQuery query;
+ GType derived_atk_type;
+
+ if (!type) {
+ static GTypeInfo tinfo = {
+ sizeof (EaMinicardViewClass),
+ (GBaseInitFunc) NULL, /* base_init */
+ (GBaseFinalizeFunc) NULL, /* base_finalize */
+ (GClassInitFunc) ea_minicard_view_class_init,
+ (GClassFinalizeFunc) NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EaMinicardView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL, /* instance init */
+ NULL /* value table */
+ };
+
+ static const GInterfaceInfo atk_selection_info = {
+ (GInterfaceInitFunc) atk_selection_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ static const GInterfaceInfo atk_action_info = {
+ (GInterfaceInitFunc) atk_action_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ /*
+ * Figure out the size of the class and instance
+ * we are run-time deriving from (GailWidget, in this case) */
+
+ factory = atk_registry_get_factory (
+ atk_get_default_registry (),
+ GNOME_TYPE_CANVAS_GROUP);
+ derived_atk_type = atk_object_factory_get_accessible_type (factory);
+ g_type_query (derived_atk_type, &query);
+
+ tinfo.class_size = query.class_size;
+ tinfo.instance_size = query.instance_size;
+
+ type = g_type_register_static (
+ derived_atk_type,
+ "EaMinicardView", &tinfo, 0);
+ g_type_add_interface_static (
+ type, ATK_TYPE_SELECTION,
+ &atk_selection_info);
+ g_type_add_interface_static (
+ type, ATK_TYPE_ACTION,
+ &atk_action_info);
+
+ }
+
+ return type;
+}
+
+static void
+ea_minicard_view_class_init (EaMinicardViewClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ class->get_name = ea_minicard_view_get_name;
+ class->get_description = ea_minicard_view_get_description;
+ class->ref_state_set = ea_minicard_view_ref_state_set;
+ class->get_n_children = ea_minicard_view_get_n_children;
+ class->ref_child = ea_minicard_view_ref_child;
+}
+
+static const gchar *
+ea_minicard_view_get_name (AtkObject *accessible)
+{
+ EReflow *reflow;
+ gchar *string;
+ EMinicardView *card_view;
+ EBookClient *book_client = NULL;
+ ESource *source;
+ const gchar *display_name;
+
+ g_return_val_if_fail (EA_IS_MINICARD_VIEW (accessible), NULL);
+
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (
+ ATK_GOBJECT_ACCESSIBLE (accessible)));
+
+ if (!reflow)
+ return NULL;
+
+ /* Get the current name of minicard view*/
+ card_view = E_MINICARD_VIEW (reflow);
+ g_object_get (card_view->adapter, "client", &book_client, NULL);
+ g_return_val_if_fail (E_IS_BOOK_CLIENT (book_client), NULL);
+ source = e_client_get_source (E_CLIENT (book_client));
+ display_name = e_source_get_display_name (source);
+ if (display_name == NULL)
+ display_name = "";
+
+ string = g_strdup_printf (
+ ngettext ("current address book folder %s has %d card",
+ "current address book folder %s has %d cards",
+ reflow->count), display_name, reflow->count);
+
+ ATK_OBJECT_CLASS (parent_class)->set_name (accessible, string);
+ g_free (string);
+ g_object_unref (book_client);
+ return accessible->name;
+}
+
+static const gchar *
+ea_minicard_view_get_description (AtkObject *accessible)
+{
+ g_return_val_if_fail (EA_IS_MINICARD_VIEW (accessible), NULL);
+ if (accessible->description)
+ return accessible->description;
+
+ return _("evolution address book");
+}
+
+AtkObject *
+ea_minicard_view_new (GObject *obj)
+{
+ GObject *object;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (E_IS_MINICARD_VIEW (obj), NULL);
+ object = g_object_new (EA_TYPE_MINICARD_VIEW, NULL);
+ accessible = ATK_OBJECT (object);
+ atk_object_initialize (accessible, obj);
+ accessible->role = ATK_ROLE_PANEL;
+ return accessible;
+}
+
+static gint
+ea_minicard_view_get_n_children (AtkObject *accessible)
+{
+ EReflow *reflow;
+
+ gint child_num = 0;
+
+ g_return_val_if_fail (EA_IS_MINICARD_VIEW (accessible), -1);
+
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (
+ ATK_GOBJECT_ACCESSIBLE (accessible)));
+
+ if (!reflow)
+ return -1;
+
+ child_num = reflow->count;
+
+ return child_num;
+}
+
+static AtkStateSet *ea_minicard_view_ref_state_set (AtkObject *obj)
+{
+ AtkStateSet *state_set = NULL;
+ GObject *gobj = NULL;
+
+ state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (obj);
+ if (!state_set)
+ state_set = atk_state_set_new ();
+
+ gobj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (obj));
+ if (!gobj)
+ return state_set;
+
+ atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
+ atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
+
+ return state_set;
+}
+
+static AtkObject *
+ea_minicard_view_ref_child (AtkObject *accessible,
+ gint index)
+{
+ EReflow *reflow;
+ gint child_num;
+ AtkObject *atk_object = NULL;
+ EMinicard *card = NULL;
+
+ g_return_val_if_fail (EA_IS_MINICARD_VIEW (accessible), NULL);
+
+ child_num = atk_object_get_n_accessible_children (accessible);
+ if (child_num <= 0 || index < 0 || index >= child_num)
+ return NULL;
+
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (
+ ATK_GOBJECT_ACCESSIBLE (accessible)));
+ if (!reflow)
+ return NULL;
+ if (!reflow->items)
+ return NULL;
+ /* a minicard */
+ if (index < child_num) {
+ if (reflow->items[index] == NULL) {
+ reflow->items[index] = e_reflow_model_incarnate (reflow->model, index, GNOME_CANVAS_GROUP (reflow));
+ g_object_set (
+ reflow->items[index],
+ "width", (double) reflow->column_width,
+ NULL);
+ }
+ card = E_MINICARD (reflow->items[index]);
+ atk_object = atk_gobject_accessible_for_object (G_OBJECT (card));
+ } else {
+ return NULL;
+ }
+
+ g_object_ref (atk_object);
+ return atk_object;
+}
+
+/* atkselection interface */
+
+static void
+atk_selection_interface_init (AtkSelectionIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->add_selection = selection_interface_add_selection;
+ iface->clear_selection = selection_interface_clear_selection;
+ iface->ref_selection = selection_interface_ref_selection;
+ iface->get_selection_count = selection_interface_get_selection_count;
+ iface->is_child_selected = selection_interface_is_child_selected;
+}
+
+static gboolean
+selection_interface_add_selection (AtkSelection *selection,
+ gint i)
+{
+ AtkGObjectAccessible *atk_gobj= NULL;
+ EReflow *reflow = NULL;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (selection);
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (atk_gobj));
+
+ if (!reflow)
+ return FALSE;
+
+ selection_interface_clear_selection (selection);
+ e_selection_model_select_single_row (reflow->selection, i);
+
+ return TRUE;
+}
+
+static gboolean
+selection_interface_clear_selection (AtkSelection *selection)
+{
+ AtkGObjectAccessible *atk_gobj = NULL;
+ EReflow *reflow = NULL;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (selection);
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (atk_gobj));
+
+ if (!reflow)
+ return FALSE;
+
+ e_selection_model_clear (reflow->selection);
+
+ return TRUE;
+}
+
+static AtkObject *
+selection_interface_ref_selection (AtkSelection *selection,
+ gint i)
+{
+ return ea_minicard_view_ref_child (ATK_OBJECT (selection), i);
+}
+
+static gint
+selection_interface_get_selection_count (AtkSelection *selection)
+{
+ AtkGObjectAccessible *atk_gobj = NULL;
+ EReflow *reflow = NULL;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (selection);
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (atk_gobj));
+
+ if (!reflow)
+ return FALSE;
+
+ return e_selection_model_selected_count (reflow->selection);
+}
+
+static gboolean
+selection_interface_is_child_selected (AtkSelection *selection,
+ gint i)
+{
+ AtkGObjectAccessible *atk_gobj = NULL;
+ EReflow *reflow = NULL;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (selection);
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (atk_gobj));
+
+ if (!reflow)
+ return FALSE;
+
+ return e_selection_model_is_row_selected (reflow->selection, i);
+}
+
+static void atk_action_interface_init (AtkActionIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->do_action = atk_action_interface_do_action;
+ iface->get_n_actions = atk_action_interface_get_n_action;
+ iface->get_description = atk_action_interface_get_description;
+ iface->get_name = atk_action_interface_get_name;
+}
+
+static gboolean
+atk_action_interface_do_action (AtkAction *action,
+ gint i)
+{
+ gboolean return_value = TRUE;
+ EMinicardView *card_view;
+
+ AtkGObjectAccessible *atk_gobj= NULL;
+ EReflow *reflow = NULL;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (action);
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (atk_gobj));
+
+ if (reflow == NULL)
+ return FALSE;
+
+ card_view = E_MINICARD_VIEW (reflow);
+
+ switch (i) {
+ case 0:
+ /* New Contact */
+ e_minicard_view_create_contact (card_view);
+ break;
+ case 1:
+ /* New Contact List */
+ e_minicard_view_create_contact_list (card_view);
+ break;
+ default:
+ return_value = FALSE;
+ break;
+ }
+
+ return return_value;
+}
+
+static gint
+atk_action_interface_get_n_action (AtkAction *iface)
+{
+ return G_N_ELEMENTS (action_name);
+}
+
+static const gchar *
+atk_action_interface_get_description (AtkAction *iface,
+ gint i)
+{
+ return atk_action_interface_get_name (iface, i);
+}
+
+static const gchar *
+atk_action_interface_get_name (AtkAction *iface,
+ gint i)
+{
+ if (i >= G_N_ELEMENTS (action_name) || i < 0)
+ return NULL;
+
+ return action_name[i];
+}
+
diff --git a/addressbook/gui/widgets/ea-minicard-view.h b/addressbook/gui/widgets/ea-minicard-view.h
new file mode 100644
index 0000000000..889674bb92
--- /dev/null
+++ b/addressbook/gui/widgets/ea-minicard-view.h
@@ -0,0 +1,56 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EA_MINICARD_VIEW_H__
+#define __EA_MINICARD_VIEW_H__
+
+#include <atk/atkgobjectaccessible.h>
+#include "e-minicard-view.h"
+
+G_BEGIN_DECLS
+
+#define EA_TYPE_MINICARD_VIEW (ea_minicard_view_get_type ())
+#define EA_MINICARD_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_MINICARD_VIEW, EaMinicardView))
+#define EA_MINICARD_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_MINICARD_VIEW, EaMiniCardViewClass))
+#define EA_IS_MINICARD_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_MINICARD_VIEW))
+#define EA_IS_MINICARD_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EA_TYPE_MINICARD_VIEW))
+
+typedef struct _EaMinicardView EaMinicardView;
+typedef struct _EaMinicardViewClass EaMinicardViewClass;
+
+struct _EaMinicardView
+{
+ AtkGObjectAccessible parent;
+};
+
+struct _EaMinicardViewClass
+{
+ AtkGObjectAccessibleClass parent_class;
+};
+
+GType ea_minicard_view_get_type (void);
+
+AtkObject * ea_minicard_view_new (GObject *obj);
+
+G_END_DECLS
+
+#endif /* __EA_MINICARD_VIEW_H__ */
diff --git a/addressbook/gui/widgets/ea-minicard.c b/addressbook/gui/widgets/ea-minicard.c
new file mode 100644
index 0000000000..cfa35db349
--- /dev/null
+++ b/addressbook/gui/widgets/ea-minicard.c
@@ -0,0 +1,303 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include "ea-minicard.h"
+#include "ea-minicard-view.h"
+#include "e-minicard.h"
+
+static const gchar * action_name[] = {
+ N_("Open")
+};
+
+static const gchar *
+ ea_minicard_get_name (AtkObject *accessible);
+static const gchar *
+ ea_minicard_get_description (AtkObject *accessible);
+
+static void ea_minicard_class_init (EaMinicardClass *klass);
+
+static gint ea_minicard_get_n_children (AtkObject *obj);
+static AtkObject *
+ ea_minicard_ref_child (AtkObject *obj,
+ gint i);
+
+static AtkStateSet *
+ ea_minicard_ref_state_set (AtkObject *obj);
+
+static void atk_action_interface_init (AtkActionIface *iface);
+static gboolean atk_action_interface_do_action (AtkAction *iface,
+ gint i);
+static gint atk_action_interface_get_n_action
+ (AtkAction *iface);
+static const gchar *
+ atk_action_interface_get_description
+ (AtkAction *iface,
+ gint i);
+static const gchar *
+ atk_action_interface_get_name (AtkAction *iface,
+ gint i);
+
+static gpointer parent_class = NULL;
+
+GType
+ea_minicard_get_type (void)
+{
+ static GType type = 0;
+ AtkObjectFactory *factory;
+ GTypeQuery query;
+ GType derived_atk_type;
+
+ if (!type) {
+ static GTypeInfo tinfo = {
+ sizeof (EaMinicardClass),
+ (GBaseInitFunc) NULL, /* base_init */
+ (GBaseFinalizeFunc) NULL, /* base_finalize */
+ (GClassInitFunc) ea_minicard_class_init,
+ (GClassFinalizeFunc) NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EaMinicard),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL, /* instance init */
+ NULL /* value table */
+ };
+
+ static const GInterfaceInfo atk_action_info = {
+ (GInterfaceInitFunc) atk_action_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ /*
+ * Figure out the size of the class and instance
+ * we are run-time deriving from (GailWidget, in this case)
+ */
+
+ factory = atk_registry_get_factory (
+ atk_get_default_registry (),
+ GNOME_TYPE_CANVAS_GROUP);
+ derived_atk_type = atk_object_factory_get_accessible_type (factory);
+ g_type_query (derived_atk_type, &query);
+
+ tinfo.class_size = query.class_size;
+ tinfo.instance_size = query.instance_size;
+
+ type = g_type_register_static (
+ derived_atk_type,
+ "EaMinicard", &tinfo, 0);
+ g_type_add_interface_static (
+ type, ATK_TYPE_ACTION,
+ &atk_action_info);
+ }
+
+ return type;
+}
+
+static void
+ea_minicard_class_init (EaMinicardClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ class->get_name = ea_minicard_get_name;
+ class->get_description = ea_minicard_get_description;
+ class->ref_state_set = ea_minicard_ref_state_set;
+ class->get_n_children = ea_minicard_get_n_children;
+ class->ref_child = ea_minicard_ref_child;
+}
+
+/*
+ * we access the main content of current minicard, including
+ * header text, label(field, field name)
+ */
+static const gchar *
+ea_minicard_get_name (AtkObject *accessible)
+{
+#define BUFFERSIZE 500
+
+ static gchar name[BUFFERSIZE + 1];
+ GString *new_str = g_string_new (NULL);
+ gchar *string;
+ EMinicard *card;
+
+ g_return_val_if_fail (EA_IS_MINICARD (accessible), NULL);
+ memset (name, '\0', BUFFERSIZE);
+
+ card = E_MINICARD (
+ atk_gobject_accessible_get_object (
+ ATK_GOBJECT_ACCESSIBLE (accessible)));
+ if (!card)
+ return NULL;
+
+ g_object_get (card->header_text, "text", &string, NULL);
+
+ if (e_contact_get (card->contact, E_CONTACT_IS_LIST))
+ g_string_append (new_str, _("Contact List: "));
+ else g_string_append (new_str, _("Contact: "));
+
+ /* get header of current card */
+ g_string_append (new_str, string);
+ g_free (string);
+
+ /* if there exist no enough space for remain info, return */
+ if (new_str->len >= BUFFERSIZE) {
+ strncpy (name, new_str->str, BUFFERSIZE);
+ name[BUFFERSIZE] = '\0';
+ return name;
+ }
+
+ strcpy (name, new_str->str);
+ g_string_free (new_str, TRUE);
+
+ ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name);
+
+ return accessible->name;
+}
+
+static const gchar *
+ea_minicard_get_description (AtkObject *accessible)
+{
+ if (accessible->description)
+ return accessible->description;
+
+ return _("evolution minicard");
+}
+
+AtkObject *
+ea_minicard_new (GObject *obj)
+{
+ GObject *object;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (obj != NULL, NULL);
+ g_return_val_if_fail (E_IS_MINICARD (obj), NULL);
+
+ object = g_object_new (EA_TYPE_MINICARD, NULL);
+ accessible = ATK_OBJECT (object);
+ atk_object_initialize (accessible, obj);
+
+ accessible->role = ATK_ROLE_PANEL;
+ return accessible;
+}
+
+static AtkStateSet *
+ea_minicard_ref_state_set (AtkObject *obj)
+{
+ AtkStateSet *state_set = NULL;
+ GObject *gobj = NULL;
+
+ state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (obj);
+ if (!state_set)
+ state_set = atk_state_set_new ();
+
+ gobj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (obj));
+ if (!gobj)
+ return state_set;
+
+ atk_state_set_add_state (state_set, ATK_STATE_SELECTABLE);
+ atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
+ atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
+
+ return state_set;
+}
+
+static gint
+ea_minicard_get_n_children (AtkObject *accessible)
+{
+ return 0;
+}
+
+static AtkObject *
+ea_minicard_ref_child (AtkObject *accessible,
+ gint index)
+{
+ return NULL;
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->do_action = atk_action_interface_do_action;
+ iface->get_n_actions = atk_action_interface_get_n_action;
+ iface->get_description = atk_action_interface_get_description;
+ iface->get_name = atk_action_interface_get_name;
+}
+
+static gboolean
+atk_action_interface_do_action (AtkAction *iface,
+ gint i)
+{
+ EMinicard *minicard = NULL;
+
+ minicard = E_MINICARD (
+ atk_gobject_accessible_get_object (
+ ATK_GOBJECT_ACCESSIBLE (iface)));
+ if (minicard == NULL)
+ return FALSE;
+
+ if (i >= G_N_ELEMENTS (action_name) || i < 0)
+ return FALSE;
+
+ switch (i) {
+ /* open card */
+ case 0:
+ e_minicard_activate_editor (minicard);
+ break;
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gint
+atk_action_interface_get_n_action (AtkAction *iface)
+{
+ return G_N_ELEMENTS (action_name);
+}
+
+static const gchar *
+atk_action_interface_get_description (AtkAction *iface,
+ gint i)
+{
+ return atk_action_interface_get_name (iface, i);
+}
+
+static const gchar *
+atk_action_interface_get_name (AtkAction *iface,
+ gint i)
+{
+ if (i >= G_N_ELEMENTS (action_name) || i < 0)
+ return NULL;
+
+ return action_name[i];
+}
+
diff --git a/addressbook/gui/widgets/ea-minicard.h b/addressbook/gui/widgets/ea-minicard.h
new file mode 100644
index 0000000000..ea27158011
--- /dev/null
+++ b/addressbook/gui/widgets/ea-minicard.h
@@ -0,0 +1,56 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EA_MINICARD_H__
+#define __EA_MINICARD_H__
+
+#include <atk/atkgobjectaccessible.h>
+#include "e-minicard.h"
+#include "e-minicard-label.h"
+
+G_BEGIN_DECLS
+
+#define EA_TYPE_MINICARD (ea_minicard_get_type ())
+#define EA_MINICARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_MINICARD, EaMinicard))
+#define EA_MINICARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_MINICARD, EaMiniCardClass))
+#define EA_IS_MINICARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_MINICARD))
+#define EA_IS_MINICARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EA_TYPE_MINICARD))
+
+typedef struct _EaMinicard EaMinicard;
+typedef struct _EaMinicardClass EaMinicardClass;
+
+struct _EaMinicard
+{
+ AtkGObjectAccessible parent;
+};
+
+struct _EaMinicardClass
+{
+ AtkGObjectAccessibleClass parent_class;
+};
+
+GType ea_minicard_get_type (void);
+AtkObject * ea_minicard_new (GObject *obj);
+
+G_END_DECLS
+
+#endif /* __EA_MINICARD_H__ */
diff --git a/addressbook/gui/widgets/eab-config.c b/addressbook/gui/widgets/eab-config.c
new file mode 100644
index 0000000000..ad15f1cca9
--- /dev/null
+++ b/addressbook/gui/widgets/eab-config.c
@@ -0,0 +1,160 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * David Trowbridge <trowbrds@cs.colorado.edu>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "eab-config.h"
+
+#define EAB_CONFIG_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EAB_TYPE_CONFIG, EABConfigPrivate))
+
+struct _EABConfigPrivate {
+ guint source_changed_id;
+};
+
+G_DEFINE_TYPE (EABConfig, eab_config, E_TYPE_CONFIG)
+
+static void
+eab_config_init (EABConfig *cfg)
+{
+ cfg->priv = EAB_CONFIG_GET_PRIVATE (cfg);
+}
+
+static void
+ecp_target_free (EConfig *ec,
+ EConfigTarget *t)
+{
+ struct _EABConfigPrivate *p = EAB_CONFIG (ec)->priv;
+
+ if (ec->target == t) {
+ switch (t->type) {
+ case EAB_CONFIG_TARGET_SOURCE: {
+ EABConfigTargetSource *s = (EABConfigTargetSource *) t;
+
+ if (p->source_changed_id) {
+ g_signal_handler_disconnect (s->source, p->source_changed_id);
+ p->source_changed_id = 0;
+ }
+ break; }
+ case EAB_CONFIG_TARGET_PREFS:
+ break;
+ }
+ }
+
+ switch (t->type) {
+ case EAB_CONFIG_TARGET_SOURCE: {
+ EABConfigTargetSource *s = (EABConfigTargetSource *) t;
+
+ if (s->source)
+ g_object_unref (s->source);
+ break; }
+ case EAB_CONFIG_TARGET_PREFS: {
+ EABConfigTargetPrefs *s = (EABConfigTargetPrefs *) t;
+
+ if (s->settings)
+ g_object_unref (s->settings);
+ break; }
+ }
+
+ ((EConfigClass *) eab_config_parent_class)->target_free (ec, t);
+}
+
+static void
+ecp_source_changed (ESource *source,
+ EConfig *ec)
+{
+ e_config_target_changed (ec, E_CONFIG_TARGET_CHANGED_STATE);
+}
+
+static void
+ecp_set_target (EConfig *ec,
+ EConfigTarget *t)
+{
+ struct _EABConfigPrivate *p = EAB_CONFIG_GET_PRIVATE (ec);
+
+ ((EConfigClass *) eab_config_parent_class)->set_target (ec, t);
+
+ if (t) {
+ switch (t->type) {
+ case EAB_CONFIG_TARGET_SOURCE: {
+ EABConfigTargetSource *s = (EABConfigTargetSource *) t;
+
+ p->source_changed_id = g_signal_connect (
+ s->source, "changed",
+ G_CALLBACK (ecp_source_changed), ec);
+ break; }
+ case EAB_CONFIG_TARGET_PREFS:
+ break;
+ }
+ }
+}
+
+static void
+eab_config_class_init (EABConfigClass *class)
+{
+ EConfigClass *config_class;
+
+ g_type_class_add_private (class, sizeof (struct _EABConfigPrivate));
+
+ config_class = E_CONFIG_CLASS (class);
+ config_class->set_target = ecp_set_target;
+ config_class->target_free = ecp_target_free;
+}
+
+EABConfig *
+eab_config_new (const gchar *menuid)
+{
+ EABConfig *ecp = g_object_new (eab_config_get_type (), NULL);
+ e_config_construct (&ecp->config, menuid);
+ return ecp;
+}
+
+EABConfigTargetSource *
+eab_config_target_new_source (EABConfig *ecp,
+ ESource *source)
+{
+ EABConfigTargetSource *t = e_config_target_new (
+ &ecp->config, EAB_CONFIG_TARGET_SOURCE, sizeof (*t));
+
+ t->source = source;
+ g_object_ref (source);
+
+ return t;
+}
+
+EABConfigTargetPrefs *
+eab_config_target_new_prefs (EABConfig *ecp,
+ GSettings *settings)
+{
+ EABConfigTargetPrefs *t = e_config_target_new (
+ &ecp->config, EAB_CONFIG_TARGET_PREFS, sizeof (*t));
+
+ if (settings)
+ t->settings = g_object_ref (settings);
+ else
+ t->settings = NULL;
+
+ return t;
+}
diff --git a/addressbook/gui/widgets/eab-config.h b/addressbook/gui/widgets/eab-config.h
new file mode 100644
index 0000000000..55612ec65a
--- /dev/null
+++ b/addressbook/gui/widgets/eab-config.h
@@ -0,0 +1,82 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * David Trowbridge <trowbrds@cs.colorado.edu>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EAB_CONFIG_H__
+#define __EAB_CONFIG_H__
+
+#include <libedataserver/libedataserver.h>
+
+#include <e-util/e-util.h>
+
+#define EAB_TYPE_CONFIG (eab_config_get_type ())
+#define EAB_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EAB_TYPE_CONFIG, EABConfig))
+
+G_BEGIN_DECLS
+
+typedef struct _EABConfig EABConfig;
+typedef struct _EABConfigClass EABConfigClass;
+typedef struct _EABConfigPrivate EABConfigPrivate;
+
+struct _EABConfig {
+ EConfig config;
+
+ EABConfigPrivate *priv;
+};
+
+struct _EABConfigClass {
+ EConfigClass config_class;
+};
+
+enum _eab_config_target_t {
+ EAB_CONFIG_TARGET_SOURCE,
+ EAB_CONFIG_TARGET_PREFS
+};
+
+typedef struct _EABConfigTargetSource EABConfigTargetSource;
+
+struct _EABConfigTargetSource {
+ EConfigTarget target;
+
+ ESource *source;
+};
+
+typedef struct _EABConfigTargetPrefs EABConfigTargetPrefs;
+
+struct _EABConfigTargetPrefs {
+ EConfigTarget target;
+
+ /* preferences are global from GSettings */
+ GSettings *settings;
+};
+
+typedef struct _EConfigItem EABConfigItem;
+
+GType eab_config_get_type (void);
+EABConfig *eab_config_new (const gchar *menuid);
+
+EABConfigTargetSource *eab_config_target_new_source (EABConfig *ecp, ESource *source);
+EABConfigTargetPrefs *eab_config_target_new_prefs (EABConfig *ecp, GSettings *settings);
+
+G_END_DECLS
+
+#endif
diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c
new file mode 100644
index 0000000000..c467e385e4
--- /dev/null
+++ b/addressbook/gui/widgets/eab-contact-display.c
@@ -0,0 +1,626 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "eab-contact-display.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include <webkit/webkit.h>
+
+#include "e-contact-map.h"
+#include "eab-contact-formatter.h"
+#include "eab-gui-util.h"
+
+#define EAB_CONTACT_DISPLAY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplayPrivate))
+
+#define TEXT_IS_RIGHT_TO_LEFT \
+ (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
+
+struct _EABContactDisplayPrivate {
+ EContact *contact;
+
+ EABContactDisplayMode mode;
+ gboolean show_maps;
+};
+
+enum {
+ PROP_0,
+ PROP_CONTACT,
+ PROP_MODE,
+ PROP_SHOW_MAPS
+};
+
+enum {
+ SEND_MESSAGE,
+ LAST_SIGNAL
+};
+
+static const gchar *ui =
+"<ui>"
+" <popup name='context'>"
+" <placeholder name='custom-actions-1'>"
+" <menuitem action='contact-send-message'/>"
+" </placeholder>"
+" <placeholder name='custom-actions-2'>"
+" <menuitem action='contact-mailto-copy'/>"
+" </placeholder>"
+" </popup>"
+"</ui>";
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (
+ EABContactDisplay,
+ eab_contact_display,
+ E_TYPE_WEB_VIEW)
+
+static void
+contact_display_emit_send_message (EABContactDisplay *display,
+ gint email_num)
+{
+ EDestination *destination;
+ EContact *contact;
+
+ g_return_if_fail (email_num >= 0);
+
+ destination = e_destination_new ();
+ contact = eab_contact_display_get_contact (display);
+ e_destination_set_contact (destination, contact, email_num);
+ g_signal_emit (display, signals[SEND_MESSAGE], 0, destination);
+ g_object_unref (destination);
+}
+
+static void
+action_contact_mailto_copy_cb (GtkAction *action,
+ EABContactDisplay *display)
+{
+ GtkClipboard *clipboard;
+ EWebView *web_view;
+ EContact *contact;
+ GList *list;
+ const gchar *text;
+ const gchar *uri;
+ gint index;
+
+ web_view = E_WEB_VIEW (display);
+ uri = e_web_view_get_selected_uri (web_view);
+ g_return_if_fail (uri != NULL);
+
+ index = atoi (uri + strlen ("internal-mailto:"));
+ g_return_if_fail (index >= 0);
+
+ contact = eab_contact_display_get_contact (display);
+ list = e_contact_get (contact, E_CONTACT_EMAIL);
+ text = g_list_nth_data (list, index);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text (clipboard, text, -1);
+ gtk_clipboard_store (clipboard);
+
+ g_list_foreach (list, (GFunc) g_free, NULL);
+ g_list_free (list);
+}
+
+static void
+action_contact_send_message_cb (GtkAction *action,
+ EABContactDisplay *display)
+{
+ EWebView *web_view;
+ const gchar *uri;
+ gint index;
+
+ web_view = E_WEB_VIEW (display);
+ uri = e_web_view_get_selected_uri (web_view);
+ g_return_if_fail (uri != NULL);
+
+ index = atoi (uri + strlen ("internal-mailto:"));
+ contact_display_emit_send_message (display, index);
+}
+
+static GtkActionEntry internal_mailto_entries[] = {
+
+ { "contact-mailto-copy",
+ GTK_STOCK_COPY,
+ N_("Copy _Email Address"),
+ NULL,
+ N_("Copy the email address to the clipboard"),
+ G_CALLBACK (action_contact_mailto_copy_cb) },
+
+ { "contact-send-message",
+ "mail-message-new",
+ N_("_Send New Message To..."),
+ NULL,
+ N_("Send a mail message to this address"),
+ G_CALLBACK (action_contact_send_message_cb) }
+};
+
+static void
+load_contact (EABContactDisplay *display)
+{
+ EABContactFormatter *formatter;
+ GString *buffer;
+
+ if (!display->priv->contact) {
+ e_web_view_clear (E_WEB_VIEW (display));
+ return;
+ }
+
+ formatter = eab_contact_formatter_new ();
+ g_object_set (
+ G_OBJECT (formatter),
+ "display-mode", display->priv->mode,
+ "render-maps", display->priv->show_maps,
+ NULL);
+
+ buffer = g_string_sized_new (1024);
+
+ eab_contact_formatter_format_contact (
+ formatter, display->priv->contact, buffer);
+ e_web_view_load_string (E_WEB_VIEW (display), buffer->str);
+
+ g_string_free (buffer, TRUE);
+
+ g_object_unref (formatter);
+}
+
+static void
+contact_display_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CONTACT:
+ eab_contact_display_set_contact (
+ EAB_CONTACT_DISPLAY (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_MODE:
+ eab_contact_display_set_mode (
+ EAB_CONTACT_DISPLAY (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_SHOW_MAPS:
+ eab_contact_display_set_show_maps (
+ EAB_CONTACT_DISPLAY (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+contact_display_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CONTACT:
+ g_value_set_object (
+ value, eab_contact_display_get_contact (
+ EAB_CONTACT_DISPLAY (object)));
+ return;
+
+ case PROP_MODE:
+ g_value_set_int (
+ value, eab_contact_display_get_mode (
+ EAB_CONTACT_DISPLAY (object)));
+ return;
+
+ case PROP_SHOW_MAPS:
+ g_value_set_boolean (
+ value, eab_contact_display_get_show_maps (
+ EAB_CONTACT_DISPLAY (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+contact_display_dispose (GObject *object)
+{
+ EABContactDisplayPrivate *priv;
+
+ priv = EAB_CONTACT_DISPLAY_GET_PRIVATE (object);
+
+ if (priv->contact != NULL) {
+ g_object_unref (priv->contact);
+ priv->contact = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (eab_contact_display_parent_class)->dispose (object);
+}
+
+static void
+contact_display_hovering_over_link (EWebView *web_view,
+ const gchar *title,
+ const gchar *uri)
+{
+ EWebViewClass *web_view_class;
+ EABContactDisplay *display;
+ EContact *contact;
+ const gchar *name;
+ gchar *message;
+
+ if (uri == NULL || *uri == '\0')
+ goto chainup;
+
+ if (!g_str_has_prefix (uri, "internal-mailto:"))
+ goto chainup;
+
+ display = EAB_CONTACT_DISPLAY (web_view);
+ contact = eab_contact_display_get_contact (display);
+
+ name = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ if (name == NULL)
+ e_contact_get_const (contact, E_CONTACT_FULL_NAME);
+ g_return_if_fail (name != NULL);
+
+ message = g_strdup_printf (_("Click to mail %s"), name);
+ e_web_view_status_message (web_view, message);
+ g_free (message);
+
+ return;
+
+chainup:
+ /* Chain up to parent's hovering_over_link() method. */
+ web_view_class = E_WEB_VIEW_CLASS (eab_contact_display_parent_class);
+ web_view_class->hovering_over_link (web_view, title, uri);
+}
+
+static void
+contact_display_link_clicked (EWebView *web_view,
+ const gchar *uri)
+{
+ EABContactDisplay *display;
+ gsize length;
+
+ display = EAB_CONTACT_DISPLAY (web_view);
+
+ length = strlen ("internal-mailto:");
+ if (g_ascii_strncasecmp (uri, "internal-mailto:", length) == 0) {
+ gint index;
+
+ index = atoi (uri + length);
+ contact_display_emit_send_message (display, index);
+ return;
+ }
+
+ /* Chain up to parent's link_clicked() method. */
+ E_WEB_VIEW_CLASS (eab_contact_display_parent_class)->
+ link_clicked (web_view, uri);
+}
+
+#ifdef WITH_CONTACT_MAPS
+/* XXX Clutter event handling workaround. Clutter-gtk propagates events down
+ * to parent widgets. In this case it leads to GtkHTML scrolling up and
+ * down while user's trying to zoom in the champlain widget. This
+ * workaround stops the propagation from map widget down to GtkHTML. */
+static gboolean
+handle_map_scroll_event (GtkWidget *widget,
+ GdkEvent *event)
+{
+ return TRUE;
+}
+
+static GtkWidget *
+contact_display_object_requested (WebKitWebView *web_view,
+ gchar *mime_type,
+ gchar *uri,
+ GHashTable *param,
+ EABContactDisplay *display)
+{
+ EContact *contact = display->priv->contact;
+ const gchar *name = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ const gchar *contact_uid = e_contact_get_const (contact, E_CONTACT_UID);
+ gchar *full_name;
+ EContactAddress *address;
+ GtkWidget *map = NULL;
+
+ if (strstr (mime_type, "work") != NULL) {
+ address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK);
+ full_name = g_strconcat (name, " (", _("Work"), ")", NULL);
+ } else if (strstr (mime_type, "home") != NULL) {
+ address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME);
+ full_name = g_strconcat (name, " (", _("Home"), ")", NULL);
+ }
+
+ if (address) {
+ map = e_contact_map_new ();
+ gtk_widget_set_size_request (map, 250, 250);
+ g_signal_connect (
+ E_CONTACT_MAP (map), "contact-added",
+ G_CALLBACK (e_contact_map_zoom_on_marker), NULL);
+ g_signal_connect_swapped (
+ E_CONTACT_MAP (map), "contact-added",
+ G_CALLBACK (gtk_widget_show_all), map);
+ g_signal_connect (
+ GTK_CHAMPLAIN_EMBED (map), "scroll-event",
+ G_CALLBACK (handle_map_scroll_event), NULL);
+
+ /* No need to display photo in contact preview. */
+ e_contact_map_add_marker (
+ E_CONTACT_MAP (map), full_name,
+ contact_uid, address, NULL);
+
+ gtk_widget_show_all (map);
+
+ e_contact_address_free (address);
+ }
+
+ g_free (full_name);
+
+ return map;
+}
+#endif
+
+static void
+contact_display_load_status_changed (WebKitWebView *web_view,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ WebKitLoadStatus load_status;
+ WebKitDOMDocument *document;
+
+ load_status = webkit_web_view_get_load_status (web_view);
+ if (load_status != WEBKIT_LOAD_FINISHED)
+ return;
+
+ document = webkit_web_view_get_dom_document (web_view);
+ eab_contact_formatter_bind_dom (document);
+}
+
+static void
+contact_display_update_actions (EWebView *web_view)
+{
+ GtkActionGroup *action_group;
+ gboolean scheme_is_internal_mailto;
+ gboolean visible;
+ const gchar *group_name;
+ const gchar *uri;
+
+ /* Chain up to parent's update_actions() method. */
+ E_WEB_VIEW_CLASS (eab_contact_display_parent_class)->
+ update_actions (web_view);
+
+ uri = e_web_view_get_selected_uri (web_view);
+
+ scheme_is_internal_mailto = (uri == NULL) ? FALSE :
+ (g_ascii_strncasecmp (uri, "internal-mailto:", 16) == 0);
+
+ /* Override how EWebView treats internal-mailto URIs. */
+ group_name = "uri";
+ action_group = e_web_view_get_action_group (web_view, group_name);
+ visible = gtk_action_group_get_visible (action_group);
+ visible &= !scheme_is_internal_mailto;
+ gtk_action_group_set_visible (action_group, visible);
+
+ group_name = "internal-mailto";
+ visible = scheme_is_internal_mailto;
+ action_group = e_web_view_get_action_group (web_view, group_name);
+ gtk_action_group_set_visible (action_group, visible);
+}
+
+static void
+eab_contact_display_class_init (EABContactDisplayClass *class)
+{
+ GObjectClass *object_class;
+ EWebViewClass *web_view_class;
+
+ g_type_class_add_private (class, sizeof (EABContactDisplayPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = contact_display_set_property;
+ object_class->get_property = contact_display_get_property;
+ object_class->dispose = contact_display_dispose;
+
+ web_view_class = E_WEB_VIEW_CLASS (class);
+ web_view_class->hovering_over_link = contact_display_hovering_over_link;
+ web_view_class->link_clicked = contact_display_link_clicked;
+ web_view_class->update_actions = contact_display_update_actions;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CONTACT,
+ g_param_spec_object (
+ "contact",
+ NULL,
+ NULL,
+ E_TYPE_CONTACT,
+ G_PARAM_READWRITE));
+
+ /* XXX Make this a real enum property. */
+ g_object_class_install_property (
+ object_class,
+ PROP_MODE,
+ g_param_spec_int (
+ "mode",
+ NULL,
+ NULL,
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL,
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT,
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_MAPS,
+ g_param_spec_boolean (
+ "show-maps",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ signals[SEND_MESSAGE] = g_signal_new (
+ "send-message",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EABContactDisplayClass, send_message),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_DESTINATION);
+}
+
+static void
+eab_contact_display_init (EABContactDisplay *display)
+{
+ EWebView *web_view;
+ GtkUIManager *ui_manager;
+ GtkActionGroup *action_group;
+ const gchar *domain = GETTEXT_PACKAGE;
+ GError *error = NULL;
+
+ display->priv = EAB_CONTACT_DISPLAY_GET_PRIVATE (display);
+
+ web_view = E_WEB_VIEW (display);
+ ui_manager = e_web_view_get_ui_manager (web_view);
+
+#ifdef WITH_CONTACT_MAPS
+ g_signal_connect (
+ web_view, "create-plugin-widget",
+ G_CALLBACK (contact_display_object_requested), display);
+#endif
+ g_signal_connect (
+ web_view, "notify::load-status",
+ G_CALLBACK (contact_display_load_status_changed), NULL);
+ g_signal_connect (
+ web_view, "style-set",
+ G_CALLBACK (load_contact), NULL);
+
+ e_web_view_install_request_handler (E_WEB_VIEW (display), E_TYPE_FILE_REQUEST);
+ e_web_view_install_request_handler (E_WEB_VIEW (display), E_TYPE_STOCK_REQUEST);
+
+ action_group = gtk_action_group_new ("internal-mailto");
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
+ g_object_unref (action_group);
+
+ gtk_action_group_add_actions (
+ action_group, internal_mailto_entries,
+ G_N_ELEMENTS (internal_mailto_entries), display);
+
+ /* Because we are loading from a hard-coded string, there is
+ * no chance of I/O errors. Failure here implies a malformed
+ * UI definition. Full stop. */
+ gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
+ if (error != NULL)
+ g_error ("%s", error->message);
+}
+
+GtkWidget *
+eab_contact_display_new (void)
+{
+ return g_object_new (EAB_TYPE_CONTACT_DISPLAY, NULL);
+}
+
+EContact *
+eab_contact_display_get_contact (EABContactDisplay *display)
+{
+ g_return_val_if_fail (EAB_IS_CONTACT_DISPLAY (display), NULL);
+
+ return display->priv->contact;
+}
+
+void
+eab_contact_display_set_contact (EABContactDisplay *display,
+ EContact *contact)
+{
+ g_return_if_fail (EAB_IS_CONTACT_DISPLAY (display));
+
+ if (display->priv->contact == contact)
+ return;
+
+ if (contact != NULL)
+ g_object_ref (contact);
+
+ if (display->priv->contact != NULL)
+ g_object_unref (display->priv->contact);
+
+ display->priv->contact = contact;
+
+ load_contact (display);
+
+ g_object_notify (G_OBJECT (display), "contact");
+}
+
+EABContactDisplayMode
+eab_contact_display_get_mode (EABContactDisplay *display)
+{
+ g_return_val_if_fail (EAB_IS_CONTACT_DISPLAY (display), 0);
+
+ return display->priv->mode;
+}
+
+void
+eab_contact_display_set_mode (EABContactDisplay *display,
+ EABContactDisplayMode mode)
+{
+ g_return_if_fail (EAB_IS_CONTACT_DISPLAY (display));
+
+ if (display->priv->mode == mode)
+ return;
+
+ display->priv->mode = mode;
+
+ load_contact (display);
+
+ g_object_notify (G_OBJECT (display), "mode");
+}
+
+gboolean
+eab_contact_display_get_show_maps (EABContactDisplay *display)
+{
+ g_return_val_if_fail (EAB_IS_CONTACT_DISPLAY (display), FALSE);
+
+ return display->priv->show_maps;
+}
+
+void
+eab_contact_display_set_show_maps (EABContactDisplay *display,
+ gboolean show_maps)
+{
+ g_return_if_fail (EAB_IS_CONTACT_DISPLAY (display));
+
+ if (display->priv->show_maps == show_maps)
+ return;
+
+ display->priv->show_maps = show_maps;
+
+ load_contact (display);
+
+ g_object_notify (G_OBJECT (display), "show-maps");
+}
diff --git a/addressbook/gui/widgets/eab-contact-display.h b/addressbook/gui/widgets/eab-contact-display.h
new file mode 100644
index 0000000000..484e312b6b
--- /dev/null
+++ b/addressbook/gui/widgets/eab-contact-display.h
@@ -0,0 +1,103 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef EAB_CONTACT_DISPLAY_H
+#define EAB_CONTACT_DISPLAY_H
+
+#include <libebook/libebook.h>
+
+#include <e-util/e-util.h>
+
+/* Standard GObject macros */
+#define EAB_TYPE_CONTACT_DISPLAY \
+ (eab_contact_display_get_type ())
+#define EAB_CONTACT_DISPLAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplay))
+#define EAB_CONTACT_DISPLAY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplayClass))
+#define EAB_IS_CONTACT_DISPLAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EAB_TYPE_CONTACT_DISPLAY))
+#define EAB_IS_CONTACT_DISPLAY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EAB_TYPE_CONTACT_DISPLAY))
+#define EAB_CONTACT_DISPLAY_GET_CLASS(obj) \
+ (G_TYPE_ISNTANCE_GET_CLASS \
+ ((obj), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplayClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EABContactDisplay EABContactDisplay;
+typedef struct _EABContactDisplayClass EABContactDisplayClass;
+typedef struct _EABContactDisplayPrivate EABContactDisplayPrivate;
+
+/**
+ * EABContactDisplayMode:
+ * @EAB_CONTACT_DISPLAY_RENDER_NORMAL:
+ * For use in the preview pane.
+ * @EAB_CONTACT_DISPLAY_RENDER_COMPACT:
+ * For use with embedded vcards.
+ **/
+typedef enum {
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL,
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT
+} EABContactDisplayMode;
+
+struct _EABContactDisplay {
+ EWebView parent;
+ EABContactDisplayPrivate *priv;
+};
+
+struct _EABContactDisplayClass {
+ EWebViewClass parent_class;
+
+ /* Signals */
+ void (*send_message) (EABContactDisplay *display,
+ EDestination *destination);
+};
+
+GType eab_contact_display_get_type (void);
+GtkWidget * eab_contact_display_new (void);
+
+EContact * eab_contact_display_get_contact (EABContactDisplay *display);
+void eab_contact_display_set_contact (EABContactDisplay *display,
+ EContact *contact);
+EABContactDisplayMode
+ eab_contact_display_get_mode (EABContactDisplay *display);
+void eab_contact_display_set_mode (EABContactDisplay *display,
+ EABContactDisplayMode mode);
+GtkOrientation eab_contact_display_get_orientation
+ (EABContactDisplay *display);
+void eab_contact_display_set_orientation
+ (EABContactDisplay *display,
+ GtkOrientation orientation);
+gboolean eab_contact_display_get_show_maps
+ (EABContactDisplay *display);
+void eab_contact_display_set_show_maps
+ (EABContactDisplay *display,
+ gboolean display_maps);
+
+G_END_DECLS
+
+#endif /* EAB_CONTACT_DISPLAY_H */
diff --git a/addressbook/gui/widgets/eab-contact-formatter.c b/addressbook/gui/widgets/eab-contact-formatter.c
new file mode 100644
index 0000000000..60beefa5c3
--- /dev/null
+++ b/addressbook/gui/widgets/eab-contact-formatter.c
@@ -0,0 +1,1207 @@
+/*
+ * eab-contact-formatter.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#include "eab-contact-formatter.h"
+
+#include <config.h>
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include <e-util/e-util.h>
+
+#include "eab-book-util.h"
+#include "eab-gui-util.h"
+
+#define EAB_CONTACT_FORMATTER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EAB_TYPE_CONTACT_FORMATTER, EABContactFormatterPrivate))
+
+#define TEXT_IS_RIGHT_TO_LEFT \
+ (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
+
+#define IMAGE_COL_WIDTH "20"
+#define CONTACT_LIST_ICON "stock_contact-list"
+#define AIM_ICON "im-aim"
+#define GROUPWISE_ICON "im-nov"
+#define ICQ_ICON "im-icq"
+#define JABBER_ICON "im-jabber"
+#define MSN_ICON "im-msn"
+#define YAHOO_ICON "im-yahoo"
+#define GADUGADU_ICON "im-gadugadu"
+#define SKYPE_ICON "stock_people"
+#define TWITTER_ICON "im-twitter"
+#define VIDEOCONF_ICON "stock_video-conferencing"
+
+#define MAX_COMPACT_IMAGE_DIMENSION 48
+
+#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" \
+"<link type=\"text/css\" rel=\"stylesheet\" href=\"evo-file://" EVOLUTION_PRIVDATADIR "/theme/webview.css\">" \
+"<style type=\"text/css\">\n" \
+" div#header { width:100%; clear: both; }\n" \
+" div#columns { width: 100%; clear: both; }\n" \
+" div#footer { width: 100%; clear: both; }\n" \
+" div.column { width: auto; float: left; margin-right: 15px; }\n" \
+" img#contact-photo { float: left; }\n" \
+" div#contact-name { float: left; margin-left: 20px; }\n" \
+"</style>\n" \
+"</head>\n"
+
+struct _EABContactFormatterPrivate {
+ EABContactDisplayMode mode;
+ gboolean render_maps;
+};
+
+enum {
+ PROP_0,
+ PROP_DISPLAY_MODE,
+ PROP_RENDER_MAPS
+};
+
+static struct {
+ const gchar *name;
+ const gchar *pretty_name;
+} common_location[] = {
+ { "WORK", N_ ("Work") },
+ { "HOME", N_ ("Home") },
+ { "OTHER", N_ ("Other") }
+};
+
+G_DEFINE_TYPE (
+ EABContactFormatter,
+ eab_contact_formatter,
+ G_TYPE_OBJECT);
+
+static gboolean
+icon_available (const gchar *icon)
+{
+ GtkIconTheme *icon_theme;
+ GtkIconInfo *icon_info;
+
+ if (!icon)
+ return FALSE;
+
+ icon_theme = gtk_icon_theme_get_default ();
+ icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon, 16, 0);
+ if (icon_info != NULL)
+ gtk_icon_info_free (icon_info);
+
+ return icon_info != NULL;
+}
+
+static void
+render_address_link (GString *buffer,
+ EContact *contact,
+ gint map_type)
+{
+ EContactAddress *adr;
+ GString *link = g_string_new ("");
+
+ adr = e_contact_get (contact, map_type);
+ if (adr &&
+ (adr->street || adr->locality || adr->region || adr->country)) {
+ gchar *escaped;
+
+ if (adr->street && *adr->street)
+ g_string_append_printf (link, "%s, ", adr->street);
+
+ if (adr->locality && *adr->locality)
+ g_string_append_printf (link, "%s, ", adr->locality);
+
+ if (adr->region && *adr->region)
+ g_string_append_printf (link, "%s, ", adr->region);
+
+ if (adr->country && *adr->country)
+ g_string_append_printf (link, "%s", adr->country);
+
+ escaped = g_uri_escape_string (link->str, NULL, TRUE);
+ g_string_assign (link, escaped);
+ g_free (escaped);
+
+ g_string_prepend (link, "<a href=\"http://maps.google.com?q=");
+ g_string_append_printf (link, "\">%s</a>", _("Open map"));
+ }
+
+ if (adr)
+ e_contact_address_free (adr);
+
+ g_string_append (buffer, link->str);
+ g_string_free (link, TRUE);
+}
+
+static void
+accum_address (GString *buffer,
+ EContact *contact,
+ const gchar *html_label,
+ EContactField adr_field,
+ EContactField label_field)
+{
+ EContactAddress *adr;
+ const gchar *label;
+ GString *map_link = g_string_new ("<br>");
+
+ render_address_link (map_link, contact, adr_field);
+
+ label = e_contact_get_const (contact, label_field);
+ if (label) {
+ gchar *html = e_text_to_html (label, E_TEXT_TO_HTML_CONVERT_NL);
+
+ if (TEXT_IS_RIGHT_TO_LEFT) {
+ g_string_append_printf (
+ buffer,
+ "<tr>"
+ "<td align=\"right\" valign=\"top\" nowrap>%s</td>"
+ "<th>%s:<br>%s</th>"
+ "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\"></td>"
+ "</tr>",
+ html, html_label, map_link->str);
+ } else {
+ g_string_append_printf (
+ buffer,
+ "<tr>"
+ "<td width=\"" IMAGE_COL_WIDTH "\"></td>"
+ "<th>%s:<br>%s</th>"
+ "<td valign=\"top\" nowrap>%s</td>"
+ "</tr>",
+ html_label, map_link->str, html);
+ }
+
+ g_free (html);
+ g_string_free (map_link, TRUE);
+ return;
+ }
+
+ adr = e_contact_get (contact, adr_field);
+ if (adr &&
+ (adr->po || adr->ext || adr->street || adr->locality ||
+ adr->region || adr->code || adr->country)) {
+
+ if (TEXT_IS_RIGHT_TO_LEFT) {
+ g_string_append_printf (
+ buffer, "<tr><td align=\"right\" valign=\"top\" nowrap>");
+ } else {
+ g_string_append_printf (
+ buffer,
+ "<tr>"
+ "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\"></td>"
+ "<th>%s:<br>%s</th>"
+ "<td valign=\"top\" nowrap>",
+ html_label, map_link->str);
+ }
+
+ if (adr->po && *adr->po)
+ g_string_append_printf (buffer, "%s<br>", adr->po);
+
+ if (adr->ext && *adr->ext)
+ g_string_append_printf (buffer, "%s<br>", adr->ext);
+
+ if (adr->street && *adr->street)
+ g_string_append_printf (buffer, "%s<br>", adr->street);
+
+ if (adr->locality && *adr->locality)
+ g_string_append_printf (buffer, "%s<br>", adr->locality);
+
+ if (adr->region && *adr->region)
+ g_string_append_printf (buffer, "%s<br>", adr->region);
+
+ if (adr->code && *adr->code)
+ g_string_append_printf (buffer, "%s<br>", adr->code);
+
+ if (adr->country && *adr->country)
+ g_string_append_printf (buffer, "%s<br>", adr->country);
+
+ if (TEXT_IS_RIGHT_TO_LEFT) {
+ g_string_append_printf (
+ buffer,
+ "</td><th%s:<br>%s</th>"
+ "<td width=\"" IMAGE_COL_WIDTH "\"></td>"
+ "</tr>", html_label, map_link->str);
+ } else {
+ g_string_append_printf (buffer, "</td></tr>");
+ }
+
+ }
+
+ if (adr)
+ e_contact_address_free (adr);
+
+ g_string_free (map_link, TRUE);
+}
+
+static void
+render_table_row (GString *buffer,
+ const gchar *label,
+ const gchar *str,
+ const gchar *icon,
+ guint html_flags)
+{
+ const gchar *icon_html;
+ gchar *value;
+
+ if (html_flags)
+ value = e_text_to_html (str, html_flags);
+ else
+ value = (gchar *) str;
+
+ if (icon && icon_available (icon)) {
+ icon_html = g_strdup_printf ("<img src=\"gtk-stock://%s\" width=\"16\" height=\"16\" />", icon);
+ } else {
+ icon_html = "";
+ }
+
+ if (TEXT_IS_RIGHT_TO_LEFT) {
+ g_string_append_printf (
+ buffer, "<tr>"
+ "<td valign=\"top\" align=\"right\">%s</td>"
+ "<th align=\"right\" valign=\"top\" width=\"100\" nowrap>:%s</th>"
+ "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">%s</td>"
+ "</tr>",
+ value, label, icon_html);
+ } else {
+ g_string_append_printf (
+ buffer, "<tr>"
+ "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">%s</td>"
+ "<th valign=\"top\" width=\"100\" nowrap>%s:</th>"
+ "<td valign=\"top\">%s</td>"
+ "</tr>",
+ icon_html, label, value);
+ }
+
+ if (html_flags)
+ g_free (value);
+}
+
+static void
+accum_attribute (GString *buffer,
+ EContact *contact,
+ const gchar *html_label,
+ EContactField field,
+ const gchar *icon,
+ guint html_flags)
+{
+ const gchar *str;
+
+ str = e_contact_get_const (contact, field);
+
+ if (str != NULL && *str != '\0')
+ render_table_row (buffer, html_label, str, icon, html_flags);
+}
+
+static void
+accum_time_attribute (GString *buffer,
+ EContact *contact,
+ const gchar *html_label,
+ EContactField field,
+ const gchar *icon,
+ guint html_flags)
+{
+ EContactDate *date;
+ GDate *gdate = NULL;
+ gchar sdate[100];
+
+ date = e_contact_get (contact, field);
+ if (date) {
+ gdate = g_date_new_dmy (
+ date->day,
+ date->month,
+ date->year);
+ g_date_strftime (sdate, 100, "%x", gdate);
+ g_date_free (gdate);
+ render_table_row (buffer, html_label, sdate, icon, html_flags);
+ e_contact_date_free (date);
+ }
+}
+
+static void
+accum_attribute_multival (GString *buffer,
+ EContact *contact,
+ const gchar *html_label,
+ EContactField field,
+ const gchar *icon,
+ guint html_flags)
+{
+ GList *val_list, *l;
+ GString *val = g_string_new ("");
+
+ val_list = e_contact_get (contact, field);
+
+ for (l = val_list; l; l = l->next) {
+ if (l != val_list)
+ g_string_append (val, "<br>");
+
+ g_string_append (val, l->data);
+ }
+
+ if (val->str && *val->str)
+ render_table_row (buffer, html_label, val->str, icon, html_flags);
+
+ g_string_free (val, TRUE);
+ g_list_foreach (val_list, (GFunc) g_free, NULL);
+ g_list_free (val_list);
+}
+
+static const gchar *
+get_email_location (EVCardAttribute *attr)
+{
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (common_location); i++) {
+ if (e_vcard_attribute_has_type (attr, common_location[i].name))
+ return _(common_location[i].pretty_name);
+ }
+
+ return _("Other");
+}
+
+static void
+render_title_block (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ const gchar *str;
+ gchar *html;
+ EContactPhoto *photo;
+
+ g_string_append_printf (
+ buffer,
+ "<table border=\"0\"><tr>"
+ "<td %s valign=\"middle\">", TEXT_IS_RIGHT_TO_LEFT ?
+ "align=\"right\"" : "");
+
+ photo = e_contact_get (contact, E_CONTACT_PHOTO);
+ if (!photo)
+ photo = e_contact_get (contact, E_CONTACT_LOGO);
+
+ if (photo && photo->type == E_CONTACT_PHOTO_TYPE_INLINED) {
+ gchar *photo_data;
+ photo_data = g_base64_encode (
+ photo->data.inlined.data,
+ photo->data.inlined.length);
+ g_string_append_printf (
+ buffer, "<img border=\"1\" src=\"data:%s;base64,%s\">",
+ photo->data.inlined.mime_type,
+ photo_data);
+ } else if (photo && photo->type == E_CONTACT_PHOTO_TYPE_URI && photo->data.uri && *photo->data.uri) {
+ gboolean is_local = g_str_has_prefix (photo->data.uri, "file://");
+ gchar *unescaped = g_uri_unescape_string (photo->data.uri, NULL);
+ g_string_append_printf (
+ buffer, "<img border=\"1\" src=\"%s%s\">",
+ is_local ? "evo-" : "", unescaped);
+ g_free (unescaped);
+ }
+
+ if (photo)
+ e_contact_photo_free (photo);
+
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ g_string_append_printf (buffer, "<img src=\"gtk-stock://%s\">", CONTACT_LIST_ICON);
+ }
+
+ g_string_append_printf (
+ buffer,
+ "</td><td width=\"20\"></td><td %s valign=\"top\">\n",
+ TEXT_IS_RIGHT_TO_LEFT ? "align=\"right\"" : "");
+
+ str = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ if (!str)
+ str = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
+
+ if (str) {
+ html = e_text_to_html (str, 0);
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ g_string_append_printf (
+ buffer,
+ "<h2><a href=\"internal-mailto:0\">%s</a></h2>",
+ html);
+ } else {
+ g_string_append_printf (buffer, "<h2>%s</h2>", html);
+ }
+ g_free (html);
+ }
+
+ g_string_append (buffer, "</td></tr></table>");
+}
+
+static void
+render_contact_list_row (EABContactFormatter *formatter,
+ EDestination *destination,
+ GString *buffer)
+{
+ gchar *evolution_imagesdir;
+ gboolean list_collapsed = FALSE;
+ const gchar *textrep;
+ gchar *name = NULL, *email_addr = NULL;
+
+ evolution_imagesdir = g_filename_to_uri (EVOLUTION_IMAGESDIR, NULL, NULL);
+
+ textrep = e_destination_get_textrep (destination, TRUE);
+ if (!eab_parse_qp_email (textrep, &name, &email_addr))
+ email_addr = g_strdup (textrep);
+
+ g_string_append (buffer, "<tr>");
+ if (e_destination_is_evolution_list (destination)) {
+ g_string_append_printf (
+ buffer,
+ "<td width=" IMAGE_COL_WIDTH " valign=\"top\" align=\"left\">"
+ "<img src=\"evo-file://%s/minus.png\" "
+ "id=\"%s\" "
+ "class=\"navigable _evo_collapse_button\">"
+ "</td><td width=\"100%%\" align=\"left\">%s",
+ evolution_imagesdir,
+ e_destination_get_contact_uid (destination),
+ name ? name : email_addr);
+
+ if (!list_collapsed) {
+ const GList *dest, *dests;
+ g_string_append_printf (
+ buffer,
+ "<br><table cellspacing=\"1\" id=\"list-%s\">",
+ e_destination_get_contact_uid (destination));
+
+ dests = e_destination_list_get_root_dests (destination);
+ for (dest = dests; dest; dest = dest->next) {
+ render_contact_list_row (
+ formatter, dest->data, buffer);
+ }
+
+ g_string_append (buffer, "</table>");
+ }
+
+ g_string_append (buffer, "</td>");
+
+ } else {
+ if (name && *name) {
+ g_string_append_printf (
+ buffer,
+ "<td colspan=\"2\">%s &lt"
+ "<a href=\"mailto:%s\">%s</a>&gt;"
+ "</td>",
+ name, email_addr, email_addr);
+ } else {
+ g_string_append_printf (
+ buffer,
+ "<td colspan=\"2\">"
+ "<a href=\"mailto:%s\">%s</a>"
+ "</td>",
+ email_addr, email_addr);
+ }
+ }
+
+ g_string_append (buffer, "</tr>");
+
+ g_free (evolution_imagesdir);
+ g_free (name);
+ g_free (email_addr);
+}
+
+static void
+render_contact_list (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ EDestination *destination;
+ const GList *dest, *dests;
+
+ destination = e_destination_new ();
+ e_destination_set_contact (destination, contact, 0);
+ dests = e_destination_list_get_root_dests (destination);
+
+ render_title_block (formatter, contact, buffer);
+
+ g_string_append_printf (
+ buffer,
+ "<table border=\"0\"><tr><th colspan=\"2\">%s</th></tr>"
+ "<tr><td with=" IMAGE_COL_WIDTH "></td><td>", _("List Members:"));
+
+ g_string_append (buffer, "<table border=\"0\" cellspacing=\"1\">");
+
+ for (dest = dests; dest; dest = dest->next)
+ render_contact_list_row (formatter, dest->data, buffer);
+
+ g_string_append (buffer, "</table>");
+ g_string_append (buffer, "</td></tr></table>");
+
+ g_object_unref (destination);
+}
+
+static void
+render_contact_column (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ GString *accum, *email;
+ GList *email_list, *l, *email_attr_list, *al;
+ gint email_num = 0;
+ const gchar *nl;
+
+ email = g_string_new ("");
+ nl = "";
+
+ email_list = e_contact_get (contact, E_CONTACT_EMAIL);
+ email_attr_list = e_contact_get_attributes (contact, E_CONTACT_EMAIL);
+
+ for (l = email_list, al = email_attr_list; l && al; l = l->next, al = al->next) {
+ gchar *name = NULL, *mail = NULL;
+ gchar *attr_str = (gchar *) get_email_location ((EVCardAttribute *) al->data);
+
+ if (!eab_parse_qp_email (l->data, &name, &mail))
+ mail = e_text_to_html (l->data, 0);
+
+ g_string_append_printf (
+ email,
+ "%s%s%s<a href=\"internal-mailto:%d\">%s</a>%s "
+ "<span class=\"header\">(%s)</span>",
+ nl,
+ name ? name : "",
+ name ? " &lt;" : "",
+ email_num,
+ mail,
+ name ? "&gt;" : "",
+ attr_str ? attr_str : "");
+ email_num++;
+ nl = "<br>";
+
+ g_free (name);
+ g_free (mail);
+ }
+ g_list_foreach (email_list, (GFunc) g_free, NULL);
+ g_list_foreach (email_attr_list, (GFunc) e_vcard_attribute_free, NULL);
+ g_list_free (email_list);
+ g_list_free (email_attr_list);
+
+ accum = g_string_new ("");
+
+ if (email->len)
+ render_table_row (accum, _("Email"), email->str, NULL, 0);
+
+ accum_attribute (accum, contact, _("Nickname"), E_CONTACT_NICKNAME, NULL, 0);
+ accum_attribute_multival (accum, contact, _("AIM"), E_CONTACT_IM_AIM, AIM_ICON, 0);
+ accum_attribute_multival (accum, contact, _("GroupWise"), E_CONTACT_IM_GROUPWISE, GROUPWISE_ICON, 0);
+ accum_attribute_multival (accum, contact, _("ICQ"), E_CONTACT_IM_ICQ, ICQ_ICON, 0);
+ accum_attribute_multival (accum, contact, _("Jabber"), E_CONTACT_IM_JABBER, JABBER_ICON, 0);
+ accum_attribute_multival (accum, contact, _("MSN"), E_CONTACT_IM_MSN, MSN_ICON, 0);
+ accum_attribute_multival (accum, contact, _("Yahoo"), E_CONTACT_IM_YAHOO, YAHOO_ICON, 0);
+ accum_attribute_multival (accum, contact, _("Gadu-Gadu"), E_CONTACT_IM_GADUGADU, GADUGADU_ICON, 0);
+ accum_attribute_multival (accum, contact, _("Skype"), E_CONTACT_IM_SKYPE, SKYPE_ICON, 0);
+ accum_attribute_multival (accum, contact, _("Twitter"), E_CONTACT_IM_TWITTER, TWITTER_ICON, 0);
+
+ if (accum->len)
+ g_string_append_printf (
+ buffer,
+ "<div class=\"column\" id=\"contact-internet\">"
+ "<table border=\"0\" cellspacing=\"5\">%s</table>"
+ "</div>", accum->str);
+
+ g_string_free (accum, TRUE);
+ g_string_free (email, TRUE);
+}
+
+static void
+accum_address_map (GString *buffer,
+ EContact *contact,
+ gint map_type)
+{
+#ifdef WITH_CONTACT_MAPS
+ g_string_append (buffer, "<tr><td colspan=\"3\">");
+
+ if (map_type == E_CONTACT_ADDRESS_WORK) {
+ g_string_append (
+ buffer,
+ "<object type=\"application/x-work-map-widget\" "
+ "width=\"250\" height=\"250\"></object>");
+ } else {
+ g_string_append (
+ buffer,
+ "<object type=\"application/x-home-map-widget\" "
+ "width=\"250\" height=\"250\"></object>");
+ }
+
+ g_string_append (buffer, "</td></tr>");
+#endif /* WITH_CONTACT_MAPS */
+}
+
+static void
+render_work_column (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ GString *accum = g_string_new ("");
+
+ accum_attribute (accum, contact, _("Company"), E_CONTACT_ORG, NULL, 0);
+ accum_attribute (accum, contact, _("Department"), E_CONTACT_ORG_UNIT, NULL, 0);
+ accum_attribute (accum, contact, _("Profession"), E_CONTACT_ROLE, NULL, 0);
+ accum_attribute (accum, contact, _("Position"), E_CONTACT_TITLE, NULL, 0);
+ accum_attribute (accum, contact, _("Manager"), E_CONTACT_MANAGER, NULL, 0);
+ accum_attribute (accum, contact, _("Assistant"), E_CONTACT_ASSISTANT, NULL, 0);
+ accum_attribute (accum, contact, _("Video Chat"), E_CONTACT_VIDEO_URL, VIDEOCONF_ICON, E_TEXT_TO_HTML_CONVERT_URLS);
+ accum_attribute (accum, contact, _("Calendar"), E_CONTACT_CALENDAR_URI, NULL, E_TEXT_TO_HTML_CONVERT_URLS);
+ accum_attribute (accum, contact, _("Free/Busy"), E_CONTACT_FREEBUSY_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS);
+ accum_attribute (accum, contact, _("Phone"), E_CONTACT_PHONE_BUSINESS, NULL, 0);
+ accum_attribute (accum, contact, _("Fax"), E_CONTACT_PHONE_BUSINESS_FAX, NULL, 0);
+ accum_address (accum, contact, _("Address"), E_CONTACT_ADDRESS_WORK, E_CONTACT_ADDRESS_LABEL_WORK);
+ if (formatter->priv->render_maps)
+ accum_address_map (accum, contact, E_CONTACT_ADDRESS_WORK);
+
+ if (accum->len > 0) {
+ g_string_append_printf (
+ buffer,
+ "<div class=\"column\" id=\"contact-work\">"
+ "<h3>%s</h3>"
+ "<table border=\"0\" cellspacing=\"5\">%s</table>"
+ "</div>", _("Work"), accum->str);
+ }
+
+ g_string_free (accum, TRUE);
+}
+
+static void
+render_personal_column (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ GString *accum = g_string_new ("");
+
+ accum_attribute (accum, contact, _("Home Page"), E_CONTACT_HOMEPAGE_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS);
+ accum_attribute (accum, contact, _("Web Log"), E_CONTACT_BLOG_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS);
+ accum_attribute (accum, contact, _("Phone"), E_CONTACT_PHONE_HOME, NULL, 0);
+ accum_attribute (accum, contact, _("Mobile Phone"), E_CONTACT_PHONE_MOBILE, NULL, 0);
+ accum_address (accum, contact, _("Address"), E_CONTACT_ADDRESS_HOME, E_CONTACT_ADDRESS_LABEL_HOME);
+ accum_time_attribute (accum, contact, _("Birthday"), E_CONTACT_BIRTH_DATE, NULL, 0);
+ accum_time_attribute (accum, contact, _("Anniversary"), E_CONTACT_ANNIVERSARY, NULL, 0);
+ accum_attribute (accum, contact, _("Spouse"), E_CONTACT_SPOUSE, NULL, 0);
+ if (formatter->priv->render_maps)
+ accum_address_map (accum, contact, E_CONTACT_ADDRESS_HOME);
+
+ if (accum->len > 0) {
+ g_string_append_printf (
+ buffer,
+ "<div class=\"column\" id=\"contact-personal\">"
+ "<h3>%s</h3>"
+ "<table border=\"0\" cellspacing=\"5\">%s</table>"
+ "</div>", _("Personal"), accum->str);
+ }
+
+ g_string_free (accum, TRUE);
+}
+
+static void
+render_footer (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ const gchar *str;
+
+ str = e_contact_get_const (contact, E_CONTACT_NOTE);
+ if (!str || !*str)
+ return;
+
+ g_string_append (
+ buffer,
+ "<div id=\"footer\"><table border=\"0\" cellspacing=\"5\">");
+
+ render_table_row (
+ buffer, _("Note"),
+ e_contact_get_const (contact, E_CONTACT_NOTE),
+ NULL,
+ E_TEXT_TO_HTML_CONVERT_ADDRESSES |
+ E_TEXT_TO_HTML_CONVERT_URLS |
+ E_TEXT_TO_HTML_CONVERT_NL);
+
+ g_string_append (buffer, "</table></div>");
+}
+
+static void
+render_contact (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ render_title_block (formatter, contact, buffer);
+
+ g_string_append (buffer, "<div id=\"columns\">");
+ render_contact_column (formatter, contact, buffer);
+ render_work_column (formatter, contact, buffer);
+ render_personal_column (formatter, contact, buffer);
+ g_string_append (buffer, "</div>");
+
+ render_footer (formatter, contact, buffer);
+}
+
+static void
+render_normal (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ g_string_append (buffer, HTML_HEADER);
+ g_string_append (buffer, "<body bgcolor=\"white\">");
+
+ if (contact != NULL) {
+ if (e_contact_get (contact, E_CONTACT_IS_LIST))
+ render_contact_list (formatter, contact, buffer);
+ else
+ render_contact (formatter, contact, buffer);
+ }
+
+ g_string_append (buffer, "</body></html>\n");
+}
+
+static void
+render_compact (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ const gchar *str;
+ gchar *html;
+ EContactPhoto *photo;
+
+ g_string_append (buffer, HTML_HEADER);
+ g_string_append (buffer, "<body>\n");
+
+ if (contact == NULL) {
+ g_string_append (buffer, "</body></html>");
+ return;
+ }
+
+ g_string_append_printf (
+ buffer,
+ "<table><tr><td valign=\"top\">");
+
+ photo = e_contact_get (contact, E_CONTACT_PHOTO);
+
+ if (photo == NULL)
+ photo = e_contact_get (contact, E_CONTACT_LOGO);
+
+ if (photo != NULL) {
+ gint calced_width = MAX_COMPACT_IMAGE_DIMENSION;
+ gint 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 */
+ if (photo->type == E_CONTACT_PHOTO_TYPE_INLINED) {
+ gdk_pixbuf_loader_write (
+ loader, photo->data.inlined.data,
+ photo->data.inlined.length, NULL);
+ } else if (photo->type == E_CONTACT_PHOTO_TYPE_URI &&
+ photo->data.uri &&
+ g_ascii_strncasecmp (photo->data.uri, "file://", 7) == 0) {
+ gchar *filename, *contents = NULL;
+ gsize length;
+
+ filename = g_filename_from_uri (photo->data.uri, NULL, NULL);
+
+ if (filename) {
+ if (g_file_get_contents (filename, &contents, &length, NULL)) {
+ gdk_pixbuf_loader_write (loader, (const guchar *) contents, length, NULL);
+ g_free (contents);
+ }
+
+ g_free (filename);
+ }
+ }
+
+ gdk_pixbuf_loader_close (loader, NULL);
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+
+ if (pixbuf)
+ g_object_ref (pixbuf);
+
+ g_object_unref (loader);
+
+ if (pixbuf) {
+ gint max_dimension;
+
+ calced_width = gdk_pixbuf_get_width (pixbuf);
+ calced_height = gdk_pixbuf_get_height (pixbuf);
+
+ max_dimension = calced_width;
+
+ if (max_dimension < calced_height)
+ max_dimension = calced_height;
+
+ if (max_dimension > MAX_COMPACT_IMAGE_DIMENSION) {
+ calced_width *= ((gfloat) MAX_COMPACT_IMAGE_DIMENSION / max_dimension);
+ calced_height *= ((gfloat) MAX_COMPACT_IMAGE_DIMENSION / max_dimension);
+ }
+
+ g_object_unref (pixbuf);
+ }
+
+ if (photo->type == E_CONTACT_PHOTO_TYPE_URI &&
+ photo->data.uri && *photo->data.uri) {
+ gboolean is_local = g_str_has_prefix (photo->data.uri, "file://");
+ gchar *unescaped = g_uri_unescape_string (photo->data.uri, NULL);
+ g_string_append_printf (
+ buffer,
+ "<img width=\"%d\" height=\"%d\" src=\"%s%s\">",
+ calced_width, calced_height,
+ is_local ? "evo-" : "", unescaped);
+ g_free (unescaped);
+ } else {
+ gchar *photo_data;
+
+ photo_data = g_base64_encode (
+ photo->data.inlined.data,
+ photo->data.inlined.length);
+ g_string_append_printf (
+ buffer,
+ "<img border=\"1\" src=\"data:%s;base64,%s\" "
+ "width=\"%d\" height=\"%d\">",
+ photo->data.inlined.mime_type,
+ photo_data,
+ calced_width, calced_height);
+ g_free (photo_data);
+ }
+
+ e_contact_photo_free (photo);
+ }
+
+ g_string_append (buffer, "</td><td width=\"5\"></td><td valign=\"top\">\n");
+
+ str = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+
+ if (str) {
+ html = e_text_to_html (str, 0);
+ g_string_append_printf (buffer, "<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);
+ g_string_append_printf (buffer, "<b>%s</b>", html);
+ g_free (html);
+ }
+ }
+
+ g_string_append (buffer, "<hr>");
+
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ GList *email_list;
+ GList *l;
+
+ g_string_append (
+ buffer,
+ "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
+ "<tr><td valign=\"top\">");
+ g_string_append_printf (
+ buffer,
+ "<b>%s:</b>&nbsp;<td>", _ ("List Members"));
+
+ email_list = e_contact_get (contact, E_CONTACT_EMAIL);
+
+ for (l = email_list; l; l = l->next) {
+ if (l->data) {
+ html = e_text_to_html (l->data, 0);
+ g_string_append_printf (buffer, "%s, ", html);
+ g_free (html);
+ }
+ }
+
+ g_string_append (buffer, "</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);
+ g_string_append_printf (buffer, "<b>%s:</b> %s<br>", _ ("Job Title"), str);
+ g_free (html);
+ }
+
+ #define print_email() { \
+ html = eab_parse_qp_email_to_html (str); \
+ \
+ if (!html) \
+ html = e_text_to_html (str, 0); \
+ \
+ g_string_append_printf (buffer, "%s%s", comma ? ", " : "", html); \
+ g_free (html); \
+ comma = TRUE; \
+ }
+
+ g_string_append_printf (buffer, "<b>%s:</b> ", _ ("Email"));
+ str = e_contact_get_const (contact, E_CONTACT_EMAIL_1);
+
+ if (str)
+ print_email ();
+
+ str = e_contact_get_const (contact, E_CONTACT_EMAIL_2);
+
+ if (str)
+ print_email ();
+
+ str = e_contact_get_const (contact, E_CONTACT_EMAIL_3);
+
+ if (str)
+ print_email ();
+
+ g_string_append (buffer, "<br>");
+
+ #undef print_email
+
+ str = e_contact_get_const (contact, E_CONTACT_HOMEPAGE_URL);
+
+ if (str) {
+ html = e_text_to_html (str, E_TEXT_TO_HTML_CONVERT_URLS);
+ g_string_append_printf (
+ buffer, "<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);
+ g_string_append_printf (
+ buffer, "<b>%s:</b> %s<br>",
+ _ ("Blog"), html);
+ }
+ }
+
+ g_string_append (buffer, "</td></tr></table>\n");
+
+ g_string_append (buffer, "</body></html>\n");
+}
+
+static void
+eab_contact_formatter_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_DISPLAY_MODE:
+ eab_contact_formatter_set_display_mode (
+ EAB_CONTACT_FORMATTER (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_RENDER_MAPS:
+ eab_contact_formatter_set_render_maps (
+ EAB_CONTACT_FORMATTER (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+eab_contact_formatter_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_DISPLAY_MODE:
+ g_value_set_int (
+ value,
+ eab_contact_formatter_get_display_mode (
+ EAB_CONTACT_FORMATTER (object)));
+ return;
+
+ case PROP_RENDER_MAPS:
+ g_value_set_boolean (
+ value,
+ eab_contact_formatter_get_render_maps (
+ EAB_CONTACT_FORMATTER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+eab_contact_formatter_class_init (EABContactFormatterClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EABContactFormatterClass));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = eab_contact_formatter_set_property;
+ object_class->get_property = eab_contact_formatter_get_property;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_DISPLAY_MODE,
+ g_param_spec_int (
+ "display-mode",
+ "Display Mode",
+ NULL,
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL,
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT,
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_RENDER_MAPS,
+ g_param_spec_boolean (
+ "render-maps",
+ "Render Maps",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+eab_contact_formatter_init (EABContactFormatter *formatter)
+{
+ formatter->priv = EAB_CONTACT_FORMATTER_GET_PRIVATE (formatter);
+
+ formatter->priv->mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
+ formatter->priv->render_maps = FALSE;
+}
+
+EABContactFormatter *
+eab_contact_formatter_new (void)
+{
+ return g_object_new (EAB_TYPE_CONTACT_FORMATTER, NULL);
+}
+
+gboolean
+eab_contact_formatter_get_render_maps (EABContactFormatter *formatter)
+{
+ g_return_val_if_fail (EAB_IS_CONTACT_FORMATTER (formatter), FALSE);
+
+ return formatter->priv->render_maps;
+}
+
+void
+eab_contact_formatter_set_render_maps (EABContactFormatter *formatter,
+ gboolean render_maps)
+{
+ g_return_if_fail (EAB_IS_CONTACT_FORMATTER (formatter));
+
+ if (formatter->priv->render_maps == render_maps)
+ return;
+
+ formatter->priv->render_maps = render_maps;
+
+ g_object_notify (G_OBJECT (formatter), "render-maps");
+}
+
+EABContactDisplayMode
+eab_contact_formatter_get_display_mode (EABContactFormatter *formatter)
+{
+ g_return_val_if_fail (
+ EAB_IS_CONTACT_FORMATTER (formatter),
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL);
+
+ return formatter->priv->mode;
+}
+
+void
+eab_contact_formatter_set_display_mode (EABContactFormatter *formatter,
+ EABContactDisplayMode mode)
+{
+ g_return_if_fail (EAB_IS_CONTACT_FORMATTER (formatter));
+
+ if (formatter->priv->mode == mode)
+ return;
+
+ formatter->priv->mode = mode;
+
+ g_object_notify (G_OBJECT (formatter), "display-mode");
+}
+
+void
+eab_contact_formatter_format_contact (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *output_buffer)
+{
+ g_return_if_fail (EAB_IS_CONTACT_FORMATTER (formatter));
+ g_return_if_fail (E_IS_CONTACT (contact));
+ g_return_if_fail (output_buffer != NULL);
+
+ if (formatter->priv->mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL)
+ render_normal (formatter, contact, output_buffer);
+ else
+ render_compact (formatter, contact, output_buffer);
+}
+
+static void
+collapse_contacts_list (WebKitDOMEventTarget *event_target,
+ WebKitDOMEvent *event,
+ gpointer user_data)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMElement *list;
+ gchar *id, *list_id;
+ gchar *imagesdir, *src;
+ gboolean hidden;
+
+ document = user_data;
+ id = webkit_dom_html_element_get_id (WEBKIT_DOM_HTML_ELEMENT (event_target));
+
+ list_id = g_strconcat ("list-", id, NULL);
+ list = webkit_dom_document_get_element_by_id (document, list_id);
+ g_free (id);
+ g_free (list_id);
+
+ if (list == NULL)
+ return;
+
+ imagesdir = g_filename_to_uri (EVOLUTION_IMAGESDIR, NULL, NULL);
+ hidden = webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (list));
+
+ if (hidden)
+ src = g_strdup_printf ("evo-file://%s/minus.png", imagesdir);
+ else
+ src = g_strdup_printf ("evo-file://%s/plus.png", imagesdir);
+
+ webkit_dom_html_element_set_hidden (
+ WEBKIT_DOM_HTML_ELEMENT (list), !hidden);
+ webkit_dom_html_image_element_set_src (
+ WEBKIT_DOM_HTML_IMAGE_ELEMENT (event_target), src);
+
+ g_free (src);
+ g_free (imagesdir);
+}
+
+void
+eab_contact_formatter_bind_dom (WebKitDOMDocument *document)
+{
+ WebKitDOMNodeList *nodes;
+ gulong ii, length;
+
+ nodes = webkit_dom_document_get_elements_by_class_name (
+ document, "_evo_collapse_button");
+
+ length = webkit_dom_node_list_get_length (nodes);
+ for (ii = 0; ii < length; ii++) {
+
+ WebKitDOMNode *node;
+
+ node = webkit_dom_node_list_item (nodes, ii);
+ webkit_dom_event_target_add_event_listener (
+ WEBKIT_DOM_EVENT_TARGET (node), "click",
+ G_CALLBACK (collapse_contacts_list), FALSE, document);
+ }
+}
diff --git a/addressbook/gui/widgets/eab-contact-formatter.h b/addressbook/gui/widgets/eab-contact-formatter.h
new file mode 100644
index 0000000000..4dc1427960
--- /dev/null
+++ b/addressbook/gui/widgets/eab-contact-formatter.h
@@ -0,0 +1,84 @@
+/*
+ * eab-contact-formatter.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef EAB_CONTACT_FORMATTER_H
+#define EAB_CONTACT_FORMATTER_H
+
+#include <camel/camel.h>
+#include <libebook/libebook.h>
+
+#include <addressbook/gui/widgets/eab-contact-display.h>
+
+/* Standard GObject macros */
+#define EAB_TYPE_CONTACT_FORMATTER \
+ (eab_contact_formatter_get_type ())
+#define EAB_CONTACT_FORMATTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EAB_TYPE_CONTACT_FORMATTER, EABContactFormatter))
+#define EAB_CONTACT_FORMATTER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EAB_TYPE_CONTACT_FORMATTER, EABContactFormatterClass))
+#define EAB_IS_CONTACT_FORMATTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EAB_TYPE_CONTACT_FORMATTER))
+#define EAB_IS_CONTACT_FORMATTER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EAB_TYPE_CONTACT_FORMATTER))
+#define EAB_CONTACT_FORMATTER_GET_CLASS(obj) \
+ (G_TYPE_ISNTANCE_GET_CLASS \
+ ((obj), EAB_TYPE_CONTACT_FORMATTER, EABContactFormatterClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EABContactFormatter EABContactFormatter;
+typedef struct _EABContactFormatterClass EABContactFormatterClass;
+typedef struct _EABContactFormatterPrivate EABContactFormatterPrivate;
+
+struct _EABContactFormatter {
+ GObject parent;
+ EABContactFormatterPrivate *priv;
+};
+
+struct _EABContactFormatterClass {
+ GObjectClass parent_class;
+};
+
+GType eab_contact_formatter_get_type (void) G_GNUC_CONST;
+EABContactFormatter *
+ eab_contact_formatter_new (void);
+gboolean eab_contact_formatter_get_render_maps
+ (EABContactFormatter *formatter);
+void eab_contact_formatter_set_render_maps
+ (EABContactFormatter *formatter,
+ gboolean render_maps);
+EABContactDisplayMode
+ eab_contact_formatter_get_display_mode
+ (EABContactFormatter *formatter);
+void eab_contact_formatter_set_display_mode
+ (EABContactFormatter *formatter,
+ EABContactDisplayMode mode);
+void eab_contact_formatter_format_contact
+ (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *output_buffer);
+void eab_contact_formatter_bind_dom (WebKitDOMDocument *document);
+
+G_END_DECLS
+
+#endif /* EAB_CONTACT_FORMATTER_H */
+
diff --git a/addressbook/gui/widgets/eab-gui-util.c b/addressbook/gui/widgets/eab-gui-util.c
new file mode 100644
index 0000000000..5f155ad1b1
--- /dev/null
+++ b/addressbook/gui/widgets/eab-gui-util.c
@@ -0,0 +1,1119 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Toshok <toshok@ximian.com>
+ * Dan Vratil <dvratil@redhat.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <locale.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include "shell/e-shell.h"
+
+#include "eab-gui-util.h"
+#include "util/eab-book-util.h"
+#include "eab-contact-merging.h"
+
+/* we link to camel for decoding quoted printable email addresses */
+#include <camel/camel.h>
+
+/* Template tags for address format localization */
+#define ADDRESS_REALNAME "%n" /* this is not used intentionally */
+#define ADDRESS_REALNAME_UPPER "%N" /* this is not used intentionally */
+#define ADDRESS_COMPANY "%m"
+#define ADDRESS_COMPANY_UPPER "%M"
+#define ADDRESS_POBOX "%p"
+#define ADDRESS_STREET "%s"
+#define ADDRESS_STREET_UPPER "%S"
+#define ADDRESS_ZIPCODE "%z"
+#define ADDRESS_LOCATION "%l"
+#define ADDRESS_LOCATION_UPPER "%L"
+#define ADDRESS_REGION "%r"
+#define ADDRESS_REGION_UPPER "%R"
+#define ADDRESS_CONDCOMMA "%," /* Conditional comma is removed when a surrounding tag is evaluated to zero */
+#define ADDRESS_CONDWHITE "%w" /* Conditional whitespace is removed when a surrounding tag is evaluated to zero */
+#define ADDRESS_COND_PURGEEMPTY "%0" /* Purge empty has following syntax: %0(...) and is removed when no tag within () is evaluated non-zero */
+
+/* Fallback formats */
+#define ADDRESS_DEFAULT_FORMAT "%0(%n\n)%0(%m\n)%0(%s\n)%0(PO BOX %p\n)%0(%l%w%r)%,%z"
+#define ADDRESS_DEFAULT_COUNTRY_POSITION "below"
+
+enum {
+ LOCALES_LANGUAGE = 0,
+ LOCALES_COUNTRY = 1
+};
+
+typedef enum {
+ ADDRESS_FORMAT_HOME = 0,
+ ADDRESS_FORMAT_BUSINESS = 1
+} AddressFormat;
+
+void
+eab_error_dialog (EAlertSink *alert_sink,
+ GtkWindow *parent,
+ const gchar *msg,
+ const GError *error)
+{
+ if (error && error->message) {
+ if (alert_sink)
+ e_alert_submit (
+ alert_sink,
+ "addressbook:generic-error",
+ msg, error->message, NULL);
+ else {
+ if (!parent)
+ parent = e_shell_get_active_window (NULL);
+
+ e_alert_run_dialog_for_args (
+ parent,
+ "addressbook:generic-error",
+ msg, error->message, NULL);
+ }
+ }
+}
+
+void
+eab_load_error_dialog (GtkWidget *parent,
+ EAlertSink *alert_sink,
+ ESource *source,
+ const GError *error)
+{
+ ESourceBackend *extension;
+ gchar *label_string, *label = NULL;
+ gboolean can_detail_error = TRUE;
+ const gchar *backend_name;
+ const gchar *extension_name;
+
+ g_return_if_fail (source != NULL);
+
+ extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+ extension = e_source_get_extension (source, extension_name);
+ backend_name = e_source_backend_get_backend_name (extension);
+
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_OFFLINE_UNAVAILABLE)) {
+ can_detail_error = FALSE;
+ label_string =
+ _("This address book cannot be opened. This either "
+ "means this book is not marked for offline usage "
+ "or not yet downloaded for offline usage. Please "
+ "load the address book once in online mode to "
+ "download its contents.");
+ }
+
+ else if (g_strcmp0 (backend_name, "local") == 0) {
+ const gchar *user_data_dir;
+ const gchar *uid;
+ gchar *path;
+
+ uid = e_source_get_uid (source);
+ user_data_dir = e_get_user_data_dir ();
+
+ path = g_build_filename (
+ user_data_dir, "addressbook", uid, NULL);
+
+ label = g_strdup_printf (
+ _("This address book cannot be opened. Please check that the "
+ "path %s exists and that permissions are set to access it."), path);
+
+ g_free (path);
+ label_string = label;
+ }
+
+#ifndef HAVE_LDAP
+ else if (g_strcmp0 (backend_name, "ldap") == 0) {
+ /* special case for ldap: contact folders so we can tell the user about openldap */
+
+ can_detail_error = FALSE;
+ label_string =
+ _("This version of Evolution does not have LDAP support "
+ "compiled in to it. To use LDAP in Evolution "
+ "an LDAP-enabled Evolution package must be installed.");
+
+ }
+#endif
+ else {
+ /* other network folders (or if ldap is enabled and server is unreachable) */
+ label_string =
+ _("This address book cannot be opened. This either "
+ "means that an incorrect URI was entered, or the server "
+ "is unreachable.");
+ }
+
+ if (can_detail_error) {
+ /* do not show repository offline message, it's kind of generic error */
+ if (error && !g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_REPOSITORY_OFFLINE)) {
+ label = g_strconcat (label_string, "\n\n", _("Detailed error message:"), " ", error->message, NULL);
+ label_string = label;
+ }
+ }
+
+ if (alert_sink) {
+ e_alert_submit (
+ alert_sink, "addressbook:load-error",
+ label_string, NULL);
+ } else {
+ GtkWidget *dialog;
+
+ dialog = e_alert_dialog_new_for_args (
+ (GtkWindow *) parent,
+ "addressbook:load-error",
+ label_string, NULL);
+ g_signal_connect (
+ dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+ gtk_widget_show (dialog);
+ }
+
+ g_free (label);
+}
+
+void
+eab_search_result_dialog (EAlertSink *alert_sink,
+ const GError *error)
+{
+ gchar *str = NULL;
+
+ if (!error)
+ return;
+
+ if (error->domain == E_CLIENT_ERROR) {
+ switch (error->code) {
+ case E_CLIENT_ERROR_SEARCH_SIZE_LIMIT_EXCEEDED:
+ str = _("More cards matched this query than either the server is \n"
+ "configured to return or Evolution is configured to display.\n"
+ "Please make your search more specific or raise the result limit in\n"
+ "the directory server preferences for this address book.");
+ str = g_strdup (str);
+ break;
+ case E_CLIENT_ERROR_SEARCH_TIME_LIMIT_EXCEEDED:
+ str = _("The time to execute this query exceeded the server limit or the limit\n"
+ "configured for this address book. Please make your search\n"
+ "more specific or raise the time limit in the directory server\n"
+ "preferences for this address book.");
+ str = g_strdup (str);
+ break;
+ case E_CLIENT_ERROR_INVALID_QUERY:
+ /* Translators: %s is replaced with a detailed error message, or an empty string, if not provided */
+ str = _("The backend for this address book was unable to parse this query. %s");
+ str = g_strdup_printf (str, error->message);
+ break;
+ case E_CLIENT_ERROR_QUERY_REFUSED:
+ /* Translators: %s is replaced with a detailed error message, or an empty string, if not provided */
+ str = _("The backend for this address book refused to perform this query. %s");
+ str = g_strdup_printf (str, error->message);
+ break;
+ case E_CLIENT_ERROR_OTHER_ERROR:
+ default:
+ /* Translators: %s is replaced with a detailed error message, or an empty string, if not provided */
+ str = _("This query did not complete successfully. %s");
+ str = g_strdup_printf (str, error->message);
+ break;
+ }
+ } else {
+ /* Translators: %s is replaced with a detailed error message, or an empty string, if not provided */
+ str = _("This query did not complete successfully. %s");
+ str = g_strdup_printf (str, error->message);
+ }
+
+ e_alert_submit (alert_sink, "addressbook:search-error", str, NULL);
+
+ g_free (str);
+}
+
+gint
+eab_prompt_save_dialog (GtkWindow *parent)
+{
+ return e_alert_run_dialog_for_args (parent, "addressbook:prompt-save", NULL);
+}
+
+static gchar *
+make_safe_filename (gchar *name)
+{
+ gchar *safe;
+
+ if (!name) {
+ /* This is a filename. Translators take note. */
+ name = _("card.vcf");
+ }
+
+ if (!g_strrstr (name, ".vcf"))
+ safe = g_strdup_printf ("%s%s", name, ".vcf");
+ else
+ safe = g_strdup (name);
+
+ e_filename_make_safe (safe);
+
+ return safe;
+}
+
+static void
+source_selection_changed_cb (ESourceSelector *selector,
+ GtkWidget *ok_button)
+{
+ ESource *except_source = NULL, *selected;
+ gboolean sensitive;
+
+ except_source = g_object_get_data (G_OBJECT (ok_button), "except-source");
+ selected = e_source_selector_ref_primary_selection (selector);
+
+ sensitive = (selected != NULL && selected != except_source);
+ gtk_widget_set_sensitive (ok_button, sensitive);
+
+ if (selected != NULL)
+ g_object_unref (selected);
+}
+
+ESource *
+eab_select_source (ESourceRegistry *registry,
+ ESource *except_source,
+ const gchar *title,
+ const gchar *message,
+ const gchar *select_uid,
+ GtkWindow *parent)
+{
+ ESource *source;
+ GtkWidget *content_area;
+ GtkWidget *dialog;
+ GtkWidget *ok_button;
+ /* GtkWidget *label; */
+ GtkWidget *selector;
+ GtkWidget *scrolled_window;
+ const gchar *extension_name;
+ gint response;
+
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
+ dialog = gtk_dialog_new_with_buttons (
+ _("Select Address Book"), parent,
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 350, 300);
+
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, FALSE);
+
+ /* label = gtk_label_new (message); */
+
+ extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+ selector = e_source_selector_new (registry, extension_name);
+ e_source_selector_set_show_toggles (
+ E_SOURCE_SELECTOR (selector), FALSE);
+
+ ok_button = gtk_dialog_get_widget_for_response (
+ GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+
+ if (except_source)
+ g_object_set_data (
+ G_OBJECT (ok_button), "except-source", except_source);
+
+ g_signal_connect (
+ selector, "primary_selection_changed",
+ G_CALLBACK (source_selection_changed_cb), ok_button);
+
+ if (select_uid) {
+ source = e_source_registry_ref_source (registry, select_uid);
+ if (source != NULL) {
+ e_source_selector_set_primary_selection (
+ E_SOURCE_SELECTOR (selector), source);
+ g_object_unref (source);
+ }
+ }
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (scrolled_window), selector);
+
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ gtk_box_pack_start (GTK_BOX (content_area), scrolled_window, TRUE, TRUE, 4);
+
+ gtk_widget_show_all (dialog);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ source = e_source_selector_ref_primary_selection (
+ E_SOURCE_SELECTOR (selector));
+ else
+ source = NULL;
+
+ gtk_widget_destroy (dialog);
+
+ /* XXX Return a borrowed reference for backward-compatibility. */
+ if (source != NULL)
+ g_object_unref (source);
+
+ return source;
+}
+
+gchar *
+eab_suggest_filename (const GSList *contact_list)
+{
+ gchar *res = NULL;
+
+ g_return_val_if_fail (contact_list != NULL, NULL);
+
+ if (!contact_list->next) {
+ EContact *contact = E_CONTACT (contact_list->data);
+ gchar *string;
+
+ string = e_contact_get (contact, E_CONTACT_FILE_AS);
+ if (string == NULL)
+ string = e_contact_get (contact, E_CONTACT_FULL_NAME);
+ if (string != NULL)
+ res = make_safe_filename (string);
+ g_free (string);
+ }
+
+ if (res == NULL)
+ res = make_safe_filename (_("list"));
+
+ return res;
+}
+
+typedef struct ContactCopyProcess_ ContactCopyProcess;
+
+struct ContactCopyProcess_ {
+ gint count;
+ gboolean book_status;
+ GSList *contacts;
+ EBookClient *source;
+ EBookClient *destination;
+ ESourceRegistry *registry;
+ gboolean delete_from_source;
+ EAlertSink *alert_sink;
+};
+
+static void process_unref (ContactCopyProcess *process);
+
+static void
+remove_contact_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ ContactCopyProcess *process = user_data;
+ GError *error = NULL;
+
+ e_book_client_remove_contact_by_uid_finish (book_client, result, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Remove contact by uid failed: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ process_unref (process);
+}
+
+static void
+do_delete_from_source (gpointer data,
+ gpointer user_data)
+{
+ ContactCopyProcess *process = user_data;
+ EContact *contact = data;
+ const gchar *id;
+ EBookClient *book_client = process->source;
+
+ id = e_contact_get_const (contact, E_CONTACT_UID);
+ g_return_if_fail (id != NULL);
+ g_return_if_fail (book_client != NULL);
+
+ process->count++;
+ e_book_client_remove_contact_by_uid (book_client, id, NULL, remove_contact_ready_cb, process);
+}
+
+static void
+delete_contacts (ContactCopyProcess *process)
+{
+ if (process->book_status == TRUE) {
+ g_slist_foreach (process->contacts,
+ do_delete_from_source,
+ process);
+ }
+}
+
+static void
+process_unref (ContactCopyProcess *process)
+{
+ process->count--;
+ if (process->count == 0) {
+ if (process->delete_from_source) {
+ delete_contacts (process);
+ /* to not repeate this again */
+ process->delete_from_source = FALSE;
+
+ if (process->count > 0)
+ return;
+ }
+ g_slist_free_full (
+ process->contacts,
+ (GDestroyNotify) g_object_unref);
+ g_object_unref (process->source);
+ g_object_unref (process->destination);
+ g_object_unref (process->registry);
+ g_free (process);
+ }
+}
+
+static void
+contact_added_cb (EBookClient *book_client,
+ const GError *error,
+ const gchar *id,
+ gpointer user_data)
+{
+ ContactCopyProcess *process = user_data;
+
+ if (error && !g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) &&
+ !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ process->book_status = FALSE;
+ eab_error_dialog (process->alert_sink, NULL, _("Error adding contact"), error);
+ } else if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ process->book_status = FALSE;
+ }
+ else {
+ /* success */
+ process->book_status = TRUE;
+ }
+
+ process_unref (process);
+}
+
+static void
+do_copy (gpointer data,
+ gpointer user_data)
+{
+ EBookClient *book_client;
+ EContact *contact;
+ ContactCopyProcess *process;
+
+ process = user_data;
+ contact = data;
+
+ book_client = process->destination;
+ e_contact_inline_local_photos (contact, NULL);
+
+ process->count++;
+ eab_merging_book_add_contact (
+ process->registry, book_client,
+ contact, contact_added_cb, process);
+}
+
+static void
+book_client_connect_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ ContactCopyProcess *process = user_data;
+ EClient *client;
+ GError *error = NULL;
+
+ client = e_book_client_connect_finish (result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ if (error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ goto exit;
+ }
+
+ process->destination = E_BOOK_CLIENT (client);
+ process->book_status = TRUE;
+ g_slist_foreach (process->contacts, do_copy, process);
+
+exit:
+ process_unref (process);
+}
+
+void
+eab_transfer_contacts (ESourceRegistry *registry,
+ EBookClient *source_client,
+ GSList *contacts /* adopted */,
+ gboolean delete_from_source,
+ EAlertSink *alert_sink)
+{
+ ESource *source;
+ ESource *destination;
+ static gchar *last_uid = NULL;
+ ContactCopyProcess *process;
+ gchar *desc;
+ GtkWindow *window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (alert_sink)));
+
+ g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+ g_return_if_fail (E_IS_BOOK_CLIENT (source_client));
+
+ if (contacts == NULL)
+ return;
+
+ if (last_uid == NULL)
+ last_uid = g_strdup ("");
+
+ if (contacts->next == NULL) {
+ if (delete_from_source)
+ desc = _("Move contact to");
+ else
+ desc = _("Copy contact to");
+ } else {
+ if (delete_from_source)
+ desc = _("Move contacts to");
+ else
+ desc = _("Copy contacts to");
+ }
+
+ source = e_client_get_source (E_CLIENT (source_client));
+
+ destination = eab_select_source (
+ registry, source, desc, NULL, last_uid, window);
+
+ if (!destination)
+ return;
+
+ if (strcmp (last_uid, e_source_get_uid (destination)) != 0) {
+ g_free (last_uid);
+ last_uid = g_strdup (e_source_get_uid (destination));
+ }
+
+ process = g_new (ContactCopyProcess, 1);
+ process->count = 1;
+ process->book_status = FALSE;
+ process->source = g_object_ref (source_client);
+ process->contacts = contacts;
+ process->destination = NULL;
+ process->registry = g_object_ref (registry);
+ process->alert_sink = alert_sink;
+ process->delete_from_source = delete_from_source;
+
+ e_book_client_connect (
+ destination, NULL, book_client_connect_cb, process);
+}
+
+/*
+ * eab_format_address helper function
+ *
+ * Splits locales from en_US to array "en","us",NULL. When
+ * locales don't have the second part (for example "C"),
+ * the output array is "c",NULL
+ */
+static gchar **
+get_locales (void)
+{
+ gchar *locale, *l_locale;
+ gchar *dot;
+ gchar **split;
+
+#ifdef LC_ADDRESS
+ locale = g_strdup (setlocale (LC_ADDRESS, NULL));
+#else
+ locale = NULL;
+#endif
+ if (!locale)
+ return NULL;
+
+ l_locale = g_utf8_strdown (locale, -1);
+ g_free (locale);
+
+ dot = strchr (l_locale, '.');
+ if (dot != NULL) {
+ gchar *p = l_locale;
+ l_locale = g_strndup (l_locale, dot - l_locale);
+ g_free (p);
+ }
+
+ split = g_strsplit (l_locale, "_", 2);
+
+ g_free (l_locale);
+ return split;
+
+}
+
+static gchar *
+get_locales_str (void)
+{
+ gchar *ret;
+ gchar **loc = get_locales ();
+
+ if (!loc)
+ return g_strdup ("C");
+
+ if (!loc[0] ||
+ (loc[0] && !loc[1])) /* We don't care about language now, we need a country at first! */
+ ret = g_strdup ("C");
+ else if (loc[0] && loc[1]) {
+ if (*loc[0])
+ ret = g_strconcat (loc[LOCALES_COUNTRY], "_", loc[LOCALES_LANGUAGE], NULL);
+ else
+ ret = g_strdup (loc[LOCALES_COUNTRY]);
+ }
+
+ g_strfreev (loc);
+ return ret;
+}
+
+/*
+ * Reads countrytransl.map file, which contains map of localized
+ * country names and their ISO codes and tries to find matching record
+ * for given country. The search is case insensitive.
+ * When no record is found (country is probably in untranslated language), returns
+ * code of local computer country (from locales)
+ */
+static gchar *
+country_to_ISO (const gchar *country)
+{
+ FILE *file = fopen (EVOLUTION_RULEDIR "/countrytransl.map", "r");
+ gchar buffer[100];
+ gint length = 100;
+ gchar **pair;
+ gchar *res;
+ gchar *l_country = g_utf8_strdown (country, -1);
+
+ if (!file) {
+ gchar **loc;
+ g_warning ("%s: Failed to open countrytransl.map. Check your installation.", G_STRFUNC);
+ loc = get_locales ();
+ res = g_strdup (loc ? loc[LOCALES_COUNTRY] : NULL);
+ g_free (l_country);
+ g_strfreev (loc);
+ return res;
+ }
+
+ while (fgets (buffer, length, file) != NULL) {
+ gchar *low = NULL;
+ pair = g_strsplit (buffer, "\t", 2);
+
+ if (pair[0]) {
+ low = g_utf8_strdown (pair[0], -1);
+ if (g_utf8_collate (low, l_country) == 0) {
+ gchar *ret = g_strdup (pair[1]);
+ gchar *pos;
+ /* Remove trailing newline character */
+ if ((pos = g_strrstr (ret, "\n")) != NULL)
+ pos[0] = '\0';
+ fclose (file);
+ g_strfreev (pair);
+ g_free (low);
+ g_free (l_country);
+ return ret;
+ }
+ }
+
+ g_strfreev (pair);
+ g_free (low);
+ }
+
+ /* If we get here, then no match was found in the map file and we
+ * fallback to local system locales */
+ fclose (file);
+
+ pair = get_locales ();
+ res = g_strdup (pair ? pair[LOCALES_COUNTRY] : NULL);
+ g_strfreev (pair);
+ g_free (l_country);
+ return res;
+}
+
+/*
+ * Tries to find given key in "country_LANGUAGE" group. When fails to find
+ * such group, then fallbacks to "country" group. When such group does not
+ * exist either, NULL is returned
+ */
+static gchar *
+get_key_file_locale_string (GKeyFile *key_file,
+ const gchar *key,
+ const gchar *locale)
+{
+ gchar *result;
+ gchar *group;
+
+ g_return_val_if_fail (locale, NULL);
+
+ /* Default locale is in "country_lang", but such group may not exist. In such case use group "country" */
+ if (g_key_file_has_group (key_file, locale))
+ group = g_strdup (locale);
+ else {
+ gchar **locales = g_strsplit (locale, "_", 0);
+ group = g_strdup (locales[LOCALES_COUNTRY]);
+ g_strfreev (locales);
+ }
+
+ /* When group or key does not exist, returns NULL and fallback string will be used */
+ result = g_key_file_get_string (key_file, group, key, NULL);
+ g_free (group);
+ return result;
+}
+
+static void
+get_address_format (AddressFormat address_format,
+ const gchar *locale,
+ gchar **format,
+ gchar **country_position)
+{
+ GKeyFile *key_file;
+ GError *error;
+ gchar *loc;
+ const gchar *addr_key, *country_key;
+
+ if (address_format == ADDRESS_FORMAT_HOME) {
+ addr_key = "AddressFormat";
+ country_key = "CountryPosition";
+ } else if (address_format == ADDRESS_FORMAT_BUSINESS) {
+ addr_key = "BusinessAddressFormat";
+ country_key = "BusinessCountryPosition";
+ } else {
+ return;
+ }
+
+ if (locale == NULL)
+ loc = get_locales_str ();
+ else
+ loc = g_strdup (locale);
+
+ error = NULL;
+ key_file = g_key_file_new ();
+ g_key_file_load_from_file (key_file, EVOLUTION_RULEDIR "/address_formats.dat", 0, &error);
+ if (error) {
+ g_warning ("%s: Failed to load address_formats.dat file: %s", G_STRFUNC, error->message);
+ *format = g_strdup (ADDRESS_DEFAULT_FORMAT);
+ *country_position = g_strdup (ADDRESS_DEFAULT_COUNTRY_POSITION);
+ g_key_file_free (key_file);
+ g_free (loc);
+ g_error_free (error);
+ return;
+ }
+
+ if (format) {
+ if (*format)
+ g_free (*format);
+ *format = get_key_file_locale_string (key_file, addr_key, loc);
+ if (!*format && address_format == ADDRESS_FORMAT_HOME) {
+ *format = g_strdup (ADDRESS_DEFAULT_FORMAT);
+ } else if (!*format && address_format == ADDRESS_FORMAT_BUSINESS)
+ get_address_format (ADDRESS_FORMAT_HOME, loc, format, NULL);
+ }
+
+ if (country_position) {
+ if (*country_position)
+ g_free (*country_position);
+ *country_position = get_key_file_locale_string (key_file, country_key, loc);
+ if (!*country_position && address_format == ADDRESS_FORMAT_HOME)
+ *country_position = g_strdup (ADDRESS_DEFAULT_COUNTRY_POSITION);
+ else if (!*country_position && address_format == ADDRESS_FORMAT_BUSINESS)
+ get_address_format (ADDRESS_FORMAT_HOME, loc, NULL, country_position);
+ }
+
+ g_free (loc);
+ g_key_file_free (key_file);
+}
+
+static const gchar *
+find_balanced_bracket (const gchar *str)
+{
+ gint balance_counter = 0;
+ gint i = 0;
+
+ do {
+ if (str[i] == '(')
+ balance_counter++;
+
+ if (str[i] == ')')
+ balance_counter--;
+
+ i++;
+
+ } while ((balance_counter > 0) && (str[i]));
+
+ if (balance_counter > 0)
+ return str;
+
+ return str + i;
+}
+
+static GString *
+string_append_upper (GString *str,
+ const gchar *c)
+{
+ gchar *up_c;
+
+ g_return_val_if_fail (str, NULL);
+
+ if (!c || !*c)
+ return str;
+
+ up_c = g_utf8_strup (c, -1);
+ str = g_string_append (str, up_c);
+ g_free (up_c);
+
+ return str;
+}
+
+static gboolean
+parse_address_template_section (const gchar *format,
+ const gchar *realname,
+ const gchar *org_name,
+ EContactAddress *address,
+ gchar **result)
+
+{
+ const gchar *pos, *old_pos;
+ gboolean ret = FALSE; /* Indicates, wheter at least something was replaced */
+
+ GString *res = g_string_new ("");
+
+ pos = format;
+ old_pos = pos;
+ while ((pos = strchr (pos, '%')) != NULL) {
+
+ if (old_pos != pos)
+ g_string_append_len (res, old_pos, pos - old_pos);
+
+ switch (pos[1]) {
+ case 'n':
+ if (realname && *realname) {
+ g_string_append (res, realname);
+ ret = TRUE;
+ }
+ pos += 2; /* Jump behind the modifier, see what's next */
+ break;
+ case 'N':
+ if (realname && *realname) {
+ string_append_upper (res, realname);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'm':
+ if (org_name && *org_name) {
+ g_string_append (res, org_name);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'M':
+ if (org_name && *org_name) {
+ string_append_upper (res, org_name);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'p':
+ if (address->po && *(address->po)) {
+ g_string_append (res, address->po);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 's':
+ if (address->street && *(address->street)) {
+ g_string_append (res, address->street);
+ if (address->ext && *(address->ext))
+ g_string_append_printf (
+ res, "\n%s",
+ address->ext);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'S':
+ if (address->street && *(address->street)) {
+ string_append_upper (res, address->street);
+ if (address->ext && *(address->ext)) {
+ g_string_append (res, "\n");
+ string_append_upper (res, address->ext);
+ }
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'z':
+ if (address->code && *(address->code)) {
+ g_string_append (res, address->code);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'l':
+ if (address->locality && *(address->locality)) {
+ g_string_append (res, address->locality);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'L':
+ if (address->locality && *(address->locality)) {
+ string_append_upper (res, address->locality);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'r':
+ if (address->region && *(address->region)) {
+ g_string_append (res, address->region);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'R':
+ if (address->region && *(address->region)) {
+ string_append_upper (res, address->region);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case ',':
+ if (ret && (pos >= format + 2) && /* If there's something before %, */
+ (g_ascii_strcasecmp (pos - 2, "\n") != 0) && /* And if it is not a newline */
+ (g_ascii_strcasecmp (pos - 2, "%w") != 0)) /* Nor whitespace */
+ g_string_append (res, ", ");
+ pos += 2;
+ break;
+ case 'w':
+ if (ret && (pos >= format + 2) &&
+ (g_ascii_strcasecmp (pos - 2, "\n") != 0) &&
+ (g_ascii_strcasecmp (pos - 1, " ") != 0))
+ g_string_append (res, " ");
+ pos += 2;
+ break;
+ case '0': {
+ const gchar *bpos1, *bpos2;
+ gchar *inner;
+ gchar *ires;
+ gboolean replaced;
+
+ bpos1 = pos + 2;
+ bpos2 = find_balanced_bracket (bpos1);
+
+ inner = g_strndup (bpos1 + 1, bpos2 - bpos1 - 2); /* Get inner content of the %0 (...) */
+ replaced = parse_address_template_section (inner, realname, org_name, address, &ires);
+ if (replaced)
+ g_string_append (res, ires);
+
+ g_free (ires);
+ g_free (inner);
+
+ ret = replaced;
+ pos += (bpos2 - bpos1 + 2);
+ } break;
+ }
+
+ old_pos = pos;
+ }
+ g_string_append (res, old_pos);
+
+ *result = g_strdup (res->str);
+
+ g_string_free (res, TRUE);
+
+ return ret;
+}
+
+gchar *
+eab_format_address (EContact *contact,
+ EContactField address_type)
+{
+ gchar *result;
+ gchar *format = NULL;
+ gchar *country_position = NULL;
+ gchar *locale;
+ EContactAddress *addr = e_contact_get (contact, address_type);
+
+ if (!addr)
+ return NULL;
+
+ if (!addr->po && !addr->ext && !addr->street && !addr->locality && !addr->region &&
+ !addr->code && !addr->country) {
+ e_contact_address_free (addr);
+ return NULL;
+ }
+
+ if (addr->country) {
+ gchar *cntry = country_to_ISO (addr->country);
+ gchar **loc = get_locales ();
+ locale = g_strconcat (loc ? loc[LOCALES_LANGUAGE] : "C", "_", cntry, NULL);
+ g_strfreev (loc);
+ g_free (cntry);
+ } else
+ locale = get_locales_str ();
+
+ if (address_type == E_CONTACT_ADDRESS_HOME)
+ get_address_format (ADDRESS_FORMAT_HOME, locale, &format, &country_position);
+ else if (address_type == E_CONTACT_ADDRESS_WORK)
+ get_address_format (ADDRESS_FORMAT_BUSINESS, locale, &format, &country_position);
+ else {
+ e_contact_address_free (addr);
+ g_free (locale);
+ return NULL;
+ }
+
+ /* Expand all the variables in format.
+ * Don't display organization in home address;
+ * and skip full names, as it's part of the EContact itself,
+ * check this bug for reason: https://bugzilla.gnome.org/show_bug.cgi?id=667912
+ */
+ parse_address_template_section (
+ format,
+ NULL,
+ (address_type == E_CONTACT_ADDRESS_WORK) ?
+ e_contact_get_const (contact, E_CONTACT_ORG) : NULL,
+ addr,
+ &result);
+
+ /* Add the country line. In some countries, the address can be located above the
+ * rest of the address */
+ if (addr->country && country_position) {
+ gchar *country_upper = g_utf8_strup (addr->country, -1);
+ gchar *p = result;
+ if (g_strcmp0 (country_position, "BELOW") == 0) {
+ result = g_strconcat (p, "\n\n", country_upper, NULL);
+ g_free (p);
+ } else if (g_strcmp0 (country_position, "below") == 0) {
+ result = g_strconcat (p, "\n\n", addr->country, NULL);
+ g_free (p);
+ } else if (g_strcmp0 (country_position, "ABOVE") == 0) {
+ result = g_strconcat (country_upper, "\n\n", p, NULL);
+ g_free (p);
+ } else if (g_strcmp0 (country_position, "above") == 0) {
+ result = g_strconcat (addr->country, "\n\n", p, NULL);
+ g_free (p);
+ }
+ g_free (country_upper);
+ }
+
+ e_contact_address_free (addr);
+ g_free (locale);
+ g_free (format);
+ g_free (country_position);
+
+ return result;
+}
diff --git a/addressbook/gui/widgets/eab-gui-util.h b/addressbook/gui/widgets/eab-gui-util.h
new file mode 100644
index 0000000000..f169f8b8d3
--- /dev/null
+++ b/addressbook/gui/widgets/eab-gui-util.h
@@ -0,0 +1,63 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __E_ADDRESSBOOK_UTIL_H__
+#define __E_ADDRESSBOOK_UTIL_H__
+
+#include <gtk/gtk.h>
+#include <libebook/libebook.h>
+
+#include <e-util/e-util.h>
+
+G_BEGIN_DECLS
+
+void eab_error_dialog (EAlertSink *alert_sink,
+ GtkWindow *parent,
+ const gchar *msg,
+ const GError *error);
+void eab_load_error_dialog (GtkWidget *parent,
+ EAlertSink *alert_sink,
+ ESource *source,
+ const GError *error);
+void eab_search_result_dialog (EAlertSink *alert_sink,
+ const GError *error);
+gint eab_prompt_save_dialog (GtkWindow *parent);
+void eab_transfer_contacts (ESourceRegistry *registry,
+ EBookClient *source_client,
+ GSList *contacts, /* adopted */
+ gboolean delete_from_source,
+ EAlertSink *alert_sink);
+gchar * eab_suggest_filename (const GSList *contact_list);
+ESource * eab_select_source (ESourceRegistry *registry,
+ ESource *except_source,
+ const gchar *title,
+ const gchar *message,
+ const gchar *select_uid,
+ GtkWindow *parent);
+
+gchar * eab_format_address (EContact *contact,
+ EContactField address_type);
+
+G_END_DECLS
+
+#endif /* __E_ADDRESSBOOK_UTIL_H__ */
diff --git a/addressbook/gui/widgets/gal-view-factory-minicard.c b/addressbook/gui/widgets/gal-view-factory-minicard.c
deleted file mode 100644
index 10e13d9bdf..0000000000
--- a/addressbook/gui/widgets/gal-view-factory-minicard.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * gal-view-factory-minicard.c: A View Factory
- *
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * (C) 2000, 2001 Ximian, Inc.
- */
-#include <config.h>
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include "gal-view-factory-minicard.h"
-#include "gal-view-minicard.h"
-
-#define GVFE_CLASS(e) ((GalViewFactoryMinicardClass *)((GtkObject *)e)->klass)
-
-#define PARENT_TYPE gal_view_factory_get_type ()
-
-static GalViewFactoryClass *gal_view_factory_minicard_parent_class;
-
-static const char *
-gal_view_factory_minicard_get_title (GalViewFactory *factory)
-{
- return _("Card View");
-}
-
-static GalView *
-gal_view_factory_minicard_new_view (GalViewFactory *factory,
- const char *name)
-{
- return gal_view_minicard_new(name);
-}
-
-static const char *
-gal_view_factory_minicard_get_type_code (GalViewFactory *factory)
-{
- return "minicard";
-}
-
-static void
-gal_view_factory_minicard_destroy (GtkObject *object)
-{
-#if 0
- GalViewFactoryMinicard *factory = GAL_VIEW_FACTORY_MINICARD(object);
-#endif
-}
-
-static void
-gal_view_factory_minicard_class_init (GtkObjectClass *object_class)
-{
- GalViewFactoryClass *view_factory_class = GAL_VIEW_FACTORY_CLASS(object_class);
- gal_view_factory_minicard_parent_class = gtk_type_class (PARENT_TYPE);
-
- view_factory_class->get_title = gal_view_factory_minicard_get_title;
- view_factory_class->new_view = gal_view_factory_minicard_new_view;
- view_factory_class->get_type_code = gal_view_factory_minicard_get_type_code;
-
- object_class->destroy = gal_view_factory_minicard_destroy;
-}
-
-static void
-gal_view_factory_minicard_init (GalViewFactoryMinicard *factory)
-{
-}
-
-/**
- * gal_view_minicard_new
- *
- * A new GalViewFactory for creating Minicard views. Create one of
- * these and pass it to GalViewCollection for use.
- *
- * Returns: The new GalViewFactoryMinicard.
- */
-GalViewFactory *
-gal_view_factory_minicard_new (void)
-{
- return gal_view_factory_minicard_construct (gtk_type_new (gal_view_factory_minicard_get_type ()));
-}
-
-/**
- * gal_view_minicard_construct
- * @factory: The factory to construct
- *
- * constructs the GalViewFactoryMinicard. To be used by subclasses and
- * language bindings.
- *
- * Returns: The GalViewFactoryMinicard.
- */
-GalViewFactory *
-gal_view_factory_minicard_construct (GalViewFactoryMinicard *factory)
-{
- return GAL_VIEW_FACTORY(factory);
-}
-
-GtkType
-gal_view_factory_minicard_get_type (void)
-{
- static guint type = 0;
-
- if (!type)
- {
- GtkTypeInfo info =
- {
- "GalViewFactoryMinicard",
- sizeof (GalViewFactoryMinicard),
- sizeof (GalViewFactoryMinicardClass),
- (GtkClassInitFunc) gal_view_factory_minicard_class_init,
- (GtkObjectInitFunc) gal_view_factory_minicard_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
-
- return type;
-}
diff --git a/addressbook/gui/widgets/gal-view-factory-minicard.h b/addressbook/gui/widgets/gal-view-factory-minicard.h
deleted file mode 100644
index 3816fdba46..0000000000
--- a/addressbook/gui/widgets/gal-view-factory-minicard.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * gal-view-factory-minicard.c: A View Factory
- *
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * (C) 2000, 2001 Ximian, Inc.
- */
-#ifndef _GAL_VIEW_FACTORY_MINICARD_H_
-#define _GAL_VIEW_FACTORY_MINICARD_H_
-
-#include <gtk/gtkobject.h>
-#include <gal/menus/gal-view-factory.h>
-
-#define GAL_VIEW_FACTORY_MINICARD_TYPE (gal_view_factory_minicard_get_type ())
-#define GAL_VIEW_FACTORY_MINICARD(o) (GTK_CHECK_CAST ((o), GAL_VIEW_FACTORY_MINICARD_TYPE, GalViewFactoryMinicard))
-#define GAL_VIEW_FACTORY_MINICARD_CLASS(k) (GTK_CHECK_CLASS_CAST((k), GAL_VIEW_FACTORY_MINICARD_TYPE, GalViewFactoryMinicardClass))
-#define GAL_IS_VIEW_FACTORY_MINICARD(o) (GTK_CHECK_TYPE ((o), GAL_VIEW_FACTORY_MINICARD_TYPE))
-#define GAL_IS_VIEW_FACTORY_MINICARD_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), GAL_VIEW_FACTORY_MINICARD_TYPE))
-
-typedef struct {
- GalViewFactory base;
-} GalViewFactoryMinicard;
-
-typedef struct {
- GalViewFactoryClass parent_class;
-} GalViewFactoryMinicardClass;
-
-/* Standard functions */
-GtkType gal_view_factory_minicard_get_type (void);
-GalViewFactory *gal_view_factory_minicard_new (void);
-GalViewFactory *gal_view_factory_minicard_construct (GalViewFactoryMinicard *factory);
-
-#endif /* _GAL_VIEW_FACTORY_MINICARD_H_ */
diff --git a/addressbook/gui/widgets/gal-view-minicard.c b/addressbook/gui/widgets/gal-view-minicard.c
index b3162e51d1..99e8686675 100644
--- a/addressbook/gui/widgets/gal-view-minicard.c
+++ b/addressbook/gui/widgets/gal-view-minicard.c
@@ -1,120 +1,146 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
+ *
* gal-view-minicard.c: An Minicard View
*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
* Authors:
- * Chris Lahey <clahey@ximian.com>
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * (C) 2000, 2001 Ximian, Inc.
*/
+
+#ifdef HAVE_CONFIG_H
#include <config.h>
-#include "gal-view-minicard.h"
-#include <gnome-xml/parser.h>
-#include <gal/util/e-xml-utils.h>
+#endif
+
+#include <libxml/parser.h>
-#define PARENT_TYPE gal_view_get_type ()
-#define d(x) x
+#include "gal-view-minicard.h"
-static GalViewClass *gal_view_minicard_parent_class;
+G_DEFINE_TYPE (
+ GalViewMinicard,
+ gal_view_minicard,
+ GAL_TYPE_VIEW)
static void
-gal_view_minicard_edit (GalView *view)
+view_minicard_column_width_changed (EAddressbookView *address_view,
+ gdouble width)
{
- /* GalViewMinicard *minicard_view = GAL_VIEW_MINICARD(view); */
+ GalView *view;
+ GalViewInstance *view_instance;
+ GalViewMinicard *view_minicard;
+
+ view_instance = e_addressbook_view_get_view_instance (address_view);
+ view = gal_view_instance_get_current_view (view_instance);
+ view_minicard = GAL_VIEW_MINICARD (view);
+
+ if (view_minicard->column_width != width) {
+ view_minicard->column_width = width;
+ gal_view_changed (view);
+ }
}
-static void
-gal_view_minicard_load (GalView *view,
- const char *filename)
+static void
+view_minicard_finalize (GObject *object)
{
- xmlDoc *doc;
- doc = xmlParseFile (filename);
- if (doc) {
- xmlNode *root = xmlDocGetRootElement(doc);
- GAL_VIEW_MINICARD (view)->column_width = e_xml_get_double_prop_by_name_with_default (root, "column_width", 150);
- xmlFreeDoc(doc);
- }
+ GalViewMinicard *view = GAL_VIEW_MINICARD (object);
+
+ gal_view_minicard_detach (view);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (gal_view_minicard_parent_class)->finalize (object);
}
static void
-gal_view_minicard_save (GalView *view,
- const char *filename)
+view_minicard_load (GalView *view,
+ const gchar *filename)
{
+ GalViewMinicard *view_minicard;
xmlDoc *doc;
xmlNode *root;
- doc = xmlNewDoc("1.0");
- root = xmlNewNode (NULL, "EMinicardViewState");
- e_xml_set_double_prop_by_name (root, "column_width", GAL_VIEW_MINICARD (view)->column_width);
- xmlDocSetRootElement(doc, root);
- xmlSaveFile(filename, doc);
- xmlFreeDoc(doc);
-}
+ view_minicard = GAL_VIEW_MINICARD (view);
-static const char *
-gal_view_minicard_get_title (GalView *view)
-{
- return GAL_VIEW_MINICARD(view)->title;
+ doc = e_xml_parse_file (filename);
+ g_return_if_fail (doc != NULL);
+
+ root = xmlDocGetRootElement (doc);
+ view_minicard->column_width =
+ e_xml_get_double_prop_by_name_with_default (
+ root, (guchar *) "column_width", 225);
+ xmlFreeDoc (doc);
}
static void
-gal_view_minicard_set_title (GalView *view,
- const char *title)
+view_minicard_save (GalView *view,
+ const gchar *filename)
{
- g_free(GAL_VIEW_MINICARD(view)->title);
- GAL_VIEW_MINICARD(view)->title = g_strdup(title);
-}
+ GalViewMinicard *view_minicard;
+ xmlDoc *doc;
+ xmlNode *root;
-static const char *
-gal_view_minicard_get_type_code (GalView *view)
-{
- return "minicard";
+ view_minicard = GAL_VIEW_MINICARD (view);
+
+ doc = xmlNewDoc ((guchar *) "1.0");
+ root = xmlNewNode (NULL, (guchar *) "EMinicardViewState");
+ e_xml_set_double_prop_by_name (
+ root, (guchar *) "column_width",
+ view_minicard->column_width);
+ xmlDocSetRootElement (doc, root);
+ e_xml_save_file (filename, doc);
+ xmlFreeDoc (doc);
}
static GalView *
-gal_view_minicard_clone (GalView *view)
+view_minicard_clone (GalView *view)
{
- GalViewMinicard *gvm, *new;
+ GalViewMinicard *view_minicard;
+ GalView *clone;
- gvm = GAL_VIEW_MINICARD(view);
+ /* Chain up to parent's clone() method. */
+ clone = GAL_VIEW_CLASS (gal_view_minicard_parent_class)->clone (view);
- new = gtk_type_new (gal_view_minicard_get_type ());
- new->title = g_strdup (gvm->title);
- new->column_width = gvm->column_width;
+ view_minicard = GAL_VIEW_MINICARD (view);
+ GAL_VIEW_MINICARD (clone)->column_width = view_minicard->column_width;
- return GAL_VIEW(new);
+ return clone;
}
static void
-gal_view_minicard_destroy (GtkObject *object)
+gal_view_minicard_class_init (GalViewMinicardClass *class)
{
- GalViewMinicard *view = GAL_VIEW_MINICARD(object);
- gal_view_minicard_detach (view);
- g_free(view->title);
-}
+ GObjectClass *object_class;
+ GalViewClass *gal_view_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = view_minicard_finalize;
+
+ gal_view_class = GAL_VIEW_CLASS (class);
+ gal_view_class->type_code = "minicard";
+ gal_view_class->load = view_minicard_load;
+ gal_view_class->save = view_minicard_save;
+ gal_view_class->clone = view_minicard_clone;
-static void
-gal_view_minicard_class_init (GtkObjectClass *object_class)
-{
- GalViewClass *gal_view_class = GAL_VIEW_CLASS(object_class);
- gal_view_minicard_parent_class = gtk_type_class (PARENT_TYPE);
-
- gal_view_class->edit = gal_view_minicard_edit ;
- gal_view_class->load = gal_view_minicard_load ;
- gal_view_class->save = gal_view_minicard_save ;
- gal_view_class->get_title = gal_view_minicard_get_title ;
- gal_view_class->set_title = gal_view_minicard_set_title ;
- gal_view_class->get_type_code = gal_view_minicard_get_type_code;
- gal_view_class->clone = gal_view_minicard_clone ;
-
- object_class->destroy = gal_view_minicard_destroy ;
}
static void
-gal_view_minicard_init (GalViewMinicard *gvm)
+gal_view_minicard_init (GalViewMinicard *gvm)
{
- gvm->title = NULL;
- gvm->column_width = 150.0;
+ gvm->column_width = 225.0;
gvm->emvw = NULL;
gvm->emvw_column_width_changed_id = 0;
@@ -132,90 +158,47 @@ gal_view_minicard_init (GalViewMinicard *gvm)
GalView *
gal_view_minicard_new (const gchar *title)
{
- return gal_view_minicard_construct (gtk_type_new (gal_view_minicard_get_type ()), title);
-}
-
-/**
- * gal_view_minicard_construct
- * @view: The view to construct.
- * @title: The name of the new view.
- *
- * constructs the GalViewMinicard. To be used by subclasses and
- * language bindings.
- *
- * Returns: The GalViewMinicard.
- */
-GalView *
-gal_view_minicard_construct (GalViewMinicard *view,
- const gchar *title)
-{
- view->title = g_strdup(title);
- return GAL_VIEW(view);
+ return g_object_new (GAL_TYPE_VIEW_MINICARD, "title", title, NULL);
}
-GtkType
-gal_view_minicard_get_type (void)
+void
+gal_view_minicard_attach (GalViewMinicard *view,
+ EAddressbookView *address_view)
{
- static guint type = 0;
-
- if (!type)
- {
- GtkTypeInfo info =
- {
- "GalViewMinicard",
- sizeof (GalViewMinicard),
- sizeof (GalViewMinicardClass),
- (GtkClassInitFunc) gal_view_minicard_class_init,
- (GtkObjectInitFunc) gal_view_minicard_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
+ GObject *object;
- return type;
-}
+ g_return_if_fail (GAL_IS_VIEW_MINICARD (view));
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (address_view));
-static void
-column_width_changed (ETable *table, double width, GalViewMinicard *view)
-{
- d(g_print("%s: Old width = %f, New width = %f\n", __FUNCTION__, view->column_width, width));
- if (view->column_width != width) {
- view->column_width = width;
- gal_view_changed(GAL_VIEW(view));
- }
-}
+ object = e_addressbook_view_get_view_object (address_view);
+ g_return_if_fail (E_IS_MINICARD_VIEW_WIDGET (object));
-void
-gal_view_minicard_attach (GalViewMinicard *view, EMinicardViewWidget *emvw)
-{
gal_view_minicard_detach (view);
+ view->emvw = g_object_ref (object);
- view->emvw = emvw;
-
- gtk_object_ref (GTK_OBJECT (view->emvw));
-
- gtk_object_set (GTK_OBJECT (view->emvw),
- "column_width", (int) view->column_width,
- NULL);
+ g_object_set (view->emvw, "column-width", view->column_width, NULL);
view->emvw_column_width_changed_id =
- gtk_signal_connect(GTK_OBJECT(view->emvw), "column_width_changed",
- GTK_SIGNAL_FUNC (column_width_changed), view);
+ g_signal_connect_swapped (
+ view->emvw, "column-width-changed",
+ G_CALLBACK (view_minicard_column_width_changed),
+ address_view);
}
void
gal_view_minicard_detach (GalViewMinicard *view)
{
+ g_return_if_fail (GAL_IS_VIEW_MINICARD (view));
+
if (view->emvw == NULL)
return;
- if (view->emvw_column_width_changed_id) {
- gtk_signal_disconnect (GTK_OBJECT (view->emvw),
- view->emvw_column_width_changed_id);
+
+ if (view->emvw_column_width_changed_id > 0) {
+ g_signal_handler_disconnect (
+ view->emvw, view->emvw_column_width_changed_id);
view->emvw_column_width_changed_id = 0;
}
- gtk_object_unref (GTK_OBJECT (view->emvw));
+
+ g_object_unref (view->emvw);
view->emvw = NULL;
}
diff --git a/addressbook/gui/widgets/gal-view-minicard.h b/addressbook/gui/widgets/gal-view-minicard.h
index 31a28c56d9..4cec9568ca 100644
--- a/addressbook/gui/widgets/gal-view-minicard.h
+++ b/addressbook/gui/widgets/gal-view-minicard.h
@@ -1,46 +1,77 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* gal-view-minicard.h: An Minicard View
*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
* Authors:
- * Chris Lahey <clahey@ximian.com>
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * (C) 2000, 2001 Ximian, Inc.
*/
-#ifndef _GAL_VIEW_MINICARD_H_
-#define _GAL_VIEW_MINICARD_H_
-#include <gtk/gtkobject.h>
-#include <gal/menus/gal-view.h>
+#ifndef GAL_VIEW_MINICARD_H
+#define GAL_VIEW_MINICARD_H
+
+#include <e-util/e-util.h>
#include <e-minicard-view-widget.h>
+#include "e-addressbook-view.h"
-#define GAL_VIEW_MINICARD_TYPE (gal_view_minicard_get_type ())
-#define GAL_VIEW_MINICARD(o) (GTK_CHECK_CAST ((o), GAL_VIEW_MINICARD_TYPE, GalViewMinicard))
-#define GAL_VIEW_MINICARD_CLASS(k) (GTK_CHECK_CLASS_CAST((k), GAL_VIEW_MINICARD_TYPE, GalViewMinicardClass))
-#define GAL_IS_VIEW_MINICARD(o) (GTK_CHECK_TYPE ((o), GAL_VIEW_MINICARD_TYPE))
-#define GAL_IS_VIEW_MINICARD_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), GAL_VIEW_MINICARD_TYPE))
+/* Standard GObject macros */
+#define GAL_TYPE_VIEW_MINICARD \
+ (gal_view_minicard_get_type ())
+#define GAL_VIEW_MINICARD(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), GAL_TYPE_VIEW_MINICARD, GalViewMinicard))
+#define GAL_VIEW_MINICARD_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), GAL_TYPE_VIEW_MINICARD, GalViewMinicardClass))
+#define GAL_IS_VIEW_MINICARD(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), GAL_TYPE_VIEW_MINICARD))
+#define GAL_IS_VIEW_MINICARD_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), GAL_TYPE_VIEW_MINICARD))
+#define GAL_VIEW_MINICARD_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), GAL_TYPE_VIEW_MINICARD, GalViewMinicardClass))
-typedef struct {
- GalView base;
+G_BEGIN_DECLS
- char *title;
- double column_width;
+typedef struct _GalViewMinicard GalViewMinicard;
+typedef struct _GalViewMinicardClass GalViewMinicardClass;
+
+struct _GalViewMinicard {
+ GalView parent;
+
+ gdouble column_width;
EMinicardViewWidget *emvw;
guint emvw_column_width_changed_id;
-} GalViewMinicard;
+};
-typedef struct {
+struct _GalViewMinicardClass {
GalViewClass parent_class;
-} GalViewMinicardClass;
-
-/* Standard functions */
-GtkType gal_view_minicard_get_type (void);
-GalView *gal_view_minicard_new (const gchar *title);
-GalView *gal_view_minicard_construct (GalViewMinicard *view,
- const gchar *title);
-void gal_view_minicard_attach (GalViewMinicard *view,
- EMinicardViewWidget *emvw);
-void gal_view_minicard_detach (GalViewMinicard *view);
-
-#endif /* _GAL_VIEW_MINICARD_H_ */
+};
+
+GType gal_view_minicard_get_type (void);
+GalView * gal_view_minicard_new (const gchar *title);
+void gal_view_minicard_attach (GalViewMinicard *view,
+ EAddressbookView *address_view);
+void gal_view_minicard_detach (GalViewMinicard *view);
+
+G_END_DECLS
+
+#endif /* GAL_VIEW_MINICARD_H */
diff --git a/addressbook/gui/widgets/test-minicard-label.c b/addressbook/gui/widgets/test-minicard-label.c
deleted file mode 100644
index 7b1919aef4..0000000000
--- a/addressbook/gui/widgets/test-minicard-label.c
+++ /dev/null
@@ -1,131 +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(GtkWidget *app, gpointer data)
-{
- 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 */
- gtk_signal_connect( GTK_OBJECT( app ), "destroy",
- GTK_SIGNAL_FUNC( destroy_callback ),
- ( gpointer ) app );
-
- gtk_signal_connect( GTK_OBJECT( canvas ), "size_allocate",
- GTK_SIGNAL_FUNC( allocate_callback ),
- ( gpointer ) app );
-
- gtk_signal_connect( GTK_OBJECT( canvas ), "button_press_event",
- GTK_SIGNAL_FUNC( 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 caa9dac270..0000000000
--- a/addressbook/gui/widgets/test-minicard-view.c
+++ /dev/null
@@ -1,208 +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(GtkWidget *app, gpointer data)
-{
- 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 );
- gtk_object_get(GTK_OBJECT(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;
- gtk_object_get(GTK_OBJECT(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 guint
-ebook_create (void)
-{
- EBook *book;
-
- book = e_book_new ();
-
- if (!book) {
- printf ("%s: %s(): Couldn't create EBook, bailing.\n",
- __FILE__,
- __FUNCTION__);
- return FALSE;
- }
-
-
- if (! e_book_load_uri (book, "file:/tmp/test.db", book_open_cb, NULL)) {
- printf ("error calling load_uri!\n");
- }
-
-
- 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 );
- gtk_signal_connect( GTK_OBJECT( canvas ), "reflow",
- GTK_SIGNAL_FUNC( 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 */
- gtk_signal_connect( GTK_OBJECT( app ), "destroy",
- GTK_SIGNAL_FUNC( destroy_callback ),
- ( gpointer ) app );
-
- gtk_signal_connect( GTK_OBJECT( canvas ), "size_allocate",
- GTK_SIGNAL_FUNC( allocate_callback ),
- ( gpointer ) app );
-
- gtk_widget_show_all( app );
- gdk_window_set_back_pixmap( GTK_LAYOUT(canvas)->bin_window, NULL, FALSE);
-
- gtk_idle_add ((GtkFunction) 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 b84a591bbb..0000000000
--- a/addressbook/gui/widgets/test-minicard.c
+++ /dev/null
@@ -1,122 +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(GtkWidget *app, gpointer data)
-{
- 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 */
- gtk_signal_connect( GTK_OBJECT( app ), "destroy",
- GTK_SIGNAL_FUNC( destroy_callback ),
- ( gpointer ) app );
-
- gtk_signal_connect( GTK_OBJECT( canvas ), "size_allocate",
- GTK_SIGNAL_FUNC( allocate_callback ),
- ( gpointer ) app );
-
- gtk_widget_show_all( app );
-
- gtk_main();
-
- /* Not reached. */
- return 0;
-}
diff --git a/addressbook/gui/widgets/test-reflow.c b/addressbook/gui/widgets/test-reflow.c
deleted file mode 100644
index 14066c4cd0..0000000000
--- a/addressbook/gui/widgets/test-reflow.c
+++ /dev/null
@@ -1,201 +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.
- */
-
-#define TEST_VCARD \
-"BEGIN:VCARD
-" \
-"FN:Nat
-" \
-"N:Friedman;Nat;D;Mr.
-" \
-"TITLE:Head Geek
-" \
-"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 <gtk/gtkvbox.h>
-#include <libgnomeui/gnome-canvas-rect-ellipse.h>
-#include <libgnomeui/gnome-init.h>
-#include <gal/widgets/e-canvas.h>
-#include <gal/widgets/e-reflow.h>
-#include <gal/widgets/e-scroll-frame.h>
-
-#include "e-minicard.h"
-
-/* This is a horrible thing to do, but it is just a test. */
-GnomeCanvasItem *reflow;
-GnomeCanvasItem *rect;
-GtkAllocation last_alloc;
-
-static void destroy_callback(GtkWidget *app, gpointer data)
-{
- 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 );
- gtk_object_get(GTK_OBJECT(reflow),
- "width", &width,
- NULL);
- width = MAX(width, allocation->width);
- gnome_canvas_set_scroll_region(GNOME_CANVAS( canvas ), 0, 0, width - 1, allocation->height - 1);
- gnome_canvas_item_set( rect,
- "x2", (double) width,
- "y2", (double) allocation->height,
- NULL );
-}
-
-static void resize(GnomeCanvas *canvas, gpointer data)
-{
- double width;
- gtk_object_get(GTK_OBJECT(reflow),
- "width", &width,
- NULL);
- width = MAX(width, last_alloc.width);
- gnome_canvas_set_scroll_region(canvas , 0, 0, width - 1, last_alloc.height - 1);
- 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
-
-int main( int argc, char *argv[] )
-{
- GtkWidget *app;
- GtkWidget *canvas;
- GtkWidget *vbox;
- GtkWidget *scrollframe;
- int i;
-
- /* bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);*/
-
- gnome_init( "Reflow Test", VERSION, 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_reflow_get_type(),
- "height", (double) 100,
- "minimum_width", (double) 100,
- NULL );
- gtk_signal_connect( GTK_OBJECT( canvas ), "reflow",
- GTK_SIGNAL_FUNC( resize ),
- ( gpointer ) app);
- for ( i = 0; i < 200; i++ )
- {
- GnomeCanvasItem *item;
- ECard *card = e_card_new (TEST_VCARD);
- item = gnome_canvas_item_new( GNOME_CANVAS_GROUP(reflow),
- e_minicard_get_type(),
- "card", card,
- NULL);
- e_reflow_add_item(E_REFLOW(reflow), item, NULL);
- }
- gnome_canvas_set_scroll_region ( GNOME_CANVAS( canvas ),
- 0, 0,
- 100, 100 );
-
- scrollframe = e_scroll_frame_new (gtk_layout_get_hadjustment(GTK_LAYOUT(canvas)),
- gtk_layout_get_vadjustment(GTK_LAYOUT(canvas)));
- e_scroll_frame_set_policy (E_SCROLL_FRAME (scrollframe),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_NEVER);
-
- gtk_container_add (GTK_CONTAINER (scrollframe), canvas);
-
- gnome_app_set_contents( GNOME_APP( app ), scrollframe );
-
- /* Connect the signals */
- gtk_signal_connect( GTK_OBJECT( app ), "destroy",
- GTK_SIGNAL_FUNC( destroy_callback ),
- ( gpointer ) app );
-
- gtk_signal_connect( GTK_OBJECT( canvas ), "size_allocate",
- GTK_SIGNAL_FUNC( allocate_callback ),
- ( gpointer ) app );
-
- gtk_widget_show_all( app );
- gdk_window_set_back_pixmap( GTK_LAYOUT(canvas)->bin_window, NULL, FALSE);
-
- gtk_main();
-
- /* Not reached. */
- return 0;
-}
diff --git a/addressbook/importers/Makefile.am b/addressbook/importers/Makefile.am
new file mode 100644
index 0000000000..cce02a07d1
--- /dev/null
+++ b/addressbook/importers/Makefile.am
@@ -0,0 +1,32 @@
+privsolib_LTLIBRARIES = libevolution-addressbook-importers.la
+
+libevolution_addressbook_importers_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
+ -DEVOLUTION_SOUNDDIR=\""$(soundsdir)"\" \
+ -DG_LOG_DOMAIN=\"Evolution-Importer\" \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/addressbook \
+ -I$(top_builddir)/addressbook \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS)
+
+libevolution_addressbook_importers_la_SOURCES = \
+ evolution-ldif-importer.c \
+ evolution-vcard-importer.c \
+ evolution-csv-importer.c \
+ evolution-addressbook-importers.h
+
+libevolution_addressbook_importers_la_LDFLAGS = -avoid-version $(NO_UNDEFINED)
+
+libevolution_addressbook_importers_la_LIBADD = \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(top_builddir)/shell/libevolution-shell.la \
+ $(top_builddir)/addressbook/util/libeabutil.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_LIBS) \
+ $(IMPORTERS_LIBS)
+
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/importers/evolution-addressbook-importers.h b/addressbook/importers/evolution-addressbook-importers.h
new file mode 100644
index 0000000000..0ba2c9b6f4
--- /dev/null
+++ b/addressbook/importers/evolution-addressbook-importers.h
@@ -0,0 +1,30 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <gtk/gtk.h>
+
+struct _EImportImporter *evolution_ldif_importer_peek (void);
+struct _EImportImporter *evolution_vcard_importer_peek (void);
+struct _EImportImporter *evolution_csv_outlook_importer_peek (void);
+struct _EImportImporter *evolution_csv_mozilla_importer_peek (void);
+struct _EImportImporter *evolution_csv_evolution_importer_peek (void);
+
+/* private utility function for importers only */
+GtkWidget *evolution_contact_importer_get_preview_widget (const GSList *contacts);
diff --git a/addressbook/importers/evolution-csv-importer.c b/addressbook/importers/evolution-csv-importer.c
new file mode 100644
index 0000000000..6d5423e064
--- /dev/null
+++ b/addressbook/importers/evolution-csv-importer.c
@@ -0,0 +1,1101 @@
+/*
+ * Evolution CSV and TAB importer
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Devashish Sharma <sdevashish@novell.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+
+#include <libebook/libebook.h>
+
+#include <shell/e-shell.h>
+
+#include "evolution-addressbook-importers.h"
+
+#define NOMAP -1
+#define EVOLUTION_IMPORTER 3
+#define MOZILLA_IMPORTER 2
+#define OUTLOOK_IMPORTER 1
+#define CSV_FILE_DELIMITER ','
+#define TAB_FILE_DELIMITER '\t'
+
+typedef struct {
+ EImport *import;
+ EImportTarget *target;
+
+ guint idle_id;
+
+ gint state;
+ FILE *file;
+ gulong size;
+ gint count;
+
+ /* gint -> gint -- Column index in the CSV
+ * file to an index in the known fields array. */
+ GHashTable *fields_map;
+
+ EBookClient *book_client;
+ GSList *contacts;
+} CSVImporter;
+
+static gint importer;
+static gchar delimiter;
+
+static void csv_import_done (CSVImporter *gci);
+
+typedef struct {
+ const gchar *csv_attribute;
+ EContactField contact_field;
+#define FLAG_HOME_ADDRESS 0x01
+#define FLAG_WORK_ADDRESS 0x02
+#define FLAG_OTHER_ADDRESS 0x04
+#define FLAG_STREET 0x08
+#define FLAG_CITY 0x10
+#define FLAG_STATE 0x20
+#define FLAG_POSTAL_CODE 0x40
+#define FLAG_COUNTRY 0x80
+#define FLAG_POBOX 0x70
+#define FLAG_DATE_BDAY 0x03
+#define FLAG_BIRTH_DAY 0x05
+#define FLAG_BIRTH_YEAR 0x07
+#define FLAG_BIRTH_MONTH 0x50
+#define FLAG_DATE_ANNIVERSARY 0x30
+#define FLAG_INVALID 0xff
+ gint flags;
+}import_fields;
+
+static import_fields csv_fields_outlook[] = {
+ {"Title", NOMAP},
+ {"First Name", E_CONTACT_GIVEN_NAME},
+ {"Middle Name", NOMAP},
+ {"Last Name", E_CONTACT_FAMILY_NAME},
+ {"Suffix", NOMAP},
+ {"Company", E_CONTACT_ORG},
+ {"Department", E_CONTACT_ORG_UNIT},
+ {"Job Title", E_CONTACT_TITLE},
+ {"Business Street", NOMAP, FLAG_WORK_ADDRESS | FLAG_STREET },
+ {"Business Street 2", NOMAP, FLAG_WORK_ADDRESS | FLAG_STREET },
+ {"Business Street 3", NOMAP, FLAG_WORK_ADDRESS | FLAG_STREET},
+ {"Business City", NOMAP, FLAG_WORK_ADDRESS | FLAG_CITY},
+ {"Business State", NOMAP, FLAG_WORK_ADDRESS | FLAG_STATE},
+ {"Business Postal Code", NOMAP, FLAG_WORK_ADDRESS | FLAG_POSTAL_CODE},
+ {"Business Country", NOMAP, FLAG_WORK_ADDRESS | FLAG_COUNTRY},
+ {"Home Street", NOMAP, FLAG_HOME_ADDRESS | FLAG_STREET},
+ {"Home Street 2", NOMAP, FLAG_HOME_ADDRESS | FLAG_STREET},
+ {"Home Street 3", NOMAP, FLAG_HOME_ADDRESS | FLAG_STREET},
+ {"Home City", NOMAP, FLAG_HOME_ADDRESS | FLAG_CITY},
+ {"Home State", NOMAP, FLAG_HOME_ADDRESS | FLAG_STATE},
+ {"Home Postal Code", NOMAP,FLAG_HOME_ADDRESS | FLAG_POSTAL_CODE},
+ {"Home Country", NOMAP, FLAG_HOME_ADDRESS | FLAG_COUNTRY},
+ {"Other Street", NOMAP, FLAG_OTHER_ADDRESS | FLAG_STREET},
+ {"Other Street 2", NOMAP, FLAG_OTHER_ADDRESS | FLAG_STREET},
+ {"Other Street 3", NOMAP, FLAG_OTHER_ADDRESS | FLAG_STREET},
+ {"Other City", NOMAP, FLAG_OTHER_ADDRESS | FLAG_CITY},
+ {"Other State", NOMAP, FLAG_OTHER_ADDRESS | FLAG_STATE},
+ {"Other Postal Code", NOMAP, FLAG_OTHER_ADDRESS | FLAG_POSTAL_CODE},
+ {"Other Country", NOMAP, FLAG_OTHER_ADDRESS | FLAG_COUNTRY},
+ {"Assistant's Phone", E_CONTACT_PHONE_ASSISTANT},
+ {"Business Fax", E_CONTACT_PHONE_BUSINESS_FAX},
+ {"Business Phone", E_CONTACT_PHONE_BUSINESS},
+ {"Business Phone 2", E_CONTACT_PHONE_BUSINESS_2},
+ {"Callback", E_CONTACT_PHONE_CALLBACK},
+ {"Car Phone", E_CONTACT_PHONE_CAR},
+ {"Company Main Phone", E_CONTACT_PHONE_COMPANY},
+ {"Home Fax", E_CONTACT_PHONE_HOME_FAX},
+ {"Home Phone", E_CONTACT_PHONE_HOME},
+ {"Home Phone 2", E_CONTACT_PHONE_HOME_2},
+ {"ISDN", E_CONTACT_PHONE_ISDN},
+ {"Mobile Phone", E_CONTACT_PHONE_MOBILE},
+ {"Other Fax", E_CONTACT_PHONE_OTHER_FAX},
+ {"Other Phone", E_CONTACT_PHONE_OTHER},
+ {"Pager", E_CONTACT_PHONE_PAGER},
+ {"Primary Phone", E_CONTACT_PHONE_PRIMARY},
+ {"Radio Phone", E_CONTACT_PHONE_RADIO},
+ {"TTY/TDD Phone", E_CONTACT_PHONE_TTYTDD},
+ {"Telex", E_CONTACT_PHONE_TELEX},
+ {"Account", NOMAP},
+ {"Anniversary", NOMAP, FLAG_DATE_ANNIVERSARY},
+ {"Assistant's Name", E_CONTACT_ASSISTANT},
+ {"Billing Information", NOMAP},
+ {"Birthday", NOMAP, FLAG_DATE_BDAY},
+ {"Business Address PO Box", NOMAP, FLAG_WORK_ADDRESS | FLAG_POBOX},
+ {"Categories", E_CONTACT_CATEGORIES},
+ {"Children", NOMAP},
+ {"Directory Server", NOMAP},
+ {"E-mail Address", E_CONTACT_EMAIL_1},
+ {"E-mail Type", NOMAP},
+ {"E-mail Display Name", NOMAP},
+ {"E-mail 2 Address", E_CONTACT_EMAIL_2},
+ {"E-mail 2 Type", NOMAP},
+ {"E-mail 2 Display Name", NOMAP},
+ {"E-mail 3 Address", E_CONTACT_EMAIL_3},
+ {"E-mail 3 Type", NOMAP},
+ {"E-mail 3 Display Name", NOMAP},
+ {"Gender", NOMAP},
+ {"Government ID Number", NOMAP},
+ {"Hobby", NOMAP},
+ {"Home Address PO Box", NOMAP, FLAG_HOME_ADDRESS | FLAG_POBOX},
+ {"Initials", NOMAP},
+ {"Internet FREE/BUSY", E_CONTACT_FREEBUSY_URL},
+ {"Keywords", NOMAP},
+ {"Language", NOMAP},
+ {"Location", NOMAP},
+ {"Managers Name", E_CONTACT_MANAGER},
+ {"Mileage", NOMAP},
+ {"Notes", NOMAP},
+ {"Office Location", NOMAP},
+ {"Organizational ID Number", NOMAP},
+ {"Other Address PO Box", NOMAP, FLAG_OTHER_ADDRESS | FLAG_POBOX},
+ {"Priority", NOMAP},
+ {"Private", NOMAP},
+ {"Profession", NOMAP},
+ {"Referred By", NOMAP},
+ {"Senstivity", NOMAP},
+ {"Spouse", E_CONTACT_SPOUSE},
+ {"User 1", NOMAP},
+ {"User 2", NOMAP},
+ {"User 3", NOMAP},
+ {"User 4", NOMAP},
+ {"Web Page", E_CONTACT_HOMEPAGE_URL},
+};
+
+static import_fields csv_fields_mozilla[] = {
+ {"First Name", E_CONTACT_GIVEN_NAME},
+ {"Last Name", E_CONTACT_FAMILY_NAME},
+ {"Display Name", NOMAP},
+ {"NickName", E_CONTACT_NICKNAME},
+ {"E-mail Address", E_CONTACT_EMAIL_1},
+ {"E-mail 2 Address", E_CONTACT_EMAIL_2},
+ {"Business Phone", E_CONTACT_PHONE_BUSINESS},
+ {"Home Phone", E_CONTACT_PHONE_HOME},
+ {"Business Fax", E_CONTACT_PHONE_BUSINESS_FAX},
+ {"Pager", E_CONTACT_PHONE_PAGER},
+ {"Mobile Phone", E_CONTACT_PHONE_MOBILE},
+ {"Home Street", NOMAP, FLAG_HOME_ADDRESS | FLAG_STREET},
+ {"Home Street 2", NOMAP, FLAG_HOME_ADDRESS | FLAG_STREET},
+ {"Home City", NOMAP, FLAG_HOME_ADDRESS | FLAG_CITY},
+ {"Home State", NOMAP, FLAG_HOME_ADDRESS | FLAG_STATE},
+ {"Home Postal Code", NOMAP,FLAG_HOME_ADDRESS | FLAG_POSTAL_CODE},
+ {"Home Country", NOMAP, FLAG_HOME_ADDRESS | FLAG_COUNTRY},
+ {"Business Street", NOMAP, FLAG_WORK_ADDRESS | FLAG_STREET },
+ {"Business Street 2", NOMAP, FLAG_WORK_ADDRESS | FLAG_STREET },
+ {"Business City", NOMAP, FLAG_WORK_ADDRESS | FLAG_CITY},
+ {"Business State", NOMAP, FLAG_WORK_ADDRESS | FLAG_STATE},
+ {"Business Postal Code", NOMAP, FLAG_WORK_ADDRESS | FLAG_POSTAL_CODE},
+ {"Business Country", NOMAP, FLAG_WORK_ADDRESS | FLAG_COUNTRY},
+ {"Job Title", E_CONTACT_TITLE},
+ {"Department", E_CONTACT_ORG_UNIT},
+ {"Company", E_CONTACT_ORG},
+ {"Web Page", E_CONTACT_HOMEPAGE_URL},
+ {"Home Web Page", NOMAP},
+ {"Birth Year", NOMAP, FLAG_BIRTH_YEAR},
+ {"Birth Month", NOMAP,FLAG_BIRTH_MONTH},
+ {"Birth Day", NOMAP, FLAG_BIRTH_DAY},
+ {"Custom 1", NOMAP},
+ {"Custom 2", NOMAP},
+ {"Custom 3", NOMAP},
+ {"Custom 4", NOMAP},
+ {"Notes", NOMAP},
+
+};
+
+static import_fields csv_fields_evolution[] = {
+ {"First Name", E_CONTACT_GIVEN_NAME},
+ {"Last Name", E_CONTACT_FAMILY_NAME},
+ {"id", NOMAP, FLAG_INVALID},
+ {"NickName", E_CONTACT_NICKNAME},
+ {"E-mail Address", E_CONTACT_EMAIL_1},
+ {"E-mail 2 Address", E_CONTACT_EMAIL_2},
+ {"E-mail 3 Address", E_CONTACT_EMAIL_3},
+ {"E-mail 4 Address", E_CONTACT_EMAIL_4},
+ {"Wants HTML", E_CONTACT_WANTS_HTML},
+ {"Business Phone", E_CONTACT_PHONE_BUSINESS},
+ {"Home Phone", E_CONTACT_PHONE_HOME},
+ {"Business Fax", E_CONTACT_PHONE_BUSINESS_FAX},
+ {"Pager", E_CONTACT_PHONE_PAGER},
+ {"Mobile Phone", E_CONTACT_PHONE_MOBILE},
+ {"Home Street", NOMAP, FLAG_HOME_ADDRESS | FLAG_STREET},
+ {"Home Street 2", NOMAP, FLAG_INVALID},
+ {"Home City", NOMAP, FLAG_HOME_ADDRESS | FLAG_CITY},
+ {"Home State", NOMAP, FLAG_HOME_ADDRESS | FLAG_STATE},
+ {"Home Postal Code", NOMAP,FLAG_HOME_ADDRESS | FLAG_POSTAL_CODE},
+ {"Home Country", NOMAP, FLAG_HOME_ADDRESS | FLAG_COUNTRY},
+ {"Business Street", NOMAP, FLAG_WORK_ADDRESS | FLAG_STREET },
+ {"Business Street 2", NOMAP, FLAG_INVALID },
+ {"Business City", NOMAP, FLAG_WORK_ADDRESS | FLAG_CITY},
+ {"Business State", NOMAP, FLAG_WORK_ADDRESS | FLAG_STATE},
+ {"Business Postal Code", NOMAP, FLAG_WORK_ADDRESS | FLAG_POSTAL_CODE},
+ {"Business Country", NOMAP, FLAG_WORK_ADDRESS | FLAG_COUNTRY},
+ {"Job Title", E_CONTACT_TITLE},
+ {"Office", E_CONTACT_OFFICE},
+ {"Company", E_CONTACT_ORG},
+ {"Web Page", E_CONTACT_HOMEPAGE_URL},
+ {"Cal uri", E_CONTACT_CALENDAR_URI},
+ {"Birth Year", NOMAP, FLAG_BIRTH_YEAR},
+ {"Birth Month", NOMAP,FLAG_BIRTH_MONTH},
+ {"Birth Day", NOMAP, FLAG_BIRTH_DAY},
+ {"Notes", E_CONTACT_NOTE},
+};
+
+static void
+add_to_notes (EContact *contact,
+ const gchar *field_text,
+ gchar *val)
+{
+ GString *new_text;
+
+ if (!field_text || !val || !*val)
+ return;
+
+ new_text = g_string_new (e_contact_get_const (contact, E_CONTACT_NOTE));
+ if (strlen (new_text->str) != 0)
+ new_text = g_string_append_c (new_text, '\n');
+ new_text = g_string_append (new_text, field_text);
+ new_text = g_string_append_c (new_text, ':');
+ new_text = g_string_append (new_text, val);
+
+ e_contact_set (contact, E_CONTACT_NOTE, new_text->str);
+ g_string_free (new_text, TRUE);
+}
+
+/* @str: a date string in the format MM-DD-YYYY or MMDDYYYY */
+static EContactDate *
+date_from_string (const gchar *str)
+{
+ EContactDate * date;
+ gint i = 0;
+
+ g_return_val_if_fail (str != NULL, NULL);
+
+ date = e_contact_date_new ();
+
+ if (g_ascii_isdigit (str[i]) && g_ascii_isdigit (str[i + 1])) {
+ date->month = str[i] * 10 + str[i + 1] - '0' * 11;
+ i = i + 3;
+ }
+ else {
+ date->month = str[i] - '0' * 1;
+ i = i + 2;
+ }
+
+ if (g_ascii_isdigit (str[i]) && g_ascii_isdigit (str[i + 1])) {
+ date->day = str[i] * 10 + str[i + 1] - '0' * 11;
+ i = i + 3;
+ }
+ else {
+ date->day = str[i] - '0' * 1;
+ i = i + 2;
+ }
+ date->year = str[i] * 1000 + str[i + 1] * 100 +
+ str[i + 2] * 10 + str[i + 3] - '0' * 1111;
+
+ return date;
+}
+
+static GString *
+parseNextValue (const gchar **pptr)
+{
+ GString *value;
+ const gchar *ptr = *pptr;
+
+ g_return_val_if_fail (pptr != NULL, NULL);
+ g_return_val_if_fail (*pptr != NULL, NULL);
+
+ if (!*ptr || *ptr == '\n')
+ return NULL;
+
+ value = g_string_new ("");
+
+ while (*ptr != delimiter) {
+ if (*ptr == '\n')
+ break;
+ if (*ptr != '"') {
+ g_string_append_unichar (value, g_utf8_get_char (ptr));
+ } else {
+ ptr = g_utf8_next_char (ptr);
+ while (*ptr && *ptr != '"') {
+ g_string_append_unichar (value, g_utf8_get_char (ptr));
+ ptr = g_utf8_next_char (ptr);
+ }
+
+ if (!*ptr)
+ break;
+ }
+
+ ptr = g_utf8_next_char (ptr);
+ }
+
+ if (*ptr != 0 && *ptr != '\n')
+ ptr = g_utf8_next_char (ptr);
+
+ *pptr = ptr;
+
+ return value;
+}
+
+static GHashTable *
+map_fields (const gchar *header_line,
+ gint pimporter)
+{
+ import_fields *fields_array = NULL;
+ gint n_fields = -1, idx, j;
+ GString *value;
+ GHashTable *fmap;
+ const gchar *pptr = header_line;
+ gboolean any_found = FALSE;
+
+ if (pimporter == OUTLOOK_IMPORTER) {
+ fields_array = csv_fields_outlook;
+ n_fields = G_N_ELEMENTS (csv_fields_outlook);
+ } else if (pimporter == EVOLUTION_IMPORTER) {
+ fields_array = csv_fields_evolution;
+ n_fields = G_N_ELEMENTS (csv_fields_evolution);
+ }
+
+ g_return_val_if_fail (fields_array != NULL, NULL);
+ g_return_val_if_fail (n_fields > 0, NULL);
+
+ fmap = g_hash_table_new (g_direct_hash, g_direct_equal);
+ idx = 0;
+ while (value = parseNextValue (&pptr), value != NULL) {
+ for (j = 0; j < n_fields; j++) {
+ if (g_ascii_strcasecmp (fields_array[j].csv_attribute, value->str) == 0) {
+ g_hash_table_insert (
+ fmap, GINT_TO_POINTER (idx),
+ GINT_TO_POINTER (j + 1));
+ any_found = TRUE;
+ break;
+ }
+ }
+
+ if (j >= n_fields)
+ g_hash_table_insert (fmap, GINT_TO_POINTER (idx), GINT_TO_POINTER (-1));
+
+ g_string_free (value, TRUE);
+ idx++;
+ }
+
+ if (!any_found) {
+ /* column names not in English? */
+ g_hash_table_destroy (fmap);
+ fmap = NULL;
+ } else {
+ /* also add last index, to be always skipped */
+ g_hash_table_insert (fmap, GINT_TO_POINTER (idx), GINT_TO_POINTER (-1));
+ }
+
+ return fmap;
+}
+
+static gboolean
+parseLine (CSVImporter *gci,
+ EContact *contact,
+ gchar *buf)
+{
+ const gchar *pptr = buf, *field_text;
+ gchar *do_free = NULL;
+ GString *value;
+ gint ii = 0, idx;
+ gint flags = 0;
+ gint contact_field;
+ EContactAddress *home_address = NULL, *work_address = NULL, *other_address = NULL;
+ EContactDate *bday = NULL;
+ GString *home_street, *work_street, *other_street;
+ home_street = g_string_new ("");
+ work_street = g_string_new ("");
+ other_street = g_string_new ("");
+ home_address = g_new0 (EContactAddress, 1);
+ work_address = g_new0 (EContactAddress, 1);
+ other_address = g_new0 (EContactAddress, 1);
+ bday = g_new0 (EContactDate, 1);
+
+ if (!g_utf8_validate (pptr, -1, NULL)) {
+ do_free = g_convert (pptr, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
+ pptr = do_free;
+ }
+
+ while (value = parseNextValue (&pptr), value != NULL) {
+ contact_field = NOMAP;
+ flags = FLAG_INVALID;
+ field_text = NULL;
+
+ idx = ii;
+ if (gci->fields_map) {
+ gpointer found;
+
+ found = g_hash_table_lookup (
+ gci->fields_map, GINT_TO_POINTER (idx));
+
+ if (found == NULL) {
+ g_warning ("%s: No map for index %d, skipping it", G_STRFUNC, idx);
+ idx = -1;
+ } else {
+ idx = GPOINTER_TO_INT (found) - 1;
+ }
+ }
+
+ if (importer == OUTLOOK_IMPORTER) {
+ if (idx >= 0 && idx < G_N_ELEMENTS (csv_fields_outlook)) {
+ contact_field = csv_fields_outlook[idx].contact_field;
+ flags = csv_fields_outlook[idx].flags;
+ field_text = csv_fields_outlook[idx].csv_attribute;
+ }
+ }
+ else if (importer == MOZILLA_IMPORTER) {
+ if (idx >= 0 && idx < G_N_ELEMENTS (csv_fields_mozilla)) {
+ contact_field = csv_fields_mozilla[idx].contact_field;
+ flags = csv_fields_mozilla[idx].flags;
+ field_text = csv_fields_mozilla[idx].csv_attribute;
+ }
+ }
+ else {
+ if (idx >= 0 && idx < G_N_ELEMENTS (csv_fields_evolution)) {
+ contact_field = csv_fields_evolution[idx].contact_field;
+ flags = csv_fields_evolution[idx].flags;
+ field_text = csv_fields_evolution[idx].csv_attribute;
+ }
+ }
+
+ if (*value->str) {
+ if (contact_field != NOMAP) {
+ if (importer == OUTLOOK_IMPORTER || importer == MOZILLA_IMPORTER) {
+ e_contact_set (contact, contact_field, value->str);
+ } else {
+ if (contact_field == E_CONTACT_WANTS_HTML)
+ e_contact_set (
+ contact, contact_field,
+ GINT_TO_POINTER (
+ g_ascii_strcasecmp (
+ value->str, "TRUE") == 0));
+ else
+ e_contact_set (contact, contact_field, value->str);
+ }
+ }
+ else {
+ switch (flags) {
+
+ case FLAG_HOME_ADDRESS | FLAG_STREET:
+ if (strlen (home_street->str) != 0) {
+ home_street = g_string_append (home_street, ",\n");
+ }
+ home_street = g_string_append (home_street, value->str);
+ break;
+ case FLAG_HOME_ADDRESS | FLAG_CITY:
+ home_address->locality = g_strdup (value->str);
+ break;
+ case FLAG_HOME_ADDRESS | FLAG_STATE:
+ home_address->region = g_strdup (value->str);
+ break;
+ case FLAG_HOME_ADDRESS | FLAG_POSTAL_CODE:
+ home_address->code = g_strdup (value->str);
+ break;
+ case FLAG_HOME_ADDRESS | FLAG_POBOX:
+ home_address->po = g_strdup (value->str);
+ break;
+ case FLAG_HOME_ADDRESS | FLAG_COUNTRY:
+ home_address->country = g_strdup (value->str);
+ break;
+
+ case FLAG_WORK_ADDRESS | FLAG_STREET:
+ if (strlen (work_street->str) != 0) {
+ work_street = g_string_append (work_street, ",\n");
+ }
+ work_street = g_string_append (work_street, value->str);
+ break;
+ case FLAG_WORK_ADDRESS | FLAG_CITY:
+ work_address->locality = g_strdup (value->str);
+ break;
+ case FLAG_WORK_ADDRESS | FLAG_STATE:
+ work_address->region = g_strdup (value->str);
+ break;
+ case FLAG_WORK_ADDRESS | FLAG_POSTAL_CODE:
+ work_address->code = g_strdup (value->str);
+ break;
+ case FLAG_WORK_ADDRESS | FLAG_POBOX:
+ work_address->po = g_strdup (value->str);
+ break;
+ case FLAG_WORK_ADDRESS | FLAG_COUNTRY:
+ work_address->country = g_strdup (value->str);
+ break;
+
+ case FLAG_OTHER_ADDRESS | FLAG_STREET:
+ if (strlen (other_street->str) != 0) {
+ other_street = g_string_append (other_street, ",\n");
+ }
+ other_street = g_string_append (other_street, value->str);
+ break;
+ case FLAG_OTHER_ADDRESS | FLAG_CITY:
+ other_address->locality = g_strdup (value->str);
+ break;
+ case FLAG_OTHER_ADDRESS | FLAG_STATE:
+ other_address->region = g_strdup (value->str);
+ break;
+ case FLAG_OTHER_ADDRESS | FLAG_POSTAL_CODE:
+ other_address->code = g_strdup (value->str);
+ break;
+ case FLAG_OTHER_ADDRESS | FLAG_POBOX:
+ other_address->po = g_strdup (value->str);
+ break;
+ case FLAG_OTHER_ADDRESS | FLAG_COUNTRY:
+ other_address->country = g_strdup (value->str);
+ break;
+
+ case FLAG_DATE_BDAY:
+ e_contact_set (
+ contact,
+ E_CONTACT_BIRTH_DATE,
+ date_from_string (value->str));
+ break;
+
+ case FLAG_DATE_ANNIVERSARY:
+ e_contact_set (
+ contact,
+ E_CONTACT_ANNIVERSARY,
+ date_from_string (value->str));
+ break;
+
+ case FLAG_BIRTH_DAY:
+ bday->day = atoi (value->str);
+ break;
+ case FLAG_BIRTH_YEAR:
+ bday->year = atoi (value->str);
+ break;
+ case FLAG_BIRTH_MONTH:
+ bday->month = atoi (value->str);
+ break;
+
+ case FLAG_INVALID:
+ break;
+
+ default:
+ add_to_notes (contact, field_text, value->str);
+
+ }
+ }
+ }
+ ii++;
+ g_string_free (value, TRUE);
+ }
+ if (strlen (home_street->str) != 0)
+ home_address->street = g_strdup (home_street->str);
+ if (strlen (work_street->str) != 0)
+ work_address->street = g_strdup (work_street->str);
+ if (strlen (other_street->str) != 0)
+ other_address->street = g_strdup (other_street->str);
+ g_string_free (home_street, TRUE);
+ g_string_free (work_street, TRUE);
+ g_string_free (other_street, TRUE);
+
+ if (home_address->locality || home_address->country ||
+ home_address->code || home_address->region || home_address->street)
+ e_contact_set (contact, E_CONTACT_ADDRESS_HOME, home_address);
+ if (work_address->locality || work_address->country ||
+ work_address->code || work_address->region || work_address->street)
+ e_contact_set (contact, E_CONTACT_ADDRESS_WORK, work_address);
+ if (other_address->locality || other_address->country ||
+ other_address->code || other_address->region || other_address->street)
+ e_contact_set (contact, E_CONTACT_ADDRESS_OTHER, other_address);
+
+ if (importer != OUTLOOK_IMPORTER) {
+ if (bday->day || bday->year || bday->month)
+ e_contact_set (contact, E_CONTACT_BIRTH_DATE, bday);
+ }
+
+ g_free (do_free);
+
+ return TRUE;
+}
+
+static EContact *
+getNextCSVEntry (CSVImporter *gci,
+ FILE *f)
+{
+ EContact *contact = NULL;
+ GString *line;
+ GString *str;
+ gchar *buf;
+ gchar c;
+
+ line = g_string_new ("");
+ while (1) {
+ c = fgetc (f);
+ if (c == EOF)
+ return NULL;
+ if (c == '\n') {
+ g_string_append_c (line, c);
+ break;
+ }
+ if (c == '"') {
+ g_string_append_c (line, c);
+ c = fgetc (f);
+ while (!feof (f) && c != '"') {
+ g_string_append_c (line, c);
+ c = fgetc (f);
+ }
+ g_string_append_c (line, c);
+ }
+ else
+ g_string_append_c (line, c);
+ }
+
+ if (gci->count == 0 && importer != MOZILLA_IMPORTER) {
+ gci->fields_map = map_fields (line->str, importer);
+ g_string_free (line, TRUE);
+ line = g_string_new ("");
+ while (1) {
+ c = fgetc (f);
+ if (c == EOF)
+ return NULL;
+ if (c == '\n') {
+ g_string_append_c (line, c);
+ break;
+ }
+ if (c == '"') {
+ g_string_append_c (line, c);
+ c = fgetc (f);
+ while (!feof (f) && c != '"') {
+ g_string_append_c (line, c);
+ c = fgetc (f);
+ }
+ g_string_append_c (line, c);
+ }
+ else
+ g_string_append_c (line, c);
+ }
+ gci->count++;
+ }
+
+ str = g_string_new ("");
+ str = g_string_append (str, line->str);
+
+ g_string_free (line, TRUE);
+
+ if (strlen (str->str) == 0) {
+ g_string_free (str, TRUE);
+ return NULL;
+ }
+
+ contact = e_contact_new ();
+
+ buf = str->str;
+
+ if (!parseLine (gci, contact, buf)) {
+ g_object_unref (contact);
+ return NULL;
+ }
+ gci->count++;
+
+ g_string_free (str, TRUE);
+
+ return contact;
+}
+
+static gboolean
+csv_import_contacts (gpointer d)
+{
+ CSVImporter *gci = d;
+ EContact *contact = NULL;
+
+ while ((contact = getNextCSVEntry (gci, gci->file))) {
+ gchar *uid = NULL;
+ if (e_book_client_add_contact_sync (gci->book_client, contact, &uid, NULL, NULL) && uid) {
+ e_contact_set (contact, E_CONTACT_UID, uid);
+ g_free (uid);
+ }
+ gci->contacts = g_slist_prepend (gci->contacts, contact);
+ }
+ if (contact == NULL) {
+ gci->state = 1;
+ }
+ if (gci->state == 1) {
+ csv_import_done (gci);
+ return FALSE;
+ }
+ else {
+ e_import_status (
+ gci->import, gci->target, _("Importing..."),
+ ftell (gci->file) * 100 / gci->size);
+ return TRUE;
+ }
+}
+
+static void
+primary_selection_changed_cb (ESourceSelector *selector,
+ EImportTarget *target)
+{
+ ESource *source;
+
+ source = e_source_selector_ref_primary_selection (selector);
+ g_return_if_fail (source != NULL);
+
+ g_datalist_set_data_full (
+ &target->data, "csv-source",
+ source, (GDestroyNotify) g_object_unref);
+}
+
+static GtkWidget *
+csv_getwidget (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ EShell *shell;
+ GtkWidget *vbox, *selector;
+ ESourceRegistry *registry;
+ ESource *primary;
+ const gchar *extension_name;
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+
+ shell = e_shell_get_default ();
+ registry = e_shell_get_registry (shell);
+ extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+ selector = e_source_selector_new (registry, extension_name);
+ e_source_selector_set_show_toggles (
+ E_SOURCE_SELECTOR (selector), FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox), selector, FALSE, TRUE, 6);
+
+ primary = g_datalist_get_data (&target->data, "csv-source");
+ if (primary == NULL) {
+ GList *list;
+
+ list = e_source_registry_list_sources (registry, extension_name);
+ if (list != NULL) {
+ primary = g_object_ref (list->data);
+ g_datalist_set_data_full (
+ &target->data, "csv-source", primary,
+ (GDestroyNotify) g_object_unref);
+ }
+
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+ }
+ e_source_selector_set_primary_selection (
+ E_SOURCE_SELECTOR (selector), primary);
+
+ g_signal_connect (
+ selector, "primary_selection_changed",
+ G_CALLBACK (primary_selection_changed_cb), target);
+
+ gtk_widget_show_all (vbox);
+
+ return vbox;
+}
+
+static const gchar *supported_extensions[4] = {
+ ".csv", ".tab" , ".txt", NULL
+};
+
+static gboolean
+csv_supported (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ gchar *ext;
+ gint i;
+ EImportTargetURI *s;
+
+ if (target->type != E_IMPORT_TARGET_URI)
+ return FALSE;
+
+ s = (EImportTargetURI *) target;
+ if (s->uri_src == NULL)
+ return TRUE;
+
+ if (strncmp (s->uri_src, "file:///", 8) != 0)
+ return FALSE;
+
+ ext = strrchr (s->uri_src, '.');
+ if (ext == NULL)
+ return FALSE;
+
+ for (i = 0; supported_extensions[i] != NULL; i++) {
+ if (g_ascii_strcasecmp (supported_extensions[i], ext) == 0) {
+ if (i == 0) {
+ delimiter = CSV_FILE_DELIMITER;
+ }
+ else {
+ delimiter = TAB_FILE_DELIMITER;
+ }
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+csv_import_done (CSVImporter *gci)
+{
+ if (gci->idle_id)
+ g_source_remove (gci->idle_id);
+
+ fclose (gci->file);
+ g_object_unref (gci->book_client);
+ g_slist_foreach (gci->contacts, (GFunc) g_object_unref, NULL);
+ g_slist_free (gci->contacts);
+
+ if (gci->fields_map)
+ g_hash_table_destroy (gci->fields_map);
+
+ e_import_complete (gci->import, gci->target);
+ g_object_unref (gci->import);
+
+ g_free (gci);
+}
+
+static void
+book_client_connect_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ CSVImporter *gci = user_data;
+ EClient *client;
+
+ client = e_book_client_connect_finish (result, NULL);
+
+ if (client == NULL) {
+ csv_import_done (gci);
+ return;
+ }
+
+ gci->book_client = E_BOOK_CLIENT (client);
+ gci->idle_id = g_idle_add (csv_import_contacts, gci);
+}
+
+static void
+csv_import (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ CSVImporter *gci;
+ ESource *source;
+ gchar *filename;
+ FILE *file;
+ EImportTargetURI *s = (EImportTargetURI *) target;
+
+ filename = g_filename_from_uri (s->uri_src, NULL, NULL);
+ if (filename == NULL) {
+ g_message (G_STRLOC ": Couldn't get filename from URI '%s'", s->uri_src);
+ return;
+ }
+
+ file = g_fopen (filename, "r");
+ g_free (filename);
+ if (file == NULL) {
+ g_message ("Can't open .csv file");
+ e_import_complete (ei, target);
+ return;
+ }
+
+ gci = g_malloc0 (sizeof (*gci));
+ g_datalist_set_data (&target->data, "csv-data", gci);
+ gci->import = g_object_ref (ei);
+ gci->target = target;
+ gci->file = file;
+ gci->fields_map = NULL;
+ gci->count = 0;
+ fseek (file, 0, SEEK_END);
+ gci->size = ftell (file);
+ fseek (file, 0, SEEK_SET);
+
+ source = g_datalist_get_data (&target->data, "csv-source");
+
+ e_book_client_connect (source, NULL, book_client_connect_cb, gci);
+}
+
+static void
+outlook_csv_import (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ importer = OUTLOOK_IMPORTER;
+ csv_import (ei, target, im);
+}
+
+static void
+mozilla_csv_import (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ importer = MOZILLA_IMPORTER;
+ csv_import (ei, target, im);
+}
+
+static void
+evolution_csv_import (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ importer = EVOLUTION_IMPORTER;
+ csv_import (ei, target, im);
+}
+
+static void
+csv_cancel (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ CSVImporter *gci = g_datalist_get_data (&target->data, "csv-data");
+
+ if (gci)
+ gci->state = 1;
+}
+
+static GtkWidget *
+csv_get_preview (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ GtkWidget *preview;
+ GSList *contacts = NULL;
+ EContact *contact;
+ EImportTargetURI *s = (EImportTargetURI *) target;
+ gchar *filename;
+ FILE *file;
+ CSVImporter *gci;
+
+ filename = g_filename_from_uri (s->uri_src, NULL, NULL);
+ if (filename == NULL) {
+ g_message (G_STRLOC ": Couldn't get filename from URI '%s'", s->uri_src);
+ return NULL;
+ }
+
+ file = g_fopen (filename, "r");
+ g_free (filename);
+ if (file == NULL) {
+ g_message (G_STRLOC ": Can't open .csv file");
+ return NULL;
+ }
+
+ gci = g_malloc0 (sizeof (*gci));
+ gci->file = file;
+ gci->fields_map = NULL;
+ gci->count = 0;
+ fseek (file, 0, SEEK_END);
+ gci->size = ftell (file);
+ fseek (file, 0, SEEK_SET);
+
+ while (contact = getNextCSVEntry (gci, gci->file), contact != NULL) {
+ contacts = g_slist_prepend (contacts, contact);
+ }
+
+ contacts = g_slist_reverse (contacts);
+ preview = evolution_contact_importer_get_preview_widget (contacts);
+
+ g_slist_free_full (contacts, (GDestroyNotify) g_object_unref);
+ fclose (file);
+ g_free (gci);
+
+ return preview;
+}
+
+static GtkWidget *
+outlook_csv_get_preview (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ importer = OUTLOOK_IMPORTER;
+ return csv_get_preview (ei, target, im);
+}
+
+static GtkWidget *
+mozilla_csv_get_preview (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ importer = MOZILLA_IMPORTER;
+ return csv_get_preview (ei, target, im);
+}
+
+static GtkWidget *
+evolution_csv_get_preview (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ importer = EVOLUTION_IMPORTER;
+ return csv_get_preview (ei, target, im);
+}
+
+static EImportImporter csv_outlook_importer = {
+ E_IMPORT_TARGET_URI,
+ 0,
+ csv_supported,
+ csv_getwidget,
+ outlook_csv_import,
+ csv_cancel,
+ outlook_csv_get_preview,
+};
+
+static EImportImporter csv_mozilla_importer = {
+ E_IMPORT_TARGET_URI,
+ 0,
+ csv_supported,
+ csv_getwidget,
+ mozilla_csv_import,
+ csv_cancel,
+ mozilla_csv_get_preview,
+};
+
+static EImportImporter csv_evolution_importer = {
+ E_IMPORT_TARGET_URI,
+ 0,
+ csv_supported,
+ csv_getwidget,
+ evolution_csv_import,
+ csv_cancel,
+ evolution_csv_get_preview,
+};
+
+EImportImporter *
+evolution_csv_outlook_importer_peek (void)
+{
+ csv_outlook_importer.name = _("Outlook Contacts CSV or Tab (.csv, .tab)");
+ csv_outlook_importer.description = _("Outlook Contacts CSV and Tab Importer");
+
+ return &csv_outlook_importer;
+}
+
+EImportImporter *
+evolution_csv_mozilla_importer_peek (void)
+{
+ csv_mozilla_importer.name = _("Mozilla Contacts CSV or Tab (.csv, .tab)");
+ csv_mozilla_importer.description = _("Mozilla Contacts CSV and Tab Importer");
+
+ return &csv_mozilla_importer;
+}
+
+EImportImporter *
+evolution_csv_evolution_importer_peek (void)
+{
+ csv_evolution_importer.name = _("Evolution Contacts CSV or Tab (.csv, .tab)");
+ csv_evolution_importer.description = _("Evolution Contacts CSV and Tab Importer");
+
+ return &csv_evolution_importer;
+}
diff --git a/addressbook/importers/evolution-ldif-importer.c b/addressbook/importers/evolution-ldif-importer.c
new file mode 100644
index 0000000000..ae8fb5ac95
--- /dev/null
+++ b/addressbook/importers/evolution-ldif-importer.c
@@ -0,0 +1,805 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+/*
+ * LDIF importer. LDIF is the file format of an exported Netscape
+ * addressbook.
+ *
+ * Framework copied from evolution-gnomecard-importer.c
+ *
+ * Michael M. Morrison (mmorrison@kqcorp.com)
+ *
+ * Multi-line value support, mailing list support, base64 support, and
+ * various fixups: Chris Toshok (toshok@ximian.com)
+ *
+ * Made re-entrant, converted to eplugin, Michael Zucchi <notzed@ximian.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+
+#include <libebook/libebook.h>
+
+#include <shell/e-shell.h>
+
+#include "evolution-addressbook-importers.h"
+
+typedef struct {
+ EImport *import;
+ EImportTarget *target;
+
+ guint idle_id;
+
+ GHashTable *dn_contact_hash;
+
+ gint state; /* 0 - initial scan, 1 - list cards, 2 - cancelled/complete */
+ FILE *file;
+ gulong size;
+
+ EBookClient *book_client;
+
+ GSList *contacts;
+ GSList *list_contacts;
+ GSList *list_iterator;
+} LDIFImporter;
+
+static void ldif_import_done (LDIFImporter *gci);
+
+static struct {
+ const gchar *ldif_attribute;
+ EContactField contact_field;
+#define FLAG_HOME_ADDRESS 0x01
+#define FLAG_WORK_ADDRESS 0x02
+#define FLAG_LIST 0x04
+#define FLAG_BOOLEAN 0x08
+ gint flags;
+}
+ldif_fields[] = {
+ { "cn", E_CONTACT_FULL_NAME },
+ { "mail", E_CONTACT_EMAIL, FLAG_LIST },
+ { "mozillaSecondEmail", E_CONTACT_EMAIL_2},
+#if 0
+ { "givenname", E_CONTACT_GIVEN_NAME },
+#endif
+ { "sn", E_CONTACT_FAMILY_NAME },
+ { "xmozillanickname", E_CONTACT_NICKNAME },
+
+ { "o", E_CONTACT_ORG },
+ { "ou", E_CONTACT_ORG_UNIT },
+ { "title", E_CONTACT_TITLE },
+
+ { "locality", 0, FLAG_WORK_ADDRESS },
+ { "l", 0, FLAG_WORK_ADDRESS },
+ { "mozillahomelocalityname", 0, FLAG_HOME_ADDRESS },
+ { "st", 0, FLAG_WORK_ADDRESS },
+ { "mozillaHomeState", 0, FLAG_HOME_ADDRESS },
+ { "streetaddress", 0, FLAG_WORK_ADDRESS },
+ { "postalcode", 0, FLAG_WORK_ADDRESS },
+ { "mozillaHomePostalCode", 0, FLAG_HOME_ADDRESS },
+ { "countryname", 0, FLAG_WORK_ADDRESS },
+ { "c", 0, FLAG_WORK_ADDRESS },
+ { "mozillaHomeCountryName", 0, FLAG_HOME_ADDRESS },
+ { "postalAddress", 0, FLAG_WORK_ADDRESS },
+ { "homePostalAddress", 0, FLAG_HOME_ADDRESS },
+ { "mozillaPostalAddress2", 0, FLAG_WORK_ADDRESS },
+ { "mozillaHomePostalAddress2", 0, FLAG_HOME_ADDRESS },
+
+ { "telephonenumber", E_CONTACT_PHONE_BUSINESS},
+ { "homephone", E_CONTACT_PHONE_HOME },
+ { "facsimiletelephonenumber", E_CONTACT_PHONE_BUSINESS_FAX },
+ { "pagerphone", E_CONTACT_PHONE_PAGER },
+ { "cellphone", E_CONTACT_PHONE_MOBILE },
+ { "mobile", E_CONTACT_PHONE_MOBILE },
+
+ { "homeurl", E_CONTACT_HOMEPAGE_URL },
+ { "mozillaHomeUrl", E_CONTACT_HOMEPAGE_URL },
+
+ { "description", E_CONTACT_NOTE },
+
+ { "xmozillausehtmlmail", E_CONTACT_WANTS_HTML, FLAG_BOOLEAN },
+
+ { "nsAIMid", E_CONTACT_IM_AIM, FLAG_LIST },
+ { "mozilla_AimScreenName", E_CONTACT_IM_AIM, FLAG_LIST }
+};
+
+static GString *
+getValue (gchar **src)
+{
+ GString *dest = g_string_new ("");
+ gchar *s = *src;
+ gboolean need_base64 = (*s == ':');
+
+ copy_line:
+ while (*s != 0 && *s != '\n' && *s != '\r')
+ dest = g_string_append_c (dest, *s++);
+
+ if (*s == '\r') s++;
+ if (*s == '\n') s++;
+
+ /* check for continuation here */
+ if (*s == ' ') {
+ s++;
+ goto copy_line;
+ }
+
+ if (need_base64) {
+ guchar *data;
+ gsize length;
+
+ /* XXX g_string_assign_len() would be nice here */
+ data = g_base64_decode (dest->str + 2, &length);
+ g_string_truncate (dest, 0);
+ g_string_append_len (dest, (gchar *) data, length);
+ g_free (data);
+ }
+
+ *src = s;
+
+ return dest;
+}
+
+static void
+populate_contact_address (EContactAddress *address,
+ gchar *attr,
+ gchar *value)
+{
+ if (!g_ascii_strcasecmp (attr, "locality") ||
+ !g_ascii_strcasecmp (attr, "l") ||
+ !g_ascii_strcasecmp (attr, "mozillaHomeLocalityName"))
+ address->locality = g_strdup (value);
+ else if (!g_ascii_strcasecmp (attr, "countryname") ||
+ !g_ascii_strcasecmp (attr, "c") ||
+ !g_ascii_strcasecmp (attr, "mozillaHomeCountryName"))
+ address->country = g_strdup (value);
+ else if (!g_ascii_strcasecmp (attr, "postalcode") ||
+ !g_ascii_strcasecmp (attr, "mozillaHomePostalCode"))
+ address->code = g_strdup (value);
+ else if (!g_ascii_strcasecmp (attr, "st") ||
+ !g_ascii_strcasecmp (attr, "mozillaHomeState"))
+ address->region = g_strdup (value);
+ else if (!g_ascii_strcasecmp (attr, "streetaddress"))
+ address->street = g_strdup (value);
+ else if (!g_ascii_strcasecmp (attr, "mozillaPostalAddress2") ||
+ !g_ascii_strcasecmp (attr, "mozillaHomePostalAddress2")) {
+ if (address->ext && *address->ext) {
+ gchar *temp = g_strdup (address->ext);
+ g_free (address->ext);
+ address->ext = g_strconcat (temp, ",\n", value, NULL);
+ g_free (temp);
+ }
+ else {
+ address->ext = g_strdup (value);
+ }
+ }
+ else if (!g_ascii_strcasecmp (attr, "postalAddress") ||
+ !g_ascii_strcasecmp (attr, "homepostalAddress")) {
+ gchar *c, *i, *addr_field;
+
+ addr_field = g_strdup (value);
+ i = addr_field;
+ for (c = addr_field; *c != '\0'; c++) {
+ i++;
+ if (*c == ',' && *i != '\0' && *i == ' ') {
+ *i = '\n';
+ }
+ }
+ if (address->ext && *address->ext) {
+ gchar *temp = g_strdup (address->ext);
+ g_free (address->ext);
+ address->ext = g_strconcat (addr_field, ",\n", temp, NULL);
+ g_free (temp);
+ g_free (addr_field);
+ }
+ else {
+ address->ext = addr_field;
+ }
+ }
+}
+
+static gboolean
+parseLine (GHashTable *dn_contact_hash,
+ EContact *contact,
+ EContactAddress *work_address,
+ EContactAddress *home_address,
+ gchar **buf)
+{
+ gchar *ptr;
+ gchar *colon, *value;
+ gboolean field_handled;
+ GString *ldif_value;
+
+ ptr = *buf;
+
+ /* if the string is empty, return */
+ if (*ptr == '\0') {
+ *buf = NULL;
+ return TRUE;
+ }
+
+ /* skip comment lines */
+ if (*ptr == '#') {
+ ptr = strchr (ptr, '\n');
+ if (!ptr)
+ *buf = NULL;
+ else
+ *buf = ptr + 1;
+ return TRUE;
+ }
+
+ /* first, check for a 'continuation' line */
+ if (ptr[0] == ' ' && ptr[1] != '\n') {
+ g_warning ("unexpected continuation line");
+ return FALSE;
+ }
+
+ colon = (gchar *) strchr (ptr, ':');
+ if (colon) {
+ gint i;
+
+ *colon = 0;
+ value = colon + 1;
+ while (isspace (*value))
+ value++;
+
+ ldif_value = getValue (&value);
+
+ field_handled = FALSE;
+ for (i = 0; i < G_N_ELEMENTS (ldif_fields); i++) {
+ if (!g_ascii_strcasecmp (ptr, ldif_fields[i].ldif_attribute)) {
+ if (ldif_fields[i].flags & FLAG_WORK_ADDRESS) {
+ populate_contact_address (work_address, ptr, ldif_value->str);
+ }
+ else if (ldif_fields[i].flags & FLAG_HOME_ADDRESS) {
+ populate_contact_address (home_address, ptr, ldif_value->str);
+ }
+ else if (ldif_fields[i].flags & FLAG_LIST) {
+ GList *list;
+
+ list = e_contact_get (contact, ldif_fields[i].contact_field);
+ list = g_list_append (list, g_strdup (ldif_value->str));
+ e_contact_set (contact, ldif_fields[i].contact_field, list);
+
+ g_list_foreach (list, (GFunc) g_free, NULL);
+ g_list_free (list);
+ }
+ else if (ldif_fields[i].flags & FLAG_BOOLEAN) {
+ if (!g_ascii_strcasecmp (ldif_value->str, "true")) {
+ e_contact_set (
+ contact,
+ ldif_fields[i].contact_field,
+ GINT_TO_POINTER (TRUE));
+ }
+ else {
+ e_contact_set (
+ contact,
+ ldif_fields[i].contact_field,
+ GINT_TO_POINTER (FALSE));
+ }
+ g_message ("set %s to %s", ptr, ldif_value->str);
+ }
+ else {
+ /* FIXME is everything a string? */
+ e_contact_set (
+ contact,
+ ldif_fields[i].contact_field,
+ ldif_value->str);
+ g_message ("set %s to %s", ptr, ldif_value->str);
+ }
+ field_handled = TRUE;
+ break;
+ }
+ }
+
+ /* handle objectclass/dn/member out here */
+ if (!field_handled) {
+ if (!g_ascii_strcasecmp (ptr, "dn"))
+ g_hash_table_insert (
+ dn_contact_hash,
+ g_strdup (ldif_value->str), contact);
+ else if (!g_ascii_strcasecmp (ptr, "objectclass") &&
+ !g_ascii_strcasecmp (ldif_value->str, "groupofnames")) {
+ e_contact_set (
+ contact, E_CONTACT_IS_LIST,
+ GINT_TO_POINTER (TRUE));
+ } else if (!g_ascii_strcasecmp (ptr, "member")) {
+ GList *email;
+
+ email = e_contact_get (contact, E_CONTACT_EMAIL);
+ email = g_list_append (email, g_strdup (ldif_value->str));
+ e_contact_set (contact, E_CONTACT_EMAIL, email);
+
+ g_list_foreach (email, (GFunc) g_free, NULL);
+ g_list_free (email);
+ }
+ }
+
+ /* put the colon back the way it was, just for kicks */
+ *colon = ':';
+
+ g_string_free (ldif_value, TRUE);
+
+ } else {
+ g_warning ("unrecognized entry %s", ptr);
+ return FALSE;
+ }
+
+ *buf = value;
+
+ return TRUE;
+}
+
+static EContact *
+getNextLDIFEntry (GHashTable *dn_contact_hash,
+ FILE *f)
+{
+ EContact *contact;
+ EContactAddress *work_address, *home_address;
+ GString *str;
+ gchar line[1024];
+ gchar *buf;
+
+ str = g_string_new ("");
+ /* read from the file until we get to a blank line (or eof) */
+ while (!feof (f)) {
+ if (!fgets (line, sizeof (line), f))
+ break;
+ if (line[0] == '\n' || (line[0] == '\r' && line[1] == '\n'))
+ break;
+ str = g_string_append (str, line);
+ }
+
+ if (strlen (str->str) == 0) {
+ g_string_free (str, TRUE);
+ return NULL;
+ }
+
+ /* now parse that entry */
+ contact = e_contact_new ();
+ work_address = g_new0 (EContactAddress, 1);
+ home_address = g_new0 (EContactAddress, 1);
+
+ buf = str->str;
+ while (buf) {
+ if (!parseLine (dn_contact_hash, contact, work_address, home_address, &buf)) {
+ /* parsing error */
+ g_string_free (str, TRUE);
+ e_contact_address_free (work_address);
+ e_contact_address_free (home_address);
+ g_object_unref (contact);
+ return NULL;
+ }
+ }
+
+ /* fill in the address */
+ if (work_address->locality || work_address->country || work_address->ext ||
+ work_address->code || work_address->region || work_address->street) {
+ e_contact_set (contact, E_CONTACT_ADDRESS_WORK, work_address);
+ }
+ if (home_address->locality || home_address->country || home_address->ext ||
+ home_address->code || home_address->region || home_address->street) {
+ e_contact_set (contact, E_CONTACT_ADDRESS_HOME, home_address);
+ }
+ e_contact_address_free (work_address);
+ e_contact_address_free (home_address);
+
+ g_string_free (str, TRUE);
+
+ return contact;
+}
+
+static void
+resolve_list_card (LDIFImporter *gci,
+ EContact *contact)
+{
+ GList *email, *l;
+ GList *email_attrs = NULL;
+ gchar *full_name;
+
+ /* set file_as to full_name so we don't later try and figure
+ * out a first/last name for the list. */
+ full_name = e_contact_get (contact, E_CONTACT_FULL_NAME);
+ if (full_name)
+ e_contact_set (contact, E_CONTACT_FILE_AS, full_name);
+ g_free (full_name);
+
+ /* FIMXE getting might not be implemented in ebook */
+ email = e_contact_get (contact, E_CONTACT_EMAIL);
+ for (l = email; l; l = l->next) {
+ /* mozilla stuffs dn's in the EMAIL list for contact lists */
+ gchar *dn = l->data;
+ EContact *dn_contact = g_hash_table_lookup (gci->dn_contact_hash, dn);
+
+ /* break list chains here, since we don't support them just yet */
+ if (dn_contact && !e_contact_get (dn_contact, E_CONTACT_IS_LIST)) {
+ EDestination *dest;
+ EVCardAttribute *attr = e_vcard_attribute_new (NULL, EVC_EMAIL);
+
+ /* Hard-wired for default e-mail, since
+ * netscape only exports 1 email address. */
+ dest = e_destination_new ();
+ e_destination_set_contact (dest, dn_contact, 0);
+
+ e_destination_export_to_vcard_attribute (dest, attr);
+
+ g_object_unref (dest);
+
+ email_attrs = g_list_append (email_attrs, attr);
+ }
+ }
+ e_contact_set_attributes (contact, E_CONTACT_EMAIL, email_attrs);
+
+ g_list_foreach (email, (GFunc) g_free, NULL);
+ g_list_free (email);
+ g_list_foreach (email_attrs, (GFunc) e_vcard_attribute_free, NULL);
+ g_list_free (email_attrs);
+}
+
+static void
+add_to_notes (EContact *contact,
+ EContactField field)
+{
+ const gchar *old_text;
+ const gchar *field_text;
+ gchar *new_text;
+
+ old_text = e_contact_get_const (contact, E_CONTACT_NOTE);
+ if (old_text && strstr (old_text, e_contact_pretty_name (field)))
+ return;
+
+ field_text = e_contact_get_const (contact, field);
+ if (!field_text || !*field_text)
+ return;
+
+ new_text = g_strdup_printf (
+ "%s%s%s: %s",
+ old_text ? old_text : "",
+ old_text && *old_text &&
+ *(old_text + strlen (old_text) - 1) != '\n' ? "\n" : "",
+ e_contact_pretty_name (field), field_text);
+ e_contact_set (contact, E_CONTACT_NOTE, new_text);
+ g_free (new_text);
+}
+
+static gboolean
+ldif_import_contacts (gpointer d)
+{
+ LDIFImporter *gci = d;
+ EContact *contact;
+ GSList *iter;
+ gint count = 0;
+
+ /* We process all normal cards immediately and keep the list
+ * ones till the end */
+
+ if (gci->state == 0) {
+ while (count < 50 && (contact = getNextLDIFEntry (
+ gci->dn_contact_hash, gci->file))) {
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ gci->list_contacts = g_slist_prepend (
+ gci->list_contacts, contact);
+ } else {
+ gchar *uid = NULL;
+
+ add_to_notes (contact, E_CONTACT_OFFICE);
+ add_to_notes (contact, E_CONTACT_SPOUSE);
+ add_to_notes (contact, E_CONTACT_BLOG_URL);
+ if (e_book_client_add_contact_sync (gci->book_client, contact, &uid, NULL, NULL) && uid) {
+ e_contact_set (contact, E_CONTACT_UID, uid);
+ g_free (uid);
+ }
+ gci->contacts = g_slist_prepend (gci->contacts, contact);
+ }
+ count++;
+ }
+ if (contact == NULL) {
+ gci->state = 1;
+ gci->list_iterator = gci->list_contacts;
+ }
+ }
+ if (gci->state == 1) {
+ for (iter = gci->list_iterator; count < 50 && iter; iter = iter->next) {
+ gchar *uid = NULL;
+
+ contact = iter->data;
+ resolve_list_card (gci, contact);
+ if (e_book_client_add_contact_sync (gci->book_client, contact, &uid, NULL, NULL) && uid) {
+ e_contact_set (contact, E_CONTACT_UID, uid);
+ g_free (uid);
+ }
+ count++;
+ }
+ gci->list_iterator = iter;
+ if (iter == NULL)
+ gci->state = 2;
+ }
+ if (gci->state == 2) {
+ ldif_import_done (gci);
+ return FALSE;
+ } else {
+ e_import_status (
+ gci->import, gci->target, _("Importing..."),
+ ftell (gci->file) * 100 / gci->size);
+ return TRUE;
+ }
+}
+
+static void
+primary_selection_changed_cb (ESourceSelector *selector,
+ EImportTarget *target)
+{
+ ESource *source;
+
+ source = e_source_selector_ref_primary_selection (selector);
+ g_return_if_fail (source != NULL);
+
+ g_datalist_set_data_full (
+ &target->data, "ldif-source",
+ source, (GDestroyNotify) g_object_unref);
+}
+
+static GtkWidget *
+ldif_getwidget (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ EShell *shell;
+ GtkWidget *vbox, *selector;
+ ESourceRegistry *registry;
+ ESource *primary;
+ const gchar *extension_name;
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+
+ shell = e_shell_get_default ();
+ registry = e_shell_get_registry (shell);
+ extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+ selector = e_source_selector_new (registry, extension_name);
+ e_source_selector_set_show_toggles (
+ E_SOURCE_SELECTOR (selector), FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox), selector, FALSE, TRUE, 6);
+
+ primary = g_datalist_get_data (&target->data, "ldif-source");
+ if (primary == NULL) {
+ GList *list;
+
+ list = e_source_registry_list_sources (registry, extension_name);
+ if (list != NULL) {
+ primary = g_object_ref (list->data);
+ g_datalist_set_data_full (
+ &target->data, "ldif-source", primary,
+ (GDestroyNotify) g_object_unref);
+ }
+
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+ }
+ e_source_selector_set_primary_selection (
+ E_SOURCE_SELECTOR (selector), primary);
+
+ g_signal_connect (
+ selector, "primary_selection_changed",
+ G_CALLBACK (primary_selection_changed_cb), target);
+
+ gtk_widget_show_all (vbox);
+
+ return vbox;
+}
+
+static const gchar *supported_extensions[3] = {
+ ".ldif", ".ldi", NULL
+};
+
+static gboolean
+ldif_supported (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ gchar *ext;
+ gint i;
+ EImportTargetURI *s;
+
+ if (target->type != E_IMPORT_TARGET_URI)
+ return FALSE;
+
+ s = (EImportTargetURI *) target;
+ if (s->uri_src == NULL)
+ return TRUE;
+
+ if (strncmp (s->uri_src, "file:///", 8) != 0)
+ return FALSE;
+
+ ext = strrchr (s->uri_src, '.');
+ if (ext == NULL)
+ return FALSE;
+
+ for (i = 0; supported_extensions[i] != NULL; i++) {
+ if (g_ascii_strcasecmp (supported_extensions[i], ext) == 0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+ldif_import_done (LDIFImporter *gci)
+{
+ if (gci->idle_id)
+ g_source_remove (gci->idle_id);
+
+ fclose (gci->file);
+ g_object_unref (gci->book_client);
+ g_slist_foreach (gci->contacts, (GFunc) g_object_unref, NULL);
+ g_slist_foreach (gci->list_contacts, (GFunc) g_object_unref, NULL);
+ g_slist_free (gci->contacts);
+ g_slist_free (gci->list_contacts);
+ g_hash_table_destroy (gci->dn_contact_hash);
+
+ e_import_complete (gci->import, gci->target);
+ g_object_unref (gci->import);
+
+ g_free (gci);
+}
+
+static void
+book_client_connect_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ LDIFImporter *gci = user_data;
+ EClient *client;
+
+ client = e_book_client_connect_finish (result, NULL);
+
+ if (client == NULL) {
+ ldif_import_done (gci);
+ return;
+ }
+
+ gci->book_client = E_BOOK_CLIENT (client);
+ gci->idle_id = g_idle_add (ldif_import_contacts, gci);
+}
+
+static void
+ldif_import (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ LDIFImporter *gci;
+ ESource *source;
+ FILE *file = NULL;
+ EImportTargetURI *s = (EImportTargetURI *) target;
+ gchar *filename;
+
+ filename = g_filename_from_uri (s->uri_src, NULL, NULL);
+ if (filename != NULL) {
+ file = g_fopen (filename, "r");
+ g_free (filename);
+ }
+ if (file == NULL) {
+ g_message (G_STRLOC ":Can't open .ldif file");
+ e_import_complete (ei, target);
+ return;
+ }
+
+ gci = g_malloc0 (sizeof (*gci));
+ g_datalist_set_data (&target->data, "ldif-data", gci);
+ gci->import = g_object_ref (ei);
+ gci->target = target;
+ gci->file = file;
+ fseek (file, 0, SEEK_END);
+ gci->size = ftell (file);
+ fseek (file, 0, SEEK_SET);
+ gci->dn_contact_hash = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) NULL);
+
+ source = g_datalist_get_data (&target->data, "ldif-source");
+
+ e_book_client_connect (source, NULL, book_client_connect_cb, gci);
+}
+
+static void
+ldif_cancel (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ LDIFImporter *gci = g_datalist_get_data (&target->data, "ldif-data");
+
+ if (gci)
+ gci->state = 2;
+}
+
+static GtkWidget *
+ldif_get_preview (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ GtkWidget *preview;
+ GSList *contacts = NULL;
+ EContact *contact;
+ EImportTargetURI *s = (EImportTargetURI *) target;
+ gchar *filename;
+ GHashTable *dn_contact_hash;
+ FILE *file;
+
+ filename = g_filename_from_uri (s->uri_src, NULL, NULL);
+ if (filename == NULL) {
+ g_message (G_STRLOC ": Couldn't get filename from URI '%s'", s->uri_src);
+ return NULL;
+ }
+
+ file = g_fopen (filename, "r");
+ g_free (filename);
+
+ if (file == NULL) {
+ g_message (G_STRLOC ": Can't open .ldif file");
+ return NULL;
+ }
+
+ dn_contact_hash = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) NULL);
+
+ while (contact = getNextLDIFEntry (dn_contact_hash, file), contact != NULL) {
+ if (!e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ add_to_notes (contact, E_CONTACT_OFFICE);
+ add_to_notes (contact, E_CONTACT_SPOUSE);
+ add_to_notes (contact, E_CONTACT_BLOG_URL);
+ }
+
+ contacts = g_slist_prepend (contacts, contact);
+ }
+
+ g_hash_table_destroy (dn_contact_hash);
+
+ contacts = g_slist_reverse (contacts);
+ preview = evolution_contact_importer_get_preview_widget (contacts);
+
+ g_slist_free_full (contacts, (GDestroyNotify) g_object_unref);
+ fclose (file);
+
+ return preview;
+}
+
+static EImportImporter ldif_importer = {
+ E_IMPORT_TARGET_URI,
+ 0,
+ ldif_supported,
+ ldif_getwidget,
+ ldif_import,
+ ldif_cancel,
+ ldif_get_preview,
+};
+
+EImportImporter *
+evolution_ldif_importer_peek (void)
+{
+ ldif_importer.name = _("LDAP Data Interchange Format (.ldif)");
+ ldif_importer.description = _("Evolution LDIF importer");
+
+ return &ldif_importer;
+}
diff --git a/addressbook/importers/evolution-vcard-importer.c b/addressbook/importers/evolution-vcard-importer.c
new file mode 100644
index 0000000000..09778b5f21
--- /dev/null
+++ b/addressbook/importers/evolution-vcard-importer.c
@@ -0,0 +1,1016 @@
+/*
+ * Evolution calendar importer component
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Toshok <toshok@ximian.com>
+ * JP Rosevear <jpr@ximian.com>
+ * Michael Zucchi <notzed@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+
+#include <libebook/libebook.h>
+
+#include <util/eab-book-util.h>
+
+#include <shell/e-shell.h>
+
+#include "evolution-addressbook-importers.h"
+
+enum _VCardEncoding {
+ VCARD_ENCODING_NONE,
+ VCARD_ENCODING_UTF8,
+ VCARD_ENCODING_UTF16,
+ VCARD_ENCODING_LOCALE
+};
+
+typedef enum _VCardEncoding VCardEncoding;
+
+typedef struct {
+ EImport *import;
+ EImportTarget *target;
+
+ guint idle_id;
+
+ gint state; /* 0 - importing, 1 - cancelled/complete */
+ gint total;
+ gint count;
+
+ ESource *primary;
+
+ GSList *contactlist;
+ GSList *iterator;
+ EBookClient *book_client;
+
+ /* when opening book */
+ gchar *contents;
+ VCardEncoding encoding;
+} VCardImporter;
+
+static void vcard_import_done (VCardImporter *gci);
+
+static void
+add_to_notes (EContact *contact,
+ EContactField field)
+{
+ const gchar *old_text;
+ const gchar *field_text;
+ gchar *new_text;
+
+ old_text = e_contact_get_const (contact, E_CONTACT_NOTE);
+ if (old_text && strstr (old_text, e_contact_pretty_name (field)))
+ return;
+
+ field_text = e_contact_get_const (contact, field);
+ if (!field_text || !*field_text)
+ return;
+
+ new_text = g_strdup_printf (
+ "%s%s%s: %s",
+ old_text ? old_text : "",
+ old_text && *old_text &&
+ *(old_text + strlen (old_text) - 1) != '\n' ? "\n" : "",
+ e_contact_pretty_name (field), field_text);
+ e_contact_set (contact, E_CONTACT_NOTE, new_text);
+ g_free (new_text);
+}
+
+static void
+vcard_import_contact (VCardImporter *gci,
+ EContact *contact)
+{
+ EContactPhoto *photo;
+ GList *attrs, *attr;
+ gchar *uid = NULL;
+
+ /* Apple's addressbook.app exports PHOTO's without a TYPE
+ * param, so let's figure out the format here if there's a
+ * PHOTO attribute missing a TYPE param.
+ *
+ * this is sort of a hack, as EContact sets the type for us if
+ * we use the setter. so let's e_contact_get + e_contact_set
+ * on E_CONTACT_PHOTO.
+ */
+ photo = e_contact_get (contact, E_CONTACT_PHOTO);
+ if (photo) {
+ e_contact_set (contact, E_CONTACT_PHOTO, photo);
+ e_contact_photo_free (photo);
+ }
+
+ /* Deal with our XML EDestination stuff in EMAIL attributes, if there is any. */
+ attrs = e_contact_get_attributes (contact, E_CONTACT_EMAIL);
+ for (attr = attrs; attr; attr = attr->next) {
+ EVCardAttribute *a = attr->data;
+ GList *v = e_vcard_attribute_get_values (a);
+
+ if (v && v->data) {
+ if (!strncmp ((gchar *) v->data, "<?xml", 5)) {
+ EDestination *dest = e_destination_import ((gchar *) v->data);
+
+ e_destination_export_to_vcard_attribute (dest, a);
+
+ g_object_unref (dest);
+
+ }
+ }
+ }
+ e_contact_set_attributes (contact, E_CONTACT_EMAIL, attrs);
+
+ /* Deal with TEL attributes that don't conform to what we need.
+ *
+ * 1. if there's no location (HOME/WORK/OTHER), default to OTHER.
+ * 2. if there's *only* a location specified, default to VOICE.
+ */
+ attrs = e_vcard_get_attributes (E_VCARD (contact));
+ for (attr = attrs; attr; attr = attr->next) {
+ EVCardAttribute *a = attr->data;
+ gboolean location_only = TRUE;
+ gboolean no_location = TRUE;
+ gboolean is_work_home = FALSE;
+ GList *params, *param;
+
+ if (g_ascii_strcasecmp (e_vcard_attribute_get_name (a),
+ EVC_TEL))
+ continue;
+
+ params = e_vcard_attribute_get_params (a);
+ for (param = params; param; param = param->next) {
+ EVCardAttributeParam *p = param->data;
+ GList *vs, *v;
+
+ if (g_ascii_strcasecmp (e_vcard_attribute_param_get_name (p),
+ EVC_TYPE))
+ continue;
+
+ vs = e_vcard_attribute_param_get_values (p);
+ for (v = vs; v; v = v->next) {
+ is_work_home = is_work_home ||
+ !g_ascii_strcasecmp ((gchar *) v->data, "WORK") ||
+ !g_ascii_strcasecmp ((gchar *) v->data, "HOME");
+
+ if (!g_ascii_strcasecmp ((gchar *) v->data, "WORK") ||
+ !g_ascii_strcasecmp ((gchar *) v->data, "HOME") ||
+ !g_ascii_strcasecmp ((gchar *) v->data, "OTHER"))
+ no_location = FALSE;
+ else
+ location_only = FALSE;
+ }
+ }
+
+ if (is_work_home) {
+ /* only WORK and HOME phone numbers require locations,
+ * the rest should be kept as is */
+ if (location_only) {
+ /* add VOICE */
+ e_vcard_attribute_add_param_with_value (
+ a,
+ e_vcard_attribute_param_new (EVC_TYPE),
+ "VOICE");
+ }
+ if (no_location) {
+ /* add OTHER */
+ e_vcard_attribute_add_param_with_value (
+ a,
+ e_vcard_attribute_param_new (EVC_TYPE),
+ "OTHER");
+ }
+ }
+ }
+
+ /* Deal with ADR and EMAIL attributes that don't conform to what
+ * we need. If HOME or WORK isn't specified, add TYPE=OTHER. */
+ attrs = e_vcard_get_attributes (E_VCARD (contact));
+ for (attr = attrs; attr; attr = attr->next) {
+ EVCardAttribute *a = attr->data;
+ gboolean no_location = TRUE;
+ GList *params, *param;
+
+ if (g_ascii_strcasecmp (e_vcard_attribute_get_name (a), EVC_ADR) &&
+ g_ascii_strcasecmp (e_vcard_attribute_get_name (a), EVC_EMAIL))
+ continue;
+
+ params = e_vcard_attribute_get_params (a);
+ for (param = params; param; param = param->next) {
+ EVCardAttributeParam *p = param->data;
+ GList *vs, *v;
+
+ if (g_ascii_strcasecmp (e_vcard_attribute_param_get_name (p),
+ EVC_TYPE))
+ continue;
+
+ vs = e_vcard_attribute_param_get_values (p);
+ for (v = vs; v; v = v->next) {
+ if (!g_ascii_strcasecmp ((gchar *) v->data, "WORK") ||
+ !g_ascii_strcasecmp ((gchar *) v->data, "HOME"))
+ no_location = FALSE;
+ }
+ }
+
+ if (no_location) {
+ /* add OTHER */
+ e_vcard_attribute_add_param_with_value (
+ a,
+ e_vcard_attribute_param_new (EVC_TYPE),
+ "OTHER");
+ }
+ }
+
+ /* Work around the fact that these fields no longer show up in the UI */
+ add_to_notes (contact, E_CONTACT_OFFICE);
+ add_to_notes (contact, E_CONTACT_SPOUSE);
+ add_to_notes (contact, E_CONTACT_BLOG_URL);
+
+ /* FIXME Error checking */
+ if (e_book_client_add_contact_sync (gci->book_client, contact, &uid, NULL, NULL) && uid) {
+ e_contact_set (contact, E_CONTACT_UID, uid);
+ g_free (uid);
+ }
+}
+
+static gboolean
+vcard_import_contacts (gpointer data)
+{
+ VCardImporter *gci = data;
+ gint count = 0;
+ GSList *iterator = gci->iterator;
+
+ if (gci->state == 0) {
+ while (count < 50 && iterator) {
+ vcard_import_contact (gci, iterator->data);
+ count++;
+ iterator = iterator->next;
+ }
+ gci->count += count;
+ gci->iterator = iterator;
+ if (iterator == NULL)
+ gci->state = 1;
+ }
+ if (gci->state == 1) {
+ vcard_import_done (gci);
+ return FALSE;
+ } else {
+ e_import_status (
+ gci->import, gci->target, _("Importing..."),
+ gci->count * 100 / gci->total);
+ return TRUE;
+ }
+}
+
+#define BOM (gunichar2)0xFEFF
+#define ANTIBOM (gunichar2)0xFFFE
+
+static gboolean
+has_bom (const gunichar2 *utf16)
+{
+
+ if ((utf16 == NULL) || (*utf16 == '\0')) {
+ return FALSE;
+ }
+
+ return ((*utf16 == BOM) || (*utf16 == ANTIBOM));
+}
+
+static void
+fix_utf16_endianness (gunichar2 *utf16)
+{
+ gunichar2 *it;
+
+ if ((utf16 == NULL) || (*utf16 == '\0')) {
+ return;
+ }
+
+ if (*utf16 != ANTIBOM) {
+ return;
+ }
+
+ for (it = utf16; *it != '\0'; it++) {
+ *it = GUINT16_SWAP_LE_BE (*it);
+ }
+}
+
+/* Converts an UTF-16 string to an UTF-8 string removing the BOM character
+ * WARNING: this may modify the utf16 argument if the function detects the
+ * string isn't using the local endianness
+ */
+static gchar *
+utf16_to_utf8 (gunichar2 *utf16)
+{
+
+ if (utf16 == NULL) {
+ return NULL;
+ }
+
+ fix_utf16_endianness (utf16);
+
+ if (*utf16 == BOM) {
+ utf16++;
+ }
+
+ return g_utf16_to_utf8 (utf16, -1, NULL, NULL, NULL);
+}
+
+/* Actually check the contents of this file */
+static VCardEncoding
+guess_vcard_encoding (const gchar *filename)
+{
+ FILE *handle;
+ gchar line[4096];
+ gchar *line_utf8;
+ VCardEncoding encoding = VCARD_ENCODING_NONE;
+
+ handle = g_fopen (filename, "r");
+ if (handle == NULL) {
+ g_print ("\n");
+ return VCARD_ENCODING_NONE;
+ }
+
+ if (fgets (line, 4096, handle) == NULL) {
+ fclose (handle);
+ g_print ("\n");
+ return VCARD_ENCODING_NONE;
+ }
+ fclose (handle);
+
+ if (has_bom ((gunichar2 *) line)) {
+ gunichar2 *utf16 = (gunichar2 *) line;
+ /* Check for a BOM to try to detect UTF-16 encoded vcards
+ * (MacOSX address book creates such vcards for example)
+ */
+ line_utf8 = utf16_to_utf8 (utf16);
+ if (line_utf8 == NULL) {
+ return VCARD_ENCODING_NONE;
+ }
+ encoding = VCARD_ENCODING_UTF16;
+ } else if (g_utf8_validate (line, -1, NULL)) {
+ line_utf8 = g_strdup (line);
+ encoding = VCARD_ENCODING_UTF8;
+ } else {
+ line_utf8 = g_locale_to_utf8 (line, -1, NULL, NULL, NULL);
+ if (line_utf8 == NULL) {
+ return VCARD_ENCODING_NONE;
+ }
+ encoding = VCARD_ENCODING_LOCALE;
+ }
+
+ if (g_ascii_strncasecmp (line_utf8, "BEGIN:VCARD", 11) != 0) {
+ encoding = VCARD_ENCODING_NONE;
+ }
+
+ g_free (line_utf8);
+ return encoding;
+}
+
+static void
+primary_selection_changed_cb (ESourceSelector *selector,
+ EImportTarget *target)
+{
+ ESource *source;
+
+ source = e_source_selector_ref_primary_selection (selector);
+ g_return_if_fail (source != NULL);
+
+ g_datalist_set_data_full (
+ &target->data, "vcard-source",
+ source, (GDestroyNotify) g_object_unref);
+}
+
+static GtkWidget *
+vcard_getwidget (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ EShell *shell;
+ GtkWidget *vbox, *selector;
+ ESourceRegistry *registry;
+ ESource *primary;
+ const gchar *extension_name;
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+
+ shell = e_shell_get_default ();
+ registry = e_shell_get_registry (shell);
+ extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+ selector = e_source_selector_new (registry, extension_name);
+ e_source_selector_set_show_toggles (
+ E_SOURCE_SELECTOR (selector), FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox), selector, FALSE, TRUE, 6);
+
+ primary = g_datalist_get_data (&target->data, "vcard-source");
+ if (primary == NULL) {
+ GList *list;
+
+ list = e_source_registry_list_sources (registry, extension_name);
+ if (list != NULL) {
+ primary = g_object_ref (list->data);
+ g_datalist_set_data_full (
+ &target->data, "vcard-source", primary,
+ (GDestroyNotify) g_object_unref);
+ }
+
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+ }
+ e_source_selector_set_primary_selection (
+ E_SOURCE_SELECTOR (selector), primary);
+
+ g_signal_connect (
+ selector, "primary_selection_changed",
+ G_CALLBACK (primary_selection_changed_cb), target);
+
+ gtk_widget_show_all (vbox);
+
+ return vbox;
+}
+
+static gboolean
+vcard_supported (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ EImportTargetURI *s;
+ gchar *filename;
+ gboolean retval;
+
+ if (target->type != E_IMPORT_TARGET_URI)
+ return FALSE;
+
+ s = (EImportTargetURI *) target;
+ if (s->uri_src == NULL)
+ return TRUE;
+
+ if (strncmp (s->uri_src, "file:///", 8) != 0)
+ return FALSE;
+
+ filename = g_filename_from_uri (s->uri_src, NULL, NULL);
+ if (filename == NULL)
+ return FALSE;
+ retval = (guess_vcard_encoding (filename) != VCARD_ENCODING_NONE);
+ g_free (filename);
+
+ return retval;
+}
+
+static void
+vcard_import_done (VCardImporter *gci)
+{
+ if (gci->idle_id)
+ g_source_remove (gci->idle_id);
+
+ g_free (gci->contents);
+ g_object_unref (gci->book_client);
+ g_slist_free_full (gci->contactlist, (GDestroyNotify) g_object_unref);
+
+ e_import_complete (gci->import, gci->target);
+ g_object_unref (gci->import);
+ g_free (gci);
+}
+
+static void
+book_client_connect_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ VCardImporter *gci = user_data;
+ EClient *client;
+
+ client = e_book_client_connect_finish (result, NULL);
+
+ if (client == NULL) {
+ vcard_import_done (gci);
+ return;
+ }
+
+ gci->book_client = E_BOOK_CLIENT (client);
+
+ if (gci->encoding == VCARD_ENCODING_UTF16) {
+ gchar *tmp;
+
+ gunichar2 *contents_utf16 = (gunichar2 *) gci->contents;
+ tmp = utf16_to_utf8 (contents_utf16);
+ g_free (gci->contents);
+ gci->contents = tmp;
+
+ } else if (gci->encoding == VCARD_ENCODING_LOCALE) {
+ gchar *tmp;
+ tmp = g_locale_to_utf8 (gci->contents, -1, NULL, NULL, NULL);
+ g_free (gci->contents);
+ gci->contents = tmp;
+ }
+
+ gci->contactlist = eab_contact_list_from_string (gci->contents);
+ g_free (gci->contents);
+ gci->contents = NULL;
+ gci->iterator = gci->contactlist;
+ gci->total = g_slist_length (gci->contactlist);
+
+ if (gci->iterator)
+ gci->idle_id = g_idle_add (vcard_import_contacts, gci);
+ else
+ vcard_import_done (gci);
+}
+
+static void
+vcard_import (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ VCardImporter *gci;
+ ESource *source;
+ EImportTargetURI *s = (EImportTargetURI *) target;
+ gchar *filename;
+ gchar *contents;
+ VCardEncoding encoding;
+
+ filename = g_filename_from_uri (s->uri_src, NULL, NULL);
+ if (filename == NULL) {
+ g_message (G_STRLOC ": Couldn't get filename from URI '%s'", s->uri_src);
+ e_import_complete (ei, target);
+ return;
+ }
+ encoding = guess_vcard_encoding (filename);
+ if (encoding == VCARD_ENCODING_NONE) {
+ g_free (filename);
+ /* This check is superfluous, we've already
+ * checked otherwise we can't get here ... */
+ e_import_complete (ei, target);
+ return;
+ }
+
+ if (!g_file_get_contents (filename, &contents, NULL, NULL)) {
+ g_message (G_STRLOC ":Couldn't read file.");
+ g_free (filename);
+ e_import_complete (ei, target);
+ return;
+ }
+
+ g_free (filename);
+ gci = g_malloc0 (sizeof (*gci));
+ g_datalist_set_data (&target->data, "vcard-data", gci);
+ gci->import = g_object_ref (ei);
+ gci->target = target;
+ gci->encoding = encoding;
+ gci->contents = contents;
+
+ source = g_datalist_get_data (&target->data, "vcard-source");
+
+ e_book_client_connect (source, NULL, book_client_connect_cb, gci);
+}
+
+static void
+vcard_cancel (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ VCardImporter *gci = g_datalist_get_data (&target->data, "vcard-data");
+
+ if (gci)
+ gci->state = 1;
+}
+
+static GtkWidget *
+vcard_get_preview (EImport *ei,
+ EImportTarget *target,
+ EImportImporter *im)
+{
+ GtkWidget *preview;
+ GSList *contacts;
+ gchar *contents;
+ VCardEncoding encoding;
+ EImportTargetURI *s = (EImportTargetURI *) target;
+ gchar *filename;
+
+ filename = g_filename_from_uri (s->uri_src, NULL, NULL);
+ if (filename == NULL) {
+ g_message (G_STRLOC ": Couldn't get filename from URI '%s'", s->uri_src);
+ return NULL;
+ }
+
+ encoding = guess_vcard_encoding (filename);
+ if (encoding == VCARD_ENCODING_NONE) {
+ g_free (filename);
+ return NULL;
+ }
+
+ if (!g_file_get_contents (filename, &contents, NULL, NULL)) {
+ g_message (G_STRLOC ": Couldn't read file.");
+ g_free (filename);
+ return NULL;
+ }
+
+ g_free (filename);
+
+ if (encoding == VCARD_ENCODING_UTF16) {
+ gchar *tmp;
+
+ gunichar2 *contents_utf16 = (gunichar2 *) contents;
+ tmp = utf16_to_utf8 (contents_utf16);
+ g_free (contents);
+ contents = tmp;
+ } else if (encoding == VCARD_ENCODING_LOCALE) {
+ gchar *tmp;
+ tmp = g_locale_to_utf8 (contents, -1, NULL, NULL, NULL);
+ g_free (contents);
+ contents = tmp;
+ }
+
+ contacts = eab_contact_list_from_string (contents);
+ g_free (contents);
+
+ preview = evolution_contact_importer_get_preview_widget (contacts);
+
+ g_slist_free_full (contacts, (GDestroyNotify) g_object_unref);
+
+ return preview;
+}
+
+static EImportImporter vcard_importer = {
+ E_IMPORT_TARGET_URI,
+ 0,
+ vcard_supported,
+ vcard_getwidget,
+ vcard_import,
+ vcard_cancel,
+ vcard_get_preview,
+};
+
+EImportImporter *
+evolution_vcard_importer_peek (void)
+{
+ vcard_importer.name = _("vCard (.vcf, .gcrd)");
+ vcard_importer.description = _("Evolution vCard Importer");
+
+ return &vcard_importer;
+}
+
+/* utility functions shared between all contact importers */
+static void
+preview_contact (EWebViewPreview *preview,
+ EContact *contact)
+{
+ gint idx;
+ gboolean had_value = FALSE;
+
+ const gint fields[] = {
+ E_CONTACT_FILE_AS,
+ E_CONTACT_CATEGORIES,
+
+ E_CONTACT_IS_LIST,
+ E_CONTACT_LIST_SHOW_ADDRESSES,
+ E_CONTACT_WANTS_HTML,
+
+ E_CONTACT_FULL_NAME,
+ E_CONTACT_GIVEN_NAME,
+ E_CONTACT_FAMILY_NAME,
+ E_CONTACT_NICKNAME,
+ E_CONTACT_SPOUSE,
+ E_CONTACT_BIRTH_DATE,
+ E_CONTACT_ANNIVERSARY,
+ E_CONTACT_MAILER,
+ E_CONTACT_EMAIL,
+
+ -1,
+
+ E_CONTACT_ORG,
+ E_CONTACT_ORG_UNIT,
+ E_CONTACT_OFFICE,
+ E_CONTACT_TITLE,
+ E_CONTACT_ROLE,
+ E_CONTACT_MANAGER,
+ E_CONTACT_ASSISTANT,
+
+ -1,
+
+ 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,
+
+ -1,
+
+ E_CONTACT_ADDRESS_HOME,
+ E_CONTACT_ADDRESS_WORK,
+ E_CONTACT_ADDRESS_OTHER,
+
+ -1,
+
+ E_CONTACT_HOMEPAGE_URL,
+ E_CONTACT_BLOG_URL,
+ E_CONTACT_CALENDAR_URI,
+ E_CONTACT_FREEBUSY_URL,
+ E_CONTACT_ICS_CALENDAR,
+ E_CONTACT_VIDEO_URL,
+
+ -1,
+
+ E_CONTACT_IM_AIM,
+ E_CONTACT_IM_GROUPWISE,
+ E_CONTACT_IM_JABBER,
+ E_CONTACT_IM_YAHOO,
+ E_CONTACT_IM_MSN,
+ E_CONTACT_IM_ICQ,
+ E_CONTACT_IM_GADUGADU,
+ E_CONTACT_IM_SKYPE,
+ E_CONTACT_IM_TWITTER,
+
+ -1,
+
+ E_CONTACT_NOTE
+ };
+
+ g_return_if_fail (preview != NULL);
+ g_return_if_fail (contact != NULL);
+
+ for (idx = 0; idx < G_N_ELEMENTS (fields); idx++) {
+ EContactField field;
+
+ if (fields[idx] == -1) {
+ if (had_value)
+ e_web_view_preview_add_empty_line (preview);
+ had_value = FALSE;
+ continue;
+ }
+
+ field = fields[idx];
+
+ if (field == E_CONTACT_BIRTH_DATE || field == E_CONTACT_ANNIVERSARY) {
+ EContactDate *dt = e_contact_get (contact, field);
+ if (dt) {
+ GDate gd = { 0 };
+ struct tm tm;
+ gchar *value;
+
+ g_date_set_dmy (&gd, dt->day, dt->month, dt->year);
+ g_date_to_struct_tm (&gd, &tm);
+
+ value = e_datetime_format_format_tm (
+ "addressbook", "table",
+ DTFormatKindDate, &tm);
+ if (value) {
+ e_web_view_preview_add_section (
+ preview,
+ e_contact_pretty_name (field),
+ value);
+ had_value = TRUE;
+ }
+
+ g_free (value);
+ e_contact_date_free (dt);
+ }
+ } else if (field == E_CONTACT_IS_LIST ||
+ field == E_CONTACT_WANTS_HTML ||
+ field == E_CONTACT_LIST_SHOW_ADDRESSES) {
+ if (e_contact_get (contact, field)) {
+ e_web_view_preview_add_text (
+ preview, e_contact_pretty_name (field));
+ had_value = TRUE;
+ }
+ } else if (field == E_CONTACT_ADDRESS_HOME ||
+ field == E_CONTACT_ADDRESS_WORK ||
+ field == E_CONTACT_ADDRESS_OTHER) {
+ EContactAddress *addr = e_contact_get (contact, field);
+ if (addr) {
+ gboolean have = FALSE;
+
+ #define add_it(_what) \
+ if (addr->_what && *addr->_what) { \
+ e_web_view_preview_add_section ( \
+ preview, have ? NULL : \
+ e_contact_pretty_name (field), addr->_what); \
+ have = TRUE; \
+ had_value = TRUE; \
+ }
+
+ add_it (po);
+ add_it (ext);
+ add_it (street);
+ add_it (locality);
+ add_it (region);
+ add_it (code);
+ add_it (country);
+
+ #undef add_it
+
+ e_contact_address_free (addr);
+ }
+ } else if (field == E_CONTACT_IM_AIM ||
+ field == E_CONTACT_IM_GROUPWISE ||
+ field == E_CONTACT_IM_JABBER ||
+ field == E_CONTACT_IM_YAHOO ||
+ field == E_CONTACT_IM_MSN ||
+ field == E_CONTACT_IM_ICQ ||
+ field == E_CONTACT_IM_GADUGADU ||
+ field == E_CONTACT_IM_SKYPE ||
+ field == E_CONTACT_IM_TWITTER ||
+ field == E_CONTACT_EMAIL) {
+ GList *attrs, *a;
+ gboolean have = FALSE;
+ const gchar *pretty_name;
+
+ pretty_name = e_contact_pretty_name (field);
+
+ attrs = e_contact_get_attributes (contact, field);
+ for (a = attrs; a; a = a->next) {
+ EVCardAttribute *attr = a->data;
+ GList *value;
+
+ if (!attr)
+ continue;
+
+ value = e_vcard_attribute_get_values (attr);
+
+ while (value != NULL) {
+ const gchar *str = value->data;
+
+ if (str && *str) {
+ e_web_view_preview_add_section (
+ preview, have ? NULL :
+ pretty_name, str);
+ have = TRUE;
+ had_value = TRUE;
+ }
+
+ value = value->next;
+ }
+
+ e_vcard_attribute_free (attr);
+ }
+
+ g_list_free (attrs);
+
+ } else if (field == E_CONTACT_CATEGORIES) {
+ const gchar *pretty_name;
+ const gchar *value;
+
+ pretty_name = e_contact_pretty_name (field);
+ value = e_contact_get_const (contact, field);
+
+ if (value != NULL && *value != '\0') {
+ e_web_view_preview_add_section (
+ preview, pretty_name, value);
+ had_value = TRUE;
+ }
+
+ } else {
+ const gchar *pretty_name;
+ const gchar *value;
+
+ pretty_name = e_contact_pretty_name (field);
+ value = e_contact_get_const (contact, field);
+
+ if (value != NULL && *value != '\0') {
+ e_web_view_preview_add_section (
+ preview, pretty_name, value);
+ had_value = TRUE;
+ }
+ }
+ }
+}
+
+static void
+preview_selection_changed_cb (GtkTreeSelection *selection,
+ EWebViewPreview *preview)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model = NULL;
+
+ g_return_if_fail (selection != NULL);
+ g_return_if_fail (preview != NULL);
+
+ e_web_view_preview_begin_update (preview);
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter) && model) {
+ EContact *contact = NULL;
+
+ gtk_tree_model_get (model, &iter, 1, &contact, -1);
+
+ if (contact) {
+ preview_contact (preview, contact);
+ g_object_unref (contact);
+ }
+ }
+
+ e_web_view_preview_end_update (preview);
+}
+
+GtkWidget *
+evolution_contact_importer_get_preview_widget (const GSList *contacts)
+{
+ GtkWidget *preview;
+ GtkTreeView *tree_view;
+ GtkTreeSelection *selection;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ const GSList *c;
+
+ if (!contacts)
+ return NULL;
+
+ store = gtk_list_store_new (2, G_TYPE_STRING, E_TYPE_CONTACT);
+
+ for (c = contacts; c; c = c->next) {
+ const gchar *description;
+ gchar *free_description = NULL;
+ EContact *contact = (EContact *) c->data;
+
+ if (!contact || !E_IS_CONTACT (contact))
+ continue;
+
+ description = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ if (!description)
+ description = e_contact_get_const (contact, E_CONTACT_UID);
+ if (!description)
+ description = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
+ if (!description) {
+ description = e_contact_get_const (contact, E_CONTACT_EMAIL_1);
+ if (description) {
+ const gchar *at = strchr (description, '@');
+ if (at) {
+ free_description = g_strndup (
+ description,
+ (gsize) (at - description));
+ description = free_description;
+ }
+ }
+ }
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (
+ store, &iter,
+ 0, description ? description : "",
+ 1, contact,
+ -1);
+
+ g_free (free_description);
+ }
+
+ if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
+ g_object_unref (store);
+ return NULL;
+ }
+
+ preview = e_web_view_preview_new ();
+ gtk_widget_show (preview);
+
+ tree_view = e_web_view_preview_get_tree_view (E_WEB_VIEW_PREVIEW (preview));
+ g_return_val_if_fail (tree_view != NULL, NULL);
+
+ gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (store));
+ g_object_unref (store);
+
+ gtk_tree_view_insert_column_with_attributes (
+ tree_view, -1, _("Contact"),
+ gtk_cell_renderer_text_new (), "text", 0, NULL);
+
+ if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) > 1)
+ e_web_view_preview_show_tree_view (E_WEB_VIEW_PREVIEW (preview));
+
+ selection = gtk_tree_view_get_selection (tree_view);
+ gtk_tree_selection_select_iter (selection, &iter);
+ g_signal_connect (
+ selection, "changed",
+ G_CALLBACK (preview_selection_changed_cb), preview);
+
+ preview_selection_changed_cb (selection, E_WEB_VIEW_PREVIEW (preview));
+
+ return preview;
+}
diff --git a/addressbook/printing/.cvsignore b/addressbook/printing/.cvsignore
deleted file mode 100644
index 96194f7fd7..0000000000
--- a/addressbook/printing/.cvsignore
+++ /dev/null
@@ -1,9 +0,0 @@
-.deps
-.libs
-.pure
-Makefile
-Makefile.in
-*.lo
-*.la
-contact-print-test
-contact-print-style-editor-test
diff --git a/addressbook/printing/Makefile.am b/addressbook/printing/Makefile.am
index 015069e51b..c51eb14d3b 100644
--- a/addressbook/printing/Makefile.am
+++ b/addressbook/printing/Makefile.am
@@ -1,67 +1,56 @@
-ecpsdir = $(datadir)/evolution/ecps
-
+ecpsdir = $(privdatadir)/ecps
ecps_DATA = \
smallbook.ecps \
medbook.ecps \
phonelist.ecps
-gladedir = $(datadir)/evolution/glade
-
-glade_DATA = \
- e-contact-print.glade
-
-INCLUDES = \
- $(GNOME_INCLUDEDIR) \
+libecontactprint_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
-DG_LOG_DOMAIN=\"addressbook-printing\" \
-I$(top_srcdir)/addressbook \
- -I$(top_srcdir)/addressbook/backend \
- -I$(top_builddir)/addressbook/backend \
-I$(top_srcdir) \
- -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
+ -DEVOLUTION_UIDIR=\""$(uidir)"\" \
-DEVOLUTION_ECPSDIR=\""$(ecpsdir)"\" \
- -DDATADIR=\""$(datadir)"\" \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS)
-noinst_LIBRARIES = \
- libecontactprint.a
+noinst_LTLIBRARIES = libecontactprint.la
-libecontactprint_a_SOURCES = \
- e-contact-print-envelope.c \
- e-contact-print-envelope.h \
- e-contact-print-style-editor.c \
- e-contact-print-style-editor.h \
+libecontactprint_la_SOURCES = \
e-contact-print-types.h \
e-contact-print.c \
e-contact-print.h
-noinst_PROGRAMS = \
- contact-print-test \
- contact-print-style-editor-test
+libecontactprint_la_LIBADD = \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(top_builddir)/addressbook/util/libeabutil.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_LIBS)
-contact_print_test_SOURCES = \
- test-print.c
+noinst_PROGRAMS = contact-print-test
-contact_print_test_LDADD = \
- $(top_builddir)/addressbook/backend/ebook/libebook.la \
- $(top_builddir)/camel/libcamel.la \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/e-util/ename/libename.la \
- libecontactprint.a \
- $(EVOLUTION_ADDRESSBOOK_LIBS)
+contact_print_test_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DG_LOG_DOMAIN=\"addressbook-printing\" \
+ -I$(top_srcdir)/addressbook \
+ -I$(top_srcdir) \
+ -DEVOLUTION_ECPSDIR=\""$(ecpsdir)"\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS)
-contact_print_style_editor_test_SOURCES = \
- test-contact-print-style-editor.c
+contact_print_test_SOURCES = test-print.c
-contact_print_style_editor_test_LDADD = \
- $(top_builddir)/addressbook/backend/ebook/libebook.la \
- $(top_builddir)/camel/libcamel.la \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/e-util/ename/libename.la \
- libecontactprint.a \
- $(EVOLUTION_ADDRESSBOOK_LIBS)
+contact_print_test_LDADD = \
+ libecontactprint.la \
+ $(top_builddir)/addressbook/util/libeabutil.la \
+ $(top_builddir)/shell/libevolution-shell.la \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS)
EXTRA_DIST = \
- $(glade_DATA) \
$(ecps_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/printing/e-contact-print-envelope.c b/addressbook/printing/e-contact-print-envelope.c
deleted file mode 100644
index 2f65afa81b..0000000000
--- a/addressbook/printing/e-contact-print-envelope.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-contact-print-envelope.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 "addressbook/printing/e-contact-print-envelope.h"
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <time.h>
-#include <libgnome/gnome-paper.h>
-#include <libgnomeprint/gnome-print.h>
-#include <libgnomeprint/gnome-print-dialog.h>
-#include <libgnomeprint/gnome-print-master.h>
-#include <libgnomeprint/gnome-print-master-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)
-
-typedef struct {
- int start;
- int length;
-} EcpeLine;
-
-static void
-startset(void *pointer, EcpeLine **iterator)
-{
- (*iterator)--;
- (*iterator)->start = GPOINTER_TO_INT(pointer);
-}
-
-static void
-lengthset(void *pointer, EcpeLine **iterator)
-{
- (*iterator)--;
- (*iterator)->length = GPOINTER_TO_INT(pointer);
-}
-
-static EcpeLine *
-ecpe_break(char *address)
-{
- int i;
- int length = 0;
- int laststart = 0;
- GList *startlist = NULL;
- GList *lengthlist = NULL;
- EcpeLine *ret_val;
- EcpeLine *iterator;
-
- for (i = 0; address[i]; i++) {
- if (address[i] == '\n') {
- startlist = g_list_prepend (startlist, GINT_TO_POINTER(laststart));
- lengthlist = g_list_prepend (lengthlist, GINT_TO_POINTER(i - laststart));
- length ++;
- laststart = i + 1;
- }
- }
- startlist = g_list_prepend (startlist, GINT_TO_POINTER(laststart));
- lengthlist = g_list_prepend (lengthlist, GINT_TO_POINTER(i - laststart));
- length ++;
-
- ret_val = g_new(EcpeLine, length + 1);
-
- iterator = ret_val + length;
- g_list_foreach(startlist, (GFunc) startset, &iterator);
- g_list_free(startlist);
-
- iterator = ret_val + length;
- g_list_foreach(lengthlist, (GFunc) lengthset, &iterator);
- g_list_free(lengthlist);
-
- ret_val[length].start = -1;
- ret_val[length].length = -1;
-
- return ret_val;
-}
-
-static void
-ecpe_linelist_dimensions(GnomeFont *font, char *address, EcpeLine *linelist, double *widthp, double *heightp)
-{
- double width = 0;
- int i;
- if (widthp) {
- for (i = 0; linelist[i].length != -1; i++) {
- width = MAX(width, gnome_font_get_width_utf8_sized (font, address + linelist[i].start, linelist[i].length));
- }
- *widthp = width;
- } else {
- for (i = 0; linelist[i].length != -1; i++)
- /* Intentionally empty */;
- }
- if (heightp) {
- *heightp = gnome_font_get_size(font) * i;
- }
-}
-
-static void
-ecpe_linelist_print(GnomePrintContext *pc, GnomeFont *font, char *address, EcpeLine *linelist, double x, double y)
-{
- int i;
- gnome_print_setfont(pc, font);
- for (i = 0; linelist[i].length != -1; i++) {
- gnome_print_moveto(pc, x, y + gnome_font_get_ascender(font));
- gnome_print_show_sized (pc, address + linelist[i].start, linelist[i].length);
- y -= gnome_font_get_size(font);
- }
-}
-
-static gint
-e_contact_print_envelope_close(GnomeDialog *dialog, gpointer data)
-{
- return FALSE;
-}
-
-static void
-ecpe_print(GnomePrintContext *pc, ECard *ecard, gboolean as_return)
-{
- ECardSimple *card = e_card_simple_new(ecard);
- char *address;
- EcpeLine *linelist;
- double x;
- double y;
- GnomeFont *font;
-
-
- 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);
- linelist = ecpe_break(address);
- if (as_return)
- font = gnome_font_new("Helvetica", 9);
- else
- font = gnome_font_new("Helvetica", 12);
- ecpe_linelist_dimensions(font, address, linelist, NULL, &y);
- if (as_return) {
- x = 36;
- y = ENVELOPE_HEIGHT - 36;
- } else {
- x = ENVELOPE_WIDTH / 2;
- y = (ENVELOPE_HEIGHT - y) / 2;
- }
- ecpe_linelist_print(pc, font, address, linelist, x, y);
- gtk_object_unref(GTK_OBJECT(font));
- g_free(linelist);
-
- g_free(address);
-
- gnome_print_showpage(pc);
- gnome_print_context_close(pc);
-
- gtk_object_unref(GTK_OBJECT(card));
-}
-
-static void
-e_contact_print_envelope_button(GnomeDialog *dialog, gint button, gpointer data)
-{
- GnomePrintMaster *master;
- GnomePrintContext *pc;
- ECard *card = NULL;
- GtkWidget *preview;
-
- card = gtk_object_get_data(GTK_OBJECT(dialog), "card");
-
- switch( button ) {
- case GNOME_PRINT_PRINT:
- master = gnome_print_master_new_from_dialog( GNOME_PRINT_DIALOG(dialog) );
- pc = gnome_print_master_get_context( master );
-
- ecpe_print(pc, card, FALSE);
-
- gnome_print_master_print(master);
- gnome_dialog_close(dialog);
- break;
- case GNOME_PRINT_PREVIEW:
- master = gnome_print_master_new_from_dialog( GNOME_PRINT_DIALOG(dialog) );
- pc = gnome_print_master_get_context( master );
-
- ecpe_print(pc, card, FALSE);
-
- preview = GTK_WIDGET(gnome_print_master_preview_new(master, "Print Preview"));
- gtk_widget_show_all(preview);
- break;
- case GNOME_PRINT_CANCEL:
- gtk_object_unref(GTK_OBJECT(card));
- gnome_dialog_close(dialog);
- break;
- }
-}
-
-GtkWidget *
-e_contact_print_envelope_dialog_new(ECard *card)
-{
- GtkWidget *dialog;
-
- dialog = gnome_print_dialog_new(_("Print envelope"), GNOME_PRINT_DIALOG_COPIES);
-
- card = e_card_duplicate(card);
- gtk_object_set_data(GTK_OBJECT(dialog), "card", card);
- gtk_signal_connect(GTK_OBJECT(dialog),
- "clicked", GTK_SIGNAL_FUNC(e_contact_print_envelope_button), NULL);
- gtk_signal_connect(GTK_OBJECT(dialog),
- "close", GTK_SIGNAL_FUNC(e_contact_print_envelope_close), NULL);
- return dialog;
-}
-
-/* FIXME: Print all the contacts selected. */
-GtkWidget *
-e_contact_print_envelope_list_dialog_new(GList *list)
-{
- GtkWidget *dialog;
- ECard *card;
-
- if (list == NULL)
- return NULL;
-
- dialog = gnome_print_dialog_new(_("Print envelope"), GNOME_PRINT_DIALOG_COPIES);
-
- card = e_card_duplicate(list->data);
- gtk_object_set_data(GTK_OBJECT(dialog), "card", card);
- gtk_signal_connect(GTK_OBJECT(dialog),
- "clicked", GTK_SIGNAL_FUNC(e_contact_print_envelope_button), NULL);
- gtk_signal_connect(GTK_OBJECT(dialog),
- "close", GTK_SIGNAL_FUNC(e_contact_print_envelope_close), NULL);
- return dialog;
-}
diff --git a/addressbook/printing/e-contact-print-envelope.h b/addressbook/printing/e-contact-print-envelope.h
deleted file mode 100644
index 4302c4c5d7..0000000000
--- a/addressbook/printing/e-contact-print-envelope.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-contact-print-envelope.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_PRINT_ENVELOPE_H
-#define E_CONTACT_PRINT_ENVELOPE_H
-
-#include <addressbook/backend/ebook/e-card.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_list_dialog_new(GList *list);
-
-#endif /* E_CONTACT_PRINT_ENVELOPE_H */
diff --git a/addressbook/printing/e-contact-print-style-editor.c b/addressbook/printing/e-contact-print-style-editor.c
deleted file mode 100644
index f05a508ed8..0000000000
--- a/addressbook/printing/e-contact-print-style-editor.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-contact-print-style-editor.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 "e-contact-print-style-editor.h"
-
-static void e_contact_print_style_editor_init (EContactPrintStyleEditor *card);
-static void e_contact_print_style_editor_class_init (EContactPrintStyleEditorClass *klass);
-static void e_contact_print_style_editor_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_contact_print_style_editor_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_contact_print_style_editor_destroy (GtkObject *object);
-
-static GtkVBoxClass *parent_class = NULL;
-
-
-/* The arguments we take */
-enum {
- ARG_0,
- ARG_CARD
-};
-
-GtkType
-e_contact_print_style_editor_get_type (void)
-{
- static GtkType contact_print_style_editor_type = 0;
-
- if (!contact_print_style_editor_type)
- {
- static const GtkTypeInfo contact_print_style_editor_info =
- {
- "EContactPrintStyleEditor",
- sizeof (EContactPrintStyleEditor),
- sizeof (EContactPrintStyleEditorClass),
- (GtkClassInitFunc) e_contact_print_style_editor_class_init,
- (GtkObjectInitFunc) e_contact_print_style_editor_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- contact_print_style_editor_type = gtk_type_unique (gtk_vbox_get_type (), &contact_print_style_editor_info);
- }
-
- return contact_print_style_editor_type;
-}
-
-static void
-e_contact_print_style_editor_class_init (EContactPrintStyleEditorClass *klass)
-{
- GtkObjectClass *object_class;
- GtkVBoxClass *vbox_class;
-
- object_class = (GtkObjectClass*) klass;
- vbox_class = (GtkVBoxClass *) klass;
-
- parent_class = gtk_type_class (gtk_vbox_get_type ());
-
- object_class->set_arg = e_contact_print_style_editor_set_arg;
- object_class->get_arg = e_contact_print_style_editor_get_arg;
- object_class->destroy = e_contact_print_style_editor_destroy;
-}
-
-#if 0
-static void
-_add_image(GtkTable *table, gchar *image, int left, int right, int top, int bottom)
-{
- gtk_table_attach(table,
- gtk_widget_new(gtk_alignment_get_type(),
- "child", gnome_pixmap_new_from_file(image),
- "xalign", (double) 0,
- "yalign", (double) 0,
- "xscale", (double) 0,
- "yscale", (double) 0,
- NULL),
- left, right, top, bottom,
- GTK_FILL, GTK_FILL,
- 0, 0);
-}
-#endif
-
-static void
-e_contact_print_style_editor_init (EContactPrintStyleEditor *e_contact_print_style_editor)
-{
- GladeXML *gui;
-
- /* e_contact_print_style_editor->card = NULL;*/
- gui = glade_xml_new (EVOLUTION_GLADEDIR "/e-contact-print.glade", NULL);
- e_contact_print_style_editor->gui = gui;
- gtk_widget_reparent(glade_xml_get_widget(gui, "vbox-contact-print-style-editor"),
- GTK_WIDGET(e_contact_print_style_editor));
-}
-
-void
-e_contact_print_style_editor_destroy (GtkObject *object)
-{
- EContactPrintStyleEditor *e_contact_print_style_editor = E_CONTACT_PRINT_STYLE_EDITOR(object);
- gtk_object_unref(GTK_OBJECT(e_contact_print_style_editor->gui));
-}
-
-GtkWidget*
-e_contact_print_style_editor_new (char *filename)
-{
- GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_contact_print_style_editor_get_type ()));
- return widget;
-}
-
-static void
-e_contact_print_style_editor_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
-{
- EContactPrintStyleEditor *e_contact_print_style_editor;
-
- e_contact_print_style_editor = E_CONTACT_PRINT_STYLE_EDITOR (o);
-
- switch (arg_id){
- default:
- break;
- }
-}
-
-static void
-e_contact_print_style_editor_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- EContactPrintStyleEditor *e_contact_print_style_editor;
-
- e_contact_print_style_editor = E_CONTACT_PRINT_STYLE_EDITOR (object);
-
- switch (arg_id) {
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
-}
diff --git a/addressbook/printing/e-contact-print-style-editor.h b/addressbook/printing/e-contact-print-style-editor.h
deleted file mode 100644
index e4604d551c..0000000000
--- a/addressbook/printing/e-contact-print-style-editor.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-contact-print-style-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.
- */
-
-#ifndef __E_CONTACT_PRINT_STYLE_EDITOR_H__
-#define __E_CONTACT_PRINT_STYLE_EDITOR_H__
-
-#include <gtk/gtkvbox.h>
-#include <glade/glade.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* EContactPrintStyleEditor - A dialog displaying information about a contact.
- *
- * The following arguments are available:
- *
- * name type read/write description
- * --------------------------------------------------------------------------------
- * card ECard * R The card currently being edited
- */
-
-#define E_CONTACT_PRINT_STYLE_EDITOR_TYPE (e_contact_print_style_editor_get_type ())
-#define E_CONTACT_PRINT_STYLE_EDITOR(obj) (GTK_CHECK_CAST ((obj), E_CONTACT_PRINT_STYLE_EDITOR_TYPE, EContactPrintStyleEditor))
-#define E_CONTACT_PRINT_STYLE_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_CONTACT_PRINT_STYLE_EDITOR_TYPE, EContactPrintStyleEditorClass))
-#define E_IS_MINICARD(obj) (GTK_CHECK_TYPE ((obj), E_CONTACT_PRINT_STYLE_EDITOR_TYPE))
-#define E_IS_MINICARD_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_CONTACT_PRINT_STYLE_EDITOR_TYPE))
-
-
-typedef struct _EContactPrintStyleEditor EContactPrintStyleEditor;
-typedef struct _EContactPrintStyleEditorClass EContactPrintStyleEditorClass;
-
-struct _EContactPrintStyleEditor
-{
- GtkVBox parent;
-
- /* item specific fields */
- GladeXML *gui;
-};
-
-struct _EContactPrintStyleEditorClass
-{
- GtkVBoxClass parent_class;
-};
-
-
-GtkWidget *e_contact_print_style_editor_new(char *filename);
-GtkType e_contact_print_style_editor_get_type (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __E_CONTACT_PRINT_STYLE_EDITOR_H__ */
diff --git a/addressbook/printing/e-contact-print-types.h b/addressbook/printing/e-contact-print-types.h
index b7082b41f6..e21f3b7b16 100644
--- a/addressbook/printing/e-contact-print-types.h
+++ b/addressbook/printing/e-contact-print-types.h
@@ -1,29 +1,29 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-contact-print-types.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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_PRINT_TYPES_H
#define E_CONTACT_PRINT_TYPES_H
#include <glib.h>
-#include <libgnomeprint/gnome-font.h>
typedef struct _EContactPrintStyle EContactPrintStyle;
typedef enum _EContactPrintType EContactPrintType;
@@ -41,10 +41,9 @@ struct _EContactPrintStyle
gboolean sections_start_new_page;
guint num_columns;
guint blank_forms;
- gboolean letter_tabs;
gboolean letter_headings;
- GnomeFont *headings_font;
- GnomeFont *body_font;
+ PangoFontDescription *headings_font;
+ PangoFontDescription *body_font;
gboolean print_using_grey;
gint paper_type;
gdouble paper_width;
@@ -58,11 +57,11 @@ struct _EContactPrintStyle
gdouble page_width;
gdouble page_height;
gboolean orientation_portrait;
- GnomeFont *header_font;
+ PangoFontDescription *header_font;
gchar *left_header;
gchar *center_header;
gchar *right_header;
- GnomeFont *footer_font;
+ PangoFontDescription *footer_font;
gchar *left_footer;
gchar *center_footer;
gchar *right_footer;
diff --git a/addressbook/printing/e-contact-print.c b/addressbook/printing/e-contact-print.c
index 55b5480c6f..c91d77a4ee 100644
--- a/addressbook/printing/e-contact-print.c
+++ b/addressbook/printing/e-contact-print.c
@@ -1,884 +1,529 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-contact-print.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
-#include "e-contact-print.h"
+#endif
#include <ctype.h>
#include <sys/types.h>
#include <stdlib.h>
-#include <glib.h>
-#include <gnome-xml/tree.h>
-#include <gnome-xml/parser.h>
-#include <gnome-xml/xmlmemory.h>
-#include <libgnome/gnome-util.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnome/gnome-paper.h>
-#include <libgnomeprint/gnome-print.h>
-#include <libgnomeprint/gnome-print-dialog.h>
-#include <libgnomeprint/gnome-print-master.h>
-#include <libgnomeprint/gnome-print-master-preview.h>
-#include <libgnomeprint/gnome-print-multipage.h>
-#include <gal/widgets/e-unicode.h>
-#include <gal/unicode/gunicode.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>
-
-#define SCALE 5
-#define HYPHEN_PIXELS 20
-#define HYPHEN_PENALTY ( (SCALE) * (SCALE) * (HYPHEN_PIXELS) * (HYPHEN_PIXELS) )
+#include <string.h>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xmlmemory.h>
+#include <glib/gi18n.h>
+
+#include "e-util/e-util.h"
+#include "e-util/e-util-private.h"
+
+#include "addressbook/util/eab-book-util.h"
+
+#include "e-contact-print.h"
typedef struct _EContactPrintContext EContactPrintContext;
+typedef struct _ContactPrintItem ContactPrintItem;
struct _EContactPrintContext
{
- GnomePrintContext *pc;
- GnomePrintMaster *master;
+ GtkPrintOperationAction action;
+ GtkPrintContext *context;
gdouble x;
gdouble y;
gint column;
+ gdouble column_width;
+ gdouble column_spacing;
EContactPrintStyle *style;
gboolean first_section;
- gchar first_char_on_page;
- gchar last_char_on_page;
- GnomeFont *letter_heading_font;
- GnomeFont *letter_tab_font;
- char *character;
- gboolean first_contact;
- gboolean uses_book;
- int type;
- EBook *book;
- gchar *query;
+ gint page_nr, pages;
+
+ PangoFontDescription *letter_heading_font;
+ gchar *section;
+ gboolean first_contact;
- GList *cards;
+ GSList *contact_list;
};
-static gint
-e_contact_divide_text(GnomePrintContext *pc, GnomeFont *font, double width, const gchar *text, GList **return_val /* Of type char[] */)
+static gdouble
+get_font_height (PangoFontDescription *desc)
{
- if ( width == -1 || gnome_font_get_width_utf8(font, text) <= width ) {
- if ( return_val ) {
- *return_val = g_list_append(*return_val, g_strdup(text));
- }
- return 1;
- } else {
-#if 1
- int i, l;
- double x = 0;
- int lastend = 0;
- int linestart = 0;
- int firstword = 1;
- int linecount = 0;
- l = strlen(text);
- for ( i = 0; i < l; i++ ) {
- if ( text[i] == ' ' ) {
- if ( (!firstword) && x + gnome_font_get_width_utf8_sized(font, text + lastend, i - lastend) > width ) {
- if (return_val) {
- *return_val = g_list_append(*return_val, g_strndup(text + linestart, lastend - linestart));
- }
- x = gnome_font_get_width_utf8(font, " ");
- linestart = lastend + 1;
- x += gnome_font_get_width_utf8_sized(font, text + linestart, i - linestart);
- lastend = i;
- linecount ++;
- } else {
- x += gnome_font_get_width_utf8_sized(font, text + lastend, i - lastend);
- lastend = i;
- }
- firstword = 0;
- } else if ( text[i] == '\n' ) {
- if ( (!firstword) && x + gnome_font_get_width_utf8_sized(font, text + lastend, i - lastend) > width ) {
- if (return_val) {
- *return_val = g_list_append(*return_val, g_strndup(text + linestart, lastend - linestart));
- }
- linestart = lastend + 1;
- lastend = i;
- linecount ++;
- }
- if (return_val) {
- *return_val = g_list_append(*return_val, g_strndup(text + linestart, i - linestart));
- }
- linestart = i + 1;
- lastend = i + 1;
- linecount ++;
- x = gnome_font_get_width_utf8(font, " ");
+ return pango_units_to_double (
+ pango_font_description_get_size (desc));
+}
- firstword = 1;
- }
- }
- if ( (!firstword) && x + gnome_font_get_width_utf8_sized(font, text + lastend, i - lastend) > width ) {
- if (return_val) {
- *return_val = g_list_append(*return_val, g_strndup(text + linestart, lastend - linestart));
- }
- linestart = lastend + 1;
- lastend = i;
- linecount ++;
- }
- if (return_val) {
- *return_val = g_list_append(*return_val, g_strndup(text + linestart, i - linestart));
- }
- linecount ++;
- return(linecount);
-#else
- HnjBreak *breaks;
- gint *result;
- gint *is;
- gint n_breaks = 0, n_actual_breaks = 0;
- gint i;
- gint l;
- gchar *hyphenation;
- double x = - gnome_font_get_width_utf8(font, " ") * SCALE;
- HnjParams hnjparams;
-
- hnjparams.set_width = width * SCALE + x;
- hnjparams.max_neg_space = 0;
- hnjparams.tab_width = 0;
-
- l = strlen(text);
-
- /* find possible line breaks. */
- for (i = 0; i < l; i++) {
- if (text[i] == '-')
- n_breaks++;
- else if (text[i] == ' ')
- n_breaks++;
-#if 0
- else if (hyphenation[i] & 1)
- n_breaks++;
-#endif
- }
+static gdouble
+get_font_width (GtkPrintContext *context,
+ PangoFontDescription *desc,
+ const gchar *text)
+{
+ PangoLayout *layout;
+ gint width, height;
- breaks = g_new( HnjBreak, n_breaks + 1 );
- result = g_new( gint, n_breaks + 1 );
- is = g_new( gint, n_breaks + 1 );
- n_breaks = 0;
- /* find possible line breaks. */
-
- for (i = 0; i < l; i++) {
- if ( text[i] == '-' ) {
- x += gnome_font_get_width(font, text[i]) * SCALE;
- breaks[n_breaks].x0 = x;
- breaks[n_breaks].x1 = x;
- breaks[n_breaks].penalty = HYPHEN_PENALTY;
- breaks[n_breaks].flags = HNJ_JUST_FLAG_ISHYPHEN;
- is[n_breaks] = i + 1;
- n_breaks++;
- } else if ( text[i] == ' ' ) {
- breaks[ n_breaks ].x0 = x;
- x += gnome_font_get_width(font, text[i]) * SCALE;
- breaks[ n_breaks ].x1 = x;
- breaks[ n_breaks ].penalty = 0;
- breaks[ n_breaks ].flags = HNJ_JUST_FLAG_ISSPACE;
- is[ n_breaks ] = i + 1;
- n_breaks++;
-#if 0
- } else if (word->hyphenation[i] & 1) {
- breaks[n_breaks].x0 = x + gnome_font_get_width(font, '-') * SCALE;
- breaks[n_breaks].x1 = x;
- breaks[n_breaks].penalty = HYPHEN_PENALTY;
- breaks[n_breaks].flags = HNJ_JUST_FLAG_ISHYPHEN;
- is[n_breaks] = i + 1;
- n_breaks++;
-#endif
- } else
- x += gnome_font_get_width(font, text[i]) * SCALE;
+ g_return_val_if_fail (desc, .0);
+ g_return_val_if_fail (text, .0);
- }
- is[n_breaks] = i;
- breaks[n_breaks].flags = 0;
- n_breaks++;
-
- /* Calculate optimal line breaks. */
- n_actual_breaks = hnj_hs_just (breaks, n_breaks,
- &hnjparams, result);
-
- if ( return_val ) {
- gchar *next_val;
- if ( breaks[result[0]].flags == HNJ_JUST_FLAG_ISHYPHEN && text[is[result[0]]] != '-' ) {
- next_val = g_new(gchar, is[result[0]] + 2);
- strncpy(next_val, text, is[result[0]]);
- next_val[is[result[0]]] = 0;
- strcat(next_val, "-");
- } else {
- next_val = g_new(gchar, is[result[0]] + 1);
- strncpy(next_val, text, is[result[0]]);
- next_val[is[result[0]]] = 0;
- }
- *return_val = g_list_append(*return_val, next_val);
-
- for ( i = 1; i < n_actual_breaks; i++ ) {
- if ( (breaks[result[i]].flags & HNJ_JUST_FLAG_ISHYPHEN) && (text[is[result[i]]] != '-') ) {
- next_val = g_new(gchar, is[result[i]] - is[result[i - 1]] + 2);
- strncpy(next_val, text + is[result[i - 1]], is[result[i]] - is[result[i - 1]]);
- next_val[is[result[i]] - is[result[i - 1]]] = 0;
- strcat(next_val, "-");
- } else {
- next_val = g_new(gchar, is[result[i]] - is[result[i - 1]] + 1);
- strncpy(next_val, text + is[result[i - 1]], is[result[i]] - is[result[i - 1]]);
- next_val[is[result[i]] - is[result[i - 1]]] = 0;
- }
- *return_val = g_list_append(*return_val, next_val);
- }
- }
-
- g_free (breaks);
- g_free (result);
- g_free (is);
- return n_actual_breaks;
-#endif
- }
+ layout = gtk_print_context_create_pango_layout (context);
+
+ pango_layout_set_font_description (layout, desc);
+ pango_layout_set_text (layout, text, -1);
+ pango_layout_set_width (layout, -1);
+ pango_layout_set_indent (layout, 0);
+
+ pango_layout_get_size (layout, &width, &height);
+
+ g_object_unref (layout);
+
+ return pango_units_to_double (width);
}
static void
-e_contact_output(GnomePrintContext *pc, GnomeFont *font, double x, double y, double width, const gchar *text)
+e_contact_output (GtkPrintContext *context,
+ PangoFontDescription *font,
+ gdouble x,
+ gdouble y,
+ gdouble width,
+ const gchar *text)
{
- GList *list = NULL, *list_start;
- int first_line = 1;
- gnome_print_gsave(pc);
- gnome_print_setfont(pc, font);
- e_contact_divide_text(pc, font, width, text, &list);
- for ( list_start = list; list; list = g_list_next(list)) {
- y -= gnome_font_get_ascender(font);
- gnome_print_moveto(pc, x, y);
- gnome_print_show(pc, (char *)list->data);
- y -= gnome_font_get_descender(font);
- y -= .2 * gnome_font_get_size (font);
- if ( first_line ) {
- x += gnome_font_get_width_utf8(font, " ");
- first_line = 0;
- }
- }
- g_list_foreach( list_start, (GFunc) g_free, NULL );
- g_list_free( list_start );
- gnome_print_grestore(pc);
+ PangoLayout *layout;
+ gdouble indent;
+ cairo_t *cr;
+
+ layout = gtk_print_context_create_pango_layout (context);
+
+ if (width == -1 || get_font_width (context, font, text) <= width)
+ indent = .0;
+ else
+ indent = get_font_width (context, font, " ");
+
+ pango_layout_set_font_description (layout, font);
+ pango_layout_set_text (layout, text, -1);
+ pango_layout_set_width (layout, pango_units_from_double (width));
+ pango_layout_set_indent (layout, pango_units_from_double (indent));
+ pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
+
+ cr = gtk_print_context_get_cairo_context (context);
+
+ cairo_save (cr);
+ cairo_move_to (cr, x, y);
+ pango_cairo_show_layout (cr, layout);
+ cairo_restore (cr);
+
+ g_object_unref (layout);
}
static gdouble
-e_contact_text_height(GnomePrintContext *pc, GnomeFont *font, double width, gchar *text)
+e_contact_text_height (GtkPrintContext *context,
+ PangoFontDescription *desc,
+ 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)) +
- (line_count - 1) * .2 * gnome_font_get_size (font);
+ PangoLayout *layout;
+ gint width, height;
+
+ layout = gtk_print_context_create_pango_layout (context);
+
+ pango_layout_set_font_description (layout, desc);
+ pango_layout_set_text (layout, text, -1);
+
+ pango_layout_get_size (layout, &width, &height);
+
+ g_object_unref (layout);
+
+ return pango_units_to_double (height);
}
-#if 0
static void
-e_contact_output_and_advance(EContactPrintContext *ctxt, GnomeFont *font, double x, double width, gchar *text)
-{
- ctxt->y -= .1 * gnome_font_get_size (font);
- e_contact_output(ctxt->pc, font, x, ctxt->y, width, text);
- ctxt->y -= e_contact_text_height(ctxt->pc, font, width, text);
- ctxt->y -= .1 * gnome_font_get_size (font);
+e_contact_print_letter_heading (EContactPrintContext *ctxt,
+ gchar *letter)
+{
+ PangoLayout *layout;
+ PangoFontDescription *desc;
+ PangoFontMetrics *metrics;
+ gint width, height;
+ cairo_t *cr;
+
+ desc = ctxt->letter_heading_font;
+
+ layout = gtk_print_context_create_pango_layout (ctxt->context);
+
+ /* Make the rectangle thrice the average character width.
+ * XXX Works well for English, what about other locales? */
+ metrics = pango_context_get_metrics (
+ pango_layout_get_context (layout),
+ desc, pango_language_get_default ());
+ width = pango_font_metrics_get_approximate_char_width (metrics) * 3;
+ pango_font_metrics_unref (metrics);
+
+ pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
+ pango_layout_set_font_description (layout, desc);
+ pango_layout_set_text (layout, letter, -1);
+ pango_layout_set_width (layout, width);
+ pango_layout_get_size (layout, NULL, &height);
+
+ if (ctxt->page_nr == -1 || ctxt->pages != ctxt->page_nr) {
+ /* only calculating number of pages
+ * or on page we do not want to print */
+ ctxt->y += pango_units_to_double (height);
+
+ return;
+ }
+
+ /* Draw white text centered in a black rectangle. */
+ cr = gtk_print_context_get_cairo_context (ctxt->context);
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, .0, .0, .0);
+ cairo_rectangle (
+ cr, ctxt->x, ctxt->y,
+ pango_units_to_double (width),
+ pango_units_to_double (height));
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ cairo_move_to (cr, ctxt->x, ctxt->y);
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ pango_cairo_show_layout (cr, layout);
+ cairo_restore (cr);
+
+ ctxt->y += pango_units_to_double (height);
}
-#endif
static void
-e_contact_rectangle(GnomePrintContext *pc,
- gdouble x0,
- gdouble y0,
- gdouble x1,
- gdouble y1,
- gdouble r,
- gdouble g,
- gdouble b)
+e_contact_start_new_page (EContactPrintContext *ctxt)
{
- gnome_print_gsave(pc);
- gnome_print_setrgbcolor(pc, r, g, b);
- gnome_print_moveto(pc, x0, y0);
- gnome_print_lineto(pc, x1, y0);
- gnome_print_lineto(pc, x1, y1);
- gnome_print_lineto(pc, x0, y1);
- gnome_print_lineto(pc, x0, y0);
- gnome_print_fill(pc);
- gnome_print_grestore(pc);
+ ctxt->x = ctxt->y = .0;
+ ctxt->column = 0;
+ ctxt->pages++;
}
-static double
-e_contact_get_letter_tab_width (EContactPrintContext *ctxt)
+static void
+e_contact_start_new_column (EContactPrintContext *ctxt)
{
- return gnome_font_get_width_utf8(ctxt->letter_tab_font, "123") + 4 + 18;
+ if (++ctxt->column >= ctxt->style->num_columns)
+ e_contact_start_new_page (ctxt);
+ else {
+ ctxt->x = ctxt->column *
+ (ctxt->column_width + ctxt->column_spacing);
+ ctxt->y = .0;
+ }
}
-static double
-e_contact_print_letter_tab (EContactPrintContext *ctxt)
+static gchar *
+get_contact_string_value (EContact *contact,
+ gint field)
{
- unsigned char character;
- gdouble x, y;
- gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin);
- gdouble tab_height, tab_width;
- gdouble font_size;
- tab_height = 72 * (ctxt->style->page_height - ctxt->style->top_margin - ctxt->style->bottom_margin) / 27.0;
- font_size = tab_height / 2;
- tab_width = e_contact_get_letter_tab_width(ctxt) - 18;
- x = page_width + 72 * (ctxt->style->left_margin) - tab_width;
- y = 72 * (ctxt->style->page_height - ctxt->style->top_margin);
-
-
- gnome_print_gsave( ctxt->pc );
- if ( ctxt->style->print_using_grey )
- e_contact_rectangle( ctxt->pc, x, 72 * (ctxt->style->page_height - ctxt->style->top_margin), x + tab_width, ctxt->style->bottom_margin * 72, .85, .85, .85 );
- for ( character = 'A' - 1; character <= 'Z'; character ++ ) {
- char string[] = "123";
- if ( character >= 'A' ) {
- string[0] = tolower(character);
- string[1] = 0;
- }
- if ( character >= ctxt->first_char_on_page && character <= ctxt->last_char_on_page ) {
- e_contact_rectangle( ctxt->pc, x + 1, y - 1, x + tab_width - 1, y - (tab_height - 1), 0, 0, 0 );
- gnome_print_setrgbcolor( ctxt->pc, 1, 1, 1 );
- e_contact_output( ctxt->pc, ctxt->letter_tab_font, x + tab_width / 2 - gnome_font_get_width_utf8(ctxt->letter_tab_font, string) / 2, y - (tab_height - font_size) / 2, -1, string );
- } else {
- gnome_print_setrgbcolor( ctxt->pc, 0, 0, 0 );
- e_contact_output( ctxt->pc, ctxt->letter_tab_font, x + tab_width / 2 - gnome_font_get_width_utf8(ctxt->letter_tab_font, string) / 2, y - (tab_height - font_size) / 2, -1, string );
+ const gchar *value;
+
+ g_return_val_if_fail (contact != NULL, NULL);
+
+ value = e_contact_get_const (contact, field);
+ if (!value || !*value)
+ return NULL;
+
+ if (field == E_CONTACT_EMAIL_1 ||
+ field == E_CONTACT_EMAIL_2 ||
+ field == E_CONTACT_EMAIL_3 ||
+ field == E_CONTACT_EMAIL_4) {
+ gchar *email = NULL, *name = NULL;
+
+ if (eab_parse_qp_email (value, &name, &email)) {
+ gchar *res;
+
+ if (name && *name)
+ res = g_strdup_printf ("%s <%s>", name, email);
+ else
+ res = g_strdup_printf ("%s", email);
+
+ g_free (name);
+ g_free (email);
+
+ return res;
}
- y -= tab_height;
}
- gnome_print_grestore( ctxt->pc );
- return gnome_font_get_width_utf8(ctxt->style->body_font, "123") + gnome_font_get_size (ctxt->style->body_font) / 5;
+ return g_strdup (value);
}
-static double
-e_contact_get_letter_heading_height (EContactPrintContext *ctxt)
+static gdouble
+e_contact_get_contact_height (EContact *contact,
+ EContactPrintContext *ctxt)
{
- gdouble ascender, descender;
- ascender = gnome_font_get_ascender(ctxt->letter_heading_font);
- descender = gnome_font_get_descender(ctxt->letter_heading_font);
- return ascender + descender + 9;
-}
+ gchar *file_as;
+ gint field;
+ gdouble cntct_height = 0.0;
-static void
-e_contact_print_letter_heading (EContactPrintContext *ctxt, gchar *character)
-{
- gdouble ascender, descender;
- gdouble width;
-
- width = gnome_font_get_width_utf8(ctxt->letter_heading_font, "m") * 1.7;
- ascender = gnome_font_get_ascender(ctxt->letter_heading_font);
- descender = gnome_font_get_descender(ctxt->letter_heading_font);
- gnome_print_gsave( ctxt->pc );
- e_contact_rectangle( ctxt->pc, ctxt->x, ctxt->y, ctxt->x + width, ctxt->y - (ascender + descender + 6), 0, 0, 0);
- gnome_print_setrgbcolor(ctxt->pc, 1, 1, 1);
- ctxt->y -= 4;
- e_contact_output(ctxt->pc, ctxt->letter_heading_font, ctxt->x + (width - gnome_font_get_width_utf8(ctxt->letter_heading_font, character))/ 2, ctxt->y, -1, character);
- ctxt->y -= ascender + descender;
- ctxt->y -= 2;
- ctxt->y -= 3;
- gnome_print_grestore( ctxt->pc );
-}
+ cntct_height += get_font_height (ctxt->style->headings_font) * .2;
-static void
-e_contact_start_new_page(EContactPrintContext *ctxt)
-{
- ctxt->x = ctxt->style->left_margin * 72;
- ctxt->y = (ctxt->style->page_height - ctxt->style->top_margin) * 72;
- ctxt->column = 0;
- if ( ctxt->style->letter_tabs )
- e_contact_print_letter_tab(ctxt);
- gnome_print_showpage(ctxt->pc);
+ file_as = e_contact_get (contact, E_CONTACT_FILE_AS);
- ctxt->first_char_on_page = ctxt->last_char_on_page + 1;
-}
+ cntct_height += e_contact_text_height (
+ ctxt->context, ctxt->style->headings_font, file_as);
-static double
-e_contact_get_card_size(ECardSimple *simple, 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;
- gint field;
- if ( ctxt->style->letter_tabs )
- page_width -= e_contact_get_letter_tab_width(ctxt);
- column_width = (page_width + 18) / ctxt->style->num_columns - 18;
-
- height += gnome_font_get_size (ctxt->style->headings_font) * .2;
-
- height += gnome_font_get_size (ctxt->style->headings_font) * .2;
-
- gtk_object_get(GTK_OBJECT(simple->card),
- "file_as", &file_as,
- NULL);
- height += e_contact_text_height(ctxt->pc, ctxt->style->headings_font, column_width - 4, 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++) {
- char *string;
- string = e_card_simple_get(simple, 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, ": ");
- 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);
- }
- g_free(string);
- }
- height += gnome_font_get_size (ctxt->style->headings_font) * .4;
+ g_free (file_as);
- /* g_message ("%s %g", e_card_simple_get (simple, E_CARD_SIMPLE_FIELD_FILE_AS), height); */
- return height;
-}
+ cntct_height += get_font_height (ctxt->style->headings_font) * .2;
+ for (field = E_CONTACT_FILE_AS; field != E_CONTACT_LAST_SIMPLE_STRING; field++)
+ {
+ gchar *value;
+ gchar *text;
-static void
-e_contact_print_card (ECardSimple *simple, EContactPrintContext *ctxt)
-{
- gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin);
- gdouble column_width;
- char *file_as;
- int field;
-
- 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;
-
- gtk_object_get(GTK_OBJECT(simple->card),
- "file_as", &file_as,
- NULL);
- 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);
- ctxt->y -= e_contact_text_height(ctxt->pc, ctxt->style->headings_font, column_width - 4, file_as);
- 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++) {
- char *string;
- string = e_card_simple_get(simple, field);
-
- if (string && !strncmp (string, "<?xml", 4)) {
- EDestination *dest = e_destination_import (string);
- if (dest != NULL) {
- gchar *new_string = g_strdup (e_destination_get_address (dest));
- g_free (string);
- string = new_string;
- gtk_object_unref (GTK_OBJECT (dest));
- }
+ value = get_contact_string_value (contact, field);
+ if (value == NULL || *value == '\0') {
+ g_free (value);
+ continue;
}
- 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, ": ");
- 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);
- ctxt->y -= e_contact_text_height(ctxt->pc, ctxt->style->body_font, column_width - xoff, string);
- ctxt->y -= .2 * gnome_font_get_size (ctxt->style->body_font);
- }
- g_free(string);
+ text = g_strdup_printf (
+ "%s: %s",
+ e_contact_pretty_name (field), value);
+
+ cntct_height += e_contact_text_height (
+ ctxt->context, ctxt->style->body_font, text);
+
+ cntct_height += .2 * get_font_height (ctxt->style->body_font);
+
+ g_free (value);
+ g_free (text);
}
-
- ctxt->y -= gnome_font_get_size (ctxt->style->headings_font) * .4;
- gnome_print_grestore(ctxt->pc);
+
+ cntct_height += get_font_height (ctxt->style->headings_font) * .4 + 8;
+
+ return cntct_height;
}
static void
-e_contact_start_new_column (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_offset;
- if ( ctxt->style->letter_tabs )
- page_width -= e_contact_get_letter_tab_width(ctxt);
- column_offset = (page_width + 18) / ctxt->style->num_columns;
- ctxt->column ++;
- if (ctxt->column >= ctxt->style->num_columns) {
- e_contact_start_new_page(ctxt);
- ctxt->column = 0;
+ GtkPageSetup *setup;
+ gchar *file_as;
+ cairo_t *cr;
+ gdouble page_height;
+ gint field;
+
+ setup = gtk_print_context_get_page_setup (ctxt->context);
+ page_height = gtk_page_setup_get_page_height (setup, GTK_UNIT_POINTS);
+
+ cr = gtk_print_context_get_cairo_context (ctxt->context);
+ cairo_save (cr);
+ ctxt->y += get_font_height (ctxt->style->headings_font) * .2;
+
+ file_as = e_contact_get (contact, E_CONTACT_FILE_AS);
+
+ if (ctxt->style->print_using_grey && ctxt->pages == ctxt->page_nr) {
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, .85, .85, .85);
+ cairo_rectangle (
+ cr, ctxt->x, ctxt->y, ctxt->column_width,
+ e_contact_text_height (ctxt->context,
+ ctxt->style->headings_font, file_as));
+ cairo_fill (cr);
+ cairo_restore (cr);
}
- ctxt->x = (72 * ctxt->style->left_margin) + column_offset * ctxt->column;
- ctxt->y = 72 * (ctxt->style->page_height - ctxt->style->top_margin);
-}
-static void
-complete_sequence(EBookView *book_view, EBookViewStatus status, EContactPrintContext *ctxt)
-{
- GList *cards = ctxt->cards;
+ if (ctxt->pages == ctxt->page_nr)
+ e_contact_output (
+ ctxt->context, ctxt->style->headings_font,
+ ctxt->x, ctxt->y, ctxt->column_width + 4, file_as);
+ ctxt->y += e_contact_text_height (
+ ctxt->context, ctxt->style->headings_font, file_as);
- gdouble page_width = 72 * (ctxt->style->page_width - ctxt->style->left_margin - ctxt->style->right_margin);
+ g_free (file_as);
- 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;
-
- for(; cards; cards = cards->next) {
- ECard *card = cards->data;
- ECardSimple *simple = e_card_simple_new(card);
- guchar *file_as;
- gchar *letter_str = NULL;
-
- gtk_object_get(GTK_OBJECT(card),
- "file_as", &file_as,
- NULL);
- if (file_as != NULL) {
- letter_str = g_strndup (file_as, g_utf8_next_char (file_as) - (gchar *) file_as);
- }
- if ( file_as && (!ctxt->character || g_utf8_collate (ctxt->character, letter_str) != 0) ) {
- g_free (ctxt->character);
- ctxt->character = g_strdup (letter_str);
- 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))
- 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)) {
- e_contact_start_new_column(ctxt);
- if ( ctxt->style->letter_headings )
- e_contact_print_letter_heading(ctxt, ctxt->character);
+ ctxt->y += get_font_height (ctxt->style->headings_font) * .2;
+
+ for (field = E_CONTACT_FILE_AS; field != E_CONTACT_LAST_SIMPLE_STRING; field++)
+ {
+ gchar *value;
+ gchar *text;
+ gint wrapped_lines = 0;
+
+ if (ctxt->y > page_height)
+ e_contact_start_new_column (ctxt);
+
+ value = get_contact_string_value (contact, field);
+ if (value == NULL || *value == '\0') {
+ g_free (value);
+ continue;
}
- g_free (letter_str);
- 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);
- ctxt->first_contact = FALSE;
- gtk_object_unref(GTK_OBJECT(simple));
- }
- 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(ctxt->character);
- if (book_view)
- gtk_object_unref(GTK_OBJECT(book_view));
- if (ctxt->type == GNOME_PRINT_PREVIEW) {
- GtkWidget *preview;
- preview = GTK_WIDGET(gnome_print_master_preview_new(ctxt->master, "Print Preview"));
- gtk_widget_show_all(preview);
- } else {
- gnome_print_master_print(ctxt->master);
- }
- gtk_object_unref(GTK_OBJECT(ctxt->pc));
- gtk_object_unref(GTK_OBJECT(ctxt->master));
- if (ctxt->book)
- gtk_object_unref(GTK_OBJECT(ctxt->book));
- g_free(ctxt->query);
- g_list_foreach(ctxt->cards, (GFunc) gtk_object_unref, NULL);
- g_list_free(ctxt->cards);
- gtk_object_unref(GTK_OBJECT(ctxt->style->headings_font));
- gtk_object_unref(GTK_OBJECT(ctxt->style->body_font));
- gtk_object_unref(GTK_OBJECT(ctxt->style->header_font));
- gtk_object_unref(GTK_OBJECT(ctxt->style->footer_font));
- gtk_object_unref(GTK_OBJECT(ctxt->letter_heading_font));
- gtk_object_unref(GTK_OBJECT(ctxt->letter_tab_font));
- g_free(ctxt->style);
- g_free(ctxt);
-}
-static int
-card_compare (ECard *card1, ECard *card2) {
- if (card1 && card2) {
- char *file_as1, *file_as2;
- gtk_object_get(GTK_OBJECT(card1),
- "file_as", &file_as1,
- NULL);
- gtk_object_get(GTK_OBJECT(card2),
- "file_as", &file_as2,
- NULL);
- 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));
- } else {
- return 0;
+ text = g_strdup_printf (
+ "%s: %s",
+ e_contact_pretty_name (field), value);
+
+ if (ctxt->pages == ctxt->page_nr)
+ e_contact_output (
+ ctxt->context, ctxt->style->body_font,
+ ctxt->x, ctxt->y, ctxt->column_width + 4, text);
+
+ if (get_font_width (ctxt->context,
+ ctxt->style->body_font, text) > ctxt->column_width)
+ wrapped_lines =
+ (get_font_width (ctxt->context,
+ ctxt->style->body_font, text) /
+ (ctxt->column_width + 4)) + 1;
+ ctxt->y =
+ ctxt->y + ((wrapped_lines + 1) *
+ e_contact_text_height (
+ ctxt->context,
+ ctxt->style->body_font,
+ text));
+
+ ctxt->y += .2 * get_font_height (ctxt->style->body_font);
+
+ g_free (value);
+ g_free (text);
}
-}
-static void
-create_card(EBookView *book_view, const GList *cards, EContactPrintContext *ctxt)
-{
- for(; cards; cards = cards->next) {
- ECard *card = cards->data;
- gtk_object_ref(GTK_OBJECT(card));
- ctxt->cards = g_list_insert_sorted(ctxt->cards, card, (GCompareFunc) card_compare);
- }
+ ctxt->y += get_font_height (ctxt->style->headings_font) * .4 + 8;
+
+ cairo_restore (cr);
}
-static void
-book_view_loaded (EBook *book, EBookStatus status, EBookView *book_view, EContactPrintContext *ctxt)
+static gint
+contact_compare (EContact *contact1,
+ EContact *contact2)
{
- gtk_object_ref(GTK_OBJECT(book_view));
+ const gchar *field1, *field2;
- gtk_signal_connect(GTK_OBJECT(book_view),
- "card_added",
- GTK_SIGNAL_FUNC(create_card),
- ctxt);
+ if (contact1 == NULL || contact2 == NULL)
+ return 0;
- gtk_signal_connect(GTK_OBJECT(book_view),
- "sequence_complete",
- GTK_SIGNAL_FUNC(complete_sequence),
- ctxt);
-}
+ field1 = e_contact_get_const (contact1, E_CONTACT_FILE_AS);
+ field2 = e_contact_get_const (contact2, E_CONTACT_FILE_AS);
-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 (field1 != NULL && field2 != NULL)
+ return g_utf8_collate (field1, field2);
-#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;
-}
+ if (field1 != NULL || field2 != NULL)
+ return (field1 != NULL) ? -1 : 1;
+ field1 = e_contact_get_const (contact1, E_CONTACT_UID);
+ field2 = e_contact_get_const (contact2, E_CONTACT_UID);
-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);
+ g_return_val_if_fail (
+ field1 != NULL && field2 != NULL,
+ (field1 != NULL) ? -1 : 1);
+
+ return strcmp (field1, field2);
}
static void
-e_contact_do_print_phone_list (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;
+contacts_added (EBookClientView *book_view,
+ const GSList *contact_list,
+ EContactPrintContext *ctxt)
+{
+ while (contact_list != NULL) {
+ ctxt->contact_list = g_slist_prepend (
+ ctxt->contact_list,
+ g_object_ref (contact_list->data));
+ contact_list = contact_list->next;
}
- 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);
}
-#endif
static void
-e_contact_do_print (EBook *book, char *query, EContactPrintContext *ctxt)
+view_complete (EBookClientView *client_view,
+ const GError *error,
+ GtkPrintOperation *operation)
{
- switch ( ctxt->style->type ) {
- case E_CONTACT_PRINT_TYPE_CARDS:
- e_contact_do_print_cards( 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;
- }
-}
+ EContactPrintContext *ctxt;
-static void lowify( char *data )
-{
- for ( ; *data; data++ )
- *data = tolower((unsigned char) *data);
+ g_return_if_fail (operation != NULL);
+
+ ctxt = g_object_get_data (G_OBJECT (operation), "contact-print-ctx");
+ g_return_if_fail (ctxt != NULL);
+
+ e_book_client_view_stop (client_view, NULL);
+ g_signal_handlers_disconnect_by_func (
+ client_view, G_CALLBACK (contacts_added), ctxt);
+ g_signal_handlers_disconnect_by_func (
+ client_view, G_CALLBACK (view_complete), operation);
+
+ g_object_unref (client_view);
+
+ gtk_print_operation_run (operation, ctxt->action, NULL, NULL);
+ g_object_unref (operation);
}
-static gboolean get_bool( char *data )
+static gboolean
+get_bool (gchar *data)
{
- if ( data ) {
- lowify ( data );
- return ! strcmp(data, "true");
- } else
+ if (data)
+ return (g_ascii_strcasecmp (data, "true") == 0);
+ else
return FALSE;
}
-static void get_string( char *data, char **variable )
+static void
+get_string (gchar *data,
+ gchar **variable)
{
- g_free ( *variable );
- if ( data )
- *variable = g_strdup( data );
- else
- *variable = g_strdup( "" );
+ g_free (*variable);
+ *variable = g_strdup ((data != NULL) ? data : "");
}
-static int get_integer( char *data )
+static gint
+get_integer (gchar *data)
{
- if ( data )
- return atoi(data);
- else
- return 0;
+ return (data != NULL) ? atoi (data) : 0;
}
-static double get_float( char *data )
+static gdouble
+get_float (gchar *data)
{
- if ( data )
- return atof(data);
- else
- return 0;
+ return (data != NULL) ? atof (data) : .0;
}
-static void get_font( char *data, GnomeFont **variable )
+static void
+get_font (gchar *data,
+ PangoFontDescription **variable)
{
- if ( data ) {
- GnomeFont *font = gnome_font_new_from_full_name( data );
- if ( font ) {
- gtk_object_unref( GTK_OBJECT(*variable) );
- *variable = font;
- }
+ PangoFontDescription *desc = NULL;
+
+ if (data != NULL)
+ desc = pango_font_description_from_string (data);
+
+ if (desc != NULL) {
+ pango_font_description_free (*variable);
+ *variable = desc;
}
}
-
static void
-e_contact_build_style(EContactPrintStyle *style)
+e_contact_build_style (EContactPrintStyle *style)
{
xmlDocPtr styledoc;
gchar *filename;
- style->title = g_strdup("");
+
+ style->title = g_strdup ("");
style->type = E_CONTACT_PRINT_TYPE_CARDS;
style->sections_start_new_page = TRUE;
style->num_columns = 2;
style->blank_forms = 2;
- style->letter_tabs = TRUE;
style->letter_headings = FALSE;
- style->headings_font = gnome_font_new_closest("Helvetica", GNOME_FONT_BOLD, FALSE, 8);
- style->body_font = gnome_font_new_closest("Helvetica", GNOME_FONT_BOOK, FALSE, 6);
+ style->headings_font = pango_font_description_from_string ("Sans Bold 8");
+ style->body_font = pango_font_description_from_string ("Sans 6");
style->print_using_grey = TRUE;
style->paper_type = 0;
@@ -902,306 +547,381 @@ e_contact_build_style(EContactPrintStyle *style)
#endif
style->orientation_portrait = FALSE;
- style->header_font = gnome_font_new_closest("Helvetica", GNOME_FONT_BOOK, FALSE, 6);
+ style->header_font = pango_font_description_copy (style->body_font);
- style->left_header = g_strdup("");
- style->center_header = g_strdup("");
- style->right_header = g_strdup("");
+ style->left_header = g_strdup ("");
+ style->center_header = g_strdup ("");
+ style->right_header = g_strdup ("");
- style->footer_font = gnome_font_new_closest("Helvetica", GNOME_FONT_BOOK, FALSE, 6);
+ style->footer_font = pango_font_description_copy (style->body_font);
- style->left_footer = g_strdup("");
- style->center_footer = g_strdup("");
- style->right_footer = g_strdup("");
+ style->left_footer = g_strdup ("");
+ style->center_footer = g_strdup ("");
+ style->right_footer = g_strdup ("");
style->reverse_on_even_pages = FALSE;
- filename = g_concat_dir_and_file(EVOLUTION_ECPSDIR, "medbook.ecps");
- styledoc = xmlParseFile(filename);
- g_free(filename);
+
+ filename = g_build_filename (EVOLUTION_ECPSDIR, "medbook.ecps", NULL);
+ styledoc = e_xml_parse_file (filename);
+ g_free (filename);
+
if (styledoc) {
- xmlNodePtr stylenode = xmlDocGetRootElement(styledoc);
+ xmlNodePtr stylenode = xmlDocGetRootElement (styledoc);
xmlNodePtr node;
- for (node = stylenode->childs; node; node = node->next) {
- char *data = xmlNodeGetContent ( node );
- if ( !strcmp( node->name, "title" ) ) {
- get_string(data, &(style->title));
- } else if ( !strcmp( node->name, "type" ) ) {
- lowify( data );
- if ( !strcmp( data, "cards" ) )
+ for (node = stylenode->children; node; node = node->next) {
+ gchar *data = (gchar *) xmlNodeGetContent (node);
+ if (!strcmp ((gchar *) node->name, "title")) {
+ get_string (data, &(style->title));
+ } else if (!strcmp ((gchar *) node->name, "type")) {
+ if (g_ascii_strcasecmp (data, "cards") == 0)
style->type = E_CONTACT_PRINT_TYPE_CARDS;
- else if ( !strcmp( data, "memo_style" ) )
+ else if (g_ascii_strcasecmp (data, "memo_style") == 0)
style->type = E_CONTACT_PRINT_TYPE_MEMO_STYLE;
- else if ( !strcmp( data, "phone_list" ) )
+ else if (g_ascii_strcasecmp (data, "phone_list") == 0)
style->type = E_CONTACT_PRINT_TYPE_PHONE_LIST;
- } else if ( !strcmp( node->name, "sections_start_new_page" ) ) {
- style->sections_start_new_page = get_bool(data);
- } else if ( !strcmp( node->name, "num_columns" ) ) {
- style->num_columns = get_integer(data);
- } else if ( !strcmp( node->name, "blank_forms" ) ) {
- style->blank_forms = get_integer(data);
- } else if ( !strcmp( node->name, "letter_tabs" ) ) {
- style->letter_tabs = get_bool(data);
- } else if ( !strcmp( node->name, "letter_headings" ) ) {
- style->letter_headings = get_bool(data);
- } else if ( !strcmp( node->name, "headings_font" ) ) {
- get_font( data, &(style->headings_font) );
- } else if ( !strcmp( node->name, "body_font" ) ) {
- get_font( data, &(style->body_font) );
- } else if ( !strcmp( node->name, "print_using_grey" ) ) {
- style->print_using_grey = get_bool(data);
- } else if ( !strcmp( node->name, "paper_width" ) ) {
- style->paper_width = get_float(data);
- } else if ( !strcmp( node->name, "paper_height" ) ) {
- style->paper_height = get_float(data);
- } else if ( !strcmp( node->name, "top_margin" ) ) {
- style->top_margin = get_float(data);
- } else if ( !strcmp( node->name, "left_margin" ) ) {
- style->left_margin = get_float(data);
- } else if ( !strcmp( node->name, "bottom_margin" ) ) {
- style->bottom_margin = get_float(data);
- } else if ( !strcmp( node->name, "right_margin" ) ) {
- style->right_margin = get_float(data);
- } else if ( !strcmp( node->name, "page_width" ) ) {
- style->page_width = get_float(data);
- } else if ( !strcmp( node->name, "page_height" ) ) {
- style->page_height = get_float(data);
- } else if ( !strcmp( node->name, "orientation" ) ) {
- if ( data ) {
- lowify(data);
- style->orientation_portrait = strcmp(data, "landscape");
+ } else if (!strcmp ((gchar *) node->name, "sections_start_new_page")) {
+ style->sections_start_new_page = get_bool (data);
+ } else if (!strcmp ((gchar *) node->name, "num_columns")) {
+ style->num_columns = get_integer (data);
+ } else if (!strcmp ((gchar *) node->name, "blank_forms")) {
+ style->blank_forms = get_integer (data);
+ } else if (!strcmp ((gchar *) node->name, "letter_headings")) {
+ style->letter_headings = get_bool (data);
+ } else if (!strcmp ((gchar *) node->name, "headings_font")) {
+ get_font (data, &(style->headings_font));
+ } else if (!strcmp ((gchar *) node->name, "body_font")) {
+ get_font (data, &(style->body_font));
+ } else if (!strcmp ((gchar *) node->name, "print_using_grey")) {
+ style->print_using_grey = get_bool (data);
+ } else if (!strcmp ((gchar *) node->name, "paper_width")) {
+ style->paper_width = get_float (data);
+ } else if (!strcmp ((gchar *) node->name, "paper_height")) {
+ style->paper_height = get_float (data);
+ } else if (!strcmp ((gchar *) node->name, "top_margin")) {
+ style->top_margin = get_float (data);
+ } else if (!strcmp ((gchar *) node->name, "left_margin")) {
+ style->left_margin = get_float (data);
+ } else if (!strcmp ((gchar *) node->name, "bottom_margin")) {
+ style->bottom_margin = get_float (data);
+ } else if (!strcmp ((gchar *) node->name, "right_margin")) {
+ style->right_margin = get_float (data);
+ } else if (!strcmp ((gchar *) node->name, "page_width")) {
+ style->page_width = get_float (data);
+ } else if (!strcmp ((gchar *) node->name, "page_height")) {
+ style->page_height = get_float (data);
+ } else if (!strcmp ((gchar *) node->name, "orientation")) {
+ if (data) {
+ style->orientation_portrait =
+ (g_ascii_strcasecmp (data, "landscape") != 0);
} else {
style->orientation_portrait = TRUE;
}
- } else if ( !strcmp( node->name, "header_font" ) ) {
- get_font( data, &(style->header_font) );
- } else if ( !strcmp( node->name, "left_header" ) ) {
- get_string(data, &(style->left_header));
- } else if ( !strcmp( node->name, "center_header" ) ) {
- get_string(data, &(style->center_header));
- } else if ( !strcmp( node->name, "right_header" ) ) {
- get_string(data, &(style->right_header));
- } else if ( !strcmp( node->name, "footer_font" ) ) {
- get_font( data, &(style->footer_font) );
- } else if ( !strcmp( node->name, "left_footer" ) ) {
- get_string(data, &(style->left_footer));
- } else if ( !strcmp( node->name, "center_footer" ) ) {
- get_string(data, &(style->center_footer));
- } else if ( !strcmp( node->name, "right_footer" ) ) {
- get_string(data, &(style->right_footer));
- } else if ( !strcmp( node->name, "reverse_on_even_pages" ) ) {
- style->reverse_on_even_pages = get_bool(data);
+ } else if (!strcmp ((gchar *) node->name, "header_font")) {
+ get_font (data, &(style->header_font));
+ } else if (!strcmp ((gchar *) node->name, "left_header")) {
+ get_string (data, &(style->left_header));
+ } else if (!strcmp ((gchar *) node->name, "center_header")) {
+ get_string (data, &(style->center_header));
+ } else if (!strcmp ((gchar *) node->name, "right_header")) {
+ get_string (data, &(style->right_header));
+ } else if (!strcmp ((gchar *) node->name, "footer_font")) {
+ get_font (data, &(style->footer_font));
+ } else if (!strcmp ((gchar *) node->name, "left_footer")) {
+ get_string (data, &(style->left_footer));
+ } else if (!strcmp ((gchar *) node->name, "center_footer")) {
+ get_string (data, &(style->center_footer));
+ } else if (!strcmp ((gchar *) node->name, "right_footer")) {
+ get_string (data, &(style->right_footer));
+ } else if (!strcmp ((gchar *) node->name, "reverse_on_even_pages")) {
+ style->reverse_on_even_pages = get_bool (data);
}
- if ( data )
+ if (data)
xmlFree (data);
}
- xmlFreeDoc(styledoc);
+ xmlFreeDoc (styledoc);
}
-}
-static gint
-e_contact_print_close(GnomeDialog *dialog, gpointer data)
-{
- return FALSE;
}
static void
-e_contact_print_button(GnomeDialog *dialog, gint button, gpointer data)
+contact_draw (EContact *contact,
+ EContactPrintContext *ctxt)
{
- EContactPrintContext *ctxt = g_new(EContactPrintContext, 1);
- EContactPrintStyle *style = g_new(EContactPrintStyle, 1);
- GnomePrintMaster *master;
- GnomePrintContext *pc;
- gboolean uses_book = (gint) gtk_object_get_data(GTK_OBJECT(dialog), "uses_book");
- EBook *book = NULL;
- char *query = NULL;
- ECard *card = NULL;
- gdouble font_size;
- if (uses_book) {
- book = gtk_object_get_data(GTK_OBJECT(dialog), "book");
- query = gtk_object_get_data(GTK_OBJECT(dialog), "query");
- } else {
- card = gtk_object_get_data(GTK_OBJECT(dialog), "card");
+ GtkPageSetup *setup;
+ gdouble page_height;
+ gchar *file_as;
+ gboolean new_section = FALSE;
+
+ setup = gtk_print_context_get_page_setup (ctxt->context);
+ page_height = gtk_page_setup_get_page_height (setup, GTK_UNIT_POINTS);
+
+ file_as = e_contact_get (contact, E_CONTACT_FILE_AS);
+
+ if (file_as != NULL) {
+ gchar *section;
+ gsize width;
+
+ width = g_utf8_next_char (file_as) - file_as;
+ section = g_utf8_strup (file_as, width);
+
+ new_section = (ctxt->section == NULL ||
+ g_utf8_collate (ctxt->section, section) != 0);
+
+ if (new_section) {
+ g_free (ctxt->section);
+ ctxt->section = section;
+ } else
+ g_free (section);
}
- switch( button ) {
- case GNOME_PRINT_PRINT:
- master = gnome_print_master_new_from_dialog( GNOME_PRINT_DIALOG(dialog) );
- pc = gnome_print_master_get_context( master );
- e_contact_build_style(style);
-
- ctxt->x = 0;
- ctxt->y = 0;
- ctxt->column = 0;
- ctxt->style = style;
- ctxt->master = master;
- ctxt->first_section = TRUE;
- ctxt->first_char_on_page = 'A' - 1;
- ctxt->type = GNOME_PRINT_PRINT;
-
- font_size = 72 * ctxt->style->page_height / 27.0 / 2.0;
- ctxt->letter_heading_font = gnome_font_new(gnome_font_get_name(ctxt->style->headings_font), gnome_font_get_size (ctxt->style->headings_font) * 1.5);
- ctxt->letter_tab_font = gnome_font_new(gnome_font_get_name(ctxt->style->headings_font), font_size);
-
- ctxt->pc = GNOME_PRINT_CONTEXT(gnome_print_multipage_new_from_sizes(pc,
- 72 * style->paper_width,
- 72 * style->paper_height,
- 72 * style->page_width,
- 72 * style->page_height));
-
- ctxt->book = book;
- ctxt->query = query;
- if (uses_book) {
- ctxt->cards = NULL;
- e_contact_do_print(book, ctxt->query, ctxt);
- } else {
- ctxt->cards = g_list_append(NULL, card);
- complete_sequence(NULL, E_BOOK_VIEW_STATUS_SUCCESS, ctxt);
- }
- gnome_dialog_close(dialog);
- break;
- case GNOME_PRINT_PREVIEW:
- master = gnome_print_master_new_from_dialog( GNOME_PRINT_DIALOG(dialog) );
- pc = gnome_print_master_get_context( master );
- e_contact_build_style(style);
-
- ctxt->x = 0;
- ctxt->y = 0;
- ctxt->column = 0;
- ctxt->style = style;
- ctxt->master = master;
- ctxt->first_section = TRUE;
- ctxt->first_char_on_page = 'A' - 1;
- ctxt->type = GNOME_PRINT_PREVIEW;
-
- font_size = 72 * ctxt->style->page_height / 27.0 / 2.0;
- ctxt->letter_heading_font = gnome_font_new(gnome_font_get_name(ctxt->style->headings_font), gnome_font_get_size (ctxt->style->headings_font) * 1.5);
- ctxt->letter_tab_font = gnome_font_new(gnome_font_get_name(ctxt->style->headings_font), font_size);
-
- ctxt->pc = GNOME_PRINT_CONTEXT(gnome_print_multipage_new_from_sizes(pc,
- 72 * style->paper_width,
- 72 * style->paper_height,
- 72 * style->page_width,
- 72 * style->page_height));
-
- ctxt->book = book;
- ctxt->query = g_strdup(query);
- if (uses_book) {
- ctxt->cards = NULL;
- gtk_object_ref(GTK_OBJECT(book));
- e_contact_do_print(book, ctxt->query, ctxt);
- } else {
- ctxt->cards = g_list_append(NULL, card);
- gtk_object_ref(GTK_OBJECT(card));
- complete_sequence(NULL, E_BOOK_VIEW_STATUS_SUCCESS, ctxt);
+
+ if (new_section) {
+ if (!ctxt->first_contact) {
+ if (ctxt->style->sections_start_new_page)
+ e_contact_start_new_page (ctxt);
+ else if ((ctxt->y + e_contact_get_contact_height (
+ contact, ctxt)) > page_height)
+ e_contact_start_new_column (ctxt);
}
- break;
- case GNOME_PRINT_CANCEL:
- if (uses_book)
- gtk_object_unref(GTK_OBJECT(book));
- else
- gtk_object_unref(GTK_OBJECT(card));
- g_free(query);
- gnome_dialog_close(dialog);
- g_free(style);
- g_free(ctxt);
- break;
+ if (ctxt->style->letter_headings)
+ e_contact_print_letter_heading (ctxt, ctxt->section);
+ ctxt->first_section = FALSE;
+ }
+
+ else if (!ctxt->first_contact && ((ctxt->y +
+ e_contact_get_contact_height (contact, ctxt)) > page_height)) {
+ e_contact_start_new_column (ctxt);
+ if (ctxt->style->letter_headings)
+ e_contact_print_letter_heading (ctxt, ctxt->section);
}
+
+ e_contact_print_contact (contact, ctxt);
+
+ ctxt->first_contact = FALSE;
}
-GtkWidget *
-e_contact_print_dialog_new(EBook *book, char *query)
+static void
+contact_begin_print (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ EContactPrintContext *ctxt)
{
- GtkWidget *dialog;
-
-
- dialog = gnome_print_dialog_new(_("Print cards"), 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);
-
- gtk_object_ref(GTK_OBJECT(book));
- gtk_object_set_data(GTK_OBJECT(dialog), "uses_book", (void *) 1);
- gtk_object_set_data(GTK_OBJECT(dialog), "book", book);
- gtk_object_set_data(GTK_OBJECT(dialog), "query", g_strdup(query));
- gtk_signal_connect(GTK_OBJECT(dialog),
- "clicked", GTK_SIGNAL_FUNC(e_contact_print_button), NULL);
- gtk_signal_connect(GTK_OBJECT(dialog),
- "close", GTK_SIGNAL_FUNC(e_contact_print_close), NULL);
- return dialog;
+ GtkPageSetup *setup;
+ gdouble page_width;
+
+ e_contact_build_style (ctxt->style);
+
+ setup = gtk_print_context_get_page_setup (context);
+ page_width = gtk_page_setup_get_page_width (setup, GTK_UNIT_POINTS);
+
+ ctxt->context = context;
+ ctxt->x = ctxt->y = .0;
+ ctxt->column = 0;
+ ctxt->first_contact = TRUE;
+ ctxt->first_section = TRUE;
+ ctxt->section = NULL;
+
+ ctxt->column_spacing = gtk_print_context_get_dpi_x (context) / 4;
+ ctxt->column_width = (page_width + ctxt->column_spacing) /
+ ctxt->style->num_columns - ctxt->column_spacing;
+
+ ctxt->letter_heading_font = pango_font_description_new ();
+ pango_font_description_set_family (
+ ctxt->letter_heading_font,
+ pango_font_description_get_family (
+ ctxt->style->headings_font));
+ pango_font_description_set_size (
+ ctxt->letter_heading_font,
+ pango_font_description_get_size (
+ ctxt->style->headings_font) * 1.5);
+
+ if (ctxt->contact_list != NULL) {
+ ctxt->page_nr = -1;
+ ctxt->pages = 1;
+ ctxt->contact_list = g_slist_sort (
+ ctxt->contact_list,
+ (GCompareFunc) contact_compare);
+ g_slist_foreach (ctxt->contact_list, (GFunc) contact_draw, ctxt);
+ gtk_print_operation_set_n_pages (operation, ctxt->pages);
+ }
}
+/* contact_page_draw_footer inserts the
+ * page number at the end of each page
+ * while printing*/
void
-e_contact_print_preview(EBook *book, char *query)
+contact_page_draw_footer (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr)
+{
+ PangoFontDescription *desc;
+ PangoLayout *layout;
+ gdouble x, y, page_height, page_width, page_margin;
+ /*gint n_pages;*/
+ gchar *text;
+ cairo_t *cr;
+ GtkPageSetup *setup;
+
+ /*Uncomment next if it is successful to get total number if pages in list view
+ * g_object_get (operation, "n-pages", &n_pages, NULL)*/
+ text = g_strdup_printf (_("Page %d"), page_nr + 1);
+
+ setup = gtk_print_context_get_page_setup (context);
+ page_height = gtk_page_setup_get_page_height (setup, GTK_UNIT_POINTS);
+ page_width = gtk_page_setup_get_page_width (setup, GTK_UNIT_POINTS);
+ page_margin = gtk_page_setup_get_bottom_margin (setup, GTK_UNIT_POINTS);
+
+ desc = pango_font_description_from_string ("Sans Regular 8");
+ layout = gtk_print_context_create_pango_layout (context);
+ pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
+ pango_layout_set_font_description (layout, desc);
+ pango_layout_set_text (layout, text, -1);
+ pango_layout_set_width (layout, -1);
+
+ x = page_width / 2.0 - page_margin;
+ y = page_height - page_margin / 2.0;
+
+ cr = gtk_print_context_get_cairo_context (context);
+
+ cairo_save (cr);
+ cairo_set_source_rgb (cr, .0, .0, .0);
+ cairo_move_to (cr, x, y);
+ pango_cairo_show_layout (cr, layout);
+ cairo_restore (cr);
+
+ g_object_unref (layout);
+ pango_font_description_free (desc);
+
+ g_free (text);
+}
+
+static void
+contact_draw_page (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr,
+ EContactPrintContext *ctxt)
{
- EContactPrintContext *ctxt = g_new(EContactPrintContext, 1);
- EContactPrintStyle *style = g_new(EContactPrintStyle, 1);
- GnomePrintMaster *master;
- GnomePrintContext *pc;
- gdouble font_size;
-
- master = gnome_print_master_new();
- gnome_print_master_set_copies (master, 1, FALSE);
- pc = gnome_print_master_get_context (master);
- e_contact_build_style (style);
-
- ctxt->x = 0;
- ctxt->y = 0;
+ /* only text on page_nr == pages will be drawn, the pages is recalculated */
+ ctxt->page_nr = page_nr;
+ ctxt->pages = 0;
+
+ ctxt->x = ctxt->y = .0;
ctxt->column = 0;
- ctxt->style = style;
- ctxt->master = master;
+ ctxt->first_contact = TRUE;
ctxt->first_section = TRUE;
- ctxt->first_char_on_page = 'A' - 1;
- ctxt->type = GNOME_PRINT_PREVIEW;
-
- font_size = 72 * ctxt->style->page_height / 27.0 / 2.0;
- ctxt->letter_heading_font = gnome_font_new(gnome_font_get_name(ctxt->style->headings_font), gnome_font_get_size (ctxt->style->headings_font) * 1.5);
- ctxt->letter_tab_font = gnome_font_new(gnome_font_get_name(ctxt->style->headings_font), font_size);
-
- ctxt->pc = GNOME_PRINT_CONTEXT(gnome_print_multipage_new_from_sizes(pc,
- 72 * style->paper_width,
- 72 * style->paper_height,
- 72 * style->page_width,
- 72 * style->page_height));
-
- ctxt->book = book;
- ctxt->query = g_strdup(query);
- ctxt->cards = NULL;
- gtk_object_ref(GTK_OBJECT(book));
- e_contact_do_print(book, ctxt->query, ctxt);
+ ctxt->section = NULL;
+
+ g_slist_foreach (ctxt->contact_list, (GFunc) contact_draw, ctxt);
+ contact_page_draw_footer (operation, context, page_nr);
}
-GtkWidget *
-e_contact_print_card_dialog_new(ECard *card)
+static void
+contact_end_print (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ EContactPrintContext *ctxt)
{
- GtkWidget *dialog;
-
- dialog = gnome_print_dialog_new(_("Print card"), GNOME_PRINT_DIALOG_COPIES);
-
- card = e_card_duplicate(card);
- gtk_object_set_data(GTK_OBJECT(dialog), "card", card);
- gtk_object_set_data(GTK_OBJECT(dialog), "uses_book", (void *) 0);
- gtk_signal_connect(GTK_OBJECT(dialog),
- "clicked", GTK_SIGNAL_FUNC(e_contact_print_button), NULL);
- gtk_signal_connect(GTK_OBJECT(dialog),
- "close", GTK_SIGNAL_FUNC(e_contact_print_close), NULL);
- return dialog;
+ pango_font_description_free (ctxt->style->headings_font);
+ pango_font_description_free (ctxt->style->body_font);
+ pango_font_description_free (ctxt->style->header_font);
+ pango_font_description_free (ctxt->style->footer_font);
+ pango_font_description_free (ctxt->letter_heading_font);
+
+ g_slist_free_full (
+ ctxt->contact_list,
+ (GDestroyNotify) g_object_unref);
+
+ g_free (ctxt->style);
+ g_free (ctxt->section);
}
-/* FIXME: Print all the contacts selected. */
-GtkWidget *
-e_contact_print_card_list_dialog_new(GList *list)
+static void
+get_view_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- GtkWidget *dialog;
- ECard *card;
+ GtkPrintOperation *operation = user_data;
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ EBookClientView *client_view = NULL;
+ EContactPrintContext *ctxt;
+ GError *error = NULL;
- if (list == NULL)
- return NULL;
-
- dialog = gnome_print_dialog_new(_("Print card"), GNOME_PRINT_DIALOG_COPIES);
-
- card = e_card_duplicate(list->data);
- gtk_object_set_data(GTK_OBJECT(dialog), "card", card);
- gtk_object_set_data(GTK_OBJECT(dialog), "uses_book", (void *) 0);
- gtk_signal_connect(GTK_OBJECT(dialog),
- "clicked", GTK_SIGNAL_FUNC(e_contact_print_button), NULL);
- gtk_signal_connect(GTK_OBJECT(dialog),
- "close", GTK_SIGNAL_FUNC(e_contact_print_close), NULL);
- return dialog;
+ e_book_client_get_view_finish (book_client, result, &client_view, &error);
+
+ ctxt = g_object_get_data (G_OBJECT (operation), "contact-print-ctx");
+ g_return_if_fail (ctxt != NULL);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to get view: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+
+ gtk_print_operation_run (operation, ctxt->action, NULL, NULL);
+ g_object_unref (operation);
+ } else {
+ g_signal_connect (
+ client_view, "objects-added",
+ G_CALLBACK (contacts_added), ctxt);
+ g_signal_connect (
+ client_view, "complete",
+ G_CALLBACK (view_complete), operation);
+
+ e_book_client_view_start (client_view, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to start view: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+
+ gtk_print_operation_run (operation, ctxt->action, NULL, NULL);
+ g_object_unref (operation);
+ }
+ }
+}
+
+void
+e_contact_print (EBookClient *book_client,
+ EBookQuery *query,
+ const GSList *contact_list,
+ GtkPrintOperationAction action)
+{
+ GtkPrintOperation *operation;
+ EContactPrintContext *ctxt;
+
+ ctxt = g_new0 (EContactPrintContext, 1);
+ ctxt->action = action;
+ ctxt->contact_list = g_slist_copy_deep (
+ (GSList *) contact_list,
+ (GCopyFunc) g_object_ref, NULL);
+ ctxt->style = g_new0 (EContactPrintStyle, 1);
+ ctxt->page_nr = 0;
+ ctxt->pages = 0;
+
+ operation = e_print_operation_new ();
+ gtk_print_operation_set_n_pages (operation, 1);
+
+ g_object_set_data_full (
+ G_OBJECT (operation), "contact-print-ctx", ctxt, g_free);
+
+ g_signal_connect (
+ operation, "begin-print",
+ G_CALLBACK (contact_begin_print), ctxt);
+ g_signal_connect (
+ operation, "draw_page",
+ G_CALLBACK (contact_draw_page), ctxt);
+ g_signal_connect (
+ operation, "end-print",
+ G_CALLBACK (contact_end_print), ctxt);
+
+ if (book_client) {
+ gchar *query_str = e_book_query_to_string (query);
+
+ e_book_client_get_view (
+ book_client, query_str, NULL,
+ get_view_ready_cb, operation);
+
+ g_free (query_str);
+ } else {
+ gtk_print_operation_run (operation, action, NULL, NULL);
+
+ g_object_unref (operation);
+ }
}
diff --git a/addressbook/printing/e-contact-print.glade b/addressbook/printing/e-contact-print.glade
deleted file mode 100644
index 292fc8cc85..0000000000
--- a/addressbook/printing/e-contact-print.glade
+++ /dev/null
@@ -1,2003 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>Printing</name>
- <program_name>printing</program_name>
- <directory></directory>
- <source_directory></source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>False</gnome_support>
- <gettext_support>False</gettext_support>
- <output_main_file>False</output_main_file>
- <output_support_files>False</output_support_files>
- <output_build_files>False</output_build_files>
-</project>
-
-<widget>
- <class>GnomeDialog</class>
- <name>print-edit-style</name>
- <visible>False</visible>
- <title>Page Setup:</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>False</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>False</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>dialog-vbox1</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>dialog-action_area1</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button1</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button2</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_APPLY</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button3</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox-contact-print-style-editor</name>
- <homogeneous>False</homogeneous>
- <spacing>5</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox2</name>
- <border_width>5</border_width>
- <homogeneous>False</homogeneous>
- <spacing>16</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label8</name>
- <label>Style name:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>label-style-name</name>
- <can_focus>True</can_focus>
- <editable>False</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkNotebook</class>
- <name>notebook1</name>
- <can_focus>True</can_focus>
- <show_tabs>True</show_tabs>
- <show_border>True</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox2</name>
- <border_width>5</border_width>
- <homogeneous>False</homogeneous>
- <spacing>5</spacing>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment1</name>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame5</name>
- <label>Preview:</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox1</name>
- <homogeneous>True</homogeneous>
- <spacing>7</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame6</name>
- <label>Options</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment4</name>
- <xalign>0</xalign>
- <yalign>0</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
-
- <widget>
- <class>GtkTable</class>
- <name>table1</name>
- <border_width>8</border_width>
- <rows>6</rows>
- <columns>5</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>0</row_spacing>
- <column_spacing>0</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label5</name>
- <label>Include:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label4</name>
- <label>Sections:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment2</name>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>5</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>radiobutton1</name>
- <can_focus>True</can_focus>
- <label>Immediately follow each other</label>
- <active>True</active>
- <draw_indicator>True</draw_indicator>
- </widget>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>checkbutton1</name>
- <can_focus>True</can_focus>
- <label>Letter tabs on side</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <left_attach>1</left_attach>
- <right_attach>5</right_attach>
- <top_attach>4</top_attach>
- <bottom_attach>5</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>checkbutton2</name>
- <can_focus>True</can_focus>
- <label>Headings for each letter</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <left_attach>1</left_attach>
- <right_attach>5</right_attach>
- <top_attach>5</top_attach>
- <bottom_attach>6</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment3</name>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>5</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>radiobutton2</name>
- <can_focus>True</can_focus>
- <label>Start on a new page</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label6</name>
- <label>Number of columns:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>3</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>2</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label7</name>
- <label>Blank forms at end:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>3</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>2</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment6</name>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>2</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkSpinButton</class>
- <name>spinbutton2</name>
- <can_focus>True</can_focus>
- <climb_rate>1</climb_rate>
- <digits>0</digits>
- <numeric>False</numeric>
- <update_policy>GTK_UPDATE_ALWAYS</update_policy>
- <snap>False</snap>
- <wrap>False</wrap>
- <value>2</value>
- <lower>0</lower>
- <upper>100</upper>
- <step>1</step>
- <page>10</page>
- <page_size>10</page_size>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment5</name>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>2</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkSpinButton</class>
- <name>spinbutton1</name>
- <width>45</width>
- <can_focus>True</can_focus>
- <climb_rate>1</climb_rate>
- <digits>0</digits>
- <numeric>False</numeric>
- <update_policy>GTK_UPDATE_ALWAYS</update_policy>
- <snap>False</snap>
- <wrap>False</wrap>
- <value>1</value>
- <lower>0</lower>
- <upper>100</upper>
- <step>1</step>
- <page>10</page>
- <page_size>10</page_size>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox3</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame7</name>
- <label>Fonts</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkTable</class>
- <name>table2</name>
- <border_width>8</border_width>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>13</row_spacing>
- <column_spacing>8</column_spacing>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment7</name>
- <xalign>0.5</xalign>
- <yalign>1</yalign>
- <xscale>1</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button6</name>
- <can_focus>True</can_focus>
- <label>F_ont...</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment8</name>
- <xalign>0.5</xalign>
- <yalign>1</yalign>
- <xscale>1</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button5</name>
- <width>90</width>
- <can_focus>True</can_focus>
- <label>_Font...</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox4</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label10</name>
- <label>Headings</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry3</name>
- <width>100</width>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text>10 pt. Tahoma</text>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox5</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label9</name>
- <label>Body</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry2</name>
- <width>100</width>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text>8 pt. Tahoma</text>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame8</name>
- <label>Shading</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>checkbutton3</name>
- <can_focus>True</can_focus>
- <label>Print using gray shading</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label1</name>
- <label>Format</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox3</name>
- <homogeneous>True</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox6</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame9</name>
- <label>Paper</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox16</name>
- <border_width>10</border_width>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox17</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label21</name>
- <label>Type:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow1</name>
- <hscrollbar_policy>GTK_POLICY_ALWAYS</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>clist1</name>
- <can_focus>True</can_focus>
- <columns>1</columns>
- <column_widths>80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>False</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label26</name>
- <label>label26</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox18</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label24</name>
- <label>Dimensions:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox5</name>
- <homogeneous>True</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label27</name>
- <label>Width:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry9</name>
- <width>1</width>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label28</name>
- <label>Height:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry10</name>
- <width>1</width>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox19</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label25</name>
- <label>Paper source:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCombo</class>
- <name>combo1</name>
- <value_in_list>False</value_in_list>
- <ok_if_empty>True</ok_if_empty>
- <case_sensitive>False</case_sensitive>
- <use_arrows>True</use_arrows>
- <use_arrows_always>False</use_arrows_always>
- <items></items>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <child_name>GtkCombo:entry</child_name>
- <name>combo-entry1</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame10</name>
- <label>Margins</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkTable</class>
- <name>table4</name>
- <border_width>15</border_width>
- <rows>2</rows>
- <columns>4</columns>
- <homogeneous>True</homogeneous>
- <row_spacing>6</row_spacing>
- <column_spacing>9</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label29</name>
- <label>Top:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label30</name>
- <label>Bottom:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label31</name>
- <label>Left:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry11</name>
- <width>1</width>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry12</name>
- <width>1</width>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry13</name>
- <width>1</width>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>3</left_attach>
- <right_attach>4</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry14</name>
- <width>1</width>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label32</name>
- <label>Right:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox7</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame11</name>
- <label>Page</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox8</name>
- <border_width>10</border_width>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox20</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label33</name>
- <label>Size:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow2</name>
- <hscrollbar_policy>GTK_POLICY_ALWAYS</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>clist2</name>
- <can_focus>True</can_focus>
- <columns>1</columns>
- <column_widths>80</column_widths>
- <selection_mode>GTK_SELECTION_SINGLE</selection_mode>
- <show_titles>False</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label35</name>
- <label>label26</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox21</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label34</name>
- <label>Dimensions:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox6</name>
- <homogeneous>True</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label36</name>
- <label>Width:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry15</name>
- <width>1</width>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label37</name>
- <label>Height:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry16</name>
- <width>1</width>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame12</name>
- <label>Orientation</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox4</name>
- <homogeneous>False</homogeneous>
- <spacing>10</spacing>
-
- <widget>
- <class>Placeholder</class>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox9</name>
- <homogeneous>False</homogeneous>
- <spacing>5</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment9</name>
- <xalign>0</xalign>
- <yalign>1</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>radiobutton3</name>
- <can_focus>True</can_focus>
- <label>Portrait</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment10</name>
- <xalign>0</xalign>
- <yalign>0</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>radiobutton4</name>
- <can_focus>True</can_focus>
- <label>Landscape</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label2</name>
- <label>Paper</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox10</name>
- <border_width>8</border_width>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkTable</class>
- <name>table5</name>
- <rows>4</rows>
- <columns>3</columns>
- <homogeneous>True</homogeneous>
- <row_spacing>4</row_spacing>
- <column_spacing>4</column_spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment15</name>
- <xalign>0</xalign>
- <yalign>1</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button11</name>
- <can_focus>True</can_focus>
- <label>F_ont...</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
-
- <widget>
- <class>GtkText</class>
- <name>text10</name>
- <height>50</height>
- <can_focus>True</can_focus>
- <editable>False</editable>
- <text></text>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkText</class>
- <name>text11</name>
- <height>50</height>
- <can_focus>True</can_focus>
- <editable>False</editable>
- <text></text>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkText</class>
- <name>text12</name>
- <height>50</height>
- <can_focus>True</can_focus>
- <editable>False</editable>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkText</class>
- <name>text13</name>
- <height>50</height>
- <can_focus>True</can_focus>
- <editable>False</editable>
- <text></text>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>True</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkText</class>
- <name>text14</name>
- <height>5</height>
- <can_focus>True</can_focus>
- <editable>False</editable>
- <text></text>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkText</class>
- <name>text15</name>
- <height>50</height>
- <can_focus>True</can_focus>
- <editable>False</editable>
- <text></text>
- <child>
- <left_attach>2</left_attach>
- <right_attach>3</right_attach>
- <top_attach>3</top_attach>
- <bottom_attach>4</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment16</name>
- <xalign>0.5</xalign>
- <yalign>1</yalign>
- <xscale>1</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox14</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label14</name>
- <label>Header</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry7</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment17</name>
- <xalign>0.5</xalign>
- <yalign>1</yalign>
- <xscale>1</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox15</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label15</name>
- <label>Footer:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>entry8</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment14</name>
- <xalign>0</xalign>
- <yalign>1</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button10</name>
- <can_focus>True</can_focus>
- <label>_Font...</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox7</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkToolbar</class>
- <name>toolbar1</name>
- <orientation>GTK_ORIENTATION_HORIZONTAL</orientation>
- <type>GTK_TOOLBAR_ICONS</type>
- <space_size>5</space_size>
- <space_style>GTK_TOOLBAR_SPACE_EMPTY</space_style>
- <relief>GTK_RELIEF_NORMAL</relief>
- <tooltips>True</tooltips>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>Placeholder</class>
- </widget>
-
- <widget>
- <class>Placeholder</class>
- </widget>
-
- <widget>
- <class>Placeholder</class>
- </widget>
-
- <widget>
- <class>Placeholder</class>
- </widget>
-
- <widget>
- <class>Placeholder</class>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>checkbutton4</name>
- <can_focus>True</can_focus>
- <label>Reverse on even pages</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label3</name>
- <label>Header/Footer</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/addressbook/printing/e-contact-print.h b/addressbook/printing/e-contact-print.h
index 12f13f4573..6cdc231ddd 100644
--- a/addressbook/printing/e-contact-print.h
+++ b/addressbook/printing/e-contact-print.h
@@ -1,36 +1,39 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-contact-print.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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_PRINT_H
#define E_CONTACT_PRINT_H
-#include <glib.h>
-#include <gtk/gtkwidget.h>
-#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-card.h>
+#include <gtk/gtk.h>
+#include <libebook/libebook.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);
+void e_contact_print (EBookClient *book_client,
+ EBookQuery *query,
+ const GSList *contact_list,
+ GtkPrintOperationAction action);
+void contact_page_draw_footer (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr);
#endif /* E_CONTACT_PRINT_H */
diff --git a/addressbook/printing/medbook.ecps b/addressbook/printing/medbook.ecps
index ef76c0b46e..8602ca7df0 100644
--- a/addressbook/printing/medbook.ecps
+++ b/addressbook/printing/medbook.ecps
@@ -7,7 +7,7 @@
<letter_tabs>TRUE</letter_tabs>
<letter_headings>TRUE</letter_headings>
<headings_font>Helvetica Bold 12</headings_font>
-<body_font>Helvetica 8</body_font>
+<body_font>Helvetica Regular 8</body_font>
<print_using_grey>TRUE</print_using_grey>
<paper_width>8.5</paper_width>
<paper_height>11</paper_height>
@@ -18,11 +18,11 @@
<page_width>8.5</page_width>
<page_height>11</page_height>
<orientation>portrait</orientation>
-<header_font>Helvetica 8</header_font>
+<header_font>Helvetica Regular 8</header_font>
<left_header/>
<center_header/>
<right_header/>
-<footer_font>Helvetica 8</footer_font>
+<footer_font>Helvetica Regular 8</footer_font>
<left_footer/>
<center_footer>[Page #]</center_footer>
<right_footer/>
diff --git a/addressbook/printing/test-contact-print-style-editor.c b/addressbook/printing/test-contact-print-style-editor.c
deleted file mode 100644
index 0ac169468c..0000000000
--- a/addressbook/printing/test-contact-print-style-editor.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * test-contact-print-style-editor.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 <stdlib.h>
-#include <gtk/gtkmain.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-init.h>
-#include "e-contact-print-style-editor.h"
-
-/* This is a horrible thing to do, but it is just a test. */
-GtkWidget *editor;
-
-static void destroy_callback(GtkWidget *app, gpointer data)
-{
- static int count = 2;
- count --;
- if ( count <= 0 )
- 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 ( _( "Contact Print Style Editor Test" ), VERSION,
- _( "Copyright (C) 2000, Ximian, Inc." ),
- authors,
- _( "This should test the contact print style editor widget" ),
- NULL);
- gtk_widget_show (about);
-}
-#endif
-
-int main( int argc, char *argv[] )
-{
- GtkWidget *app;
-
- /* bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);*/
-
- gnome_init( "Contact Print Style Editor Test", VERSION, argc, argv);
-
- glade_gnome_init ();
-
- app = gnome_app_new("Contact Print Style Editor Test", NULL);
-
- editor = e_contact_print_style_editor_new("");
-
- gnome_app_set_contents( GNOME_APP( app ), editor );
-
- /* Connect the signals */
- gtk_signal_connect( GTK_OBJECT( app ), "destroy",
- GTK_SIGNAL_FUNC( destroy_callback ),
- ( gpointer ) app );
-
- gtk_widget_show_all( app );
-
- gtk_main();
-
- /* Not reached. */
- return 0;
-}
diff --git a/addressbook/printing/test-print.c b/addressbook/printing/test-print.c
index fc868318d8..6f461959c3 100644
--- a/addressbook/printing/test-print.c
+++ b/addressbook/printing/test-print.c
@@ -1,86 +1,51 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * test-print.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 free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <stdlib.h>
-#include <gtk/gtkmain.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <libgnomeui/gnome-init.h>
-#include <glade/glade.h>
+#include <gtk/gtk.h>
#include "e-contact-print.h"
-/* This is a horrible thing to do, but it is just a test. */
-GtkWidget *print;
-
-static gint test_close(GnomeDialog *dialog, gpointer data)
-{
- exit(0);
- return 1;
-}
-
-#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 ( _( "Contact Print Test" ), VERSION,
- _( "Copyright (C) 2000, Ximian, Inc." ),
- authors,
- _( "This should test the contact print code" ),
- NULL);
- gtk_widget_show (about);
-}
-#endif
-
-int main( int argc, char *argv[] )
+gint
+main (gint argc,
+ gchar *argv[])
{
- GList *shown_fields = NULL;
-
- /* bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);*/
+ GList *shown_fields = NULL;
- gnome_init( "Contact Print Test", VERSION, argc, argv);
+ gtk_init (&argc, &argv);
- glade_gnome_init ();
-
- shown_fields = g_list_append(shown_fields, "First field");
- shown_fields = g_list_append(shown_fields, "Second field");
- shown_fields = g_list_append(shown_fields, "Third field");
- shown_fields = g_list_append(shown_fields, "Fourth field");
+ shown_fields = g_list_append (shown_fields, (gpointer) "First field");
+ shown_fields = g_list_append (shown_fields, (gpointer) "Second field");
+ shown_fields = g_list_append (shown_fields, (gpointer) "Third field");
+ shown_fields = g_list_append (shown_fields, (gpointer) "Fourth field");
- print = e_contact_print_dialog_new(NULL, NULL);
- gtk_widget_show_all(print);
- gtk_signal_connect(GTK_OBJECT(print), "close", GTK_SIGNAL_FUNC(test_close), NULL);
+ /* does nothing */
+ e_contact_print (NULL, NULL, NULL, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
- gtk_main();
+ gtk_main ();
- /* Not reached. */
- return 0;
+ /* Not reached. */
+ return 0;
}
diff --git a/addressbook/tools/Makefile.am b/addressbook/tools/Makefile.am
new file mode 100644
index 0000000000..4d2e6d4746
--- /dev/null
+++ b/addressbook/tools/Makefile.am
@@ -0,0 +1,35 @@
+privlibexec_SCRIPTS = \
+ csv2vcard
+
+privlibexec_PROGRAMS = evolution-addressbook-export
+
+evolution_addressbook_export_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DG_LOG_DOMAIN=\"evolution-addressbook-tools\" \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
+ -DPREFIX=\""$(prefix)"\" \
+ -DSYSCONFDIR=\""$(sysconfdir)"\" \
+ -DDATADIR=\""$(datadir)"\" \
+ -DLIBDIR=\""$(libdir)"\" \
+ -I$(top_srcdir)/addressbook \
+ -I$(top_builddir)/addressbook \
+ $(EVOLUTION_DATA_SERVER_CFLAGS)
+
+evolution_addressbook_export_SOURCES = \
+ evolution-addressbook-export.c \
+ evolution-addressbook-export-list-cards.c \
+ evolution-addressbook-export-list-folders.c \
+ evolution-addressbook-export.h
+
+evolution_addressbook_export_LDADD = \
+ $(EVOLUTION_DATA_SERVER_LIBS)
+
+if OS_WIN32
+evolution_addressbook_export_LDFLAGS = -mwindows
+endif
+
+EXTRA_DIST = $(privlibexec_SCRIPTS)
+
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/tools/csv2vcard.in b/addressbook/tools/csv2vcard.in
new file mode 100755
index 0000000000..8c2961cf99
--- /dev/null
+++ b/addressbook/tools/csv2vcard.in
@@ -0,0 +1,236 @@
+#!@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., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, 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-export-list-cards.c b/addressbook/tools/evolution-addressbook-export-list-cards.c
new file mode 100644
index 0000000000..d6e9ecca57
--- /dev/null
+++ b/addressbook/tools/evolution-addressbook-export-list-cards.c
@@ -0,0 +1,750 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Gilbert Fang <gilbert.fang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+
+#include <libebook/libebook.h>
+
+#include "evolution-addressbook-export.h"
+
+#define COMMA_SEPARATOR ","
+
+typedef enum _CARD_FORMAT CARD_FORMAT;
+typedef enum _DeliveryAddressField DeliveryAddressField;
+typedef enum _EContactFieldCSV EContactFieldCSV;
+typedef struct _EContactCSVFieldData EContactCSVFieldData;
+
+enum _CARD_FORMAT
+{
+ CARD_FORMAT_CSV,
+ CARD_FORMAT_VCARD
+};
+
+enum _DeliveryAddressField
+{
+ DELIVERY_ADDRESS_STREET,
+ DELIVERY_ADDRESS_EXT,
+ DELIVERY_ADDRESS_LOCALITY,
+ DELIVERY_ADDRESS_REGION,
+ DELIVERY_ADDRESS_CODE,
+ DELIVERY_ADDRESS_COUNTRY
+};
+
+enum _EContactFieldCSV
+{
+ E_CONTACT_CSV_FILE_AS,
+ E_CONTACT_CSV_FULL_NAME,
+ E_CONTACT_CSV_EMAIL_1,
+ E_CONTACT_CSV_EMAIL_2,
+ E_CONTACT_CSV_EMAIL_3,
+ E_CONTACT_CSV_EMAIL_4,
+ E_CONTACT_CSV_PHONE_PRIMARY,
+ E_CONTACT_CSV_PHONE_ASSISTANT,
+ E_CONTACT_CSV_PHONE_BUSINESS,
+ E_CONTACT_CSV_PHONE_CALLBACK,
+ E_CONTACT_CSV_PHONE_COMPANY,
+ E_CONTACT_CSV_PHONE_HOME,
+ E_CONTACT_CSV_ORG,
+ /*E_CONTACT_CSV_ADDRESS_BUSINESS, */
+ E_CONTACT_CSV_ADDRESS_BUSINESS_STREET,
+ E_CONTACT_CSV_ADDRESS_BUSINESS_EXT,
+ E_CONTACT_CSV_ADDRESS_BUSINESS_CITY,
+ E_CONTACT_CSV_ADDRESS_BUSINESS_REGION,
+ E_CONTACT_CSV_ADDRESS_BUSINESS_POSTCODE,
+ E_CONTACT_CSV_ADDRESS_BUSINESS_COUNTRY,
+ /*E_CONTACT_CSV_ADDRESS_HOME, */
+ E_CONTACT_CSV_ADDRESS_HOME_STREET,
+ E_CONTACT_CSV_ADDRESS_HOME_EXT,
+ E_CONTACT_CSV_ADDRESS_HOME_CITY,
+ E_CONTACT_CSV_ADDRESS_HOME_REGION,
+ E_CONTACT_CSV_ADDRESS_HOME_POSTCODE,
+ E_CONTACT_CSV_ADDRESS_HOME_COUNTRY,
+ E_CONTACT_CSV_PHONE_MOBILE,
+ E_CONTACT_CSV_PHONE_CAR,
+ E_CONTACT_CSV_PHONE_BUSINESS_FAX,
+ E_CONTACT_CSV_PHONE_HOME_FAX,
+ E_CONTACT_CSV_PHONE_BUSINESS_2,
+ E_CONTACT_CSV_PHONE_HOME_2,
+ E_CONTACT_CSV_PHONE_ISDN,
+ E_CONTACT_CSV_PHONE_OTHER,
+ E_CONTACT_CSV_PHONE_OTHER_FAX,
+ E_CONTACT_CSV_PHONE_PAGER,
+ E_CONTACT_CSV_PHONE_RADIO,
+ E_CONTACT_CSV_PHONE_TELEX,
+ E_CONTACT_CSV_PHONE_TTYTDD,
+ /*E_CONTACT_CSV_ADDRESS_OTHER, */
+ E_CONTACT_CSV_ADDRESS_OTHER_STREET,
+ E_CONTACT_CSV_ADDRESS_OTHER_EXT,
+ E_CONTACT_CSV_ADDRESS_OTHER_CITY,
+ E_CONTACT_CSV_ADDRESS_OTHER_REGION,
+ E_CONTACT_CSV_ADDRESS_OTHER_POSTCODE,
+ E_CONTACT_CSV_ADDRESS_OTHER_COUNTRY,
+ E_CONTACT_CSV_HOMEPAGE_URL,
+ E_CONTACT_CSV_ORG_UNIT,
+ E_CONTACT_CSV_OFFICE,
+ E_CONTACT_CSV_TITLE,
+ E_CONTACT_CSV_ROLE,
+ E_CONTACT_CSV_MANAGER,
+ E_CONTACT_CSV_ASSISTANT,
+ E_CONTACT_CSV_NICKNAME,
+ E_CONTACT_CSV_SPOUSE,
+ E_CONTACT_CSV_NOTE,
+ E_CONTACT_CSV_CALENDAR_URI,
+ E_CONTACT_CSV_FREEBUSY_URL,
+ /*E_CONTACT_CSV_ANNIVERSARY, */
+ E_CONTACT_CSV_ANNIVERSARY_YEAR,
+ E_CONTACT_CSV_ANNIVERSARY_MONTH,
+ E_CONTACT_CSV_ANNIVERSARY_DAY,
+ /*E_CONTACT_CSV_BIRTH_DATE, */
+ E_CONTACT_CSV_BIRTH_DATE_YEAR,
+ E_CONTACT_CSV_BIRTH_DATE_MONTH,
+ E_CONTACT_CSV_BIRTH_DATE_DAY,
+ E_CONTACT_CSV_MAILER,
+ E_CONTACT_CSV_NAME_OR_ORG,
+ E_CONTACT_CSV_CATEGORIES,
+ E_CONTACT_CSV_FAMILY_NAME,
+ E_CONTACT_CSV_GIVEN_NAME,
+ E_CONTACT_CSV_WANTS_HTML,
+ E_CONTACT_CSV_IS_LIST,
+ E_CONTACT_CSV_LAST
+};
+
+typedef enum {
+ DT_STRING,
+ DT_BOOLEAN
+} EContactCSVDataType;
+
+struct _EContactCSVFieldData
+{
+ gint csv_field;
+ gint contact_field;
+ const gchar *csv_name;
+ EContactCSVDataType data_type;
+};
+
+#define NOMAP -1
+static EContactCSVFieldData csv_field_data[] = {
+ {E_CONTACT_CSV_FILE_AS, E_CONTACT_FILE_AS, "", DT_STRING},
+ {E_CONTACT_CSV_FULL_NAME, E_CONTACT_CSV_FULL_NAME, "", DT_STRING},
+ {E_CONTACT_CSV_EMAIL_1, E_CONTACT_EMAIL_1, "", DT_STRING},
+ {E_CONTACT_CSV_EMAIL_2, E_CONTACT_EMAIL_2, "", DT_STRING},
+ {E_CONTACT_CSV_EMAIL_3, E_CONTACT_EMAIL_3, "", DT_STRING},
+ {E_CONTACT_CSV_EMAIL_4, E_CONTACT_EMAIL_4, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_PRIMARY, E_CONTACT_PHONE_PRIMARY, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_ASSISTANT, E_CONTACT_PHONE_ASSISTANT, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_BUSINESS, E_CONTACT_PHONE_BUSINESS, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_CALLBACK, E_CONTACT_PHONE_CALLBACK, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_COMPANY, E_CONTACT_PHONE_COMPANY, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_HOME, E_CONTACT_PHONE_HOME, "", DT_STRING},
+ {E_CONTACT_CSV_ORG, E_CONTACT_ORG, "", DT_STRING},
+ /*E_CONTACT_CSV_ADDRESS_BUSINESS, */
+ {E_CONTACT_CSV_ADDRESS_BUSINESS_STREET, NOMAP, "Business Address", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_BUSINESS_EXT, NOMAP, "Business Address2", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_BUSINESS_CITY, NOMAP, "Business Address City", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_BUSINESS_REGION, NOMAP, "Business Address State", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_BUSINESS_POSTCODE, NOMAP, "Business Address PostCode", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_BUSINESS_COUNTRY, NOMAP, "Business Address Country", DT_STRING},
+ /*E_CONTACT_CSV_ADDRESS_HOME, */
+ {E_CONTACT_CSV_ADDRESS_HOME_STREET, NOMAP, "Home Address", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_HOME_EXT, NOMAP, "Home Address2", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_HOME_CITY, NOMAP, "Home Address City", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_HOME_REGION, NOMAP, "Home Address State", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_HOME_POSTCODE, NOMAP, "Home Address PostCode", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_HOME_COUNTRY, NOMAP, "Home Address Country", DT_STRING},
+ {E_CONTACT_CSV_PHONE_MOBILE, E_CONTACT_PHONE_MOBILE, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_CAR, E_CONTACT_PHONE_CAR, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_BUSINESS_FAX, E_CONTACT_PHONE_BUSINESS_FAX, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_HOME_FAX, E_CONTACT_PHONE_HOME_FAX, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_BUSINESS_2, E_CONTACT_PHONE_BUSINESS_2, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_HOME_2, E_CONTACT_PHONE_HOME_2, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_ISDN, E_CONTACT_PHONE_ISDN, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_OTHER, E_CONTACT_PHONE_OTHER, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_OTHER_FAX, E_CONTACT_PHONE_OTHER_FAX, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_PAGER, E_CONTACT_PHONE_PAGER, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_RADIO, E_CONTACT_PHONE_RADIO, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_TELEX, E_CONTACT_PHONE_TELEX, "", DT_STRING},
+ {E_CONTACT_CSV_PHONE_TTYTDD, E_CONTACT_PHONE_TTYTDD, "", DT_STRING},
+ /*E_CONTACT_CSV_ADDRESS_OTHER, */
+ {E_CONTACT_CSV_ADDRESS_OTHER_STREET, NOMAP, "Other Address", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_OTHER_EXT, NOMAP, "Other Address2", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_OTHER_CITY, NOMAP, "Other Address City", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_OTHER_REGION, NOMAP, "Other Address State", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_OTHER_POSTCODE, NOMAP, "Other Address PostCode", DT_STRING},
+ {E_CONTACT_CSV_ADDRESS_OTHER_COUNTRY, NOMAP, "Other Address Country", DT_STRING},
+ {E_CONTACT_CSV_HOMEPAGE_URL, E_CONTACT_HOMEPAGE_URL, "", DT_STRING},
+ {E_CONTACT_CSV_ORG_UNIT, E_CONTACT_ORG_UNIT, "", DT_STRING},
+ {E_CONTACT_CSV_OFFICE, E_CONTACT_OFFICE, "", DT_STRING},
+ {E_CONTACT_CSV_TITLE, E_CONTACT_TITLE, "", DT_STRING},
+ {E_CONTACT_CSV_ROLE, E_CONTACT_ROLE, "", DT_STRING},
+ {E_CONTACT_CSV_MANAGER, E_CONTACT_MANAGER, "", DT_STRING},
+ {E_CONTACT_CSV_ASSISTANT, E_CONTACT_ASSISTANT, "", DT_STRING},
+ {E_CONTACT_CSV_NICKNAME, E_CONTACT_NICKNAME, "", DT_STRING},
+ {E_CONTACT_CSV_SPOUSE, E_CONTACT_SPOUSE, "", DT_STRING},
+ {E_CONTACT_CSV_NOTE, E_CONTACT_NOTE, "", DT_STRING},
+ {E_CONTACT_CSV_CALENDAR_URI, E_CONTACT_CALENDAR_URI, "", DT_STRING},
+ {E_CONTACT_CSV_FREEBUSY_URL, E_CONTACT_FREEBUSY_URL, "", DT_STRING},
+ /*E_CONTACT_ANNIVERSARY, */
+ {E_CONTACT_CSV_ANNIVERSARY_YEAR, NOMAP, "Anniversary Year", DT_STRING},
+ {E_CONTACT_CSV_ANNIVERSARY_MONTH, NOMAP, "Anniversary Month", DT_STRING},
+ {E_CONTACT_CSV_ANNIVERSARY_DAY, NOMAP, "Anniversary Day", DT_STRING},
+ /*E_CONTACT_BIRTH_DATE, */
+ {E_CONTACT_CSV_BIRTH_DATE_YEAR, NOMAP, "Birth Year", DT_STRING},
+ {E_CONTACT_CSV_BIRTH_DATE_MONTH, NOMAP, "Birth Month", DT_STRING},
+ {E_CONTACT_CSV_BIRTH_DATE_DAY, NOMAP, "Birth Day", DT_STRING},
+ {E_CONTACT_CSV_MAILER, E_CONTACT_MAILER, "", DT_STRING},
+ {E_CONTACT_CSV_NAME_OR_ORG, E_CONTACT_NAME_OR_ORG, "", DT_STRING},
+ {E_CONTACT_CSV_CATEGORIES, E_CONTACT_CATEGORIES, "", DT_STRING},
+ {E_CONTACT_CSV_FAMILY_NAME, E_CONTACT_FAMILY_NAME, "", DT_STRING},
+ {E_CONTACT_CSV_GIVEN_NAME, E_CONTACT_GIVEN_NAME, "", DT_STRING},
+ {E_CONTACT_CSV_WANTS_HTML, E_CONTACT_WANTS_HTML, "", DT_BOOLEAN},
+ {E_CONTACT_CSV_IS_LIST, E_CONTACT_IS_LIST, "", DT_BOOLEAN},
+ {E_CONTACT_CSV_LAST, NOMAP, "", DT_STRING}
+
+};
+
+static GSList *pre_defined_fields;
+
+/*function prototypes*/
+gint e_contact_csv_get_contact_field (EContactFieldCSV csv_field);
+gchar *e_contact_csv_get_name (EContactFieldCSV csv_field);
+gchar *e_contact_csv_get (EContact * contact, EContactFieldCSV csv_field);
+gchar *e_contact_csv_get_header_line (GSList * csv_all_fields);
+gchar *e_contact_to_csv (EContact * contact, GSList * csv_all_fields);
+gchar *e_contact_get_csv (EContact * contact, GSList * csv_all_fields);
+gchar *delivery_address_get_sub_field (const EContactAddress * delivery_address, DeliveryAddressField sub_field);
+gchar *check_null_pointer (gchar * orig);
+gchar *escape_string (gchar * orig);
+gint output_n_cards_file (FILE * outputfile, GSList *contacts, gint size, gint begin_no, CARD_FORMAT format);
+void set_pre_defined_field (GSList ** pre_defined_fields);
+
+/* function declarations*/
+gint
+e_contact_csv_get_contact_field (EContactFieldCSV csv_field)
+{
+ return csv_field_data[csv_field].contact_field;
+}
+
+static EContactCSVDataType
+e_contact_csv_get_data_type (EContactFieldCSV csv_field)
+{
+ return csv_field_data[csv_field].data_type;
+}
+
+gchar *
+e_contact_csv_get_name (EContactFieldCSV csv_field)
+{
+ gint contact_field;
+ gchar *name;
+ gchar *quoted_name;
+
+ contact_field = e_contact_csv_get_contact_field (csv_field);
+
+ if (contact_field != NOMAP) {
+ name = g_strdup (e_contact_field_name (contact_field));
+ } else {
+ name = g_strdup (csv_field_data[csv_field].csv_name);
+ }
+ quoted_name = escape_string (name);
+ g_free (name);
+ return quoted_name;
+}
+
+gchar *
+e_contact_csv_get (EContact *contact,
+ EContactFieldCSV csv_field)
+{
+ gint contact_field;
+ gchar *field_value;
+ gchar *quoted_field_value;
+
+ EContactAddress *delivery_address = NULL;
+ EContactDate *date;
+
+ contact_field = e_contact_csv_get_contact_field (csv_field);
+
+ if (contact_field != NOMAP) {
+ field_value = e_contact_get (contact, contact_field);
+ if (e_contact_csv_get_data_type (csv_field) == DT_BOOLEAN) {
+ field_value = g_strdup ((GPOINTER_TO_INT (field_value)) ? "TRUE" : "FALSE");
+ }
+ } else {
+ switch (csv_field) {
+ case E_CONTACT_CSV_ADDRESS_HOME_STREET:
+ delivery_address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME);
+ field_value = delivery_address_get_sub_field (delivery_address, DELIVERY_ADDRESS_STREET);
+ break;
+ case E_CONTACT_CSV_ADDRESS_HOME_EXT:
+ delivery_address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME);
+ field_value = delivery_address_get_sub_field (delivery_address, DELIVERY_ADDRESS_EXT);
+ break;
+ case E_CONTACT_CSV_ADDRESS_HOME_CITY:
+ delivery_address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME);
+ field_value = delivery_address_get_sub_field (delivery_address, DELIVERY_ADDRESS_LOCALITY);
+ break;
+ case E_CONTACT_CSV_ADDRESS_HOME_REGION:
+ delivery_address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME);
+ field_value = delivery_address_get_sub_field (delivery_address, DELIVERY_ADDRESS_REGION);
+ break;
+ case E_CONTACT_CSV_ADDRESS_HOME_POSTCODE:
+ delivery_address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME);
+ field_value = delivery_address_get_sub_field (delivery_address, DELIVERY_ADDRESS_CODE);
+ break;
+ case E_CONTACT_CSV_ADDRESS_HOME_COUNTRY:
+ delivery_address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME);
+ field_value = delivery_address_get_sub_field (delivery_address, DELIVERY_ADDRESS_COUNTRY);
+ break;
+ case E_CONTACT_CSV_ADDRESS_BUSINESS_STREET:
+ delivery_address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK);
+ field_value = delivery_address_get_sub_field (delivery_address, DELIVERY_ADDRESS_STREET);
+ break;
+ case E_CONTACT_CSV_ADDRESS_BUSINESS_EXT:
+ delivery_address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK);
+ field_value = delivery_address_get_sub_field (delivery_address, DELIVERY_ADDRESS_EXT);
+ break;
+ case E_CONTACT_CSV_ADDRESS_BUSINESS_CITY:
+ delivery_address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK);
+ field_value = delivery_address_get_sub_field (delivery_address, DELIVERY_ADDRESS_LOCALITY);
+ break;
+ case E_CONTACT_CSV_ADDRESS_BUSINESS_REGION:
+ delivery_address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK);
+ field_value = delivery_address_get_sub_field (delivery_address, DELIVERY_ADDRESS_REGION);
+ break;
+ case E_CONTACT_CSV_ADDRESS_BUSINESS_POSTCODE:
+ delivery_address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK);
+ field_value = delivery_address_get_sub_field (delivery_address, DELIVERY_ADDRESS_CODE);
+ break;
+ case E_CONTACT_CSV_ADDRESS_BUSINESS_COUNTRY:
+ delivery_address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK);
+ field_value = delivery_address_get_sub_field (delivery_address, DELIVERY_ADDRESS_COUNTRY);
+ break;
+ case E_CONTACT_CSV_BIRTH_DATE_YEAR:
+ date = e_contact_get (contact, E_CONTACT_BIRTH_DATE);
+ if (date) {
+ field_value = g_strdup_printf ("%04d", date->year);
+ e_contact_date_free (date);
+ }
+ else {
+ field_value = g_strdup ("");
+ }
+ break;
+
+ case E_CONTACT_CSV_BIRTH_DATE_MONTH:
+ date = e_contact_get (contact, E_CONTACT_BIRTH_DATE);
+ if (date) {
+ field_value = g_strdup_printf ("%04d", date->month);
+ e_contact_date_free (date);
+ }
+ else {
+ field_value = g_strdup ("");
+ }
+ break;
+
+ case E_CONTACT_CSV_BIRTH_DATE_DAY:
+ date = e_contact_get (contact, E_CONTACT_BIRTH_DATE);
+ if (date) {
+ field_value = g_strdup_printf ("%04d", date->day);
+ e_contact_date_free (date);
+ }
+ else {
+ field_value = g_strdup ("");
+ }
+ break;
+
+ default:
+ field_value = g_strdup ("");
+ }
+ }
+
+ /*checking to avoid the NULL pointer */
+ if (field_value == NULL)
+ field_value = g_strdup ("");
+
+ quoted_field_value = escape_string (field_value);
+ g_free (field_value);
+
+ if (delivery_address)
+ e_contact_address_free (delivery_address);
+
+ return quoted_field_value;
+}
+
+gchar *
+e_contact_csv_get_header_line (GSList *csv_all_fields)
+{
+
+ guint field_number;
+ gint csv_field;
+ gchar **field_name_array;
+ gchar *header_line;
+
+ gint loop_counter;
+
+ field_number = g_slist_length (csv_all_fields);
+ field_name_array = g_new0 (gchar *, field_number + 1);
+
+ for (loop_counter = 0; loop_counter < field_number; loop_counter++) {
+ csv_field = GPOINTER_TO_INT (g_slist_nth_data (csv_all_fields, loop_counter));
+ *(field_name_array + loop_counter) = e_contact_csv_get_name (csv_field);
+ }
+
+ header_line = g_strjoinv (COMMA_SEPARATOR, field_name_array);
+
+ for (loop_counter = 0; loop_counter < field_number; loop_counter++) {
+ g_free (*(field_name_array + loop_counter));
+ }
+ g_free (field_name_array);
+
+ return header_line;
+
+}
+
+gchar *
+e_contact_to_csv (EContact *contact,
+ GSList *csv_all_fields)
+{
+ guint field_number;
+ gint csv_field;
+ gchar **field_value_array;
+ gchar *aline;
+
+ gint loop_counter;
+
+ field_number = g_slist_length (csv_all_fields);
+ field_value_array = g_new0 (gchar *, field_number + 1);
+
+ for (loop_counter = 0; loop_counter < field_number; loop_counter++) {
+ csv_field = GPOINTER_TO_INT (g_slist_nth_data (csv_all_fields, loop_counter));
+ *(field_value_array + loop_counter) = e_contact_csv_get (contact, csv_field);
+ }
+
+ aline = g_strjoinv (COMMA_SEPARATOR, field_value_array);
+
+ for (loop_counter = 0; loop_counter < field_number; loop_counter++) {
+ g_free (*(field_value_array + loop_counter));
+ }
+ g_free (field_value_array);
+
+ return aline;
+
+}
+
+gchar *
+e_contact_get_csv (EContact *contact,
+ GSList *csv_all_fields)
+{
+ gchar *aline;
+
+ aline = e_contact_to_csv (contact, csv_all_fields);
+ return aline;
+}
+
+gchar *
+check_null_pointer (gchar *orig)
+{
+ gchar *result;
+ if (orig == NULL)
+ result = g_strdup ("");
+ else
+ result = g_strdup (orig);
+ return result;
+}
+
+gchar *
+delivery_address_get_sub_field (const EContactAddress *address,
+ DeliveryAddressField sub_field)
+{
+ gchar *sub_field_value;
+ gchar *str_temp, *str_temp_a;
+ if (address != NULL) {
+ switch (sub_field) {
+ case DELIVERY_ADDRESS_STREET:
+ str_temp_a = check_null_pointer (address->po);
+ str_temp = check_null_pointer (address->street);
+ sub_field_value = g_strdup_printf ("%s %s", str_temp_a, str_temp);
+ g_free (str_temp);
+ g_free (str_temp_a);
+ break;
+ case DELIVERY_ADDRESS_EXT:
+ sub_field_value = check_null_pointer (address->ext);
+ break;
+ case DELIVERY_ADDRESS_LOCALITY:
+ sub_field_value = check_null_pointer (address->locality);
+ break;
+ case DELIVERY_ADDRESS_REGION:
+ sub_field_value = check_null_pointer (address->region);
+ break;
+ case DELIVERY_ADDRESS_CODE:
+ sub_field_value = check_null_pointer (address->code);
+ break;
+ case DELIVERY_ADDRESS_COUNTRY:
+ sub_field_value = check_null_pointer (address->country);
+ break;
+ default:
+ sub_field_value = g_strdup ("");
+ }
+ } else {
+ sub_field_value = g_strdup ("");
+ }
+ return sub_field_value;
+}
+
+gchar *
+escape_string (gchar *orig)
+{
+ const guchar *p;
+ gchar *dest;
+ gchar *q;
+
+ if (orig == NULL)
+ return g_strdup ("\"\"");
+
+ p = (guchar *) orig;
+ /* Each source byte needs maximally two destination chars (\n), and the extra 2 is for the leading and trailing '"' */
+ q = dest = g_malloc (strlen (orig) * 2 + 1 + 2);
+
+ *q++ = '\"';
+ while (*p)
+ {
+ switch (*p)
+ {
+ case '\n':
+ *q++ = '\\';
+ *q++ = 'n';
+ break;
+ case '\r':
+ *q++ = '\\';
+ *q++ = 'r';
+ break;
+ case '\\':
+ *q++ = '\\';
+ *q++ = '\\';
+ break;
+ case '"':
+ *q++ = '"';
+ *q++ = '"';
+ break;
+ default:
+ *q++ = *p;
+ }
+ p++;
+ }
+
+ *q++ = '\"';
+ *q = 0;
+
+ return dest;
+}
+
+gint
+output_n_cards_file (FILE *outputfile,
+ GSList *contacts,
+ gint size,
+ gint begin_no,
+ CARD_FORMAT format)
+{
+ gint i;
+ if (format == CARD_FORMAT_VCARD) {
+ for (i = begin_no; i < size + begin_no; i++) {
+ EContact *contact = g_slist_nth_data (contacts, i);
+ gchar *vcard = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
+ fprintf (outputfile, "%s\n", vcard);
+ g_free (vcard);
+ }
+ } else if (format == CARD_FORMAT_CSV) {
+ gchar *csv_fields_name;
+
+ if (!pre_defined_fields)
+ set_pre_defined_field (&pre_defined_fields);
+
+ csv_fields_name = e_contact_csv_get_header_line (pre_defined_fields);
+ fprintf (outputfile, "%s\n", csv_fields_name);
+ g_free (csv_fields_name);
+
+ for (i = begin_no; i < size + begin_no; i++) {
+ EContact *contact = g_slist_nth_data (contacts, i);
+ gchar *csv = e_contact_get_csv (contact, pre_defined_fields);
+ fprintf (outputfile, "%s\n", csv);
+ g_free (csv);
+ }
+ }
+
+ return SUCCESS;
+
+}
+
+static void
+action_list_cards (GSList *contacts,
+ ActionContext *p_actctx)
+{
+ FILE *outputfile;
+ long length;
+ CARD_FORMAT format;
+
+ length = g_slist_length (contacts);
+
+ if (length <= 0) {
+ g_warning ("Couldn't load addressbook correctly!!!! %s####", p_actctx->addressbook_source_uid ?
+ p_actctx->addressbook_source_uid : "NULL");
+ exit (-1);
+ }
+
+ if (p_actctx->output_file == NULL) {
+ outputfile = stdout;
+ } else {
+ /* fopen output file */
+ if (!(outputfile = g_fopen (p_actctx->output_file, "w"))) {
+ g_warning (_("Can not open file"));
+ exit (-1);
+ }
+ }
+
+ if (p_actctx->IsVCard == TRUE)
+ format = CARD_FORMAT_VCARD;
+ else
+ format = CARD_FORMAT_CSV;
+
+ output_n_cards_file (outputfile, contacts, length, 0, format);
+
+ if (p_actctx->output_file != NULL) {
+ fclose (outputfile);
+ }
+}
+
+void
+set_pre_defined_field (GSList **pre_defined_fields)
+{
+ *pre_defined_fields = NULL;
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_GIVEN_NAME));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_FAMILY_NAME));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_FULL_NAME));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_NICKNAME));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_EMAIL_1));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_EMAIL_2));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_EMAIL_3));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_EMAIL_4));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_WANTS_HTML));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_PHONE_BUSINESS));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_PHONE_HOME));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_PHONE_BUSINESS_FAX));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_PHONE_PAGER));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_PHONE_MOBILE));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_ADDRESS_HOME_STREET));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_ADDRESS_HOME_EXT));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_ADDRESS_HOME_CITY));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_ADDRESS_HOME_REGION));
+ *pre_defined_fields =
+ g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_ADDRESS_HOME_POSTCODE));
+ *pre_defined_fields =
+ g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_ADDRESS_HOME_COUNTRY));
+ *pre_defined_fields =
+ g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_ADDRESS_BUSINESS_STREET));
+ *pre_defined_fields =
+ g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_ADDRESS_BUSINESS_EXT));
+ *pre_defined_fields =
+ g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_ADDRESS_BUSINESS_CITY));
+ *pre_defined_fields =
+ g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_ADDRESS_BUSINESS_REGION));
+ *pre_defined_fields =
+ g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_ADDRESS_BUSINESS_POSTCODE));
+ *pre_defined_fields =
+ g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_ADDRESS_BUSINESS_COUNTRY));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_TITLE));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_OFFICE));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_ORG));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_HOMEPAGE_URL));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_CALENDAR_URI));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_BIRTH_DATE_YEAR));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_BIRTH_DATE_MONTH));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_BIRTH_DATE_DAY));
+ *pre_defined_fields = g_slist_append (*pre_defined_fields, GINT_TO_POINTER (E_CONTACT_CSV_NOTE));
+}
+
+void
+action_list_cards_init (ActionContext *p_actctx)
+{
+ ESourceRegistry *registry;
+ EClient *client;
+ EBookClient *book_client;
+ EBookQuery *query;
+ ESource *source;
+ GSList *contacts;
+ const gchar *uid;
+ gchar *query_str;
+ GError *error = NULL;
+
+ registry = p_actctx->registry;
+ uid = p_actctx->addressbook_source_uid;
+
+ if (uid != NULL)
+ source = e_source_registry_ref_source (registry, uid);
+ else
+ source = e_source_registry_ref_default_address_book (registry);
+
+ client = e_book_client_connect_sync (source, NULL, &error);
+
+ g_object_unref (source);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ if (error != NULL) {
+ g_warning (
+ "Couldn't load addressbook %s: %s",
+ p_actctx->addressbook_source_uid ?
+ p_actctx->addressbook_source_uid :
+ "'default'", error->message);
+ g_error_free (error);
+ exit (-1);
+ }
+
+ book_client = E_BOOK_CLIENT (client);
+
+ query = e_book_query_any_field_contains ("");
+ query_str = e_book_query_to_string (query);
+ e_book_query_unref (query);
+
+ if (!e_book_client_get_contacts_sync (book_client, query_str, &contacts, NULL, &error))
+ contacts = NULL;
+
+ action_list_cards (contacts, p_actctx);
+
+ g_slist_foreach (contacts, (GFunc) g_object_unref, NULL);
+ g_slist_free (contacts);
+ g_object_unref (book_client);
+
+ if (error) {
+ g_warning ("Failed to get contacts: %s", error->message);
+ g_error_free (error);
+ }
+}
diff --git a/addressbook/tools/evolution-addressbook-export-list-folders.c b/addressbook/tools/evolution-addressbook-export-list-folders.c
new file mode 100644
index 0000000000..2ff9d790a4
--- /dev/null
+++ b/addressbook/tools/evolution-addressbook-export-list-folders.c
@@ -0,0 +1,114 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Gilbert Fang <gilbert.fang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+#include <stdlib.h>
+
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+
+#include <libebook/libebook.h>
+
+#include "evolution-addressbook-export.h"
+
+void
+action_list_folders_init (ActionContext *p_actctx)
+{
+ ESourceRegistry *registry;
+ GList *list, *iter;
+ FILE *outputfile = NULL;
+ const gchar *extension_name;
+
+ registry = p_actctx->registry;
+
+ if (p_actctx->output_file != NULL) {
+ if (!(outputfile = g_fopen (p_actctx->output_file, "w"))) {
+ g_warning (_("Can not open file"));
+ exit (-1);
+ }
+ }
+
+ extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+ list = e_source_registry_list_sources (registry, extension_name);
+
+ for (iter = list; iter != NULL; iter = g_list_next (iter)) {
+ EClient *client;
+ EBookClient *book_client;
+ EBookQuery *query;
+ ESource *source;
+ GSList *contacts;
+ const gchar *display_name;
+ const gchar *uid;
+ gchar *query_str;
+ GError *error = NULL;
+
+ source = E_SOURCE (iter->data);
+
+ client = e_book_client_connect_sync (source, NULL, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ if (error != NULL) {
+ g_warning (
+ _("Failed to open client '%s': %s"),
+ e_source_get_display_name (source),
+ error->message);
+ g_error_free (error);
+ continue;
+ }
+
+ book_client = E_BOOK_CLIENT (client);
+
+ query = e_book_query_any_field_contains ("");
+ query_str = e_book_query_to_string (query);
+ e_book_query_unref (query);
+
+ e_book_client_get_contacts_sync (
+ book_client, query_str, &contacts, NULL, NULL);
+
+ display_name = e_source_get_display_name (source);
+ uid = e_source_get_uid (source);
+
+ if (outputfile)
+ fprintf (
+ outputfile, "\"%s\",\"%s\",%d\n",
+ uid, display_name, g_slist_length (contacts));
+ else
+ printf (
+ "\"%s\",\"%s\",%d\n",
+ uid, display_name, g_slist_length (contacts));
+
+ g_slist_foreach (contacts, (GFunc) g_object_unref, NULL);
+ g_slist_free (contacts);
+
+ g_object_unref (book_client);
+ }
+
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
+ if (outputfile)
+ fclose (outputfile);
+}
diff --git a/addressbook/tools/evolution-addressbook-export.c b/addressbook/tools/evolution-addressbook-export.c
new file mode 100644
index 0000000000..685fab27f7
--- /dev/null
+++ b/addressbook/tools/evolution-addressbook-export.c
@@ -0,0 +1,190 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Gilbert Fang <gilbert.fang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include <libebook/libebook.h>
+
+#include "evolution-addressbook-export.h"
+
+#ifdef G_OS_WIN32
+#ifdef DATADIR
+#undef DATADIR
+#endif
+#include <windows.h>
+#include <conio.h>
+#ifndef PROCESS_DEP_ENABLE
+#define PROCESS_DEP_ENABLE 0x00000001
+#endif
+#ifndef PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION
+#define PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION 0x00000002
+#endif
+#endif
+
+/* Command-Line Options */
+static gchar *opt_output_file = NULL;
+static gboolean opt_list_folders_mode = FALSE;
+static gchar *opt_output_format = NULL;
+static gchar *opt_addressbook_source_uid = NULL;
+static gchar **opt_remaining = NULL;
+
+static GOptionEntry entries[] = {
+ { "output", '\0', 0,
+ G_OPTION_ARG_STRING, &opt_output_file,
+ N_("Specify the output file instead of standard output"),
+ N_("OUTPUTFILE") },
+ { "list-addressbook-folders", 'l', 0,
+ G_OPTION_ARG_NONE, &opt_list_folders_mode,
+ N_("List local address book folders") },
+ { "format", '\0', 0,
+ G_OPTION_ARG_STRING, &opt_output_format,
+ N_("Show cards as vcard or csv file"),
+ N_("[vcard|csv]") },
+ { G_OPTION_REMAINING, '\0', 0,
+ G_OPTION_ARG_STRING_ARRAY, &opt_remaining },
+ { NULL }
+};
+
+gint
+main (gint argc,
+ gchar **argv)
+{
+ ActionContext actctx;
+ GOptionContext *context;
+ GError *error = NULL;
+
+ gint current_action = ACTION_NOTHING;
+ gint IsCSV = FALSE;
+ gint IsVCard = FALSE;
+
+#ifdef G_OS_WIN32
+ /* Reduce risks */
+ {
+ typedef BOOL (WINAPI *t_SetDllDirectoryA) (LPCSTR lpPathName);
+ t_SetDllDirectoryA p_SetDllDirectoryA;
+
+ p_SetDllDirectoryA = GetProcAddress (GetModuleHandle ("kernel32.dll"), "SetDllDirectoryA");
+ if (p_SetDllDirectoryA)
+ (*p_SetDllDirectoryA) ("");
+ }
+#ifndef _WIN64
+ {
+ typedef BOOL (WINAPI *t_SetProcessDEPPolicy) (DWORD dwFlags);
+ t_SetProcessDEPPolicy p_SetProcessDEPPolicy;
+
+ p_SetProcessDEPPolicy = GetProcAddress (GetModuleHandle ("kernel32.dll"), "SetProcessDEPPolicy");
+ if (p_SetProcessDEPPolicy)
+ (*p_SetProcessDEPPolicy) (PROCESS_DEP_ENABLE | PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION);
+ }
+#endif
+#endif
+
+ g_type_init ();
+
+ /*i18n-lize */
+ bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ context = g_option_context_new (NULL);
+ g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ g_printerr ("%s\n", error->message);
+ g_error_free (error);
+ exit (-1);
+ }
+
+ actctx.registry = e_source_registry_new_sync (NULL, &error);
+ if (error != NULL) {
+ g_printerr ("%s\n", error->message);
+ g_error_free (error);
+ exit (-1);
+ }
+
+ /* Parsing Parameter */
+ if (opt_remaining && g_strv_length (opt_remaining) > 0)
+ opt_addressbook_source_uid = g_strdup (opt_remaining[0]);
+
+ if (opt_list_folders_mode != FALSE) {
+ current_action = ACTION_LIST_FOLDERS;
+ if (opt_addressbook_source_uid != NULL || opt_output_format != NULL) {
+ g_warning (_("Command line arguments error, please use --help option to see the usage."));
+ exit (-1);
+ }
+ } else {
+
+ current_action = ACTION_LIST_CARDS;
+
+ /* check the output format */
+ if (opt_output_format == NULL) {
+ IsVCard = TRUE;
+ } else {
+ IsCSV = !strcmp (opt_output_format, "csv");
+ IsVCard = !strcmp (opt_output_format, "vcard");
+ if (IsCSV == FALSE && IsVCard == FALSE) {
+ g_warning (_("Only support csv or vcard format."));
+ exit (-1);
+ }
+ }
+ }
+
+ /* do actions */
+ if (current_action == ACTION_LIST_FOLDERS) {
+ actctx.action_type = current_action;
+ if (opt_output_file == NULL) {
+ actctx.output_file = NULL;
+ } else {
+ actctx.output_file = g_strdup (opt_output_file);
+ }
+ action_list_folders_init (&actctx);
+
+ } else if (current_action == ACTION_LIST_CARDS) {
+ actctx.action_type = current_action;
+ if (opt_output_file == NULL) {
+ actctx.output_file = NULL;
+ } else {
+ actctx.output_file = g_strdup (opt_output_file);
+ }
+ actctx.IsCSV = IsCSV;
+ actctx.IsVCard = IsVCard;
+ actctx.addressbook_source_uid =
+ g_strdup (opt_addressbook_source_uid);
+
+ action_list_cards_init (&actctx);
+
+ } else {
+ g_warning (_("Unhandled error"));
+ exit (-1);
+ }
+
+ g_object_unref (actctx.registry);
+
+ /*FIXME:should free actctx's some gchar * field, such as output_file! but since the program will end, so that will not cause mem leak. */
+
+ return 0;
+}
diff --git a/addressbook/tools/evolution-addressbook-export.h b/addressbook/tools/evolution-addressbook-export.h
new file mode 100644
index 0000000000..158066fe25
--- /dev/null
+++ b/addressbook/tools/evolution-addressbook-export.h
@@ -0,0 +1,63 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Gilbert Fang <gilbert.fang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef _EVOLUTION_ADDRESSBOOK_EXPORT_H_
+#define _EVOLUTION_ADDRESSBOOK_EXPORT_H__
+
+#include <libedataserver/libedataserver.h>
+
+G_BEGIN_DECLS
+
+#define SUCCESS 0
+#define FAILED -1
+
+#define ACTION_NOTHING 0
+#define ACTION_LIST_FOLDERS 1
+#define ACTION_LIST_CARDS 2
+
+#define DEFAULT_SIZE_NUMBER 100
+
+struct _ActionContext {
+
+ guint action_type;
+
+ ESourceRegistry *registry;
+ gchar *output_file;
+
+ /* for cards only */
+ gint IsCSV;
+ gint IsVCard;
+ gchar *addressbook_source_uid;
+};
+
+typedef struct _ActionContext ActionContext;
+
+/* action_list_folders */
+void action_list_folders_init (ActionContext *p_actctx);
+
+/*action list cards*/
+void action_list_cards_init (ActionContext *p_actctx);
+
+G_END_DECLS
+
+#endif /* _EVOLUTION_ADDRESSBOOK_EXPORT_H_ */
diff --git a/addressbook/util/Makefile.am b/addressbook/util/Makefile.am
new file mode 100644
index 0000000000..f11c618da6
--- /dev/null
+++ b/addressbook/util/Makefile.am
@@ -0,0 +1,35 @@
+privsolib_LTLIBRARIES = libeabutil.la
+
+libeabutil_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DPREFIX=\"$(prefix)\" \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DLIBDIR=\"$(libdir)\" \
+ -DG_LOG_DOMAIN=\"EBook\" \
+ -I$(top_srcdir) \
+ -I$(top_builddir)/shell \
+ -I$(top_srcdir)/shell \
+ $(CAMEL_CFLAGS) \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GTKHTML_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS)
+
+libeabutil_la_SOURCES = \
+ eab-book-util.c \
+ eab-book-util.h
+
+libeabutil_la_LDFLAGS = -avoid-version $(NO_UNDEFINED)
+
+libeabutil_la_LIBADD = \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(top_builddir)/shell/libevolution-shell.la \
+ $(CAMEL_LIBS) \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GTKHTML_LIBS) \
+ $(GNOME_PLATFORM_LIBS)
+
+dist-hook:
+ cd $(distdir); rm -f $(BUILT_SOURCES)
+
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/util/eab-book-util.c b/addressbook/util/eab-book-util.c
new file mode 100644
index 0000000000..d7c0941c69
--- /dev/null
+++ b/addressbook/util/eab-book-util.c
@@ -0,0 +1,306 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Jon Trowbridge <trow@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "e-util/e-util.h"
+#include "eab-book-util.h"
+
+/* Copied from camel_strstrcase */
+static gchar *
+eab_strstrcase (const gchar *haystack,
+ const gchar *needle)
+{
+ /* find the needle in the haystack neglecting case */
+ const gchar *ptr;
+ guint len;
+
+ g_return_val_if_fail (haystack != NULL, NULL);
+ g_return_val_if_fail (needle != NULL, NULL);
+
+ len = strlen (needle);
+ if (len > strlen (haystack))
+ return NULL;
+
+ if (len == 0)
+ return (gchar *) haystack;
+
+ for (ptr = haystack; *(ptr + len - 1) != '\0'; ptr++)
+ if (!g_ascii_strncasecmp (ptr, needle, len))
+ return (gchar *) ptr;
+
+ return NULL;
+}
+
+GSList *
+eab_contact_list_from_string (const gchar *str)
+{
+ GSList *contacts = NULL;
+ GString *gstr = g_string_new (NULL);
+ gchar *str_stripped;
+ gchar *p = (gchar *) str;
+ gchar *q;
+
+ if (!p)
+ return NULL;
+
+ if (!strncmp (p, "Book: ", 6)) {
+ p = strchr (p, '\n');
+ if (!p) {
+ g_warning (G_STRLOC ": Got book but no newline!");
+ return NULL;
+ }
+ p++;
+ }
+
+ while (*p) {
+ if (*p != '\r') g_string_append_c (gstr, *p);
+
+ p++;
+ }
+
+ p = str_stripped = g_string_free (gstr, FALSE);
+
+ /* Note: The vCard standard says
+ *
+ * vcard = "BEGIN" [ws] ":" [ws] "VCARD" [ws] 1*CRLF
+ * items *CRLF "END" [ws] ":" [ws] "VCARD"
+ *
+ * which means we can have whitespace (e.g. "BEGIN : VCARD"). So we're not being
+ * fully compliant here, although I'm not sure it matters. The ideal solution
+ * would be to have a vcard parsing function that returned the end of the vcard
+ * parsed. Arguably, contact list parsing should all be in libebook's e-vcard.c,
+ * where we can do proper parsing and validation without code duplication. */
+
+ for (p = eab_strstrcase (p, "BEGIN:VCARD"); p; p = eab_strstrcase (q, "\nBEGIN:VCARD")) {
+ gchar *card_str;
+
+ if (*p == '\n')
+ p++;
+
+ for (q = eab_strstrcase (p, "END:VCARD"); q; q = eab_strstrcase (q, "END:VCARD")) {
+ gchar *temp;
+
+ q += 9;
+ temp = q;
+ if (*temp)
+ temp += strspn (temp, "\r\n\t ");
+
+ if (*temp == '\0' || !g_ascii_strncasecmp (temp, "BEGIN:VCARD", 11))
+ break; /* Found the outer END:VCARD */
+ }
+
+ if (!q)
+ break;
+
+ card_str = g_strndup (p, q - p);
+ contacts = g_slist_prepend (contacts, e_contact_new_from_vcard (card_str));
+ g_free (card_str);
+ }
+
+ g_free (str_stripped);
+
+ return g_slist_reverse (contacts);
+}
+
+gchar *
+eab_contact_list_to_string (const GSList *contacts)
+{
+ GString *str = g_string_new ("");
+ const GSList *l;
+
+ for (l = contacts; l; l = l->next) {
+ EContact *contact = l->data;
+ gchar *vcard_str;
+
+ e_contact_inline_local_photos (contact, NULL);
+ 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\r\n");
+ }
+
+ return g_string_free (str, FALSE);
+}
+
+gboolean
+eab_source_and_contact_list_from_string (ESourceRegistry *registry,
+ const gchar *str,
+ ESource **out_source,
+ GSList **out_contacts)
+{
+ ESource *source;
+ const gchar *s0, *s1;
+ gchar *uid;
+ gboolean success = FALSE;
+
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
+ g_return_val_if_fail (str != NULL, FALSE);
+
+ if (out_source != NULL)
+ *out_source = NULL; /* in case we fail */
+
+ if (out_contacts != NULL)
+ *out_contacts = NULL; /* in case we fail */
+
+ if (!strncmp (str, "Book: ", 6)) {
+ s0 = str + 6;
+ s1 = strchr (str, '\r');
+
+ if (!s1)
+ s1 = strchr (str, '\n');
+ } else {
+ s0 = NULL;
+ s1 = NULL;
+ }
+
+ if (!s0 || !s1)
+ return FALSE;
+
+ uid = g_strndup (s0, s1 - s0);
+ source = e_source_registry_ref_source (registry, uid);
+ if (source != NULL) {
+ if (out_source != NULL)
+ *out_source = g_object_ref (source);
+ g_object_unref (source);
+ success = TRUE;
+ }
+ g_free (uid);
+
+ if (success && out_contacts != NULL)
+ *out_contacts = eab_contact_list_from_string (str);
+
+ return success;
+}
+
+gchar *
+eab_book_and_contact_list_to_string (EBookClient *book_client,
+ const GSList *contacts)
+{
+ gchar *s0, *s1;
+
+ s0 = eab_contact_list_to_string (contacts);
+ if (!s0)
+ s0 = g_strdup ("");
+
+ if (book_client != NULL) {
+ EClient *client;
+ ESource *source;
+ const gchar *uid;
+
+ client = E_CLIENT (book_client);
+ source = e_client_get_source (client);
+ uid = e_source_get_uid (source);
+ s1 = g_strconcat ("Book: ", uid, "\r\n", s0, NULL);
+ } else
+ s1 = g_strdup (s0);
+
+ g_free (s0);
+ return s1;
+}
+
+/* bad place for this i know. */
+gint
+e_utf8_casefold_collate_len (const gchar *str1,
+ const gchar *str2,
+ gint len)
+{
+ gchar *s1 = g_utf8_casefold (str1, len);
+ gchar *s2 = g_utf8_casefold (str2, len);
+ gint rv;
+
+ rv = g_utf8_collate (s1, s2);
+
+ g_free (s1);
+ g_free (s2);
+
+ return rv;
+}
+
+gint
+e_utf8_casefold_collate (const gchar *str1,
+ const gchar *str2)
+{
+ return e_utf8_casefold_collate_len (str1, str2, -1);
+}
+
+/* To parse something like...
+ * =?UTF-8?Q?=E0=A4=95=E0=A4=95=E0=A4=AC=E0=A5=82=E0=A5=8B=E0=A5=87?=\t\n=?UTF-8?Q?=E0=A4=B0?=\t\n<aa@aa.ccom>
+ * and return the decoded representation of name & email parts. */
+gboolean
+eab_parse_qp_email (const gchar *string,
+ gchar **name,
+ gchar **email)
+{
+ struct _camel_header_address *address;
+ gboolean res = FALSE;
+
+ address = camel_header_address_decode (string, "UTF-8");
+
+ if (!address)
+ return FALSE;
+
+ /* report success only when we have filled both name and email address */
+ if (address->type == CAMEL_HEADER_ADDRESS_NAME && address->name && *address->name && address->v.addr && *address->v.addr) {
+ *name = g_strdup (address->name);
+ *email = g_strdup (address->v.addr);
+ res = TRUE;
+ }
+
+ camel_header_address_unref (address);
+
+ return res;
+}
+
+/* This is only wrapper to parse_qp_mail, it decodes string and if returned TRUE,
+ * then makes one string and returns it, otherwise returns NULL.
+ * Returned string is usable to place directly into GtkHtml stream.
+ * Returned value should be freed with g_free. */
+gchar *
+eab_parse_qp_email_to_html (const gchar *string)
+{
+ gchar *name = NULL, *mail = NULL;
+ gchar *html_name, *html_mail;
+ gchar *value;
+
+ if (!eab_parse_qp_email (string, &name, &mail))
+ return NULL;
+
+ html_name = e_text_to_html (name, 0);
+ html_mail = e_text_to_html (mail, E_TEXT_TO_HTML_CONVERT_ADDRESSES);
+
+ value = g_strdup_printf ("%s &lt;%s&gt;", html_name, html_mail);
+
+ g_free (html_name);
+ g_free (html_mail);
+ g_free (name);
+ g_free (mail);
+
+ return value;
+}
diff --git a/addressbook/util/eab-book-util.h b/addressbook/util/eab-book-util.h
new file mode 100644
index 0000000000..559aa79714
--- /dev/null
+++ b/addressbook/util/eab-book-util.h
@@ -0,0 +1,56 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Jon Trowbridge <trow@ximian.com>
+ * Chris Toshok <toshok@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef EAB_BOOK_UTIL_H
+#define EAB_BOOK_UTIL_H
+
+#include <libebook/libebook.h>
+
+G_BEGIN_DECLS
+
+GSList * eab_contact_list_from_string (const gchar *str);
+gchar * eab_contact_list_to_string (const GSList *contacts);
+
+gboolean eab_source_and_contact_list_from_string
+ (ESourceRegistry *registry,
+ const gchar *str,
+ ESource **out_source,
+ GSList **out_contacts);
+gchar * eab_book_and_contact_list_to_string
+ (EBookClient *book_client,
+ const GSList *contacts);
+gint e_utf8_casefold_collate_len (const gchar *str1,
+ const gchar *str2,
+ gint len);
+gint e_utf8_casefold_collate (const gchar *str1,
+ const gchar *str2);
+
+/* To parse quoted printable address & return email & name fields */
+gboolean eab_parse_qp_email (const gchar *string,
+ gchar **name,
+ gchar **email);
+gchar * eab_parse_qp_email_to_html (const gchar *string);
+
+G_END_DECLS
+
+#endif /* EAB_BOOK_UTIL_H */
diff --git a/art/.cvsignore b/art/.cvsignore
deleted file mode 100644
index c038ed7864..0000000000
--- a/art/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Makefile
-Makefile.in \ No newline at end of file
diff --git a/art/16_copy.png b/art/16_copy.png
deleted file mode 100644
index 31ede839ea..0000000000
--- a/art/16_copy.png
+++ /dev/null
Binary files differ
diff --git a/art/16_customize.png b/art/16_customize.png
deleted file mode 100644
index 1a0e15ad4e..0000000000
--- a/art/16_customize.png
+++ /dev/null
Binary files differ
diff --git a/art/16_cut.png b/art/16_cut.png
deleted file mode 100644
index 5860a9c56f..0000000000
--- a/art/16_cut.png
+++ /dev/null
Binary files differ
diff --git a/art/16_paste.png b/art/16_paste.png
deleted file mode 100644
index 56f15c5cc3..0000000000
--- a/art/16_paste.png
+++ /dev/null
Binary files differ
diff --git a/art/ChangeLog b/art/ChangeLog
deleted file mode 100644
index 811bad7072..0000000000
--- a/art/ChangeLog
+++ /dev/null
@@ -1,636 +0,0 @@
-2002-10-07 Ettore Perazzoli <ettore@ximian.com>
-
- * splash.png: New artwork from Jakub.
-
-2002-09-27 Dan Winship <danw@ximian.com>
-
- * post-reply-24.png: New icon for "Post a Reply" from Jakub.
-
-2002-02-29 Ettore Perazzoli <ettore@ximian.com>
-
- * about-box.png, splash.png: New artwork from Jakub.
-
-2002-09-03 Ettore Perazzoli <ettore@ximian.com>
-
- * folder-settings.png: New icon from Jakub.
-
-2002-09-03 Jakub Steiner <jimmac@ximian.com>
-
- * ldap-settings.png: use a more gnomeish version
-
-2002-08-01 Ettore Perazzoli <ettore@ximian.com>
-
- * contact-list-16.png: New artwork from Jakub.
- * post-message-16.png: Likewise.
- * meeting-request-16.png: Likewise.
-
- * meeting.xpm: Removed.
-
-2002-07-26 Ettore Perazzoli <ettore@ximian.com>
-
- * mail.png: New icon for mail (gnome-textfile.png from GNOME 2, by
- Tuomas' suggestion).
-
-2002-07-23 Jakub Steiner <jimmac@ximian.com>
-
- * inbox.png,outbox.png: fix the arrows
- * font.png: the former one was vector style - from gorilla
-
-2002-07-22 <jpr@ximian.com>
-
- * Makefile.am: add new image
-
-2002-07-16 Ettore Perazzoli <ettore@ximian.com>
-
- * inbox.png, outbox.png: Added final large versions of the Inbox
- and Outbox icons.
-
-2002-07-09 Dan Winship <danw@ximian.com>
-
- * Makefile.am (images_DATA): add folder.png, folder-mini.png,
- public-folder.png, and public-folder-mini.png
-
- * folder-mini.png: Renamed from local-16.png
-
- * folder.png, public-folder.png, public-folder-mini.png: New, from
- Jakub.
-
-2002-07-09 Ettore Perazzoli <ettore@ximian.com>
-
- * Makefile.am (images_DATA): inbox-mini.png instead of
- inbox-16.png, outbox-mini.png instead of outbox-16.png. Also add
- inbox.png and outbox.png.
- (inbox.png): New.
- (outbox.png): New.
-
-2002-05-20 Ettore Perazzoli <ettore@ximian.com>
-
- * schedule-meeting-24.png: New.
-
-2002-04-25 Larry Ewing <lewing@ximian.com>
-
- * Makefile.am (images_DATA): font.png: Add for the font config
- prefs.
-
-2002-04-17 Dan Winship <danw@ximian.com>
-
- * monkey-16.png: Replace with an antialiased version
-
-2002-04-10 Dan Winship <danw@ximian.com>
-
- * Makefile.am (images_DATA), folder-settings.png: Add. (Copied
- from Unscalable Gorilla because it was handy. Will probably get
- changed to something else...)
-
-2002-03-28 Ettore Perazzoli <ettore@ximian.com>
-
- * calendar-and-tasks-settings.png: New.
- * composer-settings.png: New.
- * ldap-settings.png: New.
- * mail-accounts-settings.png: New.
- * summary-settings.png: New.
-
-2002-03-25 Dan Winship <danw@ximian.com>
-
- * Makefile.am (images_DATA): Add working-16.png (the GNOME2 stock
- "wait" icon, from Jakub)
-
-2002-03-04 Jeffrey Stedfast <fejj@ximian.com>
-
- * forward.xpm, reply.xpm, reply_to_all.xpm: Rename the internal
- structure to coincide with the filenames.
-
-2002-02-29 Ettore Perazzoli <ettore@ximian.com>
-
- * about-box.png, splash.png: New cool artwork from Jakub.
-
-2002-02-22 Jeffrey Stedfast <fejj@ximian.com>
-
- * Makefile.am: Remove meeting_widget.png from the build since it
- doesn't seem to be in cvs?
-
-2002-02-20 Jakub Steiner <jimmac@ximian.com>
-
- * summary_preferences-16.png: menu icon for summary preferences
- * Makefile.am: added the icon
-
-2002-02-13 Jeffrey Stedfast <fejj@ximian.com>
-
- * flag-for-followup.xpm:
- * flag-for-followup-16.png:
- * flag-for-followup-48.png: New icons.
-
- * Makefile.am: Added the new icons...
-
-2002-02-12 Jeffrey Stedfast <fejj@ximian.com>
-
- * Makefile.am: Install mail-new.xpm, mail-read.xpm and
- priority-high.xpm in the same place as other bonobo-ui menu
- pixmaps so we can use these in menus too.
-
-2002-02-08 JP Rosevear <jpr@ximian.com>
-
- * connect_to_url-16.xpm: new icon
-
- * new_all_day_event.png: ditto
-
- * Makefile.am: install and dist new images
-
-2001-12-11 Jon Trowbridge <trow@ximian.com>
-
- * mail-need-reply.xpm: A new icon that sucks less. We still need
- some Tuomas-love.
-
-2001-12-09 Jon Trowbridge <trow@ximian.com>
-
- * mail-need-reply.xpm: Added a really, really ugly and
- awful icon to symbolize "message needs a reply".
-
- * Makefile.am (EXTRA_DIST): Added mail-need-reply.xpm.
-
-2001-11-06 Ettore Perazzoli <ettore@ximian.com>
-
- * evolution.png: New, updated icon from Tuomas.
-
-2001-11-05 JP Rosevear <jpr@ximian.com>
-
- * Makefile.am (EXTRA_DIST): dist the glade data
-
-2001-11-01 Ettore Perazzoli <ettore@ximian.com>
-
- * Makefile.am (gladedir): New.
- (glade_DATA): Pixmap files required to be installed by the glade
- files.
-
-2001-10-31 Ettore Perazzoli <ettore@ximian.com>
-
- * Makefile.am: Install `evolution.png', not `evolution-icon.png'.
-
- * evolution.png: Renamed from `evolution-icon.png', removing the
- old, now unused `evolution.png'.
-
-2001-10-30 Jakub Steiner <jimmac@ximian.com>
-
- * splash-1-0.png: new style splash
-
-2001-10-23 Tuomas Kuosmanen <tigert@ximian.com>
-
- * splash.png: Remove the "1" from "1.0 Release Candidate 1" so it
- looks better.
-
-2001-10-23 Tuomas Kuosmanen <tigert@ximian.com>
-
- * Makefile.am (appicon_DATA): Changed the filename here too
- so the icon gets installed.
-
- * evolution-icon.png: New icon that scales better.
-
-2001-10-22 Jakub Steiner <jimmac@ximian.com>
-
- * about-box.png: update the layout a bit
- * splash.png: update to 0.17
-
-2001-10-16 Ettore Perazzoli <ettore@ximian.com>
-
- * Makefile.am (images_DATA): Add `about-box.png'.
-
- * about-box.png: New image for the about box from Jakub.
-
-2001-10-18 Larry Ewing <lewing@ximian.com>
-
- * Makefile.am (images_DATA): add alarm.png for the new alarm
- notification code.
-
-2001-10-04 Chris Toshok <toshok@ximian.com>
-
- * Makefile.am (images_DATA): change ldap-16.png to ldap-mini.png,
- and add ldap.png.
-
-2001-10-04 Jakub Steiner <jimmac@ximian.com>
-
- * splash.png: bump to 0.16
- * ldap.png: 48x48 version for shortcut bar
-
-2001-09-25 Iain Holmes <iain@ximian.com>
-
- * add task.png
-
-2001-09-21 Iain Holmes <iain@ximian.com>
-
- * remove timezone.png...dunno where it came from.
-
-2001-09-21 Iain Holmes <iain@ximian.com>
-
- * install timezone-16.xpm
-
-2001-09-21 Jakub Steiner <jimmac@ximian.com>
-
- * splash.png: beta4
-
-2001-09-08 Jakub Steiner <jimmac@ximian.com>
-
- * pgp-signature-*: for the pgp signature checking
- * Makefile.am (images_DATA): add the icon files
-
-2001-09-06 Chris Toshok <toshok@ximian.com>
-
- * Makefile.am (images_DATA): add ldap-16.png.
-
-2001-09-05 Jakub Steiner <jimmac@ximian.com>
-
- * meeting-request.png: for the inline .ics stuff
- * Makefile.am (images_DATA): add the icon file
-
-2001-09-04 Jakub Steiner <jimmac@ximian.com>
-
- * timezone-48.png: for the timezone configuration step in the
- first-time-druid
- * Makefile.am (images_DATA): add the icon file
-
-2001-08-20 JP Rosevear <jpr@ximian.com>
-
- * Makefile.am: install new file
-
- * talking-heads.png: new graphic for meeting requests
-
-2001-08-20 Damon Chaplin <damon@ximian.com>
-
- * Makefile.am (images_DATA): added goto-16.png & new_task-16.png.
- (buttons_DATA): added save-24.png.
-
-2001-08-20 Damon Chaplin <damon@ximian.com>
-
- * Makefile.am (buttons_DATA): added cut.png, copy.png & paste.png,
- so we can use them for the tasks toolbar.
-
-2001-08-18 Damon Chaplin <damon@ximian.com>
-
- * Makefile.am (images_DATA): added 16_copy.png, 16_customize.png,
- 16_cut.png & 16_paste.png.
- (buttons_DATA): added new_task.png, which I made from scaling up the
- smaller task.xpm icon.
-
-2001-08-18 Ettore Perazzoli <ettore@ximian.com>
-
- * Makefile.am (buttons_DATA): Added `delete-message.png'.
-
-2001-08-17 Damon Chaplin <damon@ximian.com>
-
- * Makefile.am (images_DATA): moved task.xpm here, so it gets installed,
- so we can use it for the menus. Note that we don't have an icon to
- use in the toolbar for a new task, and we need one. Jakub?
-
-2001-08-17 Jeffrey Stedfast <fejj@ximian.com>
-
- * wax-seal.png: Added.
-
- * wax-seal-broken.png: Added.
-
-2001-08-17 Jakub Steiner <jimmac@ximian.com>
-
- * splash.png: marketing spoils the fun. boring splash again.
-
-2001-08-17 Jakub Steiner <jimmac@ximian.com>
-
- * splash.png: Ruperzilla splash
-
- * splash-1-0.png: 1.0 candidate
-
-2001-08-16 Jakub Steiner <jimmac@ximian.com>
-
- * {next,previous}-message.png: use new document template. maybe
- still a bit dark.
-
-2001-08-15 Jakub Steiner <jimmac@ximian.com>
-
- * add-attachment.png: get rid of the yellow
-
- * compose-message.png: the old one seemed too dark to me. This one
- shares the same document base as the new stuff.
-
-2001-08-15 Jakub Steiner <jimmac@ximian.com>
-
- * all_contacts.xpm, new_contact.xpm: Nat wanted something bigger
- that would match the new button style. The filename of
- all_contacts.xpm is crap, maybe you guys can fix it to be
- "new_list.xpm" or something. Didn't want to break things.
-
-2001-08-15 Jakub Steiner <jimmac@ximian.com>
-
- * save-16.png, save-as-16.png: fix bottom. Tuomas didn't like too
- much detail.
-
-2001-08-15 Tuomas Kuosmanen <tigert@ximian.com>
-
- * goto-24.png: Icon for "Goto date.." -button. Someone could add
- this into the code?
-
-2001-08-14 Tuomas Kuosmanen <tigert@ximian.com>
-
- * arrow-[left,right]-24.png: new arrow icons for calendar
- toolbar..
-
-2001-08-14 Jakub Steiner <jimmac@ximian.com>
-
- * evolution-today-mini.png: new summary tree view icon.
-
-2001-08-10 Rodrigo Moya <rodrigo@ximian.com>
-
- * 16_category_*: removed these files, which are now in gal
-
-2001-08-09 Tuomas Kuosmanen <tigert@ximian.com>
-
- * send-receive.xpm: Updated this to have the yellow/green arrows
- so it matches the style of other icons. Noticed that tasklist
- scales 16x16 icons larger, so they generally look Bad(tm). (fixes
- #6475)
-
-2001-08-07 Damon Chaplin <damon@ximian.com>
-
- * timezone-16.xpm: copied from the international category icon.
- It would be better to have 2 different icons for these, but I had
- to get rid of that square timezone icon!
-
-2001-08-07 Jakub Steiner <jimmac@ximian.com>
-
- * evolution-trash-mini.png: scaled down Tuomas' trash icon.
- tweaked a bit. looks a lot better than the previous one.
-
-2001-08-07 Jakub Steiner <jimmac@ximian.com>
-
- * inbox-*, outbox-*: tree view icons * filters.xpm, edit-16.xpm,
- marlboro_filters.xpm: remove unused * vfolder-16.xpm,
- delete-message.xpm, undelete-message.xpm: let's not use xpms *
- evolution-trash-mini.png: new version for edit>delete message,
- tree view and everything * undelete_message-16.png,
- folder-move-16.png, open-in-new-window-16.png, folder-copy-16.png:
- tree view icons * faq-16.png, mark-as-important-16.png: menu icons
- * Makefile.am (images_DATA): add new icons, change some xpms to
- pngs
-
-
-2001-08-03 Jakub Steiner <jimmac@ximian.com>
-
- * ldap-16.png, imap-16.png, local-16.png: tree view icons for
- imap, ldap and local folders.
-
-2001-08-02 Jakub Steiner <jimmac@ximian.com>
-
- * myevo-mail-summary.png, myevo-post-it.png, *
- myevo-appointments.png: icons for My Evolution -- mail summary,
- tasks, appointments. These are _NOT_TO_ replace the shortcut
- icons, but solely for My Evolution.
-
-2001-08-02 Tuomas Kuosmanen <tigert@ximian.com>
-
- * receive-24.png: Icon for the send/receive dialog at least.
-
-2001-07-31 Jakub Steiner <jimmac@ximian.com>
-
- * splash.png: beta2 splash
-
-2001-07-31 Tuomas Kuosmanen <tigert@ximian.com>
-
- * send-24-receive.png: New version, looks more consistent with the
- other icons.
-
-2001-07-30 Jakub Steiner <jimmac@ximian.com>
-
- * search-16.png, search-and-replace-16.png: menu versions for
- shell and editor. * properties-16.png: properties for shel
- (maybe other places too) * send-16.png, send-later-16.png:
- editor, shell menu. * work_online-16.png: to accompany work
- online menu toggle. * save-16.png, save-as-16.png:
- everywhere. (based on Tuomas new gnome stock panel icon)
-
-2001-07-27 <tigert@ximian.com>
-
- * new_appointment.[xpm,png]: New version, fixes bug #4704
- hopefully.
-
-2001-07-25 Damon Chaplin <damon@ximian.com>
-
- * Makefile.am (images_DATA): added print-preview-24.png.
-
-2001-07-25 Jakub Steiner <jimmac@ximian.com>
-
- * print-preview-24.png: toolbar icon for calendar's appointment
- dialog (now using the menu version)
-
-2001-07-20 JP Rosevear <jpr@ximian.com>
-
- * Pull in new splash screen
-
-2001-07-20 Rodrigo Moya <rodrigo@ximian.com>
-
- * Makefile.am: install 2 new category icons
- (16_category_suppliers.png and 16_category_time-and-expenses.png)
-
-2001-07-20 <tigert@ximian.com>
-
- * 16_category_time-and-expenses.png: Icon for "Time & Expenses"
- category..
-
- * 16_category_suppliers.png: Icon for "Suppliers" category..
-
- * evolution-calendar.png, evolution-contacts.png,
- evolution-inbox.png, evolution-tasks.png, evolution-today.png:
- Took out the colored background circles from the icons, apparently
- people found them confusing rather than useful, especially on
- small icons -mode of the shortcutbar.
-
-2001-07-19 Rodrigo Moya <rodrigo@ximian.com>
-
- * Makefile.am: install the 2 new category icons
-
-2001-07-19 <tigert@ximian.com>
-
- * 16_category_strategies.png, 16_category_status.png: New category
- icons.
-
-2001-07-19 Jakub Steiner <jimmac@ximian.com>
-
- * insert-link-24.png, insert-table-24.png, insert-image-24.png:
- toolbar icons for message editor.
-
-2001-07-17 Rodrigo Moya <rodrigo@ximian.com>
-
- * Makefile.am: install category icons
-
-2001-07-17 Tuomas Kuosmanen <tigert@ximian.com>
-
- * 16_category_holiday-cards.png 16_category_hot-contacts.png
- 16_category_ideas.png: new category icons..
-
-2001-07-16 Tuomas Kuosmanen <tigert@ximian.com>
-
- * 16_category_favorites.png 16_category_gifts.png
- 16_category_goals.png: New additions for the category stuff..
- still more to do..
-
-2001-07-13 Tuomas Kuosmanen <tigert@ximian.com>
-
- * 16_category_*.png: Some category icons for calendar/tasks, to
- match the different category types for events. Still many to do,
- but I wanted to commit them so you people can start hacking on the
- code already. More to follow shortly.
-
- * 16_customize.png: Icon for "Customize toolbars" or whatever menu
- item that deals with customizing stuff (the icon is a wrench)
-
-2001-07-12 JP Rosevear <jpr@ximian.com>
-
- * Makefile.am: extra dist another xpm
-
-2001-07-12 <tigert@ximian.com>
-
- * delete_message.[png,xpm]: New versions for the trashcan icon. I
- am wondering if we should do some filename cleanup here, all menu
- icons should really be 16_foo.png, whereas the toolbar ones should
- be foo.png. Currently we are mixing PNG and XPM here with some
- files having otherwise same names (like this one)..
-
-2001-07-11 <tigert@ximian.com>
-
- * new_appointment.[png,xpm]: New versions
-
-2001-07-10 Tuomas Kuosmanen <tigert@ximian.com>
-
- * new_appointment.png: New appointment icon. *
- new_appointment.xpm: Small version.. (should we change this to
- 16_new_appointment.png btw?
-
-2001-07-09 Iain Holmes <iain@ximian.com>
-
- * Makefile.am: Install the myweather-* icons.
-
-2001-07-07 <tigert@ximian.com>
-
- * 16_[cut,copy,paste].png: New icons for the
- Edit->[Cut,Copy,Paste] entries, the current gnome-stock ones start
- to look bad when scaled down, so these are already 16x16 pixels.
-
-2001-07-05 Jakub Steiner <jimmac@ximian.com>
-
- * myweather-*: weather status icons for My Evolution
-
-2001-07-04 Gediminas Paulauskas <menesis@delfi.lt>
-
- * Makefile.am: install apply-filters-16.xpm
-
-2001-07-03 Tuomas Kuosmanen <tigert@ximian.com>
-
- * cut.png, copy.png, paste.png: icons for cut/copy/paste to fit
- the general style.
-
-2001-07-01 Jakub Steiner <jimmac@ximian.com>
-
- * print.xpm, print-preview.xpm: nat didn't like the jaggy
- version. This one is based on tuomas 48x48 print icon.
-
-2001-06-30 Ettore Perazzoli <ettore@ximian.com>
-
- * Makefile.am (buttons_DATA): Add `print.png', `next-message.png',
- `previous-message.png'.
-
-2001-06-29 Jakub Steiner <jimmac@ximian.com>
-
- * remove-nntp-folder-24.png, add-nntp-folder-24.png,
- refresh-nntp-folders-24.png: manage subscriptions toolbar icons
-
-2001-06-29 Tuomas Kuosmanen <tigert@ximian.com>
-
- * print.png: Icon for print message.
-
- * next-message.png, previous-message.png: New icons to replace the
- < > arrows in the mailer.
-
-2001-06-29 Chris Toshok <toshok@ximian.com>
-
- * Makefile.am (images_DATA): add contact-is-a-list.png
-
-2001-06-29 Tuomas Kuosmanen <tigert@ximian.com>
-
- * contact-is-a-list.png: icon for toshok, for contact lists.
-
-2001-06-27 Jeffrey Stedfast <fejj@ximian.com>
-
- * Makefile.am: Install the add-attachment.png icon.
-
-2001-06-27 Tuomas Kuosmanen <tigert@ximian.com>
-
- * evolution-calendar-mini.png: New version of the folder tree's
- calendar icon. Doesnt look too much like the contacts icon.
-
-2001-06-19 Damon Chaplin <damon@ximian.com>
-
- * world_map-960.png: world map picture used for selecting
- timezones. * Makefile.am (images_DATA): added world_map-960.png
- for timezones.
-
-2001-06-14 Jakub Steiner <jimmac@ximian.com>
-
- * apply-filters-16.xpm: for mailer menu. * vfolder-16.xpm:
- vfolder icon for menu items * hand-16.xpm: originally ment for
- customize toolbars. might not work * edit-16.xpm: edit message
- (message open)
-
-2001-06-13 Jakub Steiner <jimmac@ximian.com>
-
- * rdf.png, ico-rdf.png: ximianize those
-
-2001-06-13 Jakub Steiner <jimmac@ximian.com>
-
- * splash-1-0.png: Initial mockup for the final splash. Didn't
- wan't to overwrite the unstable splash.png.
-
-2001-06-07 Iain Holmes <iain@ximian.com>
-
- * empty.gif: es-weather.png es-appointments.png ico-calendar.png
- ico-mail.png ico-rdf.png ico-weather.png bcg.png rdf.png
- pattern.png: Added all these for the new My Evolution
-
-2001-06-04 Jakub Steiner <jimmac@ximian.com>
-
- * timezone-16.xpm: for events in a diffrent timezone
-
-2001-05-22 Jakub Steiner <jimmac@ximian.com>
-
- * evolution-inbox-mini.png: fixed the shadow
-
-2001-05-17 Dan Winship <danw@ximian.com>
-
- * Makefile.am (images_DATA): Install Jakub's new icons
-
-2001-05-16 Jakub Steiner <jimmac@ximian.com>
-
- * mail-config-druid-48.png, mail-config-druid-identity.png,
- mail-config-druid-account-name.png,
- mail-config-druid-receive.png, mail-config-druid-send.png,
- thankyou.png: config druid icons
-
- thankyou.png can be used for the last step in every evo
- druid (like the import one)
-
-2001-05-16 Jakub Steiner <jimmac@ximian.com>
-
- * evolution-calendar.png, evolution-contacts.png,
- evolution-inbox.png, evolution-today.png, evolution-tasks.png:
- fixed bug #2862. Also changed the envelope icon Oh and we use
- #b39169 for calendar now
-
-2001-05-16 Ettore Perazzoli <ettore@ximian.com>
-
- * Makefile.am (images_DATA): Added `online.png' and `offline.png'.
-
- * online.png: New icon by Tuomas. * offline.png: New icon by
- Tuomas.
-
-2001-05-14 Duncan Mak <duncan@ximian.com>
-
- * Makefile.am (images_DATA): add in the new find_message.xpm
-
-2001-05-14 Jakub Steiner <jimmac@ximian.com>
-
- * find_message.xpm: Duncan requested this
-
diff --git a/art/Makefile.am b/art/Makefile.am
index ce8e1047a7..850be7e8ce 100644
--- a/art/Makefile.am
+++ b/art/Makefile.am
@@ -1,258 +1,12 @@
-imagesdir = $(datadir)/images/evolution
images_DATA = \
- 16_copy.png \
- 16_customize.png \
- 16_cut.png \
- 16_paste.png \
- about-box.png \
- alarm.png \
- all_contacts.xpm \
- apply-filters-16.xpm \
- bcg.png \
- briefcase.png \
- butterfly.png \
- calendar-and-tasks-settings.png \
- cellphone.png \
- compose-message.png \
- composer-settings.png \
- configure_16_addressbook.xpm \
- configure_16_calendar.xpm \
- configure_16_folder.xpm \
- configure_16_mail.xpm \
- connect_to_url-16.xpm \
- contact-is-a-list.png \
- contact-list-16.png \
- copy_16_message.xpm \
- edit.xpm \
- empty.gif \
- encrypt.xpm \
- envelope.png \
- es-appointments.png \
- es-weather.png \
- evolution-calendar-mini.png \
- evolution-calendar.png \
- evolution-contacts-mini.png \
- evolution-contacts-plain.png \
- evolution-contacts.png \
- evolution-inbox-mini.png \
- evolution-inbox.png \
- evolution-notes-mini.png \
- evolution-notes.png \
- evolution-tasks-mini.png \
- evolution-tasks.png \
- evolution-today-mini.png \
- evolution-today.png \
- evolution-trash-mini.png \
- evolution-trash.png \
- executive-summary-bg.png \
- executive-summary-curve.png \
- info-bulb.png \
- faq-16.png \
- fetch-mail.png \
- find_contact.xpm \
- find_message.xpm \
- flag-for-followup-16.png \
- folder-copy-16.png \
- folder-move-16.png \
- folder-settings.png \
- folder.png \
- folder-mini.png \
- folder.xpm \
- font.png \
- forward.xpm \
- globe.png \
- goto-16.png \
- hide_deleted_messages.xpm \
- hide_read_messages.xpm \
- hide_selected_messages.xpm \
- house.png \
- ico-calendar.png \
- ico-mail.png \
- ico-rdf.png \
- ico-weather.png \
- import.png \
- import.xpm \
- inbox.png \
- inbox-mini.png \
- ldap-mini.png \
- ldap-settings.png \
- ldap.png \
- mail.png \
- mail-accounts-settings.png \
- mail-config-druid-account-name.png \
- mail-config-druid-identity.png \
- mail-config-druid-receive.png \
- mail-config-druid-send.png \
- mail-config-druid.png \
- mail-new.xpm \
- mail-read.xpm \
- malehead.png \
- mark-as-important-16.png \
- meeting-request.png \
- meeting-request-16.png \
- monkey-16.png \
- move_message.xpm \
- myevo-appointments.png \
- myevo-mail-summary.png \
- myevo-post-it.png \
- myweather-clouds.png \
- myweather-fog.png \
- myweather-rain.png \
- myweather-snow.png \
- myweather-storm.png \
- myweather-sun.png \
- myweather-suncloud.png \
- new-message.xpm \
- new_all_day_event.png \
- new_appointment.xpm \
- new_contact.xpm \
- new_task-16.png \
- offline.png \
- online.png \
- open-in-new-window-16.png \
- outbox.png \
- outbox-mini.png \
- pattern.png \
- pgp-signature-bad.png \
- pgp-signature-nokey.png \
- pgp-signature-ok.png \
- post-message-16.png \
- post-reply-24.png \
- print-preview.xpm \
- print.xpm \
- priority-high.xpm \
- public-folder.png \
- public-folder-mini.png \
- rdf.png \
- reply.xpm \
- reply_to_all.xpm \
- save-16.png \
- save-as-16.png \
- save.xpm \
- schedule-meeting-16.xpm \
- schedule-meeting-24.png \
- search-16.png \
- search-and-replace-16.png \
- send-16.png \
- send-later-16.png \
- send-receive.xpm \
- service-close.png \
- service-configure.png \
- service-down-disabled.png \
- service-down.png \
- service-left-disabled.png \
- service-left.png \
- service-right-disabled.png \
- service-right.png \
- service-up-disabled.png \
- service-up.png \
- show_all_messages.xpm \
- splash.png \
- summary-settings.png \
- summary_preferences-16.png \
- talking-heads.png \
- task.png \
- task.xpm \
- thankyou.png \
- timezone-16.xpm \
- timezone-48.png \
- undelete_message-16.png \
- wax-seal-broken.png \
- wax-seal.png \
- work_offline.xpm \
- work_online-16.png \
- working-16.png \
- world_map-960.png
+ world_map-960.png \
+ plus.png \
+ minus.png
-buttonsdir = $(datadir)/images/evolution/buttons
-buttons_DATA = \
- arrow-right-24.png \
- arrow-left-24.png \
- add-attachment.png \
- add-service.png \
- compose-message.png \
- copy-message.png \
- copy.png \
- cut.png \
- dayview.xpm \
- delete-message.png \
- fetch-mail.png \
- forward.png \
- goto-24.png \
- monthview.xpm \
- move-message.png \
- next-message.png \
- new_appointment.png \
- new_task.png \
- paste.png \
- previous-message.png \
- print.png \
- print-preview-24.png \
- reply.png \
- reply-to-all.png \
- receive-24.png \
- save-24.png \
- send-24-receive.png \
- send-24.png \
- weekview.xpm \
- workweekview.xpm \
- yearview.xpm
-
-gladedir = $(datadir)/evolution/glade
-glade_DATA = \
- evolution.png \
- import.png \
- flag-for-followup-48.png \
- mail-config-druid-account-name.png \
- mail-config-druid-identity.png \
- mail-config-druid.png \
- mail-config-druid-receive.png \
- mail-config-druid-send.png \
- thankyou.png \
- timezone-48.png
-
-conduitsdir = $(datadir)/images/evolution/conduits
-conduits_DATA = \
- evo-16-address-conduit.png \
- evo-16-todo-conduit.png \
- evo-16-calendar-conduit.png \
- evo-48-calendar-conduit.png \
- evo-48-address-conduit.png \
- evo-48-todo-conduit.png
-
-appicondir = $(datadir)/pixmaps
-appicon_DATA = evolution.png
-
-EXTRA_DIST = \
- attachment.xpm \
- bell.xpm \
- check-filled.xpm \
+EXTRA_DIST = \
+ README \
empty.xpm \
jump.xpm \
- mail-need-reply.xpm \
- mail-new.xpm \
- mail-read.xpm \
- mail-replied.xpm \
- flag-for-followup.xpm \
- mark.xpm \
- priority-high.xpm \
- priority-low.xpm \
- recur.xpm \
- score-higher.xpm \
- score-highest.xpm \
- score-high.xpm \
- score-lower.xpm \
- score-lowest.xpm \
- score-low.xpm \
- score-normal.xpm \
- task-assigned-to.xpm \
- task-assigned.xpm \
- task-recurring.xpm \
- timezone-16.xpm \
- tree-expanded.xpm \
- tree-unexpanded.xpm \
- $(images_DATA) \
- $(buttons_DATA) \
- $(conduits_DATA) \
- $(glade_DATA) \
- $(appicon_DATA)
+ $(images_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/art/README b/art/README
new file mode 100644
index 0000000000..9f78332ce1
--- /dev/null
+++ b/art/README
@@ -0,0 +1,46 @@
+Evolution Icons
+===============
+
+Licensing
+---------
+
+FIXME: add license info here.
+
+
+Adding Icons
+------------
+
+Icons that are meant to someday be themeable MUST be for one or more
+of the following sizes:
+
+- 16x16
+- 18x18
+- 20x20
+- 24x24
+- 32x32
+- 48x48
+
+(the following sizes may also be added for use with window
+decorations: 64x64 and 128x128)
+
+All icons should be named consistantly and be placed within the proper
+subdir that corresponds to their size (if the subdir does not yet
+exist, because no icons have been made for that size - then create the
+subdir and add it to the build as well).
+
+If it is expected that the icon(s) you've created will make it into
+the GNOME icon themes package at some point (or is already there?),
+then you will want to name your icons accordingly so that if the user
+installs a GNOME icons theme package with the appropriate icon(s),
+then he or she will see those icons rather than the ones installed by
+default with Evolution.
+
+The icons within the WWxHH subdirs will ONLY be used if they cnnot be
+found in the theme.
+
+The ONLY image files that may be placed in the toplevel art/ srcdir
+(eg. *this* dir) are xpm files that are built into the Evolution binary
+(or libs) and/or are not meant to be used as "icons".
+
+
+-- fejj
diff --git a/art/about-box.png b/art/about-box.png
deleted file mode 100644
index 97c549fcbf..0000000000
--- a/art/about-box.png
+++ /dev/null
Binary files differ
diff --git a/art/add-attachment.png b/art/add-attachment.png
deleted file mode 100644
index adbec9900b..0000000000
--- a/art/add-attachment.png
+++ /dev/null
Binary files differ
diff --git a/art/add-nntp-folder-24.png b/art/add-nntp-folder-24.png
deleted file mode 100644
index 4941fe9250..0000000000
--- a/art/add-nntp-folder-24.png
+++ /dev/null
Binary files differ
diff --git a/art/add-service.png b/art/add-service.png
deleted file mode 100644
index eb20f4e068..0000000000
--- a/art/add-service.png
+++ /dev/null
Binary files differ
diff --git a/art/alarm.png b/art/alarm.png
deleted file mode 100644
index 71a9be8a48..0000000000
--- a/art/alarm.png
+++ /dev/null
Binary files differ
diff --git a/art/all_contacts.xpm b/art/all_contacts.xpm
deleted file mode 100644
index 817bff7649..0000000000
--- a/art/all_contacts.xpm
+++ /dev/null
@@ -1,158 +0,0 @@
-/* XPM */
-static char * all_contacts_xpm[] = {
-"24 24 131 2",
-" c None",
-". c #000000",
-"+ c #FDFDFD",
-"@ c #F5F5F5",
-"# c #F6F6F6",
-"$ c #D0D0D0",
-"% c #C1C1C1",
-"& c #C3C3C3",
-"* c #C6C6C6",
-"= c #C8C8C8",
-"- c #8D8D8D",
-"; c #CACACA",
-"> c #919191",
-", c #EFEFEF",
-"' c #878787",
-") c #8A8A8A",
-"! c #5C5C5C",
-"~ c #F8F8F8",
-"{ c #EAEAEA",
-"] c #CCCCCC",
-"^ c #CECECE",
-"/ c #979797",
-"( c #D2D2D2",
-"_ c #9A9A9A",
-": c #646464",
-"< c #939393",
-"[ c #9D9D9D",
-"} c #6B6B6B",
-"| c #BDBDBD",
-"1 c #FFFFFF",
-"2 c #A1A1A1",
-"3 c #D9D9D9",
-"4 c #E3E3E3",
-"5 c #EDEDED",
-"6 c #EEEEEE",
-"7 c #C9B49B",
-"8 c #8E7151",
-"9 c #876E51",
-"0 c #BAB1A5",
-"a c #FBFBFB",
-"b c #FEFEFE",
-"c c #DEDCD7",
-"d c #9E9E9E",
-"e c #BABABA",
-"f c #D1D1D1",
-"g c #A3A3A3",
-"h c #F3F3F3",
-"i c #A88D6E",
-"j c #DFD0BF",
-"k c #5E432B",
-"l c #7E6C5B",
-"m c #313131",
-"n c #575757",
-"o c #FCFCFC",
-"p c #555555",
-"q c #D5D3CF",
-"r c #868686",
-"s c #A6A6A6",
-"t c #CDCDCD",
-"u c #DBDBDB",
-"v c #EEDFCC",
-"w c #F4EEE6",
-"x c #765E45",
-"y c #736251",
-"z c #D9D7D2",
-"A c #606060",
-"B c #7D7D7D",
-"C c #9C9C9C",
-"D c #A5A5A5",
-"E c #7C7C7C",
-"F c #FAFAFA",
-"G c #7590AE",
-"H c #C1665A",
-"I c #445B71",
-"J c #D7D6D3",
-"K c #ADADAD",
-"L c #9B9B9B",
-"M c #B6B6B6",
-"N c #E6E6E6",
-"O c #F1F1F1",
-"P c #A8A8A8",
-"Q c #4B6983",
-"R c #9DB8D2",
-"S c #486481",
-"T c #314E6C",
-"U c #667A8D",
-"V c #D4D3CE",
-"W c #787878",
-"X c #D3D3D3",
-"Y c #E1E1E1",
-"Z c #ABABAB",
-"` c #5F7C96",
-" . c #5D7A95",
-".. c #4D6B87",
-"+. c #3B556D",
-"@. c #344A60",
-"#. c #999999",
-"$. c #C7C7C7",
-"%. c #DDDBD6",
-"&. c #DADADA",
-"*. c #E2E2E2",
-"=. c #898989",
-"-. c #A9A9A9",
-";. c #B0B0B0",
-">. c #5D5D5D",
-",. c #CBC9C2",
-"'. c #BBBBBB",
-"). c #ECECEC",
-"!. c #EAE8E3",
-"~. c #DAD8D3",
-"{. c #D3D2CD",
-"]. c #CECCC8",
-"^. c #CCCAC6",
-"/. c #D1CFCA",
-"(. c #D2D0CB",
-"_. c #C8C5BF",
-":. c #737169",
-"<. c #8F8F8F",
-"[. c #B3B3B3",
-"}. c #DCDCDC",
-"|. c #E8E8E8",
-"1. c #B5B5B5",
-"2. c #565656",
-"3. c #A0A0A0",
-"4. c #C2C2C2",
-"5. c #848484",
-"6. c #838383",
-"7. c #7B7B7B",
-"8. c #8B8B8B",
-"9. c #B2B2B2",
-"0. c #B8B8B8",
-" ",
-" ",
-" . . . . . . . . . . . . . . . . . . . . ",
-" . + @ @ @ @ @ @ @ # # # # # # # # # $ . ",
-" . @ % % % & & & & * * * * * = = = = - . ",
-" . # & & & * * * * = = = = = ; ; ; ; > . ",
-" . , ' ' ' ) ) ) ) - - - - - > > > > ! . ",
-" . ~ { { { { { { { { { { { { { { { { ; . ",
-" . # ; ; ; ] ] ] ] ] ^ ^ ^ ^ $ $ $ $ / . ",
-" . # ] ] ] ^ ^ ^ ^ ^ $ & ^ $ ( ( ( ( _ . ",
-" . . . . . . . . . . . . . . : < / [ [ [ [ } . ",
-". | 1 1 1 1 1 1 1 1 1 1 1 1 2 . 3 4 5 6 6 6 * . ",
-". 1 ~ 7 8 9 0 1 + 1 a 1 1 b c . d e f 3 3 3 g . ",
-". 1 h i j k l 1 m n o p + 1 q . r s t u u u g . ",
-". 1 h v w x y 1 1 1 1 1 1 1 z . A B C D D D E . ",
-". 1 F G H I J 1 K 1 L K 1 1 q . ) M N O O , P . ",
-". 1 Q R S T U 1 1 1 1 1 1 1 V . W D X Y Y Y Z . ",
-". 1 ` ...+.@.1 #.L 5 $.1 1 %.. E K &.*.*.*.K . ",
-". 1 1 1 1 1 1 1 1 1 1 1 1 1 c . A =.-.;.;.;.[ . ",
-". 1 1 >.1 >.1 W 1 L 1 * o F ,.. =.'.).@ @ @ $ . ",
-". g !.!.!.~.~.~.{.].^./.(._.:.. <.[.}.N |.|.1.. ",
-" . . . . . . . . . . . . . . 2.3.% Y N |.|.1.. ",
-" . 4.< - =.' 5.) r 6.7.E 8.2 9.1.0.0.e . ",
-" . . . . . . . . . . . . . . . . . . . . "};
diff --git a/art/apply-filters-16.xpm b/art/apply-filters-16.xpm
deleted file mode 100644
index 28410fe30b..0000000000
--- a/art/apply-filters-16.xpm
+++ /dev/null
@@ -1,48 +0,0 @@
-/* XPM */
-static char * apply_filers_16_xpm[] = {
-"16 16 29 1",
-" c None",
-". c #161616",
-"+ c #EDEAE8",
-"@ c #CDC1BA",
-"# c #6A4E3D",
-"$ c #C6B8AF",
-"% c #333333",
-"& c #F3F1EE",
-"* c #5E4537",
-"= c #D6CCC5",
-"- c #916C56",
-"; c #5A4235",
-"> c #BBA9A0",
-", c #C3B3AC",
-"' c #CEC1BB",
-") c #BBAAA0",
-"! c #A1897A",
-"~ c #664B3B",
-"{ c #383838",
-"] c #856B60",
-"^ c #C2B3A9",
-"/ c #E9E3E0",
-"( c #EEE9E7",
-"_ c #7B5A46",
-": c #F5F4F2",
-"< c #B8A69B",
-"[ c #AE998D",
-"} c #553E32",
-"| c #725442",
-" ",
-" .+. ",
-" .@. .# ",
-" .$. %&* ",
-" .$.......=-; ",
-" .$>$$$$$,'--. ",
-" .$.......)-* ",
-" .$. .!* ",
-" .$. .~ ",
-" .$. {] ",
-" .^. ./~ ",
-" .(.......,-# ",
-" _$:,$$$$$<--. ",
-" ~.......[-} ",
-" .!# ",
-" .| "};
diff --git a/art/arrow-left-24.png b/art/arrow-left-24.png
deleted file mode 100644
index a977b3fb1a..0000000000
--- a/art/arrow-left-24.png
+++ /dev/null
Binary files differ
diff --git a/art/arrow-right-24.png b/art/arrow-right-24.png
deleted file mode 100644
index 393b0dca3e..0000000000
--- a/art/arrow-right-24.png
+++ /dev/null
Binary files differ
diff --git a/art/attachment.xpm b/art/attachment.xpm
deleted file mode 100644
index 21f2ecdb0e..0000000000
--- a/art/attachment.xpm
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static char * attachment_xpm[] = {
-"16 16 3 1",
-" c None",
-". c #FFFFFF",
-"+ c #000000",
-" ",
-" ... ",
-" .+++. . ",
-" .+...+.+. ",
-" .+.+.+.+. ",
-" .+.+.+.+. ",
-" .+.+.+.+. ",
-" .+.+.+.+. ",
-" .+.+.+.+. ",
-" .+.+.+.+. ",
-" .+.+.+.+. ",
-" .+..+..+. ",
-" .+.....+. ",
-" .+...+. ",
-" .+++. ",
-" ... "};
diff --git a/art/bcg.png b/art/bcg.png
deleted file mode 100644
index ec03f8ab6e..0000000000
--- a/art/bcg.png
+++ /dev/null
Binary files differ
diff --git a/art/bell.xpm b/art/bell.xpm
deleted file mode 100644
index b1ab537a17..0000000000
--- a/art/bell.xpm
+++ /dev/null
@@ -1,83 +0,0 @@
-/* XPM */
-static char * bell_xpm[] = {
-"16 16 64 1",
-" c None",
-". c #000000",
-"+ c #E3BB43",
-"@ c #E6C049",
-"# c #EED275",
-"$ c #F4E193",
-"% c #F4DF8C",
-"& c #EAC95C",
-"* c #EFD57A",
-"= c #FAEFBB",
-"- c #FDF6D3",
-"; c #FDF5C6",
-"> c #F4E18F",
-", c #E4BD43",
-"' c #F6E295",
-") c #FEF9D8",
-"! c #FFFFFF",
-"~ c #FFFADA",
-"{ c #FCEEAA",
-"] c #EBCA5A",
-"^ c #E9C550",
-"/ c #FAEA9C",
-"( c #FEF7CB",
-"_ c #FFF8CC",
-": c #FDF1A8",
-"< c #EED060",
-"[ c #D39D12",
-"} c #F2D55D",
-"| c #FCEC91",
-"1 c #FFF4AE",
-"2 c #FFF5B6",
-"3 c #FEEF97",
-"4 c #F3D65E",
-"5 c #D5A216",
-"6 c #FAE05C",
-"7 c #FFED7C",
-"8 c #FFEF8C",
-"9 c #FFF092",
-"0 c #FDEB7A",
-"a c #F4D750",
-"b c #D8A717",
-"c c #EAC01D",
-"d c #F6D83E",
-"e c #FAE255",
-"f c #FAE362",
-"g c #F9E161",
-"h c #F6DE5B",
-"i c #F1D145",
-"j c #E6BE28",
-"k c #D09B09",
-"l c #B67E00",
-"m c #CE9100",
-"n c #D69F04",
-"o c #E0B011",
-"p c #E6BA1D",
-"q c #E3B721",
-"r c #E0B21E",
-"s c #DCAB16",
-"t c #D7A20D",
-"u c #CC9303",
-"v c #BE8400",
-"w c #AC7500",
-"x c #A06B00",
-"y c #FFDD00",
-" ",
-" .. ",
-" .+@. ",
-" .#$%&. ",
-" .*=-;>,. ",
-" .')!~{]. ",
-" .^/(~_:<[. ",
-" .}|121345. ",
-" .678980ab. ",
-" .cdefghijkl. ",
-" .mnopqrstuvwx. ",
-" .............. ",
-" .8y. ",
-" .. ",
-" ",
-" "};
diff --git a/art/briefcase.png b/art/briefcase.png
deleted file mode 100644
index 424ad09632..0000000000
--- a/art/briefcase.png
+++ /dev/null
Binary files differ
diff --git a/art/butterfly.png b/art/butterfly.png
deleted file mode 100644
index 00089774e0..0000000000
--- a/art/butterfly.png
+++ /dev/null
Binary files differ
diff --git a/art/calendar-and-tasks-settings.png b/art/calendar-and-tasks-settings.png
deleted file mode 100644
index a457bb3cc8..0000000000
--- a/art/calendar-and-tasks-settings.png
+++ /dev/null
Binary files differ
diff --git a/art/cellphone.png b/art/cellphone.png
deleted file mode 100644
index c8d70ae663..0000000000
--- a/art/cellphone.png
+++ /dev/null
Binary files differ
diff --git a/art/compose-message.png b/art/compose-message.png
deleted file mode 100644
index 0be2101b6f..0000000000
--- a/art/compose-message.png
+++ /dev/null
Binary files differ
diff --git a/art/composer-settings.png b/art/composer-settings.png
deleted file mode 100644
index f255c755e7..0000000000
--- a/art/composer-settings.png
+++ /dev/null
Binary files differ
diff --git a/art/configure_16_addressbook.xpm b/art/configure_16_addressbook.xpm
deleted file mode 100644
index 4e037fe7b5..0000000000
--- a/art/configure_16_addressbook.xpm
+++ /dev/null
@@ -1,77 +0,0 @@
-/* XPM */
-static char * 16_configure_addressbook_xpm[] = {
-"16 16 58 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #EFEFEF",
-"# c #C3C3C3",
-"$ c #EAEAEA",
-"% c #BDBDBD",
-"& c #CFCFCF",
-"* c #898989",
-"= c #A8A8A8",
-"- c #A3A3A3",
-"; c #F8F8F8",
-"> c #C9B49B",
-", c #8E7151",
-"' c #876E51",
-") c #BAB1A5",
-"! c #9D9D9D",
-"~ c #EAE8E3",
-"{ c #F3F3F3",
-"] c #A88D6E",
-"^ c #DFD0BF",
-"/ c #5E432B",
-"( c #7E6C5B",
-"_ c #A6A6A6",
-": c #EEEEEE",
-"< c #EEDFCC",
-"[ c #F4EEE6",
-"} c #765E45",
-"| c #736251",
-"1 c #C1C1C1",
-"2 c #B4B4B4",
-"3 c #FAFAFA",
-"4 c #7590AE",
-"5 c #C1665A",
-"6 c #445B71",
-"7 c #AEADAB",
-"8 c #E8E8E8",
-"9 c #4B6983",
-"0 c #9DB8D2",
-"a c #486481",
-"b c #314E6C",
-"c c #BDBCB8",
-"d c #5F7C96",
-"e c #5D7A95",
-"f c #4D6B87",
-"g c #3B556D",
-"h c #999794",
-"i c #ADABA8",
-"j c #5D5D5D",
-"k c #9B9B9B",
-"l c #DEDEDE",
-"m c #C3C0BA",
-"n c #DAD8D3",
-"o c #B1AFAB",
-"p c #CBC9C5",
-"q c #A5A3A0",
-"r c #96948F",
-"s c #918E85",
-" .. .. ",
-" .+. .@. ",
-" .+....@. ",
-" .+@@@@#. ",
-" .......$@@#... ",
-".%+++++&.+#.*=-.",
-".+;>,')+.+@.!&~.",
-".+{]^/(+.+#._:~.",
-".+{<[}|1.+@.2&~.",
-".+34567.8@##.2~.",
-".+90ab.&@@@@#.c.",
-".+defg.+....@.h.",
-".+++++.+.!2.@.i.",
-".++j+j+..kl..!m.",
-".-~~~~~noc~pqrs.",
-" .............. "};
diff --git a/art/configure_16_calendar.xpm b/art/configure_16_calendar.xpm
deleted file mode 100644
index 3dd7392a1d..0000000000
--- a/art/configure_16_calendar.xpm
+++ /dev/null
@@ -1,76 +0,0 @@
-/* XPM */
-static char * configure_16_calendar_xpm[] = {
-"16 16 57 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #EFEFEF",
-"# c #A8A8A8",
-"$ c #C3C3C3",
-"% c #D4D4D4",
-"& c #939393",
-"* c #F5F5F5",
-"= c #EAEAEA",
-"- c #E05232",
-"; c #DF4623",
-"> c #E78B76",
-", c #868686",
-"' c #4A4A4A",
-") c #DF502F",
-"! c #E87F68",
-"~ c #FDF6F4",
-"{ c #A7A7A7",
-"] c #747474",
-"^ c #CFCFCF",
-"/ c #DF4B29",
-"( c #F1B2A3",
-"_ c #E05231",
-": c #F3BFB4",
-"< c #EEEEEE",
-"[ c #FAE8E4",
-"} c #F9DDD6",
-"| c #E87B62",
-"1 c #8D8D8D",
-"2 c #7B7B7B",
-"3 c #9C9C9C",
-"4 c #989898",
-"5 c #707070",
-"6 c #E2E2E2",
-"7 c #E8E8E8",
-"8 c #B4B4B4",
-"9 c #E1E1E1",
-"0 c #B0B0B0",
-"a c #DEDEDE",
-"b c #E0E0E0",
-"c c #F4F4F4",
-"d c #9D9D9D",
-"e c #979797",
-"f c #BDBDBD",
-"g c #A0A0A0",
-"h c #C1C1C1",
-"i c #DADADA",
-"j c #D9D9D9",
-"k c #CECECE",
-"l c #7C7C7C",
-"m c #EDEDED",
-"n c #9F9F9F",
-"o c #ECECEC",
-"p c #E6E6E6",
-"q c #E7E7E7",
-"r c #808080",
-" .. .. ",
-".+....@........ ",
-".+....@.++++++#.",
-".+@@@@$.++++%&*.",
-" .=@@$.++-+;>,*.",
-" .+$.'#++)!~{*.",
-" .+@.]^+/(_:+*.",
-" .+$.#<+[+}|+<.",
-" .+@.12$3$4$56.",
-" .7@$$.8++++++9.",
-".^@@@@$.^+++0ab.",
-".+....@.{+++c#b.",
-".+.de.@.f+++ghi.",
-" ..jk..da+++++b.",
-" .lm^#n<op96qr.",
-" ............ "};
diff --git a/art/configure_16_folder.xpm b/art/configure_16_folder.xpm
deleted file mode 100644
index 4d016ca91a..0000000000
--- a/art/configure_16_folder.xpm
+++ /dev/null
@@ -1,85 +0,0 @@
-/* XPM */
-static char * 16_configure_folder_xpm[] = {
-"16 16 66 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #EFEFEF",
-"# c #C3C3C3",
-"$ c #E4E5DF",
-"% c #D5D6CB",
-"& c #D6D7CA",
-"* c #F5F6F0",
-"= c #ADB198",
-"- c #C2C6A9",
-"; c #C0C3A7",
-"> c #B4B89D",
-", c #EAECDB",
-"' c #F6F6F4",
-") c #EAECDA",
-"! c #AAAB9E",
-"~ c #E5E8D4",
-"{ c #E4E7D2",
-"] c #C7C9B6",
-"^ c #F7F7F7",
-"/ c #DADEBF",
-"( c #DADEBE",
-"_ c #D8DCBC",
-": c #D6DBB9",
-"< c #797D66",
-"[ c #CDD2AD",
-"} c #CBD1AA",
-"| c #95997C",
-"1 c #F3F3EA",
-"2 c #70745E",
-"3 c #A3A889",
-"4 c #F3F4EA",
-"5 c #D5D9B7",
-"6 c #7F8369",
-"7 c #ABB08E",
-"8 c #929778",
-"9 c #F1F3E9",
-"0 c #D3D7B4",
-"a c #7C7F65",
-"b c #8F9474",
-"c c #F0F1E7",
-"d c #D1D6B2",
-"e c #CFD4AF",
-"f c #7A7D61",
-"g c #8D9270",
-"h c #EFF1E5",
-"i c #86896D",
-"j c #909273",
-"k c #707459",
-"l c #EBECDE",
-"m c #CACFA8",
-"n c #C8CDA5",
-"o c #B8BD97",
-"p c #848769",
-"q c #BFC598",
-"r c #60634C",
-"s c #989E79",
-"t c #C9CCB9",
-"u c #919576",
-"v c #848869",
-"w c #686B52",
-"x c #838768",
-"y c #595C46",
-"z c #797D60",
-"A c #666951",
-" .. .. ",
-" .+. .@. ",
-" .+....@. ",
-" ...+@@@@#. ",
-" .$%&.+@@#. ",
-" .*=-;>.+#..... ",
-" .,',,).+@.!~{].",
-" .^/(_:.+#.<[}|.",
-" .1/(_:.+@.23}|.",
-" .4_:5.+@##.678.",
-" .950.+@@@@#.ab.",
-" .cde.+....@.fg.",
-" .h[}.+.ij.@.kg.",
-" .lmno..pq..rsg.",
-" .t8ubvwwgxyzgA.",
-" ............. "};
diff --git a/art/configure_16_mail.xpm b/art/configure_16_mail.xpm
deleted file mode 100644
index b6416735ef..0000000000
--- a/art/configure_16_mail.xpm
+++ /dev/null
@@ -1,61 +0,0 @@
-/* XPM */
-static char * 16_configure_mail_xpm[] = {
-"16 16 42 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #EFEFEF",
-"# c #C3C3C3",
-"$ c #010101",
-"% c #2F2F2F",
-"& c #A7A4A0",
-"* c #FCFCFC",
-"= c #F5F5F5",
-"- c #5D5B57",
-"; c #EBEBEB",
-"> c #1B1B1B",
-", c #FBFBF8",
-"' c #716E6B",
-") c #ECECEC",
-"! c #BEBEBE",
-"~ c #EDEDED",
-"{ c #DFDFDF",
-"] c #FBFAF7",
-"^ c #A5A29D",
-"/ c #E9E9E8",
-"( c #797873",
-"_ c #8E8C8A",
-": c #C6C3BD",
-"< c #C9C5C0",
-"[ c #7D7A77",
-"} c #F7F5F1",
-"| c #FAF9F6",
-"1 c #F8F6F2",
-"2 c #DAD8D6",
-"3 c #656360",
-"4 c #E2DFD8",
-"5 c #090808",
-"6 c #D7D4CE",
-"7 c #D8D5CF",
-"8 c #D6D3CD",
-"9 c #D9D6D0",
-"0 c #D3D1CD",
-"a c #BEBCB6",
-"b c #E0DCD5",
-"c c #222221",
-" .. .. ",
-" .+. .@.",
-" .+....@.",
-" .+@@@@#.",
-" .+@@#. ",
-" .+#. ",
-" $%$$$$$$.+@. ",
-" $&******=.+#. ",
-" $+-+++++;>+@. ",
-" $+,'+++).!@##. ",
-" $+,,'+~.{@@@@#.",
-" $+,]^'/.+....@.",
-" $+](,,_.+.:<.@.",
-" $+[,}|12..34.. ",
-" $56777890abc$ ",
-" $$$$$$$$$$$ "};
diff --git a/art/connect_to_url-16.xpm b/art/connect_to_url-16.xpm
deleted file mode 100644
index 5053d252f7..0000000000
--- a/art/connect_to_url-16.xpm
+++ /dev/null
@@ -1,123 +0,0 @@
-/* XPM */
-static char * connect_to_url_16_xpm[] = {
-"16 16 104 2",
-" c None",
-". c #000000",
-"+ c #070808",
-"@ c #677B68",
-"# c #BECFC5",
-"$ c #B4C3C6",
-"% c #8AA0B6",
-"& c #95A1AC",
-"* c #AFB8B8",
-"= c #989D98",
-"- c #373737",
-"; c #AFC1B1",
-"> c #E0E7DE",
-", c #BACFC6",
-"' c #96AFC0",
-") c #728BA4",
-"! c #889BA4",
-"~ c #829176",
-"{ c #879A81",
-"] c #AAA89A",
-"^ c #585A5B",
-"/ c #1D1D1D",
-"( c #748E79",
-"_ c #DEEADF",
-": c #B1D9B3",
-"< c #AAD8B5",
-"[ c #79B7A5",
-"} c #7A9AB5",
-"| c #839DA3",
-"1 c #74876C",
-"2 c #7E8471",
-"3 c #82755A",
-"4 c #8F7F66",
-"5 c #2D2E2D",
-"6 c #CAD7CB",
-"7 c #BCD9C2",
-"8 c #96C69D",
-"9 c #4D8550",
-"0 c #597FA7",
-"a c #418093",
-"b c #637E61",
-"c c #73755B",
-"d c #86765A",
-"e c #949290",
-"f c #CDDACD",
-"g c #518355",
-"h c #989389",
-"i c #807D74",
-"j c #3B7480",
-"k c #449268",
-"l c #819395",
-"m c #797E67",
-"n c #9D907D",
-"o c #73816F",
-"p c #43423C",
-"q c #B7B3AA",
-"r c #C4C2BD",
-"s c #EAE8E3",
-"t c #4D5C5E",
-"u c #887664",
-"v c #000001",
-"w c #010101",
-"x c #E2E1DD",
-"y c #F0EFEC",
-"z c #AAA7A0",
-"A c #C5D2C8",
-"B c #E9EEEA",
-"C c #8B8572",
-"D c #476346",
-"E c #889079",
-"F c #F2F0ED",
-"G c #EBEAE6",
-"H c #8A857B",
-"I c #ECEBE8",
-"J c #4D6C8B",
-"K c #4B6963",
-"L c #53885E",
-"M c #6E7653",
-"N c #747F6C",
-"O c #0C0B0A",
-"P c #78756B",
-"Q c #BEBBB5",
-"R c #B3B1AA",
-"S c #7D786E",
-"T c #E1DFDB",
-"U c #46698F",
-"V c #598860",
-"W c #617853",
-"X c #818667",
-"Y c #030506",
-"Z c #8C8981",
-"` c #A6A29B",
-" . c #726D63",
-".. c #CECAC3",
-"+. c #3D5143",
-"@. c #020203",
-"#. c #0F0F0D",
-"$. c #F0F3F1",
-"%. c #272622",
-"&. c #8B877E",
-"*. c #706C62",
-"=. c #B1ADA4",
-"-. c #6C685E",
-";. c #646056",
-" . . . + . . . . ",
-" . @ # $ % & * = - . ",
-" . ; > , ' ) ! ~ { ] ^ / ",
-" . ( _ : < [ } | 1 2 3 4 5 . ",
-" . 6 7 8 9 . . 0 a b c d e . ",
-" . f g . . h i . j k l m n . ",
-" . o p q r s i . . . . t u v ",
-" w . x y z s i . A A B . C v ",
-". . . i x y z s i . . . . D E v ",
-"s s s s F G H I i . J K L M N O ",
-"i i P P Q R S T P . U V W X Y ",
-". . w P Z ` ...P . . . . +.@. ",
-" #.Z ` ...P . A A $.. ",
-" %.&.*.=.-.. . . . ",
-" #.#.h ;.. ",
-" #.#. "};
diff --git a/art/contact-is-a-list.png b/art/contact-is-a-list.png
deleted file mode 100644
index 3a7bc1c143..0000000000
--- a/art/contact-is-a-list.png
+++ /dev/null
Binary files differ
diff --git a/art/copy-message.png b/art/copy-message.png
deleted file mode 100644
index 907ec1a85d..0000000000
--- a/art/copy-message.png
+++ /dev/null
Binary files differ
diff --git a/art/copy.png b/art/copy.png
deleted file mode 100644
index 23a6db32e3..0000000000
--- a/art/copy.png
+++ /dev/null
Binary files differ
diff --git a/art/copy_16_message.xpm b/art/copy_16_message.xpm
deleted file mode 100644
index a4f56cfd6e..0000000000
--- a/art/copy_16_message.xpm
+++ /dev/null
@@ -1,58 +0,0 @@
-/* XPM */
-static char * 16_copy_message_xpm[] = {
-"16 16 39 1",
-" c None",
-". c #010101",
-"+ c #2F2F2F",
-"@ c #A7A4A0",
-"# c #FCFCFC",
-"$ c #64625F",
-"% c #95938E",
-"& c #FBFBFB",
-"* c #F9F8F6",
-"= c #FBFAFA",
-"- c #F6F5F1",
-"; c #7D7B78",
-"> c #EAE8E3",
-", c #969491",
-"' c #F6F4F1",
-") c #81807C",
-"! c #E5E3DE",
-"~ c #F7F6F4",
-"{ c #B0ADA7",
-"] c #83817E",
-"^ c #E1DFDA",
-"/ c #928F8B",
-"( c #FBFBFA",
-"_ c #F7F5F2",
-": c #F5F3F0",
-"< c #B5B2AC",
-"[ c #A09C97",
-"} c #F0EFEB",
-"| c #E4E2DD",
-"1 c #AEABA6",
-"2 c #92908B",
-"3 c #E8E6E1",
-"4 c #F7F6F2",
-"5 c #F5F4F0",
-"6 c #6B6A68",
-"7 c #E2DFD9",
-"8 c #E2E0DB",
-"9 c #E3E1DC",
-"0 c #E6E4DF",
-" ",
-" .+......... ",
-".@#########$. ",
-".#%&*#*=*-;>. ",
-".#*,=*=*')'!. ",
-".#**.+......... ",
-".#*.@#########$.",
-".#~.#%&*#*=*-;>.",
-".#{.#*,=*=*')'!.",
-".]^.#**/(*_)*:!.",
-" ...#*~<)#)[-}|.",
-" .#~1**)__23|.",
-" .#{*:45_:>63.",
-" .]^777^8890$.",
-" ........... ",
-" "};
diff --git a/art/cut.png b/art/cut.png
deleted file mode 100644
index 7ffb512043..0000000000
--- a/art/cut.png
+++ /dev/null
Binary files differ
diff --git a/art/dayview.xpm b/art/dayview.xpm
deleted file mode 100644
index dbabb24c5c..0000000000
--- a/art/dayview.xpm
+++ /dev/null
@@ -1,34 +0,0 @@
-/* XPM */
-static char * dayview_xpm[] = {
-"24 24 7 1",
-" c None",
-". c #000000",
-"+ c #D8D8D4",
-"@ c #919191",
-"# c #666666",
-"$ c #FFFFFF",
-"% c #F2F1ED",
-"....................... ",
-".++++++++++++++++++++@. ",
-".+@@@@@@@@@@@@@@@@@@@#. ",
-".+@@@@@@@@@@@@@@@@@@@#. ",
-".+@@@@@@@@@@@@@@@@@@@#. ",
-".@####################. ",
-".$++@%%%%%%%%%%%%%%%%@. ",
-".$++@%%%%%%%%%%%%%%%%@. ",
-".$++@%%%%%%%%%%%%%%%%@. ",
-".@@@@@@@@@@@@@@@@@@@@#. ",
-".$++@%%%%%%%%%%%%%%%%@. ",
-".$++@%%%%%%%%%%%%%%%%@. ",
-".$++@%%%%%%%%%%%%%%%%@. ",
-".@@@@@@@@@@@@@@@@@@@@#. ",
-".$++@%%%%%%%%%%%%%%%%@. ",
-".$++@%%%%%%%%%%%%%%%%@. ",
-".$++@%%%%%%%%%%%%%%%%@. ",
-".@@@@@@@@@@@@@@@@@@@@#. ",
-".$++@%%%%%%%%%%%%%%%%@. ",
-".$++@%%%%%%%%%%%%%%%%@. ",
-".$++@%%%%%%%%%%%%%%%%@. ",
-".+@@#@@@@@@@@@@@@@@@@#. ",
-"....................... ",
-" "};
diff --git a/art/delete-message.png b/art/delete-message.png
deleted file mode 100644
index 1bec6baac7..0000000000
--- a/art/delete-message.png
+++ /dev/null
Binary files differ
diff --git a/art/drafts-16.png b/art/drafts-16.png
deleted file mode 100644
index 285646f60b..0000000000
--- a/art/drafts-16.png
+++ /dev/null
Binary files differ
diff --git a/art/edit.xpm b/art/edit.xpm
deleted file mode 100644
index 28b8f090c4..0000000000
--- a/art/edit.xpm
+++ /dev/null
@@ -1,84 +0,0 @@
-/* XPM */
-static char * 16_edit_xpm[] = {
-"16 16 65 1",
-" c None",
-". c #000000",
-"+ c #FDFDFD",
-"@ c #E2E2E2",
-"# c #BAA88F",
-"$ c #836B4E",
-"% c #FEFEFE",
-"& c #FCFCFC",
-"* c #FBFBFB",
-"= c #E5E5E5",
-"- c #C5A985",
-"; c #DC9E55",
-"> c #9E6233",
-", c #FFFFFF",
-"' c #F2F2F2",
-") c #D9D9D9",
-"! c #E4E4E4",
-"~ c #C3A783",
-"{ c #DD9D53",
-"] c #A76631",
-"^ c #EEEEEE",
-"/ c #D4D4D4",
-"( c #FAFAFA",
-"_ c #7B7B7B",
-": c #C5AA88",
-"< c #A86631",
-"[ c #DCDCDC",
-"} c #F0F0F0",
-"| c #5E5E5E",
-"1 c #C3A47A",
-"2 c #DD9D52",
-"3 c #A66430",
-"4 c #D5D5D5",
-"5 c #6A6A6A",
-"6 c #C2A174",
-"7 c #DC9B4E",
-"8 c #A96630",
-"9 c #6E6E6E",
-"0 c #D8D8D8",
-"a c #D6D6D6",
-"b c #9F9F9F",
-"c c #BEA686",
-"d c #DD9D51",
-"e c #AA682F",
-"f c #F5F5F5",
-"g c #DDDDDD",
-"h c #F9F9F9",
-"i c #7A7A7A",
-"j c #BCAC9B",
-"k c #A86E3F",
-"l c #797979",
-"m c #F4F4F4",
-"n c #F3F3F3",
-"o c #DFDFDF",
-"p c #7C7C7C",
-"q c #4F4F4F",
-"r c #6C6C6C",
-"s c #EAEAEA",
-"t c #F8F8F8",
-"u c #F6F6F6",
-"v c #F7F7F7",
-"w c #EBEBEB",
-"x c #ECECEC",
-"y c #E0E0E0",
-"z c #E8E8E8",
-" .. .. ",
-" ..+@. .#$.",
-" ..%+&*=..-;>.",
-" ..,%+')*!.~{]. ",
-".,%%^/)*(_:{<. ",
-".%%)[**}|123. ",
-" .+'*}456789. ",
-" .&*0abcde.fg. ",
-" .((hijklfmno. ",
-" .(hpq.rfmnsg. ",
-" .tilufm^oo. ",
-" .vuufwoo.. ",
-" .uxyo.. ",
-" .zg.. ",
-" .. ",
-" "};
diff --git a/art/empty.gif b/art/empty.gif
deleted file mode 100644
index 0be4006193..0000000000
--- a/art/empty.gif
+++ /dev/null
Binary files differ
diff --git a/art/empty.xpm b/art/empty.xpm
index aca06618b1..b6d9e9bada 100644
--- a/art/empty.xpm
+++ b/art/empty.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * empty_xpm[] = {
+static const gchar *empty_xpm[] = {
"16 16 2 1",
" c None",
". c #FFFFFF",
diff --git a/art/encrypt.xpm b/art/encrypt.xpm
deleted file mode 100644
index 636345ad9d..0000000000
--- a/art/encrypt.xpm
+++ /dev/null
@@ -1,80 +0,0 @@
-/* XPM */
-static char * 16_encrypt_xpm[] = {
-"16 16 61 1",
-" c None",
-". c #000000",
-"+ c #FDFDFD",
-"@ c #808080",
-"# c #FEFEFE",
-"$ c #8F8F8F",
-"% c #313131",
-"& c #CDB86D",
-"* c #EED680",
-"= c #FFFFFF",
-"- c #F2F2F2",
-"; c #343434",
-"> c #EEEEEE",
-", c #D4D4D4",
-"' c #D9D9D9",
-") c #3D3D3D",
-"! c #8D8D8D",
-"~ c #DCDCDC",
-"{ c #FBFBFB",
-"] c #B2B2B2",
-"^ c #3A3A3A",
-"/ c #A9A9A9",
-"( c #F0F0F0",
-"_ c #444444",
-": c #E4E9F1",
-"< c #B3C5D7",
-"[ c #AABDCE",
-"} c #A2B4C5",
-"| c #99ABBD",
-"1 c #8FA3B4",
-"2 c #3C5469",
-"3 c #FCFCFC",
-"4 c #D8D8D8",
-"5 c #D6D6D6",
-"6 c #6A6A6A",
-"7 c #BDCEE0",
-"8 c #8FAAC4",
-"9 c #819DB7",
-"0 c #7490AA",
-"a c #66839D",
-"b c #587690",
-"c c #314456",
-"d c #FAFAFA",
-"e c #F9F9F9",
-"f c #676767",
-"g c #DFDFDF",
-"h c #5F5F5F",
-"i c #F8F8F8",
-"j c #F7F7F7",
-"k c #696969",
-"l c #92A1B0",
-"m c #5E7081",
-"n c #556879",
-"o c #4C5F70",
-"p c #435668",
-"q c #394E5F",
-"r c #23313E",
-"s c #F6F6F6",
-"t c #7E7E7E",
-"u c #E8E8E8",
-"v c #DDDDDD",
-" ",
-" .. ",
-" ..+@... ",
-" ..#+$%&*&. ",
-" ..=#+-;&@. &. ",
-" .=##>,')*!. *. ",
-" .##'~{]^&!/.&..",
-" .+-{(_:<[}|12.",
-" .3{4567890abc.",
-" .ddef7890abc.",
-" .degh7890abc.",
-" .ijklmnopqr.",
-" .jsghkkt....",
-" .sssg.. ",
-" .uv.. ",
-" .. "};
diff --git a/art/envelope.png b/art/envelope.png
deleted file mode 100644
index 3e801181aa..0000000000
--- a/art/envelope.png
+++ /dev/null
Binary files differ
diff --git a/art/es-appointments.png b/art/es-appointments.png
deleted file mode 100644
index e194232051..0000000000
--- a/art/es-appointments.png
+++ /dev/null
Binary files differ
diff --git a/art/es-weather.png b/art/es-weather.png
deleted file mode 100644
index 3d31469e78..0000000000
--- a/art/es-weather.png
+++ /dev/null
Binary files differ
diff --git a/art/evo-16-address-conduit.png b/art/evo-16-address-conduit.png
deleted file mode 100644
index 18a2e5809e..0000000000
--- a/art/evo-16-address-conduit.png
+++ /dev/null
Binary files differ
diff --git a/art/evo-16-calendar-conduit.png b/art/evo-16-calendar-conduit.png
deleted file mode 100644
index dd8e8ab85e..0000000000
--- a/art/evo-16-calendar-conduit.png
+++ /dev/null
Binary files differ
diff --git a/art/evo-16-todo-conduit.png b/art/evo-16-todo-conduit.png
deleted file mode 100644
index d36d2c61fd..0000000000
--- a/art/evo-16-todo-conduit.png
+++ /dev/null
Binary files differ
diff --git a/art/evo-48-address-conduit.png b/art/evo-48-address-conduit.png
deleted file mode 100644
index 342a061088..0000000000
--- a/art/evo-48-address-conduit.png
+++ /dev/null
Binary files differ
diff --git a/art/evo-48-calendar-conduit.png b/art/evo-48-calendar-conduit.png
deleted file mode 100644
index bb0a49791e..0000000000
--- a/art/evo-48-calendar-conduit.png
+++ /dev/null
Binary files differ
diff --git a/art/evo-48-todo-conduit.png b/art/evo-48-todo-conduit.png
deleted file mode 100644
index dd4899e984..0000000000
--- a/art/evo-48-todo-conduit.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-calendar-mini.png b/art/evolution-calendar-mini.png
deleted file mode 100644
index cddb0396dc..0000000000
--- a/art/evolution-calendar-mini.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-calendar.png b/art/evolution-calendar.png
deleted file mode 100644
index 76afca6b6f..0000000000
--- a/art/evolution-calendar.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-contacts-mini.png b/art/evolution-contacts-mini.png
deleted file mode 100644
index 5ddb92c1ce..0000000000
--- a/art/evolution-contacts-mini.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-contacts-plain.png b/art/evolution-contacts-plain.png
deleted file mode 100644
index 542a81a508..0000000000
--- a/art/evolution-contacts-plain.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-contacts.png b/art/evolution-contacts.png
deleted file mode 100644
index 0d2cfb7e5f..0000000000
--- a/art/evolution-contacts.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-inbox-mini.png b/art/evolution-inbox-mini.png
deleted file mode 100644
index dbc20fcef1..0000000000
--- a/art/evolution-inbox-mini.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-inbox.png b/art/evolution-inbox.png
deleted file mode 100644
index 66a4ba89cd..0000000000
--- a/art/evolution-inbox.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-notes-mini.png b/art/evolution-notes-mini.png
deleted file mode 100644
index f5b5d776d0..0000000000
--- a/art/evolution-notes-mini.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-notes.png b/art/evolution-notes.png
deleted file mode 100644
index f82006b894..0000000000
--- a/art/evolution-notes.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-tasks-mini.png b/art/evolution-tasks-mini.png
deleted file mode 100644
index d23b5a0be7..0000000000
--- a/art/evolution-tasks-mini.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-tasks.png b/art/evolution-tasks.png
deleted file mode 100644
index a3771c23eb..0000000000
--- a/art/evolution-tasks.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-today-mini.png b/art/evolution-today-mini.png
deleted file mode 100644
index 6039b15e82..0000000000
--- a/art/evolution-today-mini.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-today.png b/art/evolution-today.png
deleted file mode 100644
index 010bcb8cc7..0000000000
--- a/art/evolution-today.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-trash-mini.png b/art/evolution-trash-mini.png
deleted file mode 100644
index 56a8daa51f..0000000000
--- a/art/evolution-trash-mini.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution-trash.png b/art/evolution-trash.png
deleted file mode 100644
index c2ac8da173..0000000000
--- a/art/evolution-trash.png
+++ /dev/null
Binary files differ
diff --git a/art/evolution.png b/art/evolution.png
deleted file mode 100644
index 412dcfbbc0..0000000000
--- a/art/evolution.png
+++ /dev/null
Binary files differ
diff --git a/art/executive-summary-bg.png b/art/executive-summary-bg.png
deleted file mode 100644
index fdcde6613d..0000000000
--- a/art/executive-summary-bg.png
+++ /dev/null
Binary files differ
diff --git a/art/executive-summary-curve.png b/art/executive-summary-curve.png
deleted file mode 100644
index 3ba42dd02b..0000000000
--- a/art/executive-summary-curve.png
+++ /dev/null
Binary files differ
diff --git a/art/faq-16.png b/art/faq-16.png
deleted file mode 100644
index fcf71658da..0000000000
--- a/art/faq-16.png
+++ /dev/null
Binary files differ
diff --git a/art/fetch-mail.png b/art/fetch-mail.png
deleted file mode 100644
index 30cda0564d..0000000000
--- a/art/fetch-mail.png
+++ /dev/null
Binary files differ
diff --git a/art/find_contact.xpm b/art/find_contact.xpm
deleted file mode 100644
index 37d957b13b..0000000000
--- a/art/find_contact.xpm
+++ /dev/null
@@ -1,127 +0,0 @@
-/* XPM */
-static char * 24_find_contact_xpm[] = {
-"24 24 100 2",
-" c None",
-". c #000000",
-"+ c #BDBDBD",
-"@ c #FFFFFF",
-"# c #A3A3A3",
-"$ c #F8F8F8",
-"% c #C9B49B",
-"& c #8E7151",
-"* c #876E51",
-"= c #BAB1A5",
-"- c #FDFDFD",
-"; c #FBFBFB",
-"> c #EAE8E3",
-", c #F3F3F3",
-"' c #A88D6E",
-") c #DFD0BF",
-"! c #5E432B",
-"~ c #7E6C5B",
-"{ c #313131",
-"] c #575757",
-"^ c #FCFCFC",
-"/ c #555555",
-"( c #EEDFCC",
-"_ c #F4EEE6",
-": c #765E45",
-"< c #736251",
-"[ c #FAFAFA",
-"} c #7590AE",
-"| c #C1665A",
-"1 c #445B71",
-"2 c #D7D6D3",
-"3 c #ADADAD",
-"4 c #9B9B9B",
-"5 c #4B6983",
-"6 c #9DB8D2",
-"7 c #486481",
-"8 c #314E6C",
-"9 c #667A8D",
-"0 c #E0E0E0",
-"a c #BCBCBC",
-"b c #C5C5C5",
-"c c #5F7C96",
-"d c #5D7A95",
-"e c #4D6B87",
-"f c #3B556D",
-"g c #344A60",
-"h c #47473F",
-"i c #0A0A09",
-"j c #4B4B43",
-"k c #999999",
-"l c #34342E",
-"m c #9D9D8D",
-"n c #CFCFB9",
-"o c #C4C4AF",
-"p c #8D8D7F",
-"q c #353530",
-"r c #A2A2A2",
-"s c #D2D2D2",
-"t c #5D5D5D",
-"u c #46463F",
-"v c #9C9C8C",
-"w c #E2E2D0",
-"x c #EDEDE7",
-"y c #C0C0AC",
-"z c #B2B29F",
-"A c #828274",
-"B c #4C4C44",
-"C c #B9B9B9",
-"D c #D1CFC8",
-"E c #090908",
-"F c #D5D5BF",
-"G c #FBFBFA",
-"H c #C3C3AE",
-"I c #B5B5A2",
-"J c #A6A695",
-"K c #959586",
-"L c #080807",
-"M c #72706D",
-"N c #918E85",
-"O c #090909",
-"P c #CACAB5",
-"Q c #DDDDD0",
-"R c #B7B7A4",
-"S c #AAAA98",
-"T c #9B9B8B",
-"U c #8C8C7D",
-"V c #474740",
-"W c #929283",
-"X c #BABAA7",
-"Y c #ADAD9B",
-"Z c #9F9F8E",
-"` c #909081",
-" . c #727266",
-".. c #4C4C45",
-"+. c #34342F",
-"@. c #878779",
-"#. c #A0A090",
-"$. c #737367",
-"%. c #010101",
-"&. c #414141",
-" ",
-" ",
-" ",
-" . . . . . . . . . . . . . . ",
-" . + @ @ @ @ @ @ @ @ @ @ @ @ # . ",
-" . @ $ % & * = @ - @ ; @ @ @ > . ",
-" . @ , ' ) ! ~ @ { ] ^ / - @ > . ",
-" . @ , ( _ : < @ @ @ @ @ @ @ > . ",
-" . @ [ } | 1 2 @ 3 @ 4 3 @ @ > . ",
-" . @ 5 6 7 8 9 0 3 a b 0 @ @ > . ",
-" . @ c d e f g h i i j k b @ > . ",
-" . @ @ @ @ @ l m n o p q r s > . ",
-" . @ @ t @ u v w x y z A B C D . ",
-" . # > > > E F G H I J K L M N . ",
-" . . . . O P Q R S T U i . . ",
-" V W X Y Z ` ... ",
-" +.@.#.W $.%.%. ",
-" j i i &. %.%. ",
-" %.%.%. ",
-" %.%.%. ",
-" %.%.%. ",
-" %.%. ",
-" ",
-" "};
diff --git a/art/find_message.xpm b/art/find_message.xpm
deleted file mode 100644
index 04465b4ff8..0000000000
--- a/art/find_message.xpm
+++ /dev/null
@@ -1,130 +0,0 @@
-/* XPM */
-static char * find_message_xpm[] = {
-"24 24 103 2",
-" c None",
-". c #000000",
-"+ c #E9E9E9",
-"@ c #E2E2E2",
-"# c #D7D7D7",
-"$ c #FDFDFD",
-"% c #FCFCFC",
-"& c #FBFBFB",
-"* c #D8D8D8",
-"= c #FEFEFE",
-"- c #E4E4E4",
-"; c #BABABA",
-"> c #E0E0E0",
-", c #FAFAFA",
-"' c #F9F9F9",
-") c #EAEAEA",
-"! c #F8F8F8",
-"~ c #CECECE",
-"{ c #BDBDBD",
-"] c #E6E6E6",
-"^ c #E7E7E7",
-"/ c #FFFFFF",
-"( c #C2C2C2",
-"_ c #E5E5E5",
-": c #47473F",
-"< c #0A0A09",
-"[ c #4B4B43",
-"} c #8E8E8E",
-"| c #AFAFAF",
-"1 c #34342E",
-"2 c #9D9D8D",
-"3 c #CFCFB9",
-"4 c #C4C4AF",
-"5 c #8D8D7F",
-"6 c #353530",
-"7 c #848484",
-"8 c #BFBFBF",
-"9 c #F7F7F7",
-"0 c #F5F5F5",
-"a c #46463F",
-"b c #9C9C8C",
-"c c #E2E2D0",
-"d c #EDEDE7",
-"e c #C0C0AC",
-"f c #B2B29F",
-"g c #828274",
-"h c #45453D",
-"i c #A7A7A7",
-"j c #D2D2D2",
-"k c #D5D5D5",
-"l c #090908",
-"m c #D5D5BF",
-"n c #FBFBFA",
-"o c #C3C3AE",
-"p c #B5B5A2",
-"q c #A6A695",
-"r c #959586",
-"s c #080807",
-"t c #979797",
-"u c #F4F4F4",
-"v c #090909",
-"w c #CACAB5",
-"x c #DDDDD0",
-"y c #B7B7A4",
-"z c #AAAA98",
-"A c #9B9B8B",
-"B c #8C8C7D",
-"C c #929292",
-"D c #CBCBCB",
-"E c #D3D3D3",
-"F c #474740",
-"G c #929283",
-"H c #BABAA7",
-"I c #ADAD9B",
-"J c #9F9F8E",
-"K c #909081",
-"L c #727266",
-"M c #4C4C45",
-"N c #A6A6A6",
-"O c #DFDFDF",
-"P c #34342F",
-"Q c #878779",
-"R c #A0A090",
-"S c #737367",
-"T c #010101",
-"U c #919191",
-"V c #C1C1C1",
-"W c #D1D1D1",
-"X c #414141",
-"Y c #4B4B4B",
-"Z c #131313",
-"` c #646464",
-" . c #8B8B8B",
-".. c #AEAEAE",
-"+. c #5E5E5E",
-"@. c #6E6E6E",
-"#. c #575757",
-"$. c #595959",
-"%. c #585858",
-"&. c #C4C4C4",
-"*. c #DDDDDD",
-"=. c #797979",
-"-. c #2F2F2F",
-" ",
-" ",
-" . . ",
-" . . + @ . ",
-" . . # $ % & . ",
-" . . * = = = = & - . ",
-" . ; = = = = > > , ' . . . ",
-" . ) = = > > = = = ! . . + @ . ",
-" . $ = = = = ~ . . # $ % & . ",
-" . % & = { . . * = = = = & - . ",
-" . . . , ] . * ^ ^ ^ = > > , ' . ",
-" . / = . ( _ : < < [ } | ^ = = ! - . ",
-" . # = = . 1 2 3 4 5 6 7 8 > > 9 0 . ",
-" . $ = a b c d e f g h i j = = 0 - . ",
-" . k & l m n o p q r s t j > > 0 u . ",
-" . , v w x y z A B < C D = = = = - . ",
-" . E F G H I J K L M N j = = = O O . ",
-" . ! P Q R G S T T U V ^ O O . . ",
-" . W = [ < < X Y Z ` .... . ",
-" . = = > O +.@.#.T $.%. ",
-" . &.*.. . =.. T -. ",
-" . . T T T ",
-" T T ",
-" "};
diff --git a/art/flag-for-followup.xpm b/art/flag-for-followup.xpm
deleted file mode 100644
index ddb3b37ca9..0000000000
--- a/art/flag-for-followup.xpm
+++ /dev/null
@@ -1,78 +0,0 @@
-/* XPM */
-static char * flag_for_followup_xpm[] = {
-"16 16 59 1",
-" c None",
-". c #000000",
-"+ c #282E33",
-"@ c #C1D1E0",
-"# c #929EA9",
-"$ c #69737C",
-"% c #32404B",
-"& c #363F47",
-"* c #AEC0D1",
-"= c #DAE3EB",
-"- c #C4D4E4",
-"; c #6F8498",
-"> c #4D5D6C",
-", c #3F4D5B",
-"' c #3F4952",
-") c #AABBCB",
-"! c #C6D3DE",
-"~ c #E4EAF0",
-"{ c #C0D0E0",
-"] c #73889C",
-"^ c #526271",
-"/ c #41505E",
-"( c #56636F",
-"_ c #41484E",
-": c #97A9B8",
-"< c #5D7B95",
-"[ c #6A87A1",
-"} c #B5C4D2",
-"| c #D8E1E9",
-"1 c #CFDBE6",
-"2 c #9DB8D2",
-"3 c #455461",
-"4 c #465665",
-"5 c #45515B",
-"6 c #30363A",
-"7 c #C0B094",
-"8 c #4B6983",
-"9 c #57758F",
-"0 c #64819B",
-"a c #B3C2D0",
-"b c #D2DBE4",
-"c c #DCE4EC",
-"d c #A4BBD1",
-"e c #97A1AB",
-"f c #74797F",
-"g c #727A81",
-"h c #606A74",
-"i c #B39169",
-"j c #516F89",
-"k c #AEBECC",
-"l c #AFBFCE",
-"m c #DCE4EB",
-"n c #7D94A8",
-"o c #BBC8D3",
-"p c #0E0E0E",
-"q c #D7DEE4",
-"r c #040404",
-"s c #9EA4AA",
-"t c #0B0F13",
-" . ",
-" ...+. ",
-" .@#$%&. ",
-" .*=-;>,'.. ",
-" .)!~{]^/(_.. ",
-" .:<[}|12;3456. ",
-".7.890abcdefgh. ",
-" .i.8j<klm.... ",
-" .i.88nop ",
-" .i.88qr ",
-" .i.8s. ",
-" .i.t ",
-" .i. ",
-" .i. ",
-" .i. ",
-" .. "};
diff --git a/art/folder-copy-16.png b/art/folder-copy-16.png
deleted file mode 100644
index 5c0a3c9dbd..0000000000
--- a/art/folder-copy-16.png
+++ /dev/null
Binary files differ
diff --git a/art/folder-mini.png b/art/folder-mini.png
deleted file mode 100644
index 1fc929bbf7..0000000000
--- a/art/folder-mini.png
+++ /dev/null
Binary files differ
diff --git a/art/folder-move-16.png b/art/folder-move-16.png
deleted file mode 100644
index 4a94499f1c..0000000000
--- a/art/folder-move-16.png
+++ /dev/null
Binary files differ
diff --git a/art/folder-settings.png b/art/folder-settings.png
deleted file mode 100644
index 64305acf23..0000000000
--- a/art/folder-settings.png
+++ /dev/null
Binary files differ
diff --git a/art/folder.png b/art/folder.png
deleted file mode 100644
index 30f073ea6b..0000000000
--- a/art/folder.png
+++ /dev/null
Binary files differ
diff --git a/art/folder.xpm b/art/folder.xpm
deleted file mode 100644
index 4ef29bcad7..0000000000
--- a/art/folder.xpm
+++ /dev/null
@@ -1,73 +0,0 @@
-/* XPM */
-static char * folder_xpm[] = {
-"16 16 54 1",
-" c None",
-". c #000000",
-"+ c #E4E5DF",
-"@ c #D5D6CB",
-"# c #D6D7CA",
-"$ c #A3A39D",
-"% c #F5F6F0",
-"& c #ADB198",
-"* c #C2C6A9",
-"= c #C0C3A7",
-"- c #B4B89D",
-"; c #6D705F",
-"> c #EAECDB",
-", c #F6F6F4",
-"' c #EAECDA",
-") c #E8EAD8",
-"! c #E9EBDB",
-"~ c #E7E9D6",
-"{ c #E6E8D5",
-"] c #E5E8D4",
-"^ c #E4E7D2",
-"/ c #C7C9B6",
-"( c #F7F7F7",
-"_ c #DADEBF",
-": c #DADEBE",
-"< c #D8DCBC",
-"[ c #D6DBB9",
-"} c #D5D9B7",
-"| c #D3D7B4",
-"1 c #D1D6B2",
-"2 c #CFD4AF",
-"3 c #CDD2AD",
-"4 c #CBD1AA",
-"5 c #95997C",
-"6 c #F3F3EA",
-"7 c #F3F4EA",
-"8 c #CACFA8",
-"9 c #C8CDA5",
-"0 c #929778",
-"a c #F1F3E9",
-"b c #C6CCA3",
-"c c #C4CAA0",
-"d c #8F9474",
-"e c #F0F1E7",
-"f c #C2C89D",
-"g c #C1C79B",
-"h c #8D9270",
-"i c #EFF1E5",
-"j c #BFC598",
-"k c #EBECDE",
-"l c #C9CCB9",
-"m c #919576",
-"n c #8F9372",
-"o c #666951",
-" ",
-" ",
-" .... ",
-" .+@#$. ",
-" .%&*=-;....... ",
-" .>,>>')!~~{]^/.",
-" .(_:<[}|112345.",
-" .6_:<[}|112345.",
-" .7<[}|12334890.",
-" .a}|1234889bcd.",
-" .e123489bbcfgh.",
-" .i3489bcffgjjh.",
-" .k89bcfgjjjjjh.",
-" .l0mdnhhhhhhho.",
-" ............. ",
-" "};
diff --git a/art/font.png b/art/font.png
deleted file mode 100644
index bd927d3344..0000000000
--- a/art/font.png
+++ /dev/null
Binary files differ
diff --git a/art/forget_passwords.xpm b/art/forget_passwords.xpm
deleted file mode 100644
index a121300716..0000000000
--- a/art/forget_passwords.xpm
+++ /dev/null
@@ -1,125 +0,0 @@
-/* XPM */
-static char * forget_passwords_xpm[] = {
-"16 16 106 2",
-" c None",
-". c #010101",
-"+ c #C0B09D",
-"@ c #FEC6BC",
-"# c #FFCDB4",
-"$ c #C2A887",
-"% c #DCB9A8",
-"& c #AF843A",
-"* c #755C5C",
-"= c #655E37",
-"- c #DBBCAE",
-"; c #FFC4B8",
-"> c #FFCDBC",
-", c #DDBCA3",
-"' c #DBBEB5",
-") c #B9933A",
-"! c #D3AF84",
-"~ c #BE933A",
-"{ c #CDA86F",
-"] c #A3753F",
-"^ c #554F2E",
-"/ c #FFC5A3",
-"( c #FFFFE3",
-"_ c #D4B584",
-": c #DCBEB5",
-"< c #CDAE95",
-"[ c #E6BAA8",
-"} c #BDA897",
-"| c #CCA871",
-"1 c #B9841D",
-"2 c #CCAF95",
-"3 c #A8753F",
-"4 c #C4B29C",
-"5 c #E3B89E",
-"6 c #E6BEA8",
-"7 c #C89E58",
-"8 c #DCB5A0",
-"9 c #B5841D",
-"0 c #E6B593",
-"a c #BA9E58",
-"b c #B4841D",
-"c c #C79E58",
-"d c #3B250B",
-"e c #FFE5BE",
-"f c #F2C7B2",
-"g c #F3BE9E",
-"h c #C7B5A9",
-"i c #F3C8B9",
-"j c #C29E58",
-"k c #E6C2AE",
-"l c #BBAAB1",
-"m c #C7A887",
-"n c #BE9E58",
-"o c #6D572C",
-"p c #CDB6AC",
-"q c #E6BE9E",
-"r c #C7AE95",
-"s c #E6C3B5",
-"t c #DCB593",
-"u c #B9A073",
-"v c #CAA49D",
-"w c #AE841D",
-"x c #A6781B",
-"y c #BA8E51",
-"z c #B1813F",
-"A c #C6A871",
-"B c #DCBEAF",
-"C c #E6BEB5",
-"D c #D4B0AE",
-"E c #BDA058",
-"F c #AC761B",
-"G c #A77D3F",
-"H c #A06422",
-"I c #B59358",
-"J c #BDA187",
-"K c #D3B5A0",
-"L c #BD933A",
-"M c #B09960",
-"N c #BD9D60",
-"O c #AC8131",
-"P c #935511",
-"Q c #753F20",
-"R c #753D1D",
-"S c #D4AE84",
-"T c #B09264",
-"U c #BDA475",
-"V c #B48431",
-"W c #B08431",
-"X c #A86813",
-"Y c #975C16",
-"Z c #A06413",
-"` c #5C3D1D",
-" . c #A46A36",
-".. c #903801",
-"+. c #953D1D",
-"@. c #751801",
-"#. c #681601",
-"$. c #844116",
-"%. c #1D0101",
-"&. c #A0581D",
-"*. c #933A01",
-"=. c #A67531",
-"-. c #87581D",
-";. c #A86F1D",
-">. c #A1713A",
-",. c #B09358",
-" ",
-" . . . . . . ",
-" . . + @ # $ % & * . ",
-" = - ; > , ' ) ! ~ { ] . ",
-" ^ / ( _ : < [ } | 1 2 ) 3 . ",
-". 4 5 6 7 : 8 9 0 a 2 b c ~ d ",
-". e f g h i j k l m $ < n 1 o . ",
-". p q r s t b u v 2 c w c x y . ",
-" . z A B 1 ) C D $ E j F G H . ",
-" . I ~ J K L M 2 ~ N O P Q . ",
-" . . R S T U V W X Y Z . ",
-" ` ...+.@.#.$.. ",
-" . %.&.*.=. ",
-" . -.;.>. ",
-" . ` ,.. ",
-" . . . "};
diff --git a/art/forward.png b/art/forward.png
deleted file mode 100644
index bbce8ad3c7..0000000000
--- a/art/forward.png
+++ /dev/null
Binary files differ
diff --git a/art/forward.xpm b/art/forward.xpm
deleted file mode 100644
index fcb25802a1..0000000000
--- a/art/forward.xpm
+++ /dev/null
@@ -1,51 +0,0 @@
-/* XPM */
-static char * forward_xpm[] = {
-"16 16 32 1",
-" c None",
-". c #010101",
-"+ c #2F2F2F",
-"@ c #A7A4A0",
-"# c #FCFCFC",
-"$ c #64625F",
-"% c #FFFFFF",
-"& c #5D5B57",
-"* c #868580",
-"= c #E5E2DB",
-"- c #FBFBF8",
-"; c #716E6B",
-"> c #62605C",
-", c #F8F7F2",
-"' c #DDDAD4",
-") c #000000",
-"! c #FBFAF7",
-"~ c #A5A29D",
-"{ c #797873",
-"] c #BBC2CC",
-"^ c #576E87",
-"/ c #EFEFEF",
-"( c #CCCCCC",
-"_ c #7D7A77",
-": c #F7F5F1",
-"< c #FAF9F6",
-"[ c #314E6C",
-"} c #090808",
-"| c #D7D4CE",
-"1 c #D8D5CF",
-"2 c #181818",
-"3 c #090909",
-" ",
-" ",
-" ",
-" .+......... ",
-" .@#########$. ",
-" .%&%%%%%%%*=. ",
-" .%-;%%%%%>,'. ",
-" .%--;%)))))))))",
-" .%-!~;)%%%%%%%)",
-" .%!{--)%]^///()",
-" .%_-:<)%^[[/[()",
-" .}|111)%/[[[[()",
-" .....)%//[[[()",
-" )%/[[[[()",
-" )%((((((2",
-" ))3))))))"};
diff --git a/art/globe.png b/art/globe.png
deleted file mode 100644
index 84bebd7e9a..0000000000
--- a/art/globe.png
+++ /dev/null
Binary files differ
diff --git a/art/goto-16.png b/art/goto-16.png
deleted file mode 100644
index 800db10e41..0000000000
--- a/art/goto-16.png
+++ /dev/null
Binary files differ
diff --git a/art/goto-24.png b/art/goto-24.png
deleted file mode 100644
index b6fc82fd73..0000000000
--- a/art/goto-24.png
+++ /dev/null
Binary files differ
diff --git a/art/hand-16.xpm b/art/hand-16.xpm
deleted file mode 100644
index d925e2d968..0000000000
--- a/art/hand-16.xpm
+++ /dev/null
@@ -1,115 +0,0 @@
-/* XPM */
-static char * hand_16_xpm[] = {
-"16 16 96 2",
-" c None",
-". c #010100",
-"+ c #010000",
-"@ c #090600",
-"# c #030000",
-"$ c #E8E6E1",
-"% c #A3A09C",
-"& c #080000",
-"* c #D6D2CD",
-"= c #8F8A84",
-"- c #FFFAF7",
-"; c #98938D",
-"> c #F1EDE9",
-", c #88827E",
-"' c #181510",
-") c #F8EEE4",
-"! c #F8ECE0",
-"~ c #F8ECDE",
-"{ c #0D0600",
-"] c #F8EBDE",
-"^ c #F6E7D7",
-"/ c #D5C5B6",
-"( c #070000",
-"_ c #F6E5D3",
-": c #F7E9D9",
-"< c #050200",
-"[ c #080300",
-"} c #312722",
-"| c #EFE7E0",
-"1 c #F6F2EF",
-"2 c #F6F1EE",
-"3 c #EDE4DB",
-"4 c #F1E4D6",
-"5 c #9D9790",
-"6 c #12110D",
-"7 c #958E88",
-"8 c #DDCFC2",
-"9 c #F6E8D9",
-"0 c #F6F1EC",
-"a c #F5F1EE",
-"b c #E5D7CB",
-"c c #F7E8D8",
-"d c #EEDFD3",
-"e c #CAC0B6",
-"f c #645951",
-"g c #E7D9CA",
-"h c #F6E6D5",
-"i c #F7EBDE",
-"j c #E9DCD2",
-"k c #040000",
-"l c #F7EFE7",
-"m c #EDDECF",
-"n c #D6C8BA",
-"o c #CBB9AC",
-"p c #D2C8BC",
-"q c #F8EEE3",
-"r c #F5EEE8",
-"s c #EFE3D7",
-"t c #B8A99D",
-"u c #060100",
-"v c #D7CFC7",
-"w c #F9F2E9",
-"x c #F3E3D4",
-"y c #F1DFCF",
-"z c #E6D7C7",
-"A c #F8F2ED",
-"B c #EDE1D4",
-"C c #0A0300",
-"D c #D7CFC9",
-"E c #FAF2EC",
-"F c #F1E0D1",
-"G c #F6EEE8",
-"H c #000000",
-"I c #171111",
-"J c #A79D9D",
-"K c #C8BDBC",
-"L c #A59D9A",
-"M c #ABA8A3",
-"N c #BFB7B5",
-"O c #060000",
-"P c #0E0403",
-"Q c #0A0000",
-"R c #0A0200",
-"S c #080401",
-"T c #FCF4F2",
-"U c #F9F1EF",
-"V c #F8F0EE",
-"W c #F2EDEA",
-"X c #DDD9D6",
-"Y c #E5E4E0",
-"Z c #030400",
-"` c #0B0505",
-" . c #050000",
-".. c #14100F",
-"+. c #090806",
-"@. c #000100",
-" . + ",
-" @ # $ % + + ",
-" & * = - ; > , ' ",
-" & ) ; ! ; ~ ; { ",
-" & ] ; ^ ; ] ; / ( ",
-" & _ ; _ ; : ; / ( ",
-" < [ } | 1 2 3 4 5 / ( ",
-" 6 _ 7 & 8 _ 9 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 A B _ t ( ",
-" C D E _ F G _ / H ",
-" I J K _ _ L M & ",
-" N O P Q R k S ",
-" k T U V W X Y Z ",
-" k ` ...# +.H @. "};
diff --git a/art/hide_deleted_messages.xpm b/art/hide_deleted_messages.xpm
deleted file mode 100644
index 189d8d350e..0000000000
--- a/art/hide_deleted_messages.xpm
+++ /dev/null
@@ -1,39 +0,0 @@
-/* XPM */
-static char * hide_deleted_messages_xpm[] = {
-"16 16 20 1",
-" c None",
-". c #828282",
-"+ c #A0A0A0",
-"@ c #AAAAAA",
-"# c #898989",
-"$ c #9A9A9A",
-"% c #8F8F8F",
-"& c #A9A9A9",
-"* c #A5A5A5",
-"= c #959595",
-"- c #A8A8A8",
-"; c #AEAEAE",
-"> c #B1B1B1",
-", c #B3B3B3",
-"' c #9B9B9B",
-") c #DF421E",
-"! c #000000",
-"~ c #B7B7B7",
-"{ c #ADADAD",
-"] c #AFAFAF",
-" ",
-" ",
-" ",
-" .. .+.@#$.. ",
-" .. ..%&$*=$ ",
-" .. .@.-;$#> ",
-" ",
-" .%.; .%, '. ) ",
-"!!!!!!!!!!!!! ))",
-" .~$. ... .. ) ",
-" ",
-" .+ .+.'% .+ ",
-" .{ .#%.] '& ",
-" .' .$;.% .. ",
-" ",
-" "};
diff --git a/art/hide_read_messages.xpm b/art/hide_read_messages.xpm
deleted file mode 100644
index 8df1313651..0000000000
--- a/art/hide_read_messages.xpm
+++ /dev/null
@@ -1,23 +0,0 @@
-/* XPM */
-static char * hide_read_messages_xpm[] = {
-"16 16 4 1",
-" c None",
-". c #000000",
-"+ c #DF421E",
-"@ c #828282",
-" ",
-" ",
-" ",
-" .. ....... ",
-" + ",
-" @ @@@ @@ @ ++",
-" + ",
-" ... .. ... ",
-" ",
-" ... . .... ",
-" + ",
-" @@ @@@ @@@ ++",
-" + ",
-" . ... .... ",
-" ",
-" "};
diff --git a/art/hide_selected_messages.xpm b/art/hide_selected_messages.xpm
deleted file mode 100644
index cb1989b84c..0000000000
--- a/art/hide_selected_messages.xpm
+++ /dev/null
@@ -1,33 +0,0 @@
-/* XPM */
-static char * hide_selected_messages_xpm[] = {
-"16 16 14 1",
-" c None",
-". c #4B6983",
-"+ c #DF421E",
-"@ c #FFFFFF",
-"# c #798FA2",
-"$ c #BEC8D0",
-"% c #F1F3F5",
-"& c #CDD5DC",
-"* c #A9B6C2",
-"= c #000000",
-"- c #647E94",
-"; c #A2B1BE",
-"> c #E4E8EC",
-", c #D8DEE4",
-" ",
-" ",
-" ",
-" ............ + ",
-" .@#$%%#@&*%. ++",
-" ............ + ",
-" ",
-" === == === ",
-" ",
-" === = ==== ",
-" ",
-" ............ + ",
-" .@%-@&@;>,%. ++",
-" ............ + ",
-" ",
-" "};
diff --git a/art/house.png b/art/house.png
deleted file mode 100644
index df43ec6181..0000000000
--- a/art/house.png
+++ /dev/null
Binary files differ
diff --git a/art/ico-calendar.png b/art/ico-calendar.png
deleted file mode 100644
index 3010528d7f..0000000000
--- a/art/ico-calendar.png
+++ /dev/null
Binary files differ
diff --git a/art/ico-mail.png b/art/ico-mail.png
deleted file mode 100644
index 66a4ba89cd..0000000000
--- a/art/ico-mail.png
+++ /dev/null
Binary files differ
diff --git a/art/ico-rdf.png b/art/ico-rdf.png
deleted file mode 100644
index 0e39037b95..0000000000
--- a/art/ico-rdf.png
+++ /dev/null
Binary files differ
diff --git a/art/ico-weather.png b/art/ico-weather.png
deleted file mode 100644
index 25eb161f8c..0000000000
--- a/art/ico-weather.png
+++ /dev/null
Binary files differ
diff --git a/art/imap-16.png b/art/imap-16.png
deleted file mode 100644
index 1e2932a728..0000000000
--- a/art/imap-16.png
+++ /dev/null
Binary files differ
diff --git a/art/import.png b/art/import.png
deleted file mode 100644
index 151b60a270..0000000000
--- a/art/import.png
+++ /dev/null
Binary files differ
diff --git a/art/import.xpm b/art/import.xpm
deleted file mode 100644
index a996072772..0000000000
--- a/art/import.xpm
+++ /dev/null
@@ -1,59 +0,0 @@
-/* XPM */
-static char * 16_import_xpm[] = {
-"16 16 40 1",
-" c None",
-". c #000000",
-"+ c #A50B05",
-"@ c #A1A1A1",
-"# c #FFFFFF",
-"$ c #A7A7A7",
-"% c #980000",
-"& c #DBDBDB",
-"* c #9B9B9B",
-"= c #9C9C9C",
-"- c #E4E4E4",
-"; c #9F0502",
-"> c #A90F07",
-", c #D23618",
-"' c #AEAEAE",
-") c #A3A3A3",
-"! c #D83C1B",
-"~ c #E46243",
-"{ c #E87E64",
-"] c #2C2C2C",
-"^ c #9E8754",
-"/ c #6B5B39",
-"( c #826E46",
-"_ c #9E8655",
-": c #BFA367",
-"< c #DCCBA3",
-"[ c #99804F",
-"} c #D8C7A2",
-"| c #F0DBAC",
-"1 c #E4D3AF",
-"2 c #76520D",
-"3 c #865F10",
-"4 c #E1BB65",
-"5 c #D1940C",
-"6 c #906612",
-"7 c #7D5C14",
-"8 c #CF920B",
-"9 c #714F0C",
-"0 c #E2BE6C",
-"a c #7B560E",
-"....... + ",
-".@###$. %+ ",
-".&*#=-.%;>,, ",
-".'-$-). ++ ! ",
-"....... + ~ ",
-" { ",
-" ",
-" ......]. ",
-" .^/(_:<[. ",
-" .}||||123. ",
-" .45555567. ",
-" .45555567. ",
-" .45555567. ",
-" .45585569. ",
-" .055555a. ",
-" ........ "};
diff --git a/art/inbox-16.png b/art/inbox-16.png
deleted file mode 100644
index 88071fa91e..0000000000
--- a/art/inbox-16.png
+++ /dev/null
Binary files differ
diff --git a/art/inbox-full-16.png b/art/inbox-full-16.png
deleted file mode 100644
index 289335eaa2..0000000000
--- a/art/inbox-full-16.png
+++ /dev/null
Binary files differ
diff --git a/art/inbox-mini.png b/art/inbox-mini.png
deleted file mode 100644
index 88071fa91e..0000000000
--- a/art/inbox-mini.png
+++ /dev/null
Binary files differ
diff --git a/art/inbox.png b/art/inbox.png
deleted file mode 100644
index dda0fecbb3..0000000000
--- a/art/inbox.png
+++ /dev/null
Binary files differ
diff --git a/art/info-bulb.png b/art/info-bulb.png
deleted file mode 100644
index 2d2e6be8b1..0000000000
--- a/art/info-bulb.png
+++ /dev/null
Binary files differ
diff --git a/art/insert-image-24.png b/art/insert-image-24.png
deleted file mode 100644
index 4b2fd4ffae..0000000000
--- a/art/insert-image-24.png
+++ /dev/null
Binary files differ
diff --git a/art/insert-link-24.png b/art/insert-link-24.png
deleted file mode 100644
index 9824bc8ae6..0000000000
--- a/art/insert-link-24.png
+++ /dev/null
Binary files differ
diff --git a/art/jump.xpm b/art/jump.xpm
index d974142d9a..1254a53a1b 100644
--- a/art/jump.xpm
+++ b/art/jump.xpm
@@ -1,5 +1,5 @@
/* XPM */
-static char * jump_xpm[] = {
+static const gchar *jump_xpm[] = {
"16 8 3 1",
" c None",
". c #000000",
@@ -12,3 +12,19 @@ static char * jump_xpm[] = {
".++++++++++++++.",
".++++++++++++++.",
"................"};
+
+static const gchar *jump_xpm_focused[] = {
+"16 8 3 1",
+" c None",
+". c #0000FF",
+"+ c #FFFF00",
+"................",
+"................",
+"..++++++++++++..",
+"..+..++..++..+..",
+"..+..++..++..+..",
+"..++++++++++++..",
+"................",
+"................"};
+
+
diff --git a/art/ldap-mini.png b/art/ldap-mini.png
deleted file mode 100644
index 85c4dc0cf7..0000000000
--- a/art/ldap-mini.png
+++ /dev/null
Binary files differ
diff --git a/art/ldap-settings.png b/art/ldap-settings.png
deleted file mode 100644
index dd10f98412..0000000000
--- a/art/ldap-settings.png
+++ /dev/null
Binary files differ
diff --git a/art/ldap.png b/art/ldap.png
deleted file mode 100644
index 5ff8180b35..0000000000
--- a/art/ldap.png
+++ /dev/null
Binary files differ
diff --git a/art/mail-accounts-settings.png b/art/mail-accounts-settings.png
deleted file mode 100644
index 565b1b300a..0000000000
--- a/art/mail-accounts-settings.png
+++ /dev/null
Binary files differ
diff --git a/art/mail-config-druid-48.png b/art/mail-config-druid-48.png
deleted file mode 100644
index 35b452b4e9..0000000000
--- a/art/mail-config-druid-48.png
+++ /dev/null
Binary files differ
diff --git a/art/mail-config-druid-account-name.png b/art/mail-config-druid-account-name.png
deleted file mode 100644
index 2cad5eb941..0000000000
--- a/art/mail-config-druid-account-name.png
+++ /dev/null
Binary files differ
diff --git a/art/mail-config-druid-identity.png b/art/mail-config-druid-identity.png
deleted file mode 100644
index f895a1e168..0000000000
--- a/art/mail-config-druid-identity.png
+++ /dev/null
Binary files differ
diff --git a/art/mail-config-druid-receive.png b/art/mail-config-druid-receive.png
deleted file mode 100644
index df75812db3..0000000000
--- a/art/mail-config-druid-receive.png
+++ /dev/null
Binary files differ
diff --git a/art/mail-config-druid-send.png b/art/mail-config-druid-send.png
deleted file mode 100644
index 1bf501ddb2..0000000000
--- a/art/mail-config-druid-send.png
+++ /dev/null
Binary files differ
diff --git a/art/mail-config-druid.png b/art/mail-config-druid.png
deleted file mode 100644
index 35b452b4e9..0000000000
--- a/art/mail-config-druid.png
+++ /dev/null
Binary files differ
diff --git a/art/mail-need-reply.xpm b/art/mail-need-reply.xpm
deleted file mode 100644
index 283ef3d83f..0000000000
--- a/art/mail-need-reply.xpm
+++ /dev/null
@@ -1,101 +0,0 @@
-/* XPM */
-static char * mail_need_reply_xpm[] = {
-"16 16 82 1",
-" c None",
-". c #2A2A2A",
-"+ c #AAAAAA",
-"@ c #A2A2A2",
-"# c #949494",
-"$ c #E4E4E4",
-"% c #F6F6F6",
-"& c #F7F7F7",
-"* c #F8F8F8",
-"= c #E5E5E5",
-"- c #898989",
-"; c #7A7A7A",
-"> c #DADADA",
-", c #F5F5F5",
-"' c #818181",
-") c #B1B1B1",
-"! c #858585",
-"~ c #EDEDED",
-"{ c #8E8E8E",
-"] c #E1E1E1",
-"^ c #E2E2E2",
-"/ c #7F7F7F",
-"( c #B7B7B7",
-"_ c #E0E0E0",
-": c #BEBEBE",
-"< c #737373",
-"[ c #848484",
-"} c #E8E8E8",
-"| c #DBDBDB",
-"1 c #363636",
-"2 c #9C9C9C",
-"3 c #C9C9C9",
-"4 c #919191",
-"5 c #B4B4B4",
-"6 c #AFAFAF",
-"7 c #C3C3C3",
-"8 c #6F635C",
-"9 c #372B24",
-"0 c #EBEBEB",
-"a c #F1F1F1",
-"b c #D7D7D7",
-"c c #C7C7C7",
-"d c #E9E9E9",
-"e c #F3F3F3",
-"f c #BDBDBD",
-"g c #CDCDCD",
-"h c #372E28",
-"i c #F6B893",
-"j c #88634D",
-"k c #534339",
-"l c #2C211A",
-"m c #8F8F8F",
-"n c #A8A8A8",
-"o c #6F6F6F",
-"p c #473B34",
-"q c #DBA585",
-"r c #F4A677",
-"s c #F5AD82",
-"t c #F5B189",
-"u c #72503C",
-"v c #3F3F3F",
-"w c #1C1C1C",
-"x c #2B1E15",
-"y c #DC976F",
-"z c #DA8A5B",
-"A c #583725",
-"B c #984816",
-"C c #A75223",
-"D c #43210E",
-"E c #261102",
-"F c #853F12",
-"G c #A55123",
-"H c #9C4C20",
-"I c #984B20",
-"J c #42200E",
-"K c #853E12",
-"L c #4A240E",
-"M c #291408",
-"N c #160A04",
-"O c #200E01",
-"P c #180B01",
-"Q c #000000",
-" ",
-" .++++++++++. ",
-" @#$%&**%&=-; ",
-" +>#,,,,,,')! ",
-" +*~{],,^/(_! ",
-" +*,:<,,;[]}! ",
-" +|1234-567}! ",
-" +890abcdefg! ",
-" hijkklmbbbno ",
-" pqrsttu.vvvvw ",
-" xyzzzzzA ",
-" xBCCCCCD ",
-" EFGHIIJ ",
-" EKLMMN ",
-" OP ",
-" Q "};
diff --git a/art/mail-new.xpm b/art/mail-new.xpm
deleted file mode 100644
index 767ec6366f..0000000000
--- a/art/mail-new.xpm
+++ /dev/null
@@ -1,67 +0,0 @@
-/* XPM */
-static char * mail_new_xpm[] = {
-"16 16 48 1",
-" c None",
-". c #000000",
-"+ c #202020",
-"@ c #817968",
-"# c #F5F5F5",
-"$ c #4D493C",
-"% c #736C5C",
-"& c #F5EEEE",
-"* c #FFEDC7",
-"= c #FAF3EC",
-"- c #FCE6B5",
-"; c #60594D",
-"> c #D3C29E",
-", c #746D5D",
-"' c #F5F1F1",
-") c #FDEECD",
-"! c #F8F4ED",
-"~ c #FAE3B3",
-"{ c #645F4F",
-"] c #C9BA98",
-"^ c #71685A",
-"/ c #FCF5EA",
-"( c #FFE8B7",
-"_ c #F5DEB2",
-": c #FFEABD",
-"< c #90856F",
-"[ c #7C7361",
-"} c #E4D1A9",
-"| c #C9B996",
-"1 c #FFEBC2",
-"2 c #887F6B",
-"3 c #726B59",
-"4 c #D1BF9C",
-"5 c #8B816C",
-"6 c #FFE9BA",
-"7 c #F9E2B2",
-"8 c #FFE8B8",
-"9 c #F6DFB3",
-"0 c #D4C19D",
-"a c #534D42",
-"b c #CFBF9C",
-"c c #645F51",
-"d c #C2B293",
-"e c #C4B393",
-"f c #C4B495",
-"g c #C5B596",
-"h c #CCBC99",
-"i c #4C483D",
-" ",
-" ",
-" ",
-" .+......... ",
-" .@#########$. ",
-" .#%&*#*=*-;>. ",
-" .#*,')!*~{~]. ",
-" .#**^/*({*_]. ",
-" .#*:<{#{[-}|. ",
-" .#12**{((34|. ",
-" .#5*_67890ab. ",
-" .cdeeedffghi. ",
-" ........... ",
-" ",
-" ",
-" "};
diff --git a/art/mail-read.xpm b/art/mail-read.xpm
deleted file mode 100644
index b4e3160ab4..0000000000
--- a/art/mail-read.xpm
+++ /dev/null
@@ -1,70 +0,0 @@
-/* XPM */
-static char * mail_read_xpm[] = {
-"16 16 51 1",
-" c None",
-". c #010101",
-"+ c #D9D6D0",
-"@ c #C3C0B9",
-"# c #EFEDE8",
-"$ c #F7F7F6",
-"% c #FAFAFA",
-"& c #B6B4AE",
-"* c #737373",
-"= c #C2BFB8",
-"- c #F5F4F2",
-"; c #FAFAF9",
-"> c #FFFFFF",
-", c #D2CFC9",
-"' c #707070",
-") c #5D5B57",
-"! c #868580",
-"~ c #E5E2DB",
-"{ c #FBFBF8",
-"] c #716E6B",
-"^ c #62605C",
-"/ c #F8F7F2",
-"( c #DDDAD4",
-"_ c #929191",
-": c #969390",
-"< c #92908A",
-"[ c #A1A0A0",
-"} c #F7F5F1",
-"| c #FBFAF7",
-"1 c #A5A29D",
-"2 c #908D87",
-"3 c #F9F7F3",
-"4 c #F0EEE8",
-"5 c #DDD9D2",
-"6 c #797873",
-"7 c #F9F8F4",
-"8 c #74726E",
-"9 c #E3E0D9",
-"0 c #7D7A77",
-"a c #FAF9F6",
-"b c #F8F6F2",
-"c c #FAF8F5",
-"d c #F7F5F2",
-"e c #E2DFD8",
-"f c #090808",
-"g c #D7D4CE",
-"h c #D8D5CF",
-"i c #D6D3CD",
-"j c #DAD7D1",
-"k c #E0DCD5",
-"l c #222221",
-" ..... ",
-" .+++++. ",
-" .++++++@. ",
-" .+++++#$%&. ",
-" .*==-;>>>>,'. ",
-" .>)>>>>>>>!~. ",
-" .>{]>>>>>^/(. ",
-" .>{{_::<[{}(. ",
-" .>{|1{{{2345. ",
-" .>|6{{{77895. ",
-" .>0{}abcd~8e. ",
-" .fghhhi++jkl. ",
-" ........... ",
-" ",
-" ",
-" "};
diff --git a/art/mail-replied.xpm b/art/mail-replied.xpm
deleted file mode 100644
index 06f4a7420a..0000000000
--- a/art/mail-replied.xpm
+++ /dev/null
@@ -1,52 +0,0 @@
-/* XPM */
-static char * mail_replied_xpm[] = {
-"16 16 33 1",
-" c None",
-". c #010101",
-"+ c #2F2F2F",
-"@ c #A7A4A0",
-"# c #FCFCFC",
-"$ c #64625F",
-"% c #95938E",
-"& c #FBFBFB",
-"* c #F9F8F6",
-"= c #FBFAFA",
-"- c #F6F5F1",
-"; c #7D7B78",
-"> c #EAE8E3",
-", c #969491",
-"' c #000000",
-") c #928F8B",
-"! c #FFFFFF",
-"~ c #F7F6F4",
-"{ c #B5B2AC",
-"] c #003366",
-"^ c #EFEFEF",
-"/ c #CCCCCC",
-"( c #AEABA6",
-"_ c #B0ADA7",
-": c #F5F3F0",
-"< c #83817E",
-"[ c #E1DFDA",
-"} c #E2DFD9",
-"| c #002C59",
-"1 c #002850",
-"2 c #00254A",
-"3 c #181818",
-"4 c #090909",
-" ",
-" ",
-" ",
-" .+......... ",
-" .@#########$. ",
-" .#%&*#*=*-;>. ",
-" .#*,=''''''''' ",
-" .#**)'!!!!!!!' ",
-" .#*~{'!]]]]^/' ",
-" .#~(*'!]]]^^/' ",
-" .#_*:'!]]]]^/' ",
-" .<[}}'!]^]]|/' ",
-" ....'!^^^12/' ",
-" '!//////3 ",
-" ''4'''''' ",
-" "};
diff --git a/art/mail.png b/art/mail.png
deleted file mode 100644
index bfe4bad56c..0000000000
--- a/art/mail.png
+++ /dev/null
Binary files differ
diff --git a/art/malehead.png b/art/malehead.png
deleted file mode 100644
index ada9545c85..0000000000
--- a/art/malehead.png
+++ /dev/null
Binary files differ
diff --git a/art/mark-as-important-16.png b/art/mark-as-important-16.png
deleted file mode 100644
index 393d86e77c..0000000000
--- a/art/mark-as-important-16.png
+++ /dev/null
Binary files differ
diff --git a/art/mark.xpm b/art/mark.xpm
deleted file mode 100644
index 710cd0e872..0000000000
--- a/art/mark.xpm
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static char * mark_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #36592A",
-" ",
-" ",
-" ",
-" ",
-" . ",
-" .. ",
-" .. ",
-" . .. ",
-" .. ... ",
-" .... ",
-" ... ",
-" .. ",
-" . ",
-" ",
-" ",
-" "};
diff --git a/art/meeting-request-16.png b/art/meeting-request-16.png
deleted file mode 100644
index 9874eca084..0000000000
--- a/art/meeting-request-16.png
+++ /dev/null
Binary files differ
diff --git a/art/meeting-request.png b/art/meeting-request.png
deleted file mode 100644
index 0fba577bfe..0000000000
--- a/art/meeting-request.png
+++ /dev/null
Binary files differ
diff --git a/art/minus.png b/art/minus.png
new file mode 100644
index 0000000000..9d5c21b242
--- /dev/null
+++ b/art/minus.png
Binary files differ
diff --git a/art/monkey-16.png b/art/monkey-16.png
deleted file mode 100644
index 02fb7b6eb5..0000000000
--- a/art/monkey-16.png
+++ /dev/null
Binary files differ
diff --git a/art/monthview.xpm b/art/monthview.xpm
deleted file mode 100644
index 21c76151d5..0000000000
--- a/art/monthview.xpm
+++ /dev/null
@@ -1,34 +0,0 @@
-/* XPM */
-static char * monthview_xpm[] = {
-"24 24 7 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #666666",
-"# c #919191",
-"$ c #F2F1ED",
-"% c #D8D8D4",
-"....................... ",
-".+++++++++++++++++++++. ",
-".+@@@@@@@@@@@@@@@@@@@#. ",
-".+@@@@@@@@@@@@@@@@@@@#. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".+####################. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".+####################. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".+####################. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".+$$$#$$$#$$$#$$$#$$$#. ",
-".%###################@. ",
-"....................... ",
-" "};
diff --git a/art/move-message.png b/art/move-message.png
deleted file mode 100644
index 143cea1a93..0000000000
--- a/art/move-message.png
+++ /dev/null
Binary files differ
diff --git a/art/move_message.xpm b/art/move_message.xpm
deleted file mode 100644
index 846febbe49..0000000000
--- a/art/move_message.xpm
+++ /dev/null
@@ -1,59 +0,0 @@
-/* XPM */
-static char * 16_move_message_xpm[] = {
-"16 16 40 1",
-" c None",
-". c #010101",
-"+ c #2F2F2F",
-"@ c #A7A4A0",
-"# c #FCFCFC",
-"$ c #64625F",
-"% c #95938E",
-"& c #FBFBFB",
-"* c #F9F8F6",
-"= c #FBFAFA",
-"- c #F6F5F1",
-"; c #7D7B78",
-"> c #EAE8E3",
-", c #969491",
-"' c #F6F4F1",
-") c #81807C",
-"! c #E5E3DE",
-"~ c #000000",
-"{ c #928F8B",
-"] c #FBFBFA",
-"^ c #F7F5F2",
-"/ c #F5F3F0",
-"( c #F7F6F4",
-"_ c #B5B2AC",
-": c #A09C97",
-"< c #F0EFEB",
-"[ c #E4E2DD",
-"} c #AEABA6",
-"| c #92908B",
-"1 c #E8E6E1",
-"2 c #B0ADA7",
-"3 c #F7F6F2",
-"4 c #F5F4F0",
-"5 c #6B6A68",
-"6 c #83817E",
-"7 c #E1DFDA",
-"8 c #E2DFD9",
-"9 c #E2E0DB",
-"0 c #E3E1DC",
-"a c #E6E4DF",
-" ",
-" . . . . . . ",
-". . ",
-" ",
-". . ",
-" .+......... ",
-". .@#########$.",
-" .#%&*#*=*-;>.",
-". .#*,=*=*')'!.",
-" ~ .#**{]*^)*/!.",
-" .#*(_)#):-<[.",
-" .#(}**)^^|1[.",
-" .#2*/34^/>51.",
-" .678887990a$.",
-" ........... ",
-" "};
diff --git a/art/myevo-appointments.png b/art/myevo-appointments.png
deleted file mode 100644
index 873528a964..0000000000
--- a/art/myevo-appointments.png
+++ /dev/null
Binary files differ
diff --git a/art/myevo-mail-summary.png b/art/myevo-mail-summary.png
deleted file mode 100644
index 453f9938ac..0000000000
--- a/art/myevo-mail-summary.png
+++ /dev/null
Binary files differ
diff --git a/art/myevo-post-it.png b/art/myevo-post-it.png
deleted file mode 100644
index f0ef421549..0000000000
--- a/art/myevo-post-it.png
+++ /dev/null
Binary files differ
diff --git a/art/myweather-clouds.png b/art/myweather-clouds.png
deleted file mode 100644
index fa1fa4b80f..0000000000
--- a/art/myweather-clouds.png
+++ /dev/null
Binary files differ
diff --git a/art/myweather-fog.png b/art/myweather-fog.png
deleted file mode 100644
index 60db197df7..0000000000
--- a/art/myweather-fog.png
+++ /dev/null
Binary files differ
diff --git a/art/myweather-rain.png b/art/myweather-rain.png
deleted file mode 100644
index 3ce291f788..0000000000
--- a/art/myweather-rain.png
+++ /dev/null
Binary files differ
diff --git a/art/myweather-snow.png b/art/myweather-snow.png
deleted file mode 100644
index 8a45248692..0000000000
--- a/art/myweather-snow.png
+++ /dev/null
Binary files differ
diff --git a/art/myweather-storm.png b/art/myweather-storm.png
deleted file mode 100644
index cef334a43c..0000000000
--- a/art/myweather-storm.png
+++ /dev/null
Binary files differ
diff --git a/art/myweather-sun.png b/art/myweather-sun.png
deleted file mode 100644
index 26349305bf..0000000000
--- a/art/myweather-sun.png
+++ /dev/null
Binary files differ
diff --git a/art/myweather-suncloud.png b/art/myweather-suncloud.png
deleted file mode 100644
index a2058e77b0..0000000000
--- a/art/myweather-suncloud.png
+++ /dev/null
Binary files differ
diff --git a/art/new-message.xpm b/art/new-message.xpm
deleted file mode 100644
index add4263a4d..0000000000
--- a/art/new-message.xpm
+++ /dev/null
@@ -1,38 +0,0 @@
-/* XPM */
-static char * new_message_xpm[] = {
-"16 16 19 1",
-" c None",
-". c #000000",
-"+ c #FDFDFD",
-"@ c #E2E2E2",
-"# c #FEFEFE",
-"$ c #FCFCFC",
-"% c #FBFBFB",
-"& c #FFFFFF",
-"* c #E4E4E4",
-"= c #E0E0E0",
-"- c #FAFAFA",
-"; c #F9F9F9",
-"> c #F8F8F8",
-", c #F7F7F7",
-"' c #F5F5F5",
-") c #F4F4F4",
-"! c #DFDFDF",
-"~ c #E8E8E8",
-"{ c #DDDDDD",
-" ",
-" .. ",
-" ..+@. ",
-" ..#+$%. ",
-" ..&####%*. ",
-" .&####==-;. ",
-" .###==###>*. ",
-" .+####==,'. ",
-" .$%#==###'*. ",
-" .--###=='). ",
-" .-;#==####*. ",
-" .>######!!. ",
-" .,####!!.. ",
-" .##=!.. ",
-" .~{.. ",
-" .. "};
diff --git a/art/new_all_day_event.png b/art/new_all_day_event.png
deleted file mode 100644
index ee15651725..0000000000
--- a/art/new_all_day_event.png
+++ /dev/null
Binary files differ
diff --git a/art/new_appointment.png b/art/new_appointment.png
deleted file mode 100644
index 5dc61801da..0000000000
--- a/art/new_appointment.png
+++ /dev/null
Binary files differ
diff --git a/art/new_appointment.xpm b/art/new_appointment.xpm
deleted file mode 100644
index d55eb396e8..0000000000
--- a/art/new_appointment.xpm
+++ /dev/null
@@ -1,126 +0,0 @@
-/* XPM */
-static char * new_appointment_xpm[] = {
-"16 16 107 2",
-" c None",
-". c #000000",
-"+ c #FEFEFE",
-"@ c #FDFDFD",
-"# c #E0E0E0",
-"$ c #C1C1C1",
-"% c #F1F1F1",
-"& c #C3C3C3",
-"* c #FBFBFB",
-"= c #A8A8A8",
-"- c #525252",
-"; c #141414",
-"> c #111111",
-", c #383838",
-"' c #6E6E6E",
-") c #ADADAD",
-"! c #717171",
-"~ c #5D5D5D",
-"{ c #404040",
-"] c #BA8D31",
-"^ c #EAB23D",
-"/ c #403011",
-"( c #E5E5E5",
-"_ c #B4B4B4",
-": c #606060",
-"< c #DADADA",
-"[ c #777777",
-"} c #4B4B49",
-"| c #161616",
-"1 c #EFB63E",
-"2 c #F6D591",
-"3 c #F3B840",
-"4 c #916D26",
-"5 c #F8F8F8",
-"6 c #F3F3F3",
-"7 c #E7E7E7",
-"8 c #B5B5B5",
-"9 c #A1A1A1",
-"0 c #919191",
-"a c #EEB53E",
-"b c #FAE7BC",
-"c c #FCD584",
-"d c #FEC142",
-"e c #FFC243",
-"f c #FFFFFF",
-"g c #CECECE",
-"h c #0B0B0B",
-"i c #B9B9B9",
-"j c #E4E4E4",
-"k c #B88B30",
-"l c #F9E2B2",
-"m c #FDD789",
-"n c #D0D0D0",
-"o c #373737",
-"p c #898989",
-"q c #ABABAB",
-"r c #33332D",
-"s c #CFCFB9",
-"t c #E7AF3C",
-"u c #F9DDA4",
-"v c #FECA5E",
-"w c #D09E36",
-"x c #8B8B8B",
-"y c #F6F6F6",
-"z c #131313",
-"A c #3A2B0F",
-"B c #8F6C25",
-"C c #FDC042",
-"D c #2D220C",
-"E c #6F6F6F",
-"F c #8F8F8F",
-"G c #353535",
-"H c #C3C3AE",
-"I c #DFDFDF",
-"J c #F0F0F0",
-"K c #FCFCFC",
-"L c #363636",
-"M c #AAAAAA",
-"N c #C8C8C8",
-"O c #A9A9A9",
-"P c #E1E1E1",
-"Q c #4A4A4A",
-"R c #FAFAFA",
-"S c #C4C4C4",
-"T c #3C3C36",
-"U c #ADAD9B",
-"V c #CCCCCC",
-"W c #D6D6D6",
-"X c #F4F4F4",
-"Y c #F7F7F7",
-"Z c #BABABA",
-"` c #BFBFBF",
-" . c #C9C9C9",
-".. c #767676",
-"+. c #CBCBCB",
-"@. c #ACACAC",
-"#. c #B3B3B3",
-"$. c #5C5C5C",
-"%. c #C5C5C5",
-"&. c #A0A0A0",
-"*. c #444444",
-"=. c #A7A7A7",
-"-. c #989898",
-";. c #4B4B4B",
-">. c #9C9C9C",
-",. c #A2A2A2",
-"'. c #BBBBBB",
-" . . . . . . . . . ",
-" . + + + + + + @ # $ . ",
-" . + % % % % % % & * = . ",
-" . - ; . > , ' % ) ! ~ { . ",
-" . . ] ^ / ( _ . : < [ } | . ",
-" . . 1 2 3 4 5 6 7 . : 8 9 0 . ",
-" . a b c d e f g h i . 9 j 0 . ",
-". k l m e e e n o p % q r s 0 . ",
-". t u v e e w o x + y < z j 0 . ",
-". A B C e e D E f + F G . H 0 . ",
-". I J K f f n L M @ J N z j 0 . ",
-". O P y + + f n Q R S 9 T U 0 . ",
-" . V W X R K * Y V Z . 9 j 0 . ",
-" . . ` Z ...+.@.#.. $.%.j 0 . ",
-" . . &.@.*.=.-.. ;.>.,.'.&.. ",
-" . . . . . . . . . . . . "};
diff --git a/art/new_contact.xpm b/art/new_contact.xpm
deleted file mode 100644
index 9b7e778102..0000000000
--- a/art/new_contact.xpm
+++ /dev/null
@@ -1,98 +0,0 @@
-/* XPM */
-static char * new_contact_xpm[] = {
-"24 24 71 1",
-" c None",
-". c #000000",
-"+ c #BABABA",
-"@ c #FDFDFD",
-"# c #FCFCFC",
-"$ c #959595",
-"% c #FBFBFB",
-"& c #FAFAFA",
-"* c #F9F9F9",
-"= c #F8F8F8",
-"- c #F7F7F7",
-"; c #E3E3E3",
-"> c #BDBDBD",
-", c #9D9C9A",
-"' c #999896",
-") c #A4A4A3",
-"! c #391414",
-"~ c #B1B1B1",
-"{ c #D4D4D4",
-"] c #E2E2E2",
-"^ c #DCD4C7",
-"/ c #C1B8A6",
-"( c #878682",
-"_ c #BFBFBF",
-": c #7C7C7C",
-"< c #909090",
-"[ c #747474",
-"} c #818181",
-"| c #A8A8A8",
-"1 c #B6B6B6",
-"2 c #F6F6F6",
-"3 c #7F742E",
-"4 c #E1E1E1",
-"5 c #959FA4",
-"6 c #678690",
-"7 c #9A9891",
-"8 c #959490",
-"9 c #F5F5F5",
-"0 c #2B6776",
-"a c #294E70",
-"b c #294770",
-"c c #284D6F",
-"d c #232362",
-"e c #B1B3B4",
-"f c #979797",
-"g c #B0B0B0",
-"h c #AFAFAF",
-"i c #D3D3D3",
-"j c #E0E0E0",
-"k c #27276C",
-"l c #28286D",
-"m c #282A6F",
-"n c #2A5A73",
-"o c #DFDFDF",
-"p c #A2A2A2",
-"q c #B5B5B5",
-"r c #727272",
-"s c #BCBCBC",
-"t c #F4F4F4",
-"u c #DEDEDE",
-"v c #D5D5D5",
-"w c #DDDDDD",
-"x c #BEBEBE",
-"y c #D1D1D1",
-"z c #F3F3F3",
-"A c #DCDCDC",
-"B c #E7E7E7",
-"C c #E6E6E6",
-"D c #E5E5E5",
-"E c #E4E4E4",
-"F c #686868",
-" ",
-" ",
-" ",
-" ",
-" ..................... ",
-" .+@@@@@@@@@@@@@@@@@@#$.",
-" .@%%%%%&&&&*****===--;.",
-" .@%>>,')>&*****==----;.",
-" .@%>>!..,***~={=>----].",
-" .@%>>^/.(**_:<[<}|1-2].",
-" .@%>>^3.'**={=----2224.",
-" .@&>567.8*===----22294.",
-" .@&0abcde==1<f{ghi>99j.",
-" .@&akklmn==----222999o.",
-" .@*****===-pg|qiprs9tu.",
-" .@*vvv=1>----222999ttw.",
-" .@*vxf=p---gi2h$syytzw.",
-" .@*===-----22999tttzzA.",
-" .hBBCDDE;]]]44joouwwAF.",
-" ..................... ",
-" ",
-" ",
-" ",
-" "};
diff --git a/art/new_task-16.png b/art/new_task-16.png
deleted file mode 100644
index 7937d8d53b..0000000000
--- a/art/new_task-16.png
+++ /dev/null
Binary files differ
diff --git a/art/new_task.png b/art/new_task.png
deleted file mode 100644
index 16a1c94b6b..0000000000
--- a/art/new_task.png
+++ /dev/null
Binary files differ
diff --git a/art/next-message.png b/art/next-message.png
deleted file mode 100644
index 80de893ecf..0000000000
--- a/art/next-message.png
+++ /dev/null
Binary files differ
diff --git a/art/offline.png b/art/offline.png
deleted file mode 100644
index 57bdd27be2..0000000000
--- a/art/offline.png
+++ /dev/null
Binary files differ
diff --git a/art/online.png b/art/online.png
deleted file mode 100644
index 9a6a3980c2..0000000000
--- a/art/online.png
+++ /dev/null
Binary files differ
diff --git a/art/open-in-new-window-16.png b/art/open-in-new-window-16.png
deleted file mode 100644
index 07496e8b81..0000000000
--- a/art/open-in-new-window-16.png
+++ /dev/null
Binary files differ
diff --git a/art/outbox-16.png b/art/outbox-16.png
deleted file mode 100644
index e52e00a7f3..0000000000
--- a/art/outbox-16.png
+++ /dev/null
Binary files differ
diff --git a/art/outbox-full-16.png b/art/outbox-full-16.png
deleted file mode 100644
index cb138fa2b3..0000000000
--- a/art/outbox-full-16.png
+++ /dev/null
Binary files differ
diff --git a/art/outbox-mini.png b/art/outbox-mini.png
deleted file mode 100644
index e52e00a7f3..0000000000
--- a/art/outbox-mini.png
+++ /dev/null
Binary files differ
diff --git a/art/outbox.png b/art/outbox.png
deleted file mode 100644
index 3567691c1f..0000000000
--- a/art/outbox.png
+++ /dev/null
Binary files differ
diff --git a/art/paste.png b/art/paste.png
deleted file mode 100644
index 736900531a..0000000000
--- a/art/paste.png
+++ /dev/null
Binary files differ
diff --git a/art/pattern.png b/art/pattern.png
deleted file mode 100644
index 33abc187ef..0000000000
--- a/art/pattern.png
+++ /dev/null
Binary files differ
diff --git a/art/pgp-signature-bad.png b/art/pgp-signature-bad.png
deleted file mode 100644
index 82318fbb4d..0000000000
--- a/art/pgp-signature-bad.png
+++ /dev/null
Binary files differ
diff --git a/art/pgp-signature-nokey.png b/art/pgp-signature-nokey.png
deleted file mode 100644
index 00250e090c..0000000000
--- a/art/pgp-signature-nokey.png
+++ /dev/null
Binary files differ
diff --git a/art/pgp-signature-ok.png b/art/pgp-signature-ok.png
deleted file mode 100644
index 51782b0e40..0000000000
--- a/art/pgp-signature-ok.png
+++ /dev/null
Binary files differ
diff --git a/art/pin.png b/art/pin.png
deleted file mode 100644
index fff34d7d96..0000000000
--- a/art/pin.png
+++ /dev/null
Binary files differ
diff --git a/art/plus.png b/art/plus.png
new file mode 100644
index 0000000000..cf200a04d5
--- /dev/null
+++ b/art/plus.png
Binary files differ
diff --git a/art/post-message-16.png b/art/post-message-16.png
deleted file mode 100644
index fbdaa4b2e5..0000000000
--- a/art/post-message-16.png
+++ /dev/null
Binary files differ
diff --git a/art/post-reply-24.png b/art/post-reply-24.png
deleted file mode 100644
index 43b0a229ba..0000000000
--- a/art/post-reply-24.png
+++ /dev/null
Binary files differ
diff --git a/art/previous-message.png b/art/previous-message.png
deleted file mode 100644
index 17c3dcadb6..0000000000
--- a/art/previous-message.png
+++ /dev/null
Binary files differ
diff --git a/art/print-preview-24.png b/art/print-preview-24.png
deleted file mode 100644
index cd6b90e6bd..0000000000
--- a/art/print-preview-24.png
+++ /dev/null
Binary files differ
diff --git a/art/print-preview.xpm b/art/print-preview.xpm
deleted file mode 100644
index a4b36d639d..0000000000
--- a/art/print-preview.xpm
+++ /dev/null
@@ -1,153 +0,0 @@
-/* XPM */
-static char * print_preview_xpm[] = {
-"16 16 134 2",
-" c None",
-". c #000000",
-"+ c #9D9D8D",
-"@ c #CFCFB9",
-"# c #C4C4AF",
-"$ c #8D8D7F",
-"% c #353530",
-"& c #828282",
-"* c #9C9C8C",
-"= c #E2E2D0",
-"- c #EDEDE7",
-"; c #C0C0AC",
-"> c #B2B29F",
-", c #828274",
-"' c #4C4C44",
-") c #FFFFFF",
-"! c #EFEFEF",
-"~ c #ECECEC",
-"{ c #090908",
-"] c #D5D5BF",
-"^ c #FBFBFA",
-"/ c #C3C3AE",
-"( c #B5B5A2",
-"_ c #A6A695",
-": c #959586",
-"< c #080807",
-"[ c #E3E3E3",
-"} c #CDCDCD",
-"| c #D7D7D7",
-"1 c #090909",
-"2 c #CACAB5",
-"3 c #DDDDD0",
-"4 c #B7B7A4",
-"5 c #AAAA98",
-"6 c #9B9B8B",
-"7 c #8C8C7D",
-"8 c #0A0A09",
-"9 c #E9E9E9",
-"0 c #EBEBEB",
-"a c #DBDBDB",
-"b c #929283",
-"c c #BABAA7",
-"d c #ADAD9B",
-"e c #9F9F8E",
-"f c #909081",
-"g c #727266",
-"h c #52524C",
-"i c #A4A4A4",
-"j c #34342F",
-"k c #878779",
-"l c #A0A090",
-"m c #737367",
-"n c #010101",
-"o c #575757",
-"p c #A6A6A6",
-"q c #4B4B43",
-"r c #414141",
-"s c #777777",
-"t c #979797",
-"u c #BCBBBB",
-"v c #D4D4D3",
-"w c #878787",
-"x c #323232",
-"y c #A5A5A5",
-"z c #D0D0CF",
-"A c #B5B5B5",
-"B c #C2C2C2",
-"C c #FBFBFB",
-"D c #FAFAFA",
-"E c #999999",
-"F c #363636",
-"G c #9E9E9E",
-"H c #ECECEB",
-"I c #AEADAB",
-"J c #F7F7F7",
-"K c #E5E5E4",
-"L c #8D8D8D",
-"M c #F1F1F1",
-"N c #A0A0A0",
-"O c #E2E2E2",
-"P c #D9D9D8",
-"Q c #898988",
-"R c #0C0C0C",
-"S c #302F2F",
-"T c #A4A3A1",
-"U c #CCCAC6",
-"V c #1B1B1B",
-"W c #969594",
-"X c #D6D4D2",
-"Y c #DDDBDA",
-"Z c #DCDCDB",
-"` c #DEDDDD",
-" . c #DFDEDD",
-".. c #DDDCDB",
-"+. c #DBDBD9",
-"@. c #7E7E7D",
-"#. c #383838",
-"$. c #555453",
-"%. c #9F9E9A",
-"&. c #A8A7A6",
-"*. c #9E9D9C",
-"=. c #615E59",
-"-. c #54514E",
-";. c #54524E",
-">. c #514F4B",
-",. c #52504C",
-"'. c #504D49",
-"). c #4D4B47",
-"!. c #4F4D49",
-"~. c #514F4C",
-"{. c #535251",
-"]. c #8E8D8A",
-"^. c #B4B3B1",
-"/. c #C0BFBC",
-"(. c #B9B8B5",
-"_. c #B3B1AF",
-":. c #B1B1AE",
-"<. c #AFAEAC",
-"[. c #B0AEAC",
-"}. c #ACACA9",
-"|. c #A6A6A4",
-"1. c #ABAAA7",
-"2. c #AEADAA",
-"3. c #AAA9A6",
-"4. c #201F1E",
-"5. c #403F3D",
-"6. c #444341",
-"7. c #454542",
-"8. c #42423F",
-"9. c #3F3E3C",
-"0. c #3A3936",
-"a. c #393835",
-"b. c #31302D",
-"c. c #1E1D1B",
-" . . . . ",
-" . + @ # $ % & . . . . ",
-" . * = - ; > , ' ) ! ~ . ",
-" { ] ^ / ( _ : < [ } | . ",
-" 1 2 3 4 5 6 7 8 9 0 a . ",
-" . b c d e f g h . i a . ",
-" j k l b m n o p 0 a . ",
-" q 8 8 r s n . t a . . ",
-" . u v ) 9 9 w n x y z A . ",
-" . B C ) D ) D C E n F G H I . ",
-" . D J K L M N O P Q R S T U V ",
-" . W X Y Z ` ...P +.@.#.$.%.. ",
-" . &.*.=.-.;.>.,.'.).!.~.{.].. ",
-" . ^./.(._.:.<.[.}.|.1.2.<.3.. ",
-" . 4.5.6.7.7.7.8.5.9.0.a.b.c.. ",
-" . . . . . . . . . . . . . "};
diff --git a/art/print.png b/art/print.png
deleted file mode 100644
index f223a1146d..0000000000
--- a/art/print.png
+++ /dev/null
Binary files differ
diff --git a/art/print.xpm b/art/print.xpm
deleted file mode 100644
index da46eb0157..0000000000
--- a/art/print.xpm
+++ /dev/null
@@ -1,107 +0,0 @@
-/* XPM */
-static char * print_xpm[] = {
-"16 16 88 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #ECECEC",
-"# c #353535",
-"$ c #D3D3D3",
-"% c #131313",
-"& c #C7C7C7",
-"* c #D7D7D7",
-"= c #EBEBEB",
-"- c #E9E9E9",
-"; c #DBDBDB",
-"> c #4D4D4D",
-", c #A4A4A4",
-"' c #414141",
-") c #8C8C8C",
-"! c #979797",
-"~ c #BCBBBB",
-"{ c #D4D4D3",
-"] c #D0D0CF",
-"^ c #B5B5B5",
-"/ c #C2C2C2",
-"( c #FBFBFB",
-"_ c #FAFAFA",
-": c #F8F8F8",
-"< c #F4F4F3",
-"[ c #ECECEB",
-"} c #AEADAB",
-"| c #F7F7F7",
-"1 c #E5E5E4",
-"2 c #8D8D8D",
-"3 c #F1F1F1",
-"4 c #A0A0A0",
-"5 c #E2E2E2",
-"6 c #D9D9D8",
-"7 c #DEDDDC",
-"8 c #DCDCDA",
-"9 c #D8D7D4",
-"0 c #B3B2B0",
-"a c #CCCAC6",
-"b c #1B1B1B",
-"c c #969594",
-"d c #D6D4D2",
-"e c #DDDBDA",
-"f c #DCDCDB",
-"g c #DEDDDD",
-"h c #DFDEDD",
-"i c #DDDCDB",
-"j c #DBDBD9",
-"k c #DAD9D7",
-"l c #D9D8D6",
-"m c #81807E",
-"n c #9F9E9A",
-"o c #A8A7A6",
-"p c #9E9D9C",
-"q c #615E59",
-"r c #54514E",
-"s c #54524E",
-"t c #514F4B",
-"u c #52504C",
-"v c #504D49",
-"w c #4D4B47",
-"x c #4F4D49",
-"y c #514F4C",
-"z c #939291",
-"A c #9B9A97",
-"B c #B4B3B1",
-"C c #C0BFBC",
-"D c #B9B8B5",
-"E c #B3B1AF",
-"F c #B1B1AE",
-"G c #AFAEAC",
-"H c #B0AEAC",
-"I c #ACACA9",
-"J c #A6A6A4",
-"K c #ABAAA7",
-"L c #AEADAA",
-"M c #AAA9A6",
-"N c #201F1E",
-"O c #403F3D",
-"P c #444341",
-"Q c #454542",
-"R c #42423F",
-"S c #3F3E3C",
-"T c #3A3936",
-"U c #393835",
-"V c #31302D",
-"W c #1E1D1B",
-" ",
-" ......... ",
-" .++++++@. ",
-" .+#$.%&*. ",
-" .+=---=;. ",
-" .+>.=.,;. ",
-" .+=====;. ",
-" ..+'=).!;.. ",
-" .~{+------]^. ",
-" ./(+_+_((_:<[}.",
-" ._|1234567890ab",
-" .cdefghi6jklmn.",
-" .opqrstuvwxyzA.",
-" .BCDEFGHIJKLGM.",
-" .NOPQQQROSTUVW.",
-" ............. "};
diff --git a/art/priority-high.xpm b/art/priority-high.xpm
deleted file mode 100644
index 884c8b8236..0000000000
--- a/art/priority-high.xpm
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static char * priority_high_xpm[] = {
-"16 16 3 1",
-" c None",
-". c #FFFFFF",
-"X c #A7453E",
-" ",
-" ",
-" . ",
-" .X. ",
-" .XXX. ",
-" .XXX. ",
-" .XXX. ",
-" .XX. ",
-" .XX. ",
-" .X. ",
-" .. ",
-" .XX. ",
-" .XX. ",
-" .. ",
-" ",
-" "};
diff --git a/art/priority-low.xpm b/art/priority-low.xpm
deleted file mode 100644
index ad53e9e0cc..0000000000
--- a/art/priority-low.xpm
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static char * priority_low_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #21405A",
-" ",
-" ",
-" ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" .. ",
-" ...... ",
-" .... ",
-" .... ",
-" .. ",
-" .. ",
-" ",
-" ",
-" "};
diff --git a/art/properties-16.png b/art/properties-16.png
deleted file mode 100644
index 7586e3ab27..0000000000
--- a/art/properties-16.png
+++ /dev/null
Binary files differ
diff --git a/art/public-folder-mini.png b/art/public-folder-mini.png
deleted file mode 100644
index 087eca4a85..0000000000
--- a/art/public-folder-mini.png
+++ /dev/null
Binary files differ
diff --git a/art/public-folder.png b/art/public-folder.png
deleted file mode 100644
index b23d9f805f..0000000000
--- a/art/public-folder.png
+++ /dev/null
Binary files differ
diff --git a/art/rdf.png b/art/rdf.png
deleted file mode 100644
index b4bdbafa99..0000000000
--- a/art/rdf.png
+++ /dev/null
Binary files differ
diff --git a/art/receive-24.png b/art/receive-24.png
deleted file mode 100644
index bfa7d972bc..0000000000
--- a/art/receive-24.png
+++ /dev/null
Binary files differ
diff --git a/art/recur.xpm b/art/recur.xpm
deleted file mode 100644
index bb34fa4568..0000000000
--- a/art/recur.xpm
+++ /dev/null
@@ -1,21 +0,0 @@
-/* XPM */
-static char * recur_xpm[] = {
-"16 16 2 1",
-" c None",
-". c #333366",
-" ",
-" ",
-" .. ..... ",
-" ... .... ",
-" .. .... ",
-" .. ..... ",
-" .. . .. ",
-" .. .. ",
-" .. . .. ",
-" ..... .. ",
-" .... .. ",
-" .... ... ",
-" ..... .. ",
-" ",
-" ",
-" "};
diff --git a/art/refresh-nntp-folders-24.png b/art/refresh-nntp-folders-24.png
deleted file mode 100644
index b1c339a973..0000000000
--- a/art/refresh-nntp-folders-24.png
+++ /dev/null
Binary files differ
diff --git a/art/remove-nntp-folder-24.png b/art/remove-nntp-folder-24.png
deleted file mode 100644
index 5500bdec23..0000000000
--- a/art/remove-nntp-folder-24.png
+++ /dev/null
Binary files differ
diff --git a/art/reply-to-all.png b/art/reply-to-all.png
deleted file mode 100644
index fa64fdeecf..0000000000
--- a/art/reply-to-all.png
+++ /dev/null
Binary files differ
diff --git a/art/reply.png b/art/reply.png
deleted file mode 100644
index 70ee66b8eb..0000000000
--- a/art/reply.png
+++ /dev/null
Binary files differ
diff --git a/art/reply.xpm b/art/reply.xpm
deleted file mode 100644
index 681801c7d7..0000000000
--- a/art/reply.xpm
+++ /dev/null
@@ -1,46 +0,0 @@
-/* XPM */
-static char * reply_xpm[] = {
-"16 16 27 1",
-" c None",
-". c #010101",
-"+ c #2F2F2F",
-"@ c #A7A4A0",
-"# c #FCFCFC",
-"$ c #64625F",
-"% c #FFFFFF",
-"& c #5D5B57",
-"* c #868580",
-"= c #E5E2DB",
-"- c #FBFBF8",
-"; c #716E6B",
-"> c #000000",
-", c #FBFAF7",
-"' c #A5A29D",
-") c #990000",
-"! c #EFEFEF",
-"~ c #CCCCCC",
-"{ c #797873",
-"] c #7D7A77",
-"^ c #F7F5F1",
-"/ c #090808",
-"( c #D7D4CE",
-"_ c #D8D5CF",
-": c #7F0000",
-"< c #181818",
-"[ c #090909",
-" ",
-" ",
-" ",
-" .+......... ",
-" .@#########$. ",
-" .%&%%%%%%%*=. ",
-" .%-;%>>>>>>>>> ",
-" .%--;>%%%%%%%> ",
-" .%-,'>%))))!~> ",
-" .%,{->%)))!!~> ",
-" .%]-^>%))))!~> ",
-" ./(__>%)!)):~> ",
-" ....>%!!!::~> ",
-" >%~~~~~~< ",
-" >>[>>>>>> ",
-" "};
diff --git a/art/reply_to_all.xpm b/art/reply_to_all.xpm
deleted file mode 100644
index be5c633f2a..0000000000
--- a/art/reply_to_all.xpm
+++ /dev/null
@@ -1,52 +0,0 @@
-/* XPM */
-static char * reply_to_all_xpm[] = {
-"16 16 33 1",
-" c None",
-". c #010101",
-"+ c #2F2F2F",
-"@ c #A7A4A0",
-"# c #FCFCFC",
-"$ c #64625F",
-"% c #FFFFFF",
-"& c #5D5B57",
-"* c #868580",
-"= c #E5E2DB",
-"- c #FBFBF8",
-"; c #716E6B",
-"> c #62605C",
-", c #F8F7F2",
-"' c #DDDAD4",
-") c #F7F5F1",
-"! c #FBFAF7",
-"~ c #A5A29D",
-"{ c #000000",
-"] c #797873",
-"^ c #7D7A77",
-"/ c #FAF9F6",
-"( c #F8F6F2",
-"_ c #990000",
-": c #EFEFEF",
-"< c #CCCCCC",
-"[ c #090808",
-"} c #D7D4CE",
-"| c #D8D5CF",
-"1 c #D6D3CD",
-"2 c #7F0000",
-"3 c #181818",
-"4 c #090909",
-" ",
-" ",
-" .+......... ",
-".@#########$. ",
-".%&%%%%%%%*=.. ",
-".%-;%%%%%>,'.$. ",
-".%--;%%%;-)'.=. ",
-".%-!~;-{{{{{{{{{",
-".%!]--;{%%%%%%%{",
-".%^-)/({%____:<{",
-".[}|||1{%___::<{",
-" ......{%____:<{",
-" .[}||{%_:__2<{",
-" ....{%:::22<{",
-" {%<<<<<<3",
-" {{4{{{{{{"};
diff --git a/art/save-16.png b/art/save-16.png
deleted file mode 100644
index 20a27ca2a1..0000000000
--- a/art/save-16.png
+++ /dev/null
Binary files differ
diff --git a/art/save-24.png b/art/save-24.png
deleted file mode 100644
index 51375a3f40..0000000000
--- a/art/save-24.png
+++ /dev/null
Binary files differ
diff --git a/art/save-as-16.png b/art/save-as-16.png
deleted file mode 100644
index 3b9612efdf..0000000000
--- a/art/save-as-16.png
+++ /dev/null
Binary files differ
diff --git a/art/save.xpm b/art/save.xpm
deleted file mode 100644
index 7b1812943e..0000000000
--- a/art/save.xpm
+++ /dev/null
@@ -1,45 +0,0 @@
-/* XPM */
-static char * 16_save_xpm[] = {
-"16 16 26 1",
-" c None",
-". c #000000",
-"+ c #B8CADB",
-"@ c #C5D4E3",
-"# c #687B8D",
-"$ c #D8D8D8",
-"% c #CFDBE6",
-"& c #9DB8D2",
-"* c #728699",
-"= c #BCCEDF",
-"- c #FFFFFF",
-"; c #D2DEEA",
-"> c #C0D1E2",
-", c #CFDBE7",
-"' c #798EA3",
-") c #D0DDE9",
-"! c #B7CBDE",
-"~ c #B6CADD",
-"{ c #B7CADD",
-"] c #BACCDF",
-"^ c #9FB9D3",
-"/ c #7E94A9",
-"( c #A4BDD5",
-"_ c #BABABA",
-": c #556474",
-"< c #2A303A",
-" ",
-" ",
-" ............ ",
-" .+@#$$$$$$%&*. ",
-" .=&#------;&*. ",
-" .>&#$$$$$$,&*. ",
-" .>&'------)&*. ",
-" .>&&!~~{{]^&*. ",
-" .>&&&&&&&&&&*. ",
-" .>&&//////&&*. ",
-" .>(/$$_$-$/&*. ",
-" .>&/$_$-/$/&*. ",
-" .>&/$_-$/$/&*. ",
-" .=&/_$-$$$/**. ",
-" .:........<. ",
-" "};
diff --git a/art/schedule-meeting-16.png b/art/schedule-meeting-16.png
deleted file mode 100644
index 7081e2fead..0000000000
--- a/art/schedule-meeting-16.png
+++ /dev/null
Binary files differ
diff --git a/art/schedule-meeting-16.xpm b/art/schedule-meeting-16.xpm
deleted file mode 100644
index 7cc7911439..0000000000
--- a/art/schedule-meeting-16.xpm
+++ /dev/null
@@ -1,178 +0,0 @@
-/* XPM */
-static char * schedule_meeting_16_xpm[] = {
-"16 16 159 2",
-" c None",
-". c #000000",
-"+ c #8A8575",
-"@ c #EEDEA6",
-"# c #F0DD96",
-"$ c #EFDB95",
-"% c #AFA06B",
-"& c #655C38",
-"* c #0B0B0B",
-"= c #A49D83",
-"- c #F1DD97",
-"; c #F2E5B3",
-"> c #F3E9C1",
-", c #EBDEB0",
-"' c #B4A981",
-") c #C6C6C6",
-"! c #535353",
-"~ c #131313",
-"{ c #EFDE9F",
-"] c #F1E1AA",
-"^ c #F8F3D9",
-"/ c #FBF3D5",
-"( c #EAE1BE",
-"_ c #948D73",
-": c #161615",
-"< c #4D4D4D",
-"[ c #B7B7B7",
-"} c #655D53",
-"| c #56493A",
-"1 c #564838",
-"2 c #514433",
-"3 c #D9C993",
-"4 c #F8F1CF",
-"5 c #FDF7DB",
-"6 c #FAF3D3",
-"7 c #E6DCB9",
-"8 c #867F66",
-"9 c #2D2C2A",
-"0 c #978774",
-"a c #D5B792",
-"b c #D2B38D",
-"c c #C7A882",
-"d c #B39672",
-"e c #2B2824",
-"f c #EEE7CF",
-"g c #F4EBC9",
-"h c #FEF6D5",
-"i c #FBF2CD",
-"j c #E7DCB5",
-"k c #857D63",
-"l c #5A544D",
-"m c #B89F80",
-"n c #D8BA94",
-"o c #CAAB84",
-"p c #C2A27B",
-"q c #54493C",
-"r c #C5B887",
-"s c #E9E0BF",
-"t c #FAEFC8",
-"u c #FAEDC0",
-"v c #E5D8A9",
-"w c #887F5F",
-"x c #686158",
-"y c #BFA482",
-"z c #D2B38E",
-"A c #CEAF89",
-"B c #C7A781",
-"C c #C2A17A",
-"D c #726555",
-"E c #B6A977",
-"F c #CAC4AD",
-"G c #B0A47F",
-"H c #AEA277",
-"I c #4B473C",
-"J c #8F8A82",
-"K c #BDA382",
-"L c #CCAD87",
-"M c #C9A983",
-"N c #C4A47D",
-"O c #BE9E77",
-"P c #6E6A64",
-"Q c #495946",
-"R c #3D5146",
-"S c #32483E",
-"T c #0F0F05",
-"U c #77736D",
-"V c #988A79",
-"W c #C9AA86",
-"X c #B29573",
-"Y c #856F55",
-"Z c #69726C",
-"` c #A4D3C5",
-" . c #8DCDBA",
-".. c #7BBDA9",
-"+. c #376052",
-"@. c #15241E",
-"#. c #443C31",
-"$. c #403528",
-"%. c #3C3329",
-"&. c #5A6A63",
-"*. c #85C9B7",
-"=. c #75C1AB",
-"-. c #6AB89F",
-";. c #5FAE93",
-">. c #468A73",
-",. c #173128",
-"'. c #303030",
-"). c #9A9A9A",
-"!. c #C5D2DE",
-"~. c #B7C9DA",
-"{. c #667685",
-"]. c #23292F",
-"^. c #7A998C",
-"/. c #72B7A2",
-"(. c #7EBBA7",
-"_. c #5DB093",
-":. c #53A688",
-"<. c #3A7D65",
-"[. c #2E2E2E",
-"}. c #959799",
-"|. c #B7C9DB",
-"1. c #90ABC5",
-"2. c #89A5BF",
-"3. c #809DB7",
-"4. c #758FA7",
-"5. c #171E24",
-"6. c #749786",
-"7. c #549F85",
-"8. c #85B5A4",
-"9. c #4DA584",
-"0. c #449B7A",
-"a. c #2F745A",
-"b. c #BFCFDD",
-"c. c #7F96AB",
-"d. c #85A0BA",
-"e. c #7B97B1",
-"f. c #728FA9",
-"g. c #69849D",
-"h. c #404E5C",
-"i. c #6B927E",
-"j. c #49967A",
-"k. c #7EB09D",
-"l. c #409A78",
-"m. c #38916F",
-"n. c #277153",
-"o. c #ACBFD0",
-"p. c #687F95",
-"q. c #92A9BD",
-"r. c #6F8BA5",
-"s. c #66839D",
-"t. c #577188",
-"u. c #596774",
-"v. c #A1B5C6",
-"w. c #4F6376",
-"x. c #8FA4B7",
-"y. c #607D97",
-"z. c #57758F",
-"A. c #49657D",
-"B. c #5A6773",
-" . . . . . . ",
-" . + @ # $ % & . * . . . . ",
-". = - ; > , ' . ) ! ~ . . . . ",
-". { ] ^ / ( _ : < [ } | 1 2 . . ",
-". 3 4 5 6 7 8 . 9 0 a b c d e . ",
-". f g h i j k . l m n b o p q . ",
-". r s t u v w . x y z A B C D . ",
-" . E F G H I . J K L M N O P . ",
-" . Q R S T . U V W p X Y . . ",
-" . Z ` ...+.@.. . #.$.%.. ",
-". &.*.=.-.;.>.,.'.).!.~.{.].. ",
-". ^./.(._.:.<.[.}.|.1.2.3.4.5.. ",
-". 6.7.8.9.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.A.B.. ",
-" . . . . . . . . . "};
diff --git a/art/schedule-meeting-24.png b/art/schedule-meeting-24.png
deleted file mode 100644
index 237bac1f96..0000000000
--- a/art/schedule-meeting-24.png
+++ /dev/null
Binary files differ
diff --git a/art/score-high.xpm b/art/score-high.xpm
deleted file mode 100644
index bb7bd47562..0000000000
--- a/art/score-high.xpm
+++ /dev/null
@@ -1,26 +0,0 @@
-/* XPM */
-static char * score_high_xpm[] = {
-"16 16 7 1",
-" c None",
-". c #BCBCBC",
-"+ c #00FF00",
-"@ c #000000",
-"# c #17D1EA",
-"$ c #FFFFFF",
-"% c #EF9815",
-" ",
-" .+ ",
-" @@@ .++ ",
-" @#@#@ .++ ",
-" @$%$@ .++ ",
-" @$$$@ . + ",
-" @@$@@ . ",
-" @@$$$@@ . ",
-" @@$$$$$@@@@ ",
-" @@$$$$$@@ . ",
-" @@$$$$$@ . ",
-" @@$$$$$@ . ",
-" @$$$$$@ . ",
-" %%$%% . ",
-" %% %% . ",
-" "};
diff --git a/art/score-higher.xpm b/art/score-higher.xpm
deleted file mode 100644
index 696e74bed5..0000000000
--- a/art/score-higher.xpm
+++ /dev/null
@@ -1,26 +0,0 @@
-/* XPM */
-static char * score_higher_xpm[] = {
-"16 16 7 1",
-" c None",
-". c #BCBCBC",
-"+ c #00FF00",
-"@ c #000000",
-"# c #17D1EA",
-"$ c #FFFFFF",
-"% c #EF9815",
-" ",
-" .++ ",
-" @@@ .++++",
-" @#@#@ .++++",
-" @$%$@ .++++",
-" @$$$@ . ++",
-" @@$@@ . ",
-" @@$$$@@ . ",
-" @@$$$$$@@@@ ",
-" @@$$$$$@@ . ",
-" @@$$$$$@ . ",
-" @@$$$$$@ . ",
-" @$$$$$@ . ",
-" %%$%% . ",
-" %% %% . ",
-" "};
diff --git a/art/score-highest.xpm b/art/score-highest.xpm
deleted file mode 100644
index d8dab65079..0000000000
--- a/art/score-highest.xpm
+++ /dev/null
@@ -1,26 +0,0 @@
-/* XPM */
-static char * score_highest_xpm[] = {
-"16 16 7 1",
-" c None",
-". c #BCBCBC",
-"+ c #00FF00",
-"@ c #000000",
-"# c #17D1EA",
-"$ c #FFFFFF",
-"% c #EF9815",
-" ",
-" .++++",
-" @@@ .++++",
-" @#@#@ .++++",
-" @$%$@ .++++",
-" @$$$@ . ",
-" @@$@@ . ",
-" @@$$$@@ . ",
-" @@$$$$$@@@@ ",
-" @@$$$$$@@ . ",
-" @@$$$$$@ . ",
-" @@$$$$$@ . ",
-" @$$$$$@ . ",
-" %%$%% . ",
-" %% %% . ",
-" "};
diff --git a/art/score-low.xpm b/art/score-low.xpm
deleted file mode 100644
index e071741adc..0000000000
--- a/art/score-low.xpm
+++ /dev/null
@@ -1,26 +0,0 @@
-/* XPM */
-static char * score_low_xpm[] = {
-"16 16 7 1",
-" c None",
-". c #BCBCBC",
-"+ c #FF0000",
-"@ c #000000",
-"# c #17D1EA",
-"$ c #FFFFFF",
-"% c #EF9815",
-" ",
-" .+ ",
-" @@@ .++ ",
-" @#@#@ .++ ",
-" @$%$@ .++ ",
-" @$$$@ . + ",
-" @@$@@ . ",
-" @@$$$@@ . ",
-" @@$$$$$@@@@ ",
-" @@$$$$$@@ . ",
-" @@$$$$$@ . ",
-" @@$$$$$@ . ",
-" @$$$$$@ . ",
-" %%$%% . ",
-" %% %% . ",
-" "};
diff --git a/art/score-lower.xpm b/art/score-lower.xpm
deleted file mode 100644
index 74da90d670..0000000000
--- a/art/score-lower.xpm
+++ /dev/null
@@ -1,26 +0,0 @@
-/* XPM */
-static char * score_lower_xpm[] = {
-"16 16 7 1",
-" c None",
-". c #BCBCBC",
-"+ c #FF0000",
-"@ c #000000",
-"# c #17D1EA",
-"$ c #FFFFFF",
-"% c #EF9815",
-" ",
-" .++ ",
-" @@@ .++++",
-" @#@#@ .++++",
-" @$%$@ .++++",
-" @$$$@ . ++",
-" @@$@@ . ",
-" @@$$$@@ . ",
-" @@$$$$$@@@@ ",
-" @@$$$$$@@ . ",
-" @@$$$$$@ . ",
-" @@$$$$$@ . ",
-" @$$$$$@ . ",
-" %%$%% . ",
-" %% %% . ",
-" "};
diff --git a/art/score-lowest.xpm b/art/score-lowest.xpm
deleted file mode 100644
index 9beee1849f..0000000000
--- a/art/score-lowest.xpm
+++ /dev/null
@@ -1,26 +0,0 @@
-/* XPM */
-static char * score_lowest_xpm[] = {
-"16 16 7 1",
-" c None",
-". c #BCBCBC",
-"+ c #FF0000",
-"@ c #000000",
-"# c #17D1EA",
-"$ c #FFFFFF",
-"% c #EF9815",
-" ",
-" .++++",
-" @@@ .++++",
-" @#@#@ .++++",
-" @$%$@ .++++",
-" @$$$@ . ",
-" @@$@@ . ",
-" @@$$$@@ . ",
-" @@$$$$$@@@@ ",
-" @@$$$$$@@ . ",
-" @@$$$$$@ . ",
-" @@$$$$$@ . ",
-" @$$$$$@ . ",
-" %%$%% . ",
-" %% %% . ",
-" "};
diff --git a/art/score-normal.xpm b/art/score-normal.xpm
deleted file mode 100644
index 82b618cb8d..0000000000
--- a/art/score-normal.xpm
+++ /dev/null
@@ -1,24 +0,0 @@
-/* XPM */
-static char * score_normal_xpm[] = {
-"16 16 5 1",
-" c None",
-". c #000000",
-"+ c #17D1EA",
-"@ c #FFFFFF",
-"# c #EF9815",
-" ",
-" ",
-" ... ",
-" .+.+. ",
-" .@#@. ",
-" .@@@. ",
-" ..@.. ",
-" ..@@@.. ",
-" ..@@@@@.. ",
-" ..@@@@@.. ",
-" ..@@@@@.. ",
-" ..@@@@@.. ",
-" .@@@@@. ",
-" ##@## ",
-" ## ## ",
-" "};
diff --git a/art/search-16.png b/art/search-16.png
deleted file mode 100644
index 6e9837d8ee..0000000000
--- a/art/search-16.png
+++ /dev/null
Binary files differ
diff --git a/art/search-and-replace-16.png b/art/search-and-replace-16.png
deleted file mode 100644
index 5daa4c39a0..0000000000
--- a/art/search-and-replace-16.png
+++ /dev/null
Binary files differ
diff --git a/art/send-16.png b/art/send-16.png
deleted file mode 100644
index 4cf96ead39..0000000000
--- a/art/send-16.png
+++ /dev/null
Binary files differ
diff --git a/art/send-24-receive.png b/art/send-24-receive.png
deleted file mode 100644
index 1d3d4df420..0000000000
--- a/art/send-24-receive.png
+++ /dev/null
Binary files differ
diff --git a/art/send-24.png b/art/send-24.png
deleted file mode 100644
index 5c7e4a261e..0000000000
--- a/art/send-24.png
+++ /dev/null
Binary files differ
diff --git a/art/send-48-receive.png b/art/send-48-receive.png
deleted file mode 100644
index 53f8b15d9a..0000000000
--- a/art/send-48-receive.png
+++ /dev/null
Binary files differ
diff --git a/art/send-later-16.png b/art/send-later-16.png
deleted file mode 100644
index 3b2bb791d4..0000000000
--- a/art/send-later-16.png
+++ /dev/null
Binary files differ
diff --git a/art/send-receive.xpm b/art/send-receive.xpm
deleted file mode 100644
index f9ba82e5c8..0000000000
--- a/art/send-receive.xpm
+++ /dev/null
@@ -1,58 +0,0 @@
-/* XPM */
-static char * send_receive_xpm[] = {
-"16 16 39 1",
-" c None",
-". c #000000",
-"+ c #F7EFD0",
-"@ c #F7EFD1",
-"# c #EED680",
-"$ c #C38909",
-"% c #F6ECC9",
-"& c #D1940C",
-"* c #B98208",
-"= c #A59458",
-"- c #D1BC70",
-"; c #E9D17B",
-"> c #B07C08",
-", c #916608",
-"' c #F3E3A8",
-") c #AE7B0A",
-"! c #F4E4AD",
-"~ c #F5E9BC",
-"{ c #D8E6D2",
-"] c #B9C9B1",
-"^ c #6F9059",
-"/ c #C6B26A",
-"( c #D7E5D0",
-"_ c #AECCA1",
-": c #557C3B",
-"< c #D3E3CB",
-"[ c #D0E1C9",
-"} c #DBE7D6",
-"| c #B9C3B5",
-"1 c #BDCEB6",
-"2 c #A9C79C",
-"3 c #65894C",
-"4 c #748C64",
-"5 c #668154",
-"6 c #669447",
-"7 c #58833C",
-"8 c #E1EBDC",
-"9 c #5E8A41",
-"0 c #E0EADB",
-" . ",
-" .+. ",
-" .@#$. ",
-" .%##&*. ",
-".%=-;>,,. ",
-"...'#)... ",
-" .!#). ..... ",
-" .~#). .{]^. ",
-" .#/). .(_:. ",
-" ..... .<_:. ",
-" ...[_:...",
-" .}|12345.",
-" .}__67. ",
-" .8_9. ",
-" .0. ",
-" . "};
diff --git a/art/send.png b/art/send.png
deleted file mode 100644
index fb95df6016..0000000000
--- a/art/send.png
+++ /dev/null
Binary files differ
diff --git a/art/service-close.png b/art/service-close.png
deleted file mode 100644
index d8e7cea744..0000000000
--- a/art/service-close.png
+++ /dev/null
Binary files differ
diff --git a/art/service-configure.png b/art/service-configure.png
deleted file mode 100644
index 8c56dc4c7a..0000000000
--- a/art/service-configure.png
+++ /dev/null
Binary files differ
diff --git a/art/service-down-disabled.png b/art/service-down-disabled.png
deleted file mode 100644
index f6742ff105..0000000000
--- a/art/service-down-disabled.png
+++ /dev/null
Binary files differ
diff --git a/art/service-down.png b/art/service-down.png
deleted file mode 100644
index 49f532f527..0000000000
--- a/art/service-down.png
+++ /dev/null
Binary files differ
diff --git a/art/service-left-disabled.png b/art/service-left-disabled.png
deleted file mode 100644
index fc4256346b..0000000000
--- a/art/service-left-disabled.png
+++ /dev/null
Binary files differ
diff --git a/art/service-left.png b/art/service-left.png
deleted file mode 100644
index 38fe293e39..0000000000
--- a/art/service-left.png
+++ /dev/null
Binary files differ
diff --git a/art/service-right-disabled.png b/art/service-right-disabled.png
deleted file mode 100644
index 848c2a499c..0000000000
--- a/art/service-right-disabled.png
+++ /dev/null
Binary files differ
diff --git a/art/service-right.png b/art/service-right.png
deleted file mode 100644
index 7fdabac13d..0000000000
--- a/art/service-right.png
+++ /dev/null
Binary files differ
diff --git a/art/service-up-disabled.png b/art/service-up-disabled.png
deleted file mode 100644
index 6258caa5d9..0000000000
--- a/art/service-up-disabled.png
+++ /dev/null
Binary files differ
diff --git a/art/service-up.png b/art/service-up.png
deleted file mode 100644
index a24b336c6d..0000000000
--- a/art/service-up.png
+++ /dev/null
Binary files differ
diff --git a/art/show_all_messages.xpm b/art/show_all_messages.xpm
deleted file mode 100644
index f38a42aebf..0000000000
--- a/art/show_all_messages.xpm
+++ /dev/null
@@ -1,27 +0,0 @@
-/* XPM */
-static char * show_all_messages_xpm[] = {
-"16 16 8 1",
-" c None",
-". c #000000",
-"+ c #9DB8D2",
-"@ c #FFFFFF",
-"# c #89A1B9",
-"$ c #859DB4",
-"% c #CACACA",
-"& c #8199AF",
-" ",
-" ",
-" ",
-" ",
-" . . ",
-" . . . .",
-" . . .",
-" ........... ",
-" .+@+. .+@+. ",
-" .#+$. .%+&. ",
-" ... ... ",
-" ",
-" ",
-" ",
-" ",
-" "};
diff --git a/art/splash-1-0.png b/art/splash-1-0.png
deleted file mode 100644
index 13dabfd980..0000000000
--- a/art/splash-1-0.png
+++ /dev/null
Binary files differ
diff --git a/art/splash.png b/art/splash.png
deleted file mode 100644
index 4e98b8298c..0000000000
--- a/art/splash.png
+++ /dev/null
Binary files differ
diff --git a/art/summary-settings.png b/art/summary-settings.png
deleted file mode 100644
index 011d94ac0a..0000000000
--- a/art/summary-settings.png
+++ /dev/null
Binary files differ
diff --git a/art/summary_preferences-16.png b/art/summary_preferences-16.png
deleted file mode 100644
index 4a318c2fd1..0000000000
--- a/art/summary_preferences-16.png
+++ /dev/null
Binary files differ
diff --git a/art/talking-heads.png b/art/talking-heads.png
deleted file mode 100644
index 1c2ba5b040..0000000000
--- a/art/talking-heads.png
+++ /dev/null
Binary files differ
diff --git a/art/task-assigned-to.xpm b/art/task-assigned-to.xpm
deleted file mode 100644
index d60eeafa2d..0000000000
--- a/art/task-assigned-to.xpm
+++ /dev/null
@@ -1,30 +0,0 @@
-/* XPM */
-static char * task_assigned_to_xpm[] = {
-"16 16 11 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #F3F3F3",
-"# c #CCCCCC",
-"$ c #B2B2B2",
-"% c #ECECEC",
-"& c #ABCCAB",
-"* c #768E76",
-"= c #5E705E",
-"- c #EEEEEE",
-" . . . . . ",
-" ........... ",
-" .+.+.+.+.+.@. ",
-" .+.#.#.#.#.$. ",
-" .+%%%%%%%%%$. ",
-" .+#######..$. ",
-" .+%%%%%%%.&.. ",
-" .+##......&&. ",
-" .+%%.&&&&&&&&. ",
-" .+##.&*&*&*&*&.",
-" .+%%.========. ",
-" .+##......==. ",
-" .+%%%%%%%.=.. ",
-" .-$$$$$$$..$. ",
-" ........... ",
-" "};
diff --git a/art/task-assigned.xpm b/art/task-assigned.xpm
deleted file mode 100644
index 9b245c0c49..0000000000
--- a/art/task-assigned.xpm
+++ /dev/null
@@ -1,30 +0,0 @@
-/* XPM */
-static char * task_assigned_xpm[] = {
-"16 16 11 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #F3F3F3",
-"# c #CCCCCC",
-"$ c #B2B2B2",
-"% c #ECECEC",
-"& c #FFCC66",
-"* c #CC9933",
-"= c #996600",
-"- c #EEEEEE",
-" . . . . . ",
-" ........... ",
-" .+.+.+.+.+.@. ",
-" .+.#.#.#.#.$. ",
-" .+%%%%%%%%%$. ",
-" .+##..#####$. ",
-" .+%%.&.%%%%$. ",
-"......&&.###$. ",
-".&&&&&&&&.%%$. ",
-".&*&*&*&*&.#$. ",
-".========.%%$. ",
-"......==.###$. ",
-" .+%%.=.%%%%$. ",
-" .-$$..$$$$$$. ",
-" ........... ",
-" "};
diff --git a/art/task-recurring.xpm b/art/task-recurring.xpm
deleted file mode 100644
index 634cd87a84..0000000000
--- a/art/task-recurring.xpm
+++ /dev/null
@@ -1,59 +0,0 @@
-/* XPM */
-static char * task_recurring_xpm[] = {
-"16 16 40 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #F3F3F3",
-"# c #CCCCCC",
-"$ c #B2B2B2",
-"% c #ECECEC",
-"& c #BFBFC3",
-"* c #A2A2B0",
-"= c #454572",
-"- c #9898A9",
-"; c #85859C",
-"> c #333366",
-", c #4F4F79",
-"' c #B3B3C3",
-") c #A3A3B7",
-"! c #9696AD",
-"~ c #464672",
-"{ c #7F7F99",
-"] c #C9C9CA",
-"^ c #3D3D6D",
-"/ c #3B3B6B",
-"( c #A4A4B8",
-"_ c #B5B5C4",
-": c #D1D1D8",
-"< c #9191A4",
-"[ c #B5B5BD",
-"} c #9F9FAE",
-"| c #4A4A76",
-"1 c #40406F",
-"2 c #E9E9E9",
-"3 c #8F8FA9",
-"4 c #9D9DAC",
-"5 c #9090A4",
-"6 c #55557F",
-"7 c #ADADBE",
-"8 c #484875",
-"9 c #B9B9C7",
-"0 c #DCDCE0",
-"a c #EEEEEE",
-" . . . . . ",
-" ........... ",
-" .+.+.+.+.+.@. ",
-" .+.#.#.#.#.$. ",
-" .+%%%%%%%%%$. ",
-" .+&*=-#;>>,$. ",
-" .+'>)%%!>>'$. ",
-" .+~{]##;^/~$. ",
-" .+>(%%%_:(>$. ",
-" .+><[}###<>$. ",
-" .+|^1!%%23|$. ",
-" .+4>>;##5>4$. ",
-" .+6>>!%7890$. ",
-" .a$$$$$$$$$$. ",
-" ........... ",
-" "};
diff --git a/art/task.png b/art/task.png
deleted file mode 100644
index 5b3c7b7534..0000000000
--- a/art/task.png
+++ /dev/null
Binary files differ
diff --git a/art/task.xpm b/art/task.xpm
deleted file mode 100644
index 4a53c3e9ab..0000000000
--- a/art/task.xpm
+++ /dev/null
@@ -1,27 +0,0 @@
-/* XPM */
-static char * task_xpm[] = {
-"16 16 8 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #F3F3F3",
-"# c #CCCCCC",
-"$ c #B2B2B2",
-"% c #ECECEC",
-"& c #EEEEEE",
-" . . . . . ",
-" ........... ",
-" .+.+.+.+.+.@. ",
-" .+.#.#.#.#.$. ",
-" .+%%%%%%%%%$. ",
-" .+#########$. ",
-" .+%%%%%%%%%$. ",
-" .+#########$. ",
-" .+%%%%%%%%%$. ",
-" .+#########$. ",
-" .+%%%%%%%%%$. ",
-" .+#########$. ",
-" .+%%%%%%%%%$. ",
-" .&$$$$$$$$$$. ",
-" ........... ",
-" "};
diff --git a/art/thankyou.png b/art/thankyou.png
deleted file mode 100644
index f08f553cc3..0000000000
--- a/art/thankyou.png
+++ /dev/null
Binary files differ
diff --git a/art/timezone-16.xpm b/art/timezone-16.xpm
deleted file mode 100644
index 6f3094a395..0000000000
--- a/art/timezone-16.xpm
+++ /dev/null
@@ -1,162 +0,0 @@
-/* XPM */
-static char * timezone_16_xpm[] = {
-"16 16 143 2",
-" c None",
-". c #000000",
-"+ c #2A2B2B",
-"@ c #020203",
-"# c #050709",
-"$ c #020202",
-"% c #7490B2",
-"& c #A6BDD4",
-"* c #C0D3E5",
-"= c #E6E7E6",
-"- c #C7CCC5",
-"; c #9BAC9F",
-"> c #030304",
-", c #010101",
-"' c #82848E",
-") c #80846B",
-"! c #7FA59B",
-"~ c #AECFE0",
-"{ c #C0D8EF",
-"] c #B4C4C2",
-"^ c #6A8B6C",
-"/ c #699678",
-"( c #51826F",
-"_ c #2D535E",
-": c #1C492A",
-"< c #5EA66A",
-"[ c #7BC280",
-"} c #67BA7A",
-"| c #7AC7A7",
-"1 c #B1D1EC",
-"2 c #94ADAF",
-"3 c #719177",
-"4 c #609996",
-"5 c #5B9583",
-"6 c #537762",
-"7 c #6E9874",
-"8 c #64A970",
-"9 c #6DBD77",
-"0 c #5FB565",
-"a c #5DAD6B",
-"b c #89BFF1",
-"c c #89BFF5",
-"d c #4C9DAB",
-"e c #459D82",
-"f c #55A395",
-"g c #557A5C",
-"h c #1A304E",
-"i c #74B678",
-"j c #5EB666",
-"k c #49A54F",
-"l c #4CA34F",
-"m c #90C4E4",
-"n c #7BB8F8",
-"o c #7FBCF8",
-"p c #49A09A",
-"q c #389B6F",
-"r c #81ACBF",
-"s c #617B65",
-"t c #5B735E",
-"u c #010202",
-"v c #7AAD6E",
-"w c #438C3D",
-"x c #6AA8A1",
-"y c #92C5F1",
-"z c #77B8F6",
-"A c #77B7F7",
-"B c #7BB7F2",
-"C c #5DA9BA",
-"D c #56A4A1",
-"E c #85B1D9",
-"F c #637679",
-"G c #586D86",
-"H c #040506",
-"I c #6B975F",
-"J c #749486",
-"K c #85BDD9",
-"L c #8FBFEF",
-"M c #82BBF4",
-"N c #82BAF2",
-"O c #84B9EE",
-"P c #71AFEE",
-"Q c #96ABBF",
-"R c #8AB7D4",
-"S c #668B77",
-"T c #557E74",
-"U c #040406",
-"V c #649D69",
-"W c #508B52",
-"X c #508074",
-"Y c #7EAEDD",
-"Z c #81BBF4",
-"` c #81B9F2",
-" . c #83B8EE",
-".. c #80ACD5",
-"+. c #908466",
-"@. c #64825C",
-"#. c #5C7F5A",
-"$. c #627F5C",
-"%. c #5C7677",
-"&. c #5C9D67",
-"*. c #5D9071",
-"=. c #617576",
-"-. c #7DB2E8",
-";. c #7EB4EA",
-">. c #7BB0E6",
-",. c #7698B8",
-"'. c #66855E",
-"). c #53885E",
-"!. c #51845C",
-"~. c #61825D",
-"{. c #3D362D",
-"]. c #0A1C14",
-"^. c #609D73",
-"/. c #68A879",
-"(. c #628E77",
-"_. c #7AAEE4",
-":. c #70A4DB",
-"<. c #72A7DD",
-"[. c #6997C6",
-"}. c #598860",
-"|. c #51835C",
-"1. c #638860",
-"2. c #07090A",
-"3. c #50716C",
-"4. c #6FA779",
-"5. c #5D8976",
-"6. c #7AA7D4",
-"7. c #73A5D7",
-"8. c #6495C7",
-"9. c #557FAB",
-"0. c #65855F",
-"a. c #5A875F",
-"b. c #558462",
-"c. c #778383",
-"d. c #7B98B4",
-"e. c #7CA0C3",
-"f. c #7397BD",
-"g. c #7D8FA0",
-"h. c #809980",
-"i. c #143325",
-"j. c #597658",
-"k. c #030505",
-"l. c #030404",
-" ",
-" . . + @ @ # ",
-" . $ % & * = - ; > , ",
-" . ' ) ! ~ { ] ^ / ( _ , ",
-" : < [ } | 1 2 3 4 5 6 $ ",
-" , 7 8 9 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 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 ` ...+.@.#.$.H ",
-" u %.&.*.=.-.;.>.,.'.).!.~.{. ",
-" ].^./.(._.:.<.[.}.|.1.2. ",
-" @ 3.4.5.6.7.8.9.0.a.b.> ",
-" @ H c.d.e.f.g.h.i.j. ",
-" u u k.> l.> ",
-" "};
diff --git a/art/timezone-48.png b/art/timezone-48.png
deleted file mode 100644
index 2222e6f903..0000000000
--- a/art/timezone-48.png
+++ /dev/null
Binary files differ
diff --git a/art/tree-expanded.xpm b/art/tree-expanded.xpm
deleted file mode 100644
index fc748953eb..0000000000
--- a/art/tree-expanded.xpm
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static char * tree_expanded_xpm[] = {
-"16 16 3 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-" ",
-" ",
-" ",
-" ",
-" ......... ",
-" .+++++++. ",
-" .+++++++. ",
-" .+++++++. ",
-" .+.....+. ",
-" .+++++++. ",
-" .+++++++. ",
-" .+++++++. ",
-" ......... ",
-" ",
-" ",
-" "};
diff --git a/art/tree-unexpanded.xpm b/art/tree-unexpanded.xpm
deleted file mode 100644
index 0dfb12a0a5..0000000000
--- a/art/tree-unexpanded.xpm
+++ /dev/null
@@ -1,22 +0,0 @@
-/* XPM */
-static char * tree_unexpanded_xpm[] = {
-"16 16 3 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-" ",
-" ",
-" ",
-" ",
-" ......... ",
-" .+++++++. ",
-" .+++.+++. ",
-" .+++.+++. ",
-" .+.....+. ",
-" .+++.+++. ",
-" .+++.+++. ",
-" .+++++++. ",
-" ......... ",
-" ",
-" ",
-" "};
diff --git a/art/undelete_message-16.png b/art/undelete_message-16.png
deleted file mode 100644
index 066cbfc99c..0000000000
--- a/art/undelete_message-16.png
+++ /dev/null
Binary files differ
diff --git a/art/wax-seal-broken.png b/art/wax-seal-broken.png
deleted file mode 100644
index 951f062dcc..0000000000
--- a/art/wax-seal-broken.png
+++ /dev/null
Binary files differ
diff --git a/art/wax-seal.png b/art/wax-seal.png
deleted file mode 100644
index 5b0ba63bff..0000000000
--- a/art/wax-seal.png
+++ /dev/null
Binary files differ
diff --git a/art/weekview.xpm b/art/weekview.xpm
deleted file mode 100644
index 869b9e722a..0000000000
--- a/art/weekview.xpm
+++ /dev/null
@@ -1,34 +0,0 @@
-/* XPM */
-static char * weekview_xpm[] = {
-"24 24 7 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #D8D8D4",
-"# c #F2F1ED",
-"$ c #919191",
-"% c #666666",
-"....................... ",
-".++++++++++@++++++++++. ",
-".+#..$.$###$#..$.$###$. ",
-".+#########$#########$. ",
-".+#########$#########$. ",
-".+#########$#########$. ",
-".+#########$#########$. ",
-".+$$$$$$$$$$$$$$$$$$$$. ",
-".+#..$.$###$#..$.$###$. ",
-".+#########$#########$. ",
-".+#########$#########$. ",
-".+#########$#########$. ",
-".+#########$#########$. ",
-".+$$$$$$$$$$$$$$$$$$$$. ",
-".+#..$.$###$#..$.$###$. ",
-".+#########$#########$. ",
-".+#########$#########$. ",
-".+#########$$$$$$$$$$$. ",
-".+#########$#..$.$###$. ",
-".+#########$#########$. ",
-".+#########$#########$. ",
-".@$$$$$$$$$%$$$$$$$$$%. ",
-"....................... ",
-" "};
diff --git a/art/work_offline.xpm b/art/work_offline.xpm
deleted file mode 100644
index b4c2cdc17f..0000000000
--- a/art/work_offline.xpm
+++ /dev/null
@@ -1,33 +0,0 @@
-/* XPM */
-static char * 16_work_offline_xpm[] = {
-"16 16 14 1",
-" c None",
-". c #424242",
-"+ c #212121",
-"@ c #737373",
-"# c #EFEFEF",
-"$ c #DEDEDE",
-"% c #CECECE",
-"& c #101010",
-"* c #8C8C8C",
-"= c #636363",
-"- c #ADADAD",
-"; c #9C9C9C",
-"> c #000000",
-", c #BDBDBD",
-" ",
-" ",
-" ",
-" .+++..@ ",
-" . ###$$%& ",
-" @#*=*-*=*%@ ",
-" .#;> %->;%+ ",
-" .$-> %->,%+ ",
-" .$;$#,;$ %+ ",
-" .$$ %+% #%& ",
-" @%-$@>@%-%. ",
-" .,;;;;-,. ",
-" @++++&. ",
-" ",
-" ",
-" "};
diff --git a/art/work_online-16.png b/art/work_online-16.png
deleted file mode 100644
index b11d36d277..0000000000
--- a/art/work_online-16.png
+++ /dev/null
Binary files differ
diff --git a/art/working-16.png b/art/working-16.png
deleted file mode 100644
index 5f12053a84..0000000000
--- a/art/working-16.png
+++ /dev/null
Binary files differ
diff --git a/art/workweekview.xpm b/art/workweekview.xpm
deleted file mode 100644
index 35cceedbdc..0000000000
--- a/art/workweekview.xpm
+++ /dev/null
@@ -1,34 +0,0 @@
-/* XPM */
-static char * workweekview_xpm[] = {
-"24 24 7 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #D8D8D4",
-"# c #B5B4AF",
-"$ c #666666",
-"% c #F2F1ED",
-"....................... ",
-".++++@+++@+++@+++@++++. ",
-".+###$###$###$###$###$. ",
-".+###$###$###$###$###$. ",
-".@$$$$$$$$$$$$$$$$$$$$. ",
-".++++#+++#+++#+++#+++#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".+%%%#%%%#%%%#%%%#%%%#. ",
-".@###$###$###$###$####. ",
-"....................... ",
-" "};
diff --git a/art/yearview.xpm b/art/yearview.xpm
deleted file mode 100644
index 0d4fa4135b..0000000000
--- a/art/yearview.xpm
+++ /dev/null
@@ -1,44 +0,0 @@
-/* XPM */
-static char * yearview_xpm[] = {
-"24 24 17 1",
-" c None",
-". c #000000",
-"+ c #FFFFFF",
-"@ c #F2F1ED",
-"# c #AAA9A6",
-"$ c #D7D6D2",
-"% c #92918E",
-"& c #B7B6B3",
-"* c #CBCAC6",
-"= c #919191",
-"- c #888785",
-"; c #B6B6B2",
-"> c #888884",
-", c #C1C1BD",
-"' c #A7A6A3",
-") c #D8D8D4",
-"! c #666666",
-"....................... ",
-".+++++++++++++++++++++. ",
-".+@@@@@@@#$%&*@@@@@@@=. ",
-".+@@@@@@@-;>,'@@@@@@@=. ",
-".+====================. ",
-".+@@@@@@@@@@@@@@@@@@@=. ",
-".+===@===@===@===@====. ",
-".+)=)@)=)@)=)@)=)@)=)=. ",
-".+=)=@=)=@=)=@=)=@=)==. ",
-".+@@@@@@@@@@@@@@@@@@@=. ",
-".+===@===@===@===@====. ",
-".+)=)@)=)@)=)@)=)@)=)=. ",
-".+=)=@=)=@=)=@=)=@=)==. ",
-".+@@@@@@@@@@@@@@@@@@@=. ",
-".+===@===@===@===@====. ",
-".+)=)@)=)@)=)@)=)@)=)=. ",
-".+=)=@=)=@=)=@=)=@=)==. ",
-".+@@@@@@@@@@@@@@@@@@@=. ",
-".+===@===@===@===@====. ",
-".+)=)@)=)@)=)@)=)@)=)=. ",
-".+=)=@=)=@=)=@=)=@=)==. ",
-".)===================!. ",
-"....................... ",
-" "};
diff --git a/autogen.sh b/autogen.sh
index eec4b5f56d..ab5aa84dd0 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -4,7 +4,23 @@
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
-PKG_NAME="evolution"
+PKG_NAME="Evolution"
+REQUIRED_AUTOCONF_VERSION=2.58
+REQUIRED_AUTOMAKE_VERSION=1.10
+REQUIRED_LIBTOOL_VERSION=2.2
+REQUIRED_INTLTOOL_VERSION=0.35.5
+(test -f $srcdir/configure.ac \
+ && test -f $srcdir/ChangeLog \
+ && test -d $srcdir/shell) || {
+ echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
+ echo " top-level $PKG_NAME directory"
+ exit 1
+}
-. $srcdir/macros/autogen.sh
+which gnome-autogen.sh || {
+ echo "You need to install gnome-common from the GNOME git"
+ exit 1
+}
+
+USE_GNOME2_MACROS=1 . gnome-autogen.sh
diff --git a/calendar/.cvsignore b/calendar/.cvsignore
deleted file mode 100644
index b7f7dea650..0000000000
--- a/calendar/.cvsignore
+++ /dev/null
@@ -1,6 +0,0 @@
-Makefile.in
-Makefile
-.deps
-_libs
-.libs
-*.lo
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
deleted file mode 100644
index b2d7b87ca5..0000000000
--- a/calendar/ChangeLog
+++ /dev/null
@@ -1,18035 +0,0 @@
-2002-10-11 JP Rosevear <jpr@ximian.com>
-
- * gui/gnome-cal.c
- (gnome_calendar_on_date_navigator_selection_changed): try to
- preserve the work week view setting if it makes sense
- (set_view): don't update the info again based on our view change
- call
-
-2002-10-08 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #11434
-
- * gui/dialogs/comp-editor-page.[ch]
- (comp_editor_page_display_validation_error): new function.
-
- * gui/dialogs/event-page.c (event_page_fill_component):
- * gui/dialogs/recurrence-page.c (fill_component):
- * gui/dialogs/task-details-page.c (task_details_page_fill_component):
- * gui/dialogs/task-page.c (task_page_fill_component): added
- checks for all date values, and return FALSE if we find
- some invalid date/times.
-
- * gui/dialogs/comp-editor.c (save_comp): activate the page that
- returns error in fill_component.
-
-2002-10-08 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/cal-prefs-dialog.c
- (cal_prefs_dialog_create_time_edit): set the 24 hour format
- initially
-
-2002-10-08 JP Rosevear <jpr@ximian.com>
-
- * gui/e-week-view.c: remove pilot settings from contextual menu
-
- * gui/e-day-view.c: ditto
-
-2002-10-07 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #31774
-
- * gui/dialogs/alarm-options.c (dalarm_widgets_to_alarm,
- palarm_widgets_to_alarm): use correct pointer in loop.
-
-2002-10-07 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/cal-prefs-dialog.c (setup_changes): cast the correct
- item
-
-2002-10-07 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes crash in #19159
-
- * gui/alarm-notify/alarm-queue.c (lookup_queued_alarm): don't crash if
- we don't find the queued alarm in the internal list.
- (alarm_trigger_cb, create_snooze, display_notification,
- audio_notification, procedure_notification, remove_queued_alarm):
- check return value from lookup_queued_alarm.
-
-2002-10-04 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #15892
-
- * idl/evolution-calendar.idl: added notifyErrorOccurred method to
- the Listener interface, so that backends can notify clients of errors
- that can't be reported otherwise.
-
- * pcs/cal.[ch] (cal_notify_error): new function.
-
- * pcs/cal-backend-file.c (save): made to save to temporary file and
- then moved to the correct file, so that we don't lose any data if
- there's a problem while saving.
- (notify_error): new function for notifying error messages to clients.
-
- * cal-client/cal-listener.[ch]: added new callback function for getting
- error messages from backends.
- (impl_notifyErrorOccurred): new method implementation.
- (cal_listener_class_init): initialize new epv member.
- (cal_listener_init, cal_listener_destroy, cal_listener_construct,
- cal_listener_new): initialize new function pointer.
-
- * cal-client/cal-client.[ch]: adapted to changes in CalListener class.
- (cal_client_class_init): added "backend_error" signal to CalClient class.
- (backend_error_cb): callback for "error_occurred" signal on the CalListener,
- which just emits the "backend_error" signal of CalClient.
-
- * gui/gnome-cal.c (gnome_calendar_construct): connect to "backend_error"
- signal on the CalClient's we create.
- (backend_error_cb): display error message on error from backend.
-
- * gui/e-tasks.c: likewise.
-
-2002-10-02 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/alarm-notify/notify-main.c (alarm_notify_factory_fn): removed
- unneeded g_assert which was preventing the alarm daemon to
- start correctly in some cases.
-
-2002-10-02 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #30057
-
- * cal-client/cal-client.c (cal_client_is_read_only): added check
- of the status of the client before trying to make CORBA calls.
-
- * gui/calendar-commands.c (sensitize_calendar_commands,
- sensitize_taskpad_commands):
- * gui/tasks-control.c (sensitize_commands):
- * gui/dialogs/event-editor.c (set_menu_sens):
- * gui/dialogs/task-editor.c (set_menu_sens):
- * gui/e-calendar-table.c (e_calendar_table_on_right_click):
- * gui/e-day-view.c (e_day_view_on_event_right_click):
- * gui/e-week-view.c (e_week_view_show_popup_menu): take into account
- the read-onlyness of clients to disable/enable menu items.
-
-2002-10-01 Rodrigo Moya <rodrigo@ximian.com>
-
- * idl/evolution-calendar.idl: added isReadOnly method to Cal
- interface.
-
- * pcs/cal.c (impl_Cal_is_read_only): new method implementation.
-
- * pcs/cal-backend.[ch]: added is_read_only method to CalBackend class.
- (cal_backend_is_read_only): new function.
-
- * pcs/cal-backend-file.c (cal_backend_file_is_read_only): new method.
- (cal_backend_file_class_init): set new signal's virtual method.
-
- * cal-client/cal-client.[ch] (cal_client_is_read_only): new function.
-
-2002-10-01 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #15710
-
- * gui/dialogs/alarm-page.c (alarm_page_init): added a
- X-EVOLUTION-NEEDS-DESCRIPTION property, so that we later set it
- correctly if it hasn't been set in the meanwhile (editing options for
- the alarm).
-
- * gui/dialogs/alarm-options.c (dalarm_widgets_to_alarm,
- palarm_widgets_to_alarm): removed X-EVOLUTION-NEEDS-DESCRIPTION
- property from alarms every time we set the description of the alarm.
-
-2002-10-01 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #30290
-
- * importers/icalendar-importer.c (process_item_fn): return a status of
- BUSY rather than NOT_READY, to avoid the display of the error message.
-
-2002-09-30 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c
- (calconduit_load_configuration): load multi_day_split
- (calconduit_save_configuration): save it
- (calconduit_dupe_configuration): copy it
- (e_cal_gui_new): create gui for it
- (e_cal_gui_fill_widgets): fill gui with value
- (e_cal_gui_fill_config): get value from gui and store in config
- (e_calendar_context_destroy): destroy new_cfg and gui properly
- (process_multi_day): skip item if its multi-day and we don't want
- to split
- (fill_widgets): fill local config widgets
- (create_settings_window): create local config widgets
- (save_settings): fill config from local widgets
-
- Fixes #23763
-
-2002-09-30 Aaron Weber <aaron@ximian.com>
-
- * gui/e-itip-control.c (update_item): adjust string on line 1609
- and 1517.
-
- * gui/dialogs/alarm-options.glade: rephrase string on line 270
-
-2002-09-27 Dan Winship <danw@ximian.com>
-
- * gui/calendar-commands.c (pixmaps): Remove "/Toolbar/New" and
- "/Toolbar/NewTask" since they're not there any more. Kills some
- bonobo-ui spewage.
-
-2002-09-26 Dan Winship <danw@ximian.com>
-
- Non-Connector part of #29334 (meeting created by a delegate in the
- delegator's calendar should have the delegator as Organizer).
-
- * idl/evolution-calendar.idl: add Cal_getEmailAddress, to return
- the email address associated with a backend (if any).
-
- * pcs/cal-backend.c (cal_backend_get_email_address): New.
-
- * pcs/cal-backend-file.c (cal_backend_file_get_email_address):
- Return NULL (for now).
-
- * pcs/cal.c (impl_Cal_get_email_address): Implement this by
- calling cal_backend_get_email_address and returning a NotFound
- exception if it returns NULL.
-
- * cal-client/cal-client.c (cal_client_get_email_address): New.
- (cal_client_init, cal_client_destroy, etc): initialize/free
- email_address
-
- * gui/dialogs/event-editor.c (event_editor_construct): Split this
- out of event_editor_init. Take and set a CalClient.
- (event_editor_new): Take a CalClient.
-
- * gui/dialogs/task-editor.c (task_editor_construct,
- task_editor_new): Likewise.
-
- * gui/dialogs/meeting-page.c (meeting_page_new,
- meeting_page_construct): Take a CalClient and call
- cal_client_get_email_address to find the default organizer
- address. (Also fix a bug if the default account's name has
- non-ASCII characters.)
-
- * gui/itip-utils.c (comp_from): New. When sending a REQUEST or
- CANCEL, use the Organizer as the From address.
- (itip_send_comp): Call comp_from and pass the result to
- Composer_setHeaders.
-
- * gui/comp-editor-factory.c (edit_existing, edit_new): Pass the
- CalClient to event_editor_new/task_editor_new
-
- * gui/e-calendar-table.c (open_task): Likewise.
-
- * gui/e-tasks.c (e_tasks_new_task): Likewise.
-
- * gui/gnome-cal.c (gnome_calendar_edit_object,
- gnome_calendar_new_task): Likewise.
-
-2002-09-26 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-model.c (set_value_at): only change the attendee
- value if it isn't empty
-
-2002-09-26 Rodrigo Moya <rodrigo@ximian.com>
-
- Should fix once for all #24210
-
- * idl/evolution-calendar.idl: changed the notifyObjUpdated method
- of the QueryListener interface accept a list of UIDs.
-
- * cal-client/query-listener.[ch] (impl_notifyObjUpdated): likewise for
- the QueryListener class.
-
- * cal-client/cal-query.c (obj_updated_cb): changed to adapt the
- multiple-id's received in the QueryListener class' signal to the
- one-by-one update notification of the public CalQuery class, thus
- keeping the changes needed for this minimal.
-
- * pcs/query.c (add_component, start_cached_query_cb): changed to
- send sequences of UIDs.
-
-2002-09-25 Dan Winship <danw@ximian.com>
-
- * gui/component-factory.c (folder_types): Add "calendar/public"
- and "tasks/public".
- (type_is_calendar, type_is_tasks): New utility functions
- (create_view, create_folder, remove_folder, xfer_folder,
- sc_user_create_new_item_cb): Use type_is_calendar/type_is_tasks
-
- * importers/icalendar-importer.c (get_uri_from_folder_path): allow
- importing into public calendar/task folders too.
-
- * gui/e-itip-control.c: Note that it's intentional that we use
- "calendar" and "tasks" here instead of "calendar/*" and "tasks/*".
- (31032)
-
-2002-09-25 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (itip_send_comp): if the item being sent is not
- a meeting, send it as a mixed item with a description and the
- calendar text in an attachment
-
- Fixes #30638
-
-2002-09-25 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #27961
-
- * pcs/cal-backend-file.c (cal_backend_file_update_object): set the
- LAST-MODIFIED time of the components when we save them.
-
-2002-09-24 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal-backend-file.c (cal_backend_file_get_timezone_object,
- cal_backend_file_get_timezone): return a builtin timezone if we
- don't find the timezone in our component.
-
-2002-09-24 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (comp_from_remote_record):
- make sure the start/end for no time palm events are DATE values,
- tidy code slightly
-
- Fixes #21631
-
-2002-09-24 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (process_multi_day):
- convert to date values if the original start and end were both
- dates
-
-2002-09-24 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-client/cal-query.c (cal_query_destroy): unref the query
- since now the query object on the server keeps a copy of it and
- must know when the listener is no longer valid.
-
- * pcs/query.c (listener_died_cb): unref the QueryListener object.
- (query_construct): create an EComponentListener for the non-cached
- queries' listeners also.
-
-2002-09-23 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/Makefile.am: add libeutil to the link
-
- * conduits/calendar/Makefile.am: ditto
-
-2002-09-23 Dan Winship <danw@ximian.com>
-
- * pcs/cal.c (imple_Cal_update_objects, impl_Cal_remove_object):
- fix non-ANSI switch statements.
-
- * gui/e-meeting-model.c (is_cell_editable, value_is_empty,
- process_free_busy_comp): Likewise
-
- * gui/itip-utils.c (comp_compliant): Likewise.
-
-2002-09-23 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/main.c (launch_alarm_daemon): install an idle callback that will
- start the alarm daemon.
- (launch_alarm_daemon_cb): actually activate the alarm daemon here.
-
- * pcs/query.c (start_cached_query_cb): remove timeout function always
- and re-add it if the query is in progress.
-
-2002-09-23 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/query.c (start_cached_query_cb): move success notification code
- to its own code block, since it was being run for parse errors also.
- Also, remove all traces of the query from the cache if there is an
- error. Also, use GINT_TO_POINTER instead of GPOINTER_TO_INT.
-
-2002-09-23 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #28310
-
- * gui/alarm-notify/save.c (save_notification_time): only save the
- new notification time if it is bigger than the already saved one.
- This should avoid some reminders showing up twice.
-
-2002-09-20 JP Rosevear <jpr@ximian.com>
-
- * gui/comp-util.c (cal_comp_is_on_server): check to see if the
- component is already on the server or not
-
- * gui/comp-util.h: change proto
-
- * gui/e-week-view.c (e_week_view_on_editing_stopped): only delete
- the event if the summary is empty and the component is not already
- on the server
-
- * gui/e-day-view.c (e_day_view_on_editing_stopped): same
-
- Fixes #14111
-
-2002-09-20 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/meeting-page.c (meeting_page_fill_widgets): set the
- deleted attendees array to size 0 after we clean it up
-
- Fixes #30479
-
-2002-09-20 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/query.c (parse_sexp): remove the query from the cache if it
- failed.
- (start_cached_query_cb): notify of errors in the query.
-
-2002-09-19 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/query.c: added a list of EComponentListener's to control the
- lifetime of the listeners.
- (query_init): initialize new member.
- (query_destroy): free new member.
- (start_cached_query_cb): create a EComponentListener for the new
- listener being added.
-
-2002-09-19 Rodrigo Moya <rodrigo@ximian.com>
-
- More fixes for #24210
-
- * pcs/query.c: added list of cached queries and changed the Query
- class to work with several listeners, not only one.
- (query_init): initialize new members.
- (query_destroy): free new members.
- (add_component, remove_component, parse_sexp, match_component,
- process_components_cb): notify all listeners.
- (notify_uid_cb, start_cached_query_cb): implemented integration of
- cached queries.
- (query_new): search the query in the cache before creating a new
- one. And if we create a new one, store it in the cache.
-
-2002-09-19 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/recurrence-page.c (simple_recur_to_comp): bump the
- month_num by 1 because it indexs at 0
- (recurrence_page_fill_widgets): lower the month_num by one as above
-
- Fixes #30381
-
-2002-09-17 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #26362
-
- * gui/e-itip-control.c (show current): add a default reminder if
- default reminders are set in the configuration.
-
-2002-09-11 JP Rosevear <jpr@ximian.com>
-
- * gui/e-day-view.c (e_day_view_on_top_canvas_button_press): keep
- the selection if we right click in it (but not on an appointment)
- (e_day_view_on_main_canvas_button_press): ditto
-
- * gui/e-week-view.c (e_week_view_on_button_press): same
-
-2002-09-11 JP Rosevear <jpr@ximian.com>
-
- * gui/e-week-view.c (e_week_view_new_appointment): create a new
- appointment based on the selection
- (e_week_view_on_button_press): use above
- (e_week_view_on_new_appointment): ditto
- (e_week_view_on_new_meeting): ditto
-
- Fixes #18162
-
-2002-09-10 JP Rosevear <jpr@ximian.com>
-
- * gui/comp-editor-factory.c (get_default_event): duh, don't
- blindly increment the hour without adjusting for the day
- boundaries
-
- Fixes #29983
-
-2002-09-10 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #24032
-
- * gui/e-itip-control.c (init): don't get servers here, since we don't
- know the type of the component(s) to be loaded.
- (show_current): get servers here.
- (destroy): only free stuff that needs to be freed.
-
-2002-09-09 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/gnome-cal.c (client_cal_opened_cb): display status messages for
- all operations we make, so that when using remote slow backends, so
- that users have always indication of what's happening.
-
-2002-09-06 JP Rosevear <jpr@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_edit_object): kill warning
-
- * gui/e-week-view.h: new proto
-
- * gui/e-week-view.c (e_week_view_set_selected_time_range_visible):
- select a range of time in the currently visible area, if out side
- the visible area, select as much as possible
- (e_week_view_on_text_item_event): call above
-
- * gui/e-week-view-event-item.c
- (e_week_view_event_item_button_press): call above
-
- * gui/e-day-view.c
- (e_day_view_set_selected_time_range_in_top_visible): select a
- range of time in the currently visible area, if out side the
- visible area, select as much as possible
- (e_day_view_set_selected_time_range_visible): the same for the
- main canvas
- (e_day_view_on_long_event_button_press): call above
- (e_day_view_on_event_button_press): ditto
-
-2002-09-05 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (itip_send_comp): don't try to send via the
- server if we are publishing; don't bail out on a 0 length to list
- if we are publishing
-
-2002-09-05 Anna Marie Dirks <anna@ximian.com>
-
- * gui/GNOME_Evolution_Calendar.oaf.in: Changed the description of
- the calendar/tasks page of the settings dialog, to be hopefully
- more descriptive and less awkwardly worded.
-
-
-2002-09-05 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view.c (e_day_view_on_drag_data_get): added support for
- text/x-calendar targets, in which case a VCALENDAR component, with
- full timezone information is returned.
-
-2002-09-04 JP Rosevear <jpr@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_destroy): don't listen to client
- signals after we get destroyed
-
- Fixes #17036
-
-2002-09-04 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/event-editor.c (event_editor_send_comp): bail out if
- we couldn't send the cancel
-
- * gui/dialogs/task-editor.c (task_editor_send_comp): ditto
-
- * gui/dialogs/comp-editor.c (save_comp_with_send): indicate send
- status
- (real_send_comp): return success/fail, only resave the component a
- if we successfully sent
- (comp_editor_send_comp): return success/fail
-
- * gui/itip-utils.h: update proto
-
- * gui/itip-utils.c (itip_send_comp): return true if we sent the
- message
-
-2002-09-04 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (comp_server_send): provide error message
- param, give a dialog with the message if we get a busy result;
- return TRUE if we succeed
- (itip_send_comp): bail out if we had a problem sending via the
- server
-
- * cal-client/cal-client.c (cal_client_send_object): pass back
- error message if we get the busy exception in the new param
-
- * cal-client/cal-client.h: update proto
-
- * pcs/cal.c (impl_Cal_send_object): dump backend error message
- into Busy exception
-
- * pcs/cal-backend.h: update proto
-
- * pcs/cal-backend.c (cal_backend_send_object): take/pass new error
- message parameter
-
- * pcs/cal-backend-file.c (cal_backend_file_send_object): take new param
-
- * idl/evolution-calendar.idl: add errorMsg to Busy exception
-
-2002-09-04 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c (create_object): Pass NULL as
- @unpopulate_folder_context_menu_fn to
- evolution_shell_component_new().
-
-2002-09-03 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (comp_compliant): don't make the reply
- component minimal
-
- Fixes #28956
-
-2002-08-30 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (itip_send_comp): make the sure to list is 0
- length before sending via imip
-
- Fixes #29624
-
-2002-08-30 Mike Kestner <mkestner@ximian.com>
-
- * gui/dialogs/event-page.c:
- * gui/dialogs/task-page.c: use bonobo_object_release_unref to release
- the remote SelectNames component, not CORBA_Object_release.
-
-2002-08-29 JP Rosevear <jpr@ximian.com>
-
- * gui/e-day-view.c (e_day_view_on_top_canvas_button_press): select
- the top canvas if the user right-clicks on it
- (e_day_view_on_main_canvas_button_press): select the row the user
- is right-clicking on
- (e_day_view_on_long_event_button_press): select the top canvas if
- the user right-clicks on an event there
- (e_day_view_on_event_button_press): select the relevant rows if
- the user right-clicks on an event
- (e_day_view_set_selected_time_range_in_top): select a number of
- days in the top canvas
-
- * gui/e-week-view.c (e_week_view_on_button_press): select the day
- the user is right-clicking on
- (e_week_view_on_text_item_event): select the corresponding time
- range when showing the contextual menu for an event
-
- * gui/e-week-view-event-item.c
- (e_week_view_event_item_button_press): select the corresponding
- time range when showing the contextual menu for an event
-
- Fixes #14660
-
-2002-08-28 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view.c:
- * gui/e-week-view.c: added missing header file.
-
-2002-08-28 Dan Winship <danw@ximian.com>
-
- * gui/GNOME_Evolution_Calendar.oaf.in: Add an
- evolution:shell_component_launch_order and rename
- evolution:shell_component_icon.
-
-2002-08-27 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/calendar-config.c: use EConfigListener instead of direct access
- to the bonobo-conf database.
- (calendar_config_init): create the EConfigListener here, and install
- an atexit function to unref the config listener object.
- (config_read, property_change_cb, calendar_config_write,
- calendar_config_write_on_exit): removed unneeded functions.
- (calendar_config_get_*, calendar_config_set_*): changed to make use of
- EConfigListener directly.
-
- * gui/main.c (main): removed call to calendar_config_write_on_exit.
-
- * gui/dialogs/cal-prefs-dialog.c (update_config): removed call to
- calendar_config_write.
-
-2002-08-26 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #12326
-
- * gui/alarm-notify/config-data.c (ensure_inited): create a
- EConfigListener for configuration access.
- (do_cleanup): g_atexit installed function, to clean up configuration
- database resources.
- (config_data_get_timezone): retrieve the configuration for the
- EConfigListener object.
- (config_data_get_listener): new function.
-
- * gui/alarm-notify/save.c (get_config_db, discard_config_db): removed.
- Use EConfigListener instead.
- (save_notification_time, get_saved_notification_time,
- save_calendars_to_load, get_calendars_to_load, save_blessed_program,
- is_blessed_program): use EConfigListener.
-
- * gui/alarm-notify/notify-main.c (init_alarm_notify_service): removed.
- (alarm_notify_factory_fn): create here the alarm_notify_service if it
- hasn't been created yet.
- (load_calendars): likewise.
- (main): don't call init_alarm_notify_service.
-
-2002-08-22 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-model.c (process_section): if its a
- non-participant, add it as a resource to match dialog label
- (set_value_at): if the type is set to be a resource, switch the
- role to non-participant by default
-
-2002-08-22 JP Rosevear <jpr@ximian.com>
-
- * gui/calendar-model.c (set_completed): if the value given is a
- date, convert to a time in the current zone
-
-2002-08-20 JP Rosevear <jpr@ximian.com>
-
- * gui/tasks-control.c (tasks_control_activate): don't set the
- tasks ui component until the container is set, remove unused
- pixmaps
-
-2002-08-19 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-model.c (destroy): disconnect destroy signal
- callbacks on tables
-
- Fixes #28231
-
-2002-08-19 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (comp_toplevel_with_zones): clone the ical
- component before adding it
-
- Fixes #29061
-
-2002-08-19 JP Rosevear <jpr@ximian.com>
-
- * gui/comp-editor-factory.c (get_default_event): make sure to get
- the date in the current zone, not at UTC
-
- Fixes #17692
-
-2002-08-19 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (set_date_label): stop adding redundant
- information for start/end/due/complete times
- (write_html): convert newlines properly and escape characters for
- summary, location, description; put text information on separate
- line from bolded title to make it look nicer when there are line
- breaks
-
- Fixes #26964
-
-2002-08-16 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-client/cal-client.[ch]: added internal EComponentListener
- object, to listen for the activated Cal.
- (cal_client_class_init): added "backend_died" signal.
- (cal_client_destroy): clean up component listener.
- (backend_died_cb): new callback for getting signals from the
- EComponentListener.
- (cal_opened_cb): setup component listener.
-
- * cal-client/Makefile.am: added libetuil to needed LIBS.
-
- * gui/gnome-cal.c (backend_died_cb): new callback.
- (gnome_calendar_construct): connect to "backend_died" signal
- on all CalClient's we create.
-
-2002-08-14 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/cal-prefs-dialog.c (init_widgets): listen for the
- time editors to change
- (cal_prefs_dialog_start_of_day_changed): make sure the start is
- never after the end
- (cal_prefs_dialog_end_of_day_changed): make sure the end is never
- after the start
-
- * gui/e-meeting-time-sel.c
- (e_meeting_time_selector_set_working_hours): make sure to show a
- minimum of 1 hour for work day
-
- * gui/e-day-view-main-item.c (e_day_view_main_item_draw):
- calculate the work/not working color boxes to the nearest pixel,
- rather the the nearest time division
-
- Fixes #10286, #26285
-
-2002-08-13 Dan Winship <danw@ximian.com>
-
- * gui/e-itip-control.c: Remove a bunch of old #if 0 code.
- (update_item): Set X-MICROSOFT-CDO-REPLYTIME here.
-
- * gui/itip-utils.c (comp_toplevel_with_zones): Don't set it here.
-
- * cal-util/cal-component.c (ensure_mandatory_properties): Use
- icaltime_current_time_with_zone rather than rolling our own.
- (cal_component_strip_errors): Remove unused variable.
-
-2002-08-13 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_open): set status message on
- ECalendarTable when opening the tasks.
- (client_cal_opened_cb): set ECalendarTable status message to NULL
- when we open the tasks folder. Also, clear up calendar status message
- in all cases, not only if the folder was opened successfully.
-
-2002-08-13 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_open): set status message to NULL
- if there is an error opening the calendar.
- (client_cal_opened_cb): set status message to NULL only when we have
- successfully opened the main CalClient.
-
-2002-08-09 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/comp-editor.c (real_send_comp): set the editor to
- changed so the item actually gets saved
-
-2002-08-08 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (users_has_attendee): check for an attendee in
- the list
- (comp_to_list): only add the user if they aren't on the list
- (comp_server_send): don't remove the users, pass back the list
- (itip_send_comp): send to server before doing comp_minimal
-
- * gui/dialogs/comp-editor.c (real_send_comp): edit and save the
- updated comp
-
- * pcs/cal.c (impl_Cal_send_object): copy the correct item to pass
- back
-
-2002-08-08 Dan Winship <danw@ximian.com>
-
- * pcs/query-backend.c (query_backend_new): Initialize
- loaded_backends before using it. (Just kills off a harmless
- g_warning.)
-
-2002-08-08 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #15710
-
- * cal-util/cal-component.[ch]
- (cal_component_alarm_get_icalcomponent): new function for getting
- the icalcomponent from a CalComponentAlarm.
-
- * gui/comp-util.c (cal_comp_event_new_with_defaults): added
- X-EVOLUTION-NEEDS-DESCRIPTION property to the default reminder
- alarm, so that we can identify it when saving the component.
-
- * gui/dialogs/alarm-page.c (alarm_page_fill_component): if the
- alarm has the X-EVOLUTION-NEEDS-DESCRIPTION property, set the
- description to be the same as of the component.
-
-2002-08-07 JP Rosevear <jpr@ximian.com>
-
- * pcs/cal-backend-file.c (cal_backend_file_send_object): just
- return the object untouched since we don't send anything
-
- * pcs/cal-backend.c (cal_backend_remove_object): call virtual method
-
- * pcs/cal-backend.h: add send result codes, new proto
-
- * pcs/cal.c (impl_Cal_send_object): implement sendObject corba call
- (cal_class_init): add to epv
-
- * gui/itip-utils.c (comp_toplevel_with_zones): utility function to
- create icalcomponent with necessary timezone info
- (comp_has_attendee): see if attendee is in the attendee list
- (comp_server_send): use above and remove attendees if the server
- sends them
-
- * gui/e-itip-control.c (show_current_todo): remove unused var
-
- * idl/evolution-calendar.idl: add Busy exception and
-
- * cal-client/cal-client.c (cal_client_send_object): send object
- via the server (if the server can)
-
- * cal-client/cal-client.h: add send results and new proto
-
-2002-08-05 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/query-backend.[ch] (query_backend_get_object_component): new
- function.
- (query_backend_get_uids): new function.
- (query_backend_new): create the static GHashTable if it hasn't been
- created yet.
- (query_backend_destroy): destroy the static GHashTable if empty.
- (foreach_uid_cb): call object_updated_cb, which does everything.
-
- * pcs/query.c: make use of the new QueryBackend class.
- (query_init): initialize new private structure member.
- (query_destroy): clean up new member, without freeing it, since it is
- managed internally in query-backend.c.
- (query_construct): create a QueryBackend for the query.
-
-2002-08-04 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes the crash in #19159
-
- * gui/alarm-notify/alarm-queue.c (create_snooze): check for NULL
- pointers before using them.
-
-2002-08-02 JP Rosevear <jpr@ximian.com>
-
- * gui/e-week-view.c (e_week_view_init): don't warn if we can't use
- the small font, just set use_small_font to FALSE
-
-2002-08-02 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (adjust_item): new util function to add
- information to an itip message that might not already be there for
- display purposes (summary, location, etc)
- (show_current_event): use above
- (show_current_todo): ditto
-
-2002-08-02 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-model.c (init): initialize value to corba nil
-
-2002-08-01 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c (create_object): Use
- meeting-request-16.png instead of meeting-request.png.
-
- * gui/calendar-commands.c (pixmaps): Remove pixmaps in
- /menu/File/New/NewFirstItem/.
-
-2002-08-01 JP Rosevear <jpr@ximian.com>
-
- * gui/calendar-model.c (is_overdue): use get_due_status
- (get_color): ditto
- (get_due_status): utility function to reduce replicated code,
- handle the case where the due date is just a date
-
-2002-07-31 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/query-backend.[ch]: new class for implementing a backend cache
- for the calendar queries.
-
- * pcs/Makefile.am: added new files.
-
-2002-07-31 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c (create_object): Change the order of the
- user creatable items a bit so that "New Appointment" and "New
- Meeting" are at the top when in a calendar folder.
-
-2002-07-31 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c (add_creatable_item): New arg
- @folder_type, pass it to
- evolution_shell_component_add_user_creatable_item().
- (create_object): Set the right folder types for the various
- user-creatable items.
-
-2002-07-31 JP Rosevear <jpr@ximian.com>
-
- * gui/e-tasks.c (e_tasks_destroy): we no longer need to manually
- save the state
- (e_tasks_open): we no longer need to manually load the state
- (display_view_cb): attach the gal view to the table
-
- Fixes #27894
-
-2002-07-29 JP Rosevear <jpr@ximian.com>
-
- * gui/e-day-view.c (e_day_view_find_work_week_start): make sure
- that the work week view goes to the current work week if the day
- selected is before the start of the work week
-
- Fixes #20317
-
-2002-07-28 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/dialogs/task-details-page.c: fixed mapping of popdown menu
- to ICAL_STATUS_ values.
- (task_details_page_fill_widgets): when we can't set the status,
- default to ICAL_STATUS_NONE, which maps to 'Not started'. Fixed
- use of 'percent' variable, which was being used after being freed.
- (percent_complete_changed): default to ICAL_STATUS_NONE (Not Started).
-
- * gui/dialogs/task-details-page.glade: added 'Needs Action' to
- popdown menu values.
-
-2002-07-26 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-util/cal-util.[ch] (cal_util_add_timezones_from_component):
- new function for adding VTIMEZONE components to a VCALENDAR
- component.
-
- * gui/e-calendar-table.c (copy_row_cb): added VTIMEZONE components
- to resulting VCALENDAR top-level component.
-
- * gui/e-week-view.c (e_week_view_copy_clipboard): copy to the
- clipboard a top-level VCALENDAR component, with all the needed
- VTIMEZONE components.
- (e_week_view_on_copy): likewise.
-
- * gui/e-day-view.c (e_day_view_copy_clipboard): likewise.
- (e_day_view_on_copy): likewise.
-
-2002-07-26 JP Rosevear <jpr@ximian.com>
-
- * cal-client/cal-client.c (cal_client_construct): remove useless
- debug statement
-
- Probably fixes #19333
-
-2002-07-26 JP Rosevear <jpr@ximian.com>
-
- * gui/comp-editor-factory.c (impl_editExisting): focus the editor
- if it does exist, create a new one if it doesn't (not vice-versa)
-
- Fixes #23468
-
-2002-07-25 JP Rosevear <jpr@ximian.com>
-
- * gui/e-day-view.c (e_day_view_init): set large_font to NULL
- (e_day_view_style_set): calculate large font, fall back to the
- style->font if necessary
-
- Fixes #11773
-
-2002-07-24 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (write_html): display the location in the
- itip information
-
- Fixes #24690
-
-2002-07-24 JP Rosevear <jpr@ximian.com>
-
- * gui/calendar-model.c (set_percent): set status to in progress if
- the percent is between 0 and 100
- (set_status): if the value is set to in process, change the
- percent to 50
-
- Fixes #1590
-
-2002-07-24 JP Rosevear <jpr@ximian.com>
-
- * cal-util/timeutil.c (time_day_of_year): add a day for the leap
- year only if we are currently counting Feb., not if the month
- passed in is Feb. Fixes #23446.
-
-2002-07-23 JP Rosevear <jpr@ximian.com>
-
- * gui/e-day-view.c (e_day_view_realize): use proper meeting icon
-
-2002-07-22 Dan Winship <danw@ximian.com>
-
- * pcs/Makefile.am: Split pcs-backend-file out of libpcs and build
- it as a separate (noinst) library libpcsfile.a. This gets the db3
- dependencies out of libpcs, and people trying to create a calendar
- backend shouldn't be calling functions from the existing backends
- anyway so there's no reason to install them.
-
- * cal-util/timeutil.c: Replace a bunch of old gnomecal functions
- with the functionally identical ones from Connector.
-
-2002-07-18 Rodrigo Moya <rodrigo@ximian.com>
-
- * importers/icalendar-importer.c (get_uri_from_folder_path): if
- there's an exception, continue with the next item.
-
-2002-07-08 Peter Williams <peterw@ximian.com>
-
- * cal-util/Makefile.am: Install libcal-util-static.la
- and fix the -all-static flag to make it install statically.
-
- * pcs/Makefile.am: Install libpcs.a and its headers.
-
- * pcs/cal-backend-util.h: Same sort of include namespacing fix,
- but for pcs.
-
- * pcs/cal.h:
- * pcs/query.h:
- * pcs/cal-factory.h:
- * pcs/cal-backend.h:
- * pcs/cal-backend-file.h: Same.
-
-2002-07-17 <jpr@ximian.com>
-
- * gui/calendar-model.c (calendar_model_value_at): use util
- function to see if the user is the organizer
-
- * gui/dialogs/cancel-comp.c (cancel_component_dialog): add
- deleting proto to indicate whether cancelling or deleting is the
- primary operation
-
- * gui/dialogs/cancel-comp.h: update proto
-
- * gui/dialogs/comp-editor.c (delete_cmd): offer to cancel
-
- * gui/dialogs/task-editor.c (cancel_task_cmd): call
- cancel_component_dialog with new param
-
- * gui/dialogs/event-editor.c (cancel_meeting_cmd): ditto
-
- * gui/e-week-view.c (e_week_view_on_editing_stopped): only update
- request if user is organizer
- (e_week_view_show_popup_menu): disable the meeting and meeting
- organizer mask if appropriate
- (e_week_view_delete_event_internal): offer to cancel the meeting
- (e_week_view_on_cut): ditto
- (selection_received): send request if its a meeting
-
- * gui/e-day-view.h: add meeting icon/mask
-
- * gui/e-day-view.c (e_day_view_on_event_right_click): disable the
- meeting and meeting organizer mask if appropriate
- (e_day_view_delete_event_internal): offer to cancel meeting
- (e_day_view_on_cut): ditto
- (e_day_view_finish_long_event_resize): only update request if user
- is organizer
- (e_day_view_reshape_long_event): add meeting icon to count
- (e_day_view_reshape_day_event): ditto
- (e_day_view_on_top_canvas_drag_data_received): only update request
- if user is organizer
- (e_day_view_on_main_canvas_drag_data_received): ditto
- (selection_received): offer to send meeting info
-
- * gui/e-day-view-main-item.c
- (e_day_view_main_item_draw_day_event): draw meeting icon if
- appropriate (using dummy icon atm)
-
-2002-07-14 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #8001
-
- * importers/icalendar-importer.c (connect_to_shell): new function for
- connecting the importers (both iCal and vCal) to the shell, needed for
- some information retrieval about the folders we're importing to.
- (ical_importer_new, vcal_importer_new): call connect_to_shell.
- (importer_destroy_cb): unref the shell client object.
- (get_uri_from_folder_path): retrieve the uri from the storage
- registry.
- (check_folder_type): removed.
-
- * importers/Makefile.am: included libeshell to LIBS.
-
-2002-07-12 Peter Williams <peterw@ximian.com>
-
- * pcs/cal.c: Sigh, fix for the wombat.idl -> Evolution-Wombat.idl
- rename here too. At least grep indicates that's all that needs to
- be fixed.
-
-2002-07-08 Peter Williams <peterw@ximian.com>
-
- * gui/Makefile.am (INCLUDES): Change the -I flags to get
- it to play nicely with the new Ebook header paradigm.
-
- * gui/dialogs/Makefile.am: Same.
-
- * gui/e-meeting-model.c: More of the same.
-
- * gui/dialogs/e-delegate-dialog.c:
- * gui/dialogs/e-meeting-model.c:
- * gui/dialogs/comp-editor-util.c: Fix include lines to get
- ebook headers.
-
- * pcs/Makefile.am: Same.
-
-2002-07-02 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #16034
-
- * gui/e-day-view.c (e_day_view_reshape_long_event):
- (e_day_view_reshape_day_event):
- * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event):
- * gui/e-week-view.c (e_week_view_reshape_event_span):
- * gui/e-week-view-event-item.c (e_week_view_event_item_draw_icons):
- Don't assume all categories have icons when allocating space for
- the icons.
-
-2002-07-02 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c (add_creatable_item): New arg @tooltip.
- Pass it to evolution_shell_component_add_user_creatable_item(),
- which now has a @tooltip arg.
- (create_object): Added tooltips.
-
-2002-07-01 JP Rosevear <jpr@ximian.com>
-
- * gui/calendar-config.c (config_read): listen for timezone config
- change
- (property_change_cb): set the timezone if it changed elsewhere
-
- * gui/main.c (init_bonobo): call bonobo_activate because we make
- bonobo related calls before the bonobo_main call
-
-2002-06-25 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes #25410
-
- * gui/alarm-notify.c (AlarmNotify_removeCalendar): do proper
- cleanup on removal of clients.
- (alarm_notify_add_calendar): ditto.
-
-2002-06-27 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (comp_compliant): plug leak and actually use
- the minimal comp we create
-
-2002-06-25 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/comp-editor-page.h: add back proto
-
- * gui/dialogs/comp-editor-page.c
- (comp_editor_page_notify_needs_send): add page needs_send signal
-
- * gui/e-meeting-time-sel.c
- (e_meeting_time_selector_on_invite_others_button_draw): check to
- see if the button should be sensitive when drawing
- (e_meeting_time_selector_construct): listen for the button draw
- signal
-
- * cal-util/cal-component.c (cal_component_strip_errors): remove
- X-LIC-ERROR x properties
-
- * cal-util/cal-component.h: new proto
-
- * gui/dialogs/meeting-page.c (change_clicked_cb): set needs_send
- to true
- (meeting_page_fill_widgets): set up gui based on if the user or
- someone else is the organizer
- (meeting_page_construct): read the addresses here for the combo
- box
- (get_widgets): explicitly set the value in list values
-
- * gui/dialogs/event-editor.c (set_menu_sens): base this on the
- exist org and user org values of the comp editor
- (event_editor_edit_comp): set up editable row restrictions on the
- meeting model if the user is not an organizer, and don't set needs
- send if we aren't the organizer initially
- (model_row_changed_cb): set needs_send to true
- (row_count_changed_cb): ditto
-
- * gui/dialogs/meeting-page.glade: update gui
-
- * gui/dialogs/comp-editor.c (save_comp_with_send): if the user is
- not the organizer, REPLY rather than REQUEST
- (comp_editor_set_existing_org): accessor
- (comp_editor_get_existing_org): ditto
- (comp_editor_set_user_org): ditto
- (comp_editor_get_user_org): ditto
- (real_edit_comp): determine if there is an existing organizer and
- if the organizers is a user
- (page_changed_cb): warn the user that changes may be discarded
- (page_summary_changed_cb): ditto
- (page_dates_changed_cb): ditto
-
- * gui/dialogs/comp-editor.h: new protos
-
- * gui/itip-utils.c (itip_organizer_is_user): determine if the
- organizer of a component is a user
- (itip_sentby_is_user): same for sentby field of organizer
- (comp_sentby): use above routines instead
- (comp_compliant): strip all X-LIC-ERROR fields generated by
- libical
-
- * gui/e-meeting-model.c (is_cell_editable): if there is a list of
- editable rows, allow only the status column of those rows to be
- edited
- (init): init edit_rows
- (e_meeting_model_restricted_add): add an editable row to the model
- (e_meeting_model_restricted_remove): remove an editable row
- (e_meeting_model_restricted_clear): clear all editable rows
- (e_meeting_model_etable_click_to_add): set the click to add arg on
- all tables
- (e_meeting_model_etable_from_model): track the tables
- (table_destroy_list_cb): remove the table being destroyed from the
- list
- (table_destroy_state_cb): remove the table being destroyed from
- the list
-
- * gui/e-meeting-model.h: new protos
-
- * gui/e-itip-control.c (update_attendee_status): kill warning
-
-2002-06-18 JP Rosevear <jpr@ximian.com>
-
- * zones.h: update for new zones
-
-2002-06-17 Rodrigo Moya <rodrigo@ximian.com>
-
- Fixes wombat crash (for JP and myself)
-
- * gui/gnome-cal.c (gnome_calendar_open): don't call add_alarms here,
- since the client is not yet attached to the backend, and the alarm
- daemon does unref the client before creating a new one.
- (client_cal_opened_cb): call add_alarms here.
-
-2002-06-12 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/alarm-notify.c: added timeout_id to LoadedClient structure, to
- keep track of the timeout function.
- (retry_timeout_cb): don't use RetryData, but the LoadedClient.
- (cal_opened_cb): ditto, and assigned lc->timeout_id to the return
- value of g_timeout_add().
- (alarm_notify_add_calendar): destroy the timeout callback when
- destroying the LoadedClient structure.
-
-2002-06-12 Jeffrey Stedfast <fejj@ximian.com>
-
- * pcs/cal-factory.c (open_fn): Free the uri_string once we're done
- with it.
-
-2002-06-12 Kjartan Maraas <kmaraas@gnome.org>
-
- * gui/dialogs/cal-prefs-dialog.glade: Fix a typo.
-
-2002-06-10 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/alarm-notify/alarm-notify.c (alarm_notify_add_calendar): removed
- already loaded client when asked to be opened again, and *really*
- re-open it again.
-
-2002-06-04 Christopher James Lahey <clahey@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_setup_view_menus):
- gal_view_menus_set_show_define_views (..., FALSE);
-
-2002-06-04 Christopher James Lahey <clahey@ximian.com>
-
- * gui/e-tasks.c (e_tasks_setup_view_menus), gui/gnome-cal.c
- (gnome_calendar_setup_view_menus): Set the title of our
- GalViewCollection.
-
-2002-06-03 Anna Marie Dirks <anna@ximian.com>
-
- * gui/dialogs/cal-prefs-dialog.glade: In an attempt to clean up the
- config dialog (and to reduce its overall girth), I have re-laid-out the
- calendar preferences dialog. It now conforms to standard Evolution
- spacing and padding guidelines, and exhibits proper alignment, etc.
-
-2002-06-03 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/query.c: keep a reference to the Query object, to avoid
- crashes when the queries are destroyed before finishing processing.
- Fixes #25056.
-
-2002-05-26 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/comp-editor.h: update proto
-
- * gui/dialogs/comp-editor.c (comp_editor_get_comp): new function
- to get base comp
-
- * gui/e-comp-editor-registry.c (e_comp_editor_registry_add): get
- the base comp, not the current comp, don't unref it
- (foreach_close_cb): block the signal, unblock it if the editor
- could not be closed
- (e_comp_editor_registry_close_all): fix preconditions
- (editor_destroy_cb): get the base comp, not the current comp,
- don't unref it
-
-2002-05-26 JP Rosevear <jpr@ximian.com>
-
- * gui/e-comp-editor-registry.c (e_comp_editor_registry_close_all):
- if there are remaining items, return false
- (foreach_close_cb): don't remove the item if it couldn't be closed
-
- * gui/e-comp-editor-registry.h: update proto
-
- * gui/component-factory.c (request_quit): return a boolean
- indicating if everything was closed
-
- * gui/dialogs/comp-editor.h: update proto
-
- * gui/dialogs/comp-editor.c (comp_editor_close): return true if
- the editor was closed, false otherwise
-
-2002-05-26 JP Rosevear <jpr@ximian.com>
-
- * gui/e-comp-editor-registry.[hc]: a registry of comp editors so
- we can close them all centrally
-
- * gui/gnome-cal.c (gnome_calendar_init): there is no editor hash
- now
- (gnome_calendar_destroy): ditto
- (gnome_calendar_edit_object): look for the event editor in the
- registry, if it isn't there, create it and add it to the registry
-
- * gui/e-calendar-table.c (open_task): look for the task editor in
- the registry, if it isn't there, create it and add it to the
- registry
-
- * gui/component-factory.c (request_quit): close all open editors
- (create_object): add a request_quit function to the shell
- component
-
- * gui/comp-editor-factory.c (free_client): there is no
- uid_comp_hash to free any more
- (editor_destroy_cb): we get an OpenClient as callback data now,
- reduce the editor count and destroy it if it is 0
- (edit_existing): don't create the Component, add the new editor to
- the registry, increase the editor count
- (edit_new): ditto
- (open_client): set the editor count to 0
- (impl_editExisting): look in the registry for the editor
-
- * gui/Makefile.am: Build new sources
-
- * gui/main.c (main): create the registry
-
- * gui/dialogs/comp-editor.c (comp_editor_close): prompt to save
- and then close dialog
-
- * gui/dialogs/comp-editor.h: new proto
-
- * gui/GNOME_Evolution_Calendar.oaf.in: remove dead summary stuff
-
-2002-05-24 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal-backend-file.c (save): check the value returned by
- gnome_vfs_uri_to_string before using it.
- (cal_backend_file_open): ditto.
-
-2002-05-20 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/dialogs/event-editor.c (event_editor_init): Pass the
- @component_pixmaps in so we give the new "Meeting" button an icon.
-
- * gui/dialogs/comp-editor.c (comp_editor_merge_ui): New arg
- @component_pixmaps to pass in custom pixmaps.
-
-2002-05-20 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/alarm-notify/alarm-notify.c:
- * gui/alarm-notify/notify-main.c: ported changes from evolution-1-0
- to make it work with reminders on remote backends.
-
- * pcs/cal-backend-file.c (cal_backend_file_open): check the string
- returned by gnome_vfs_uri_to_string, which can be empty. If so,
- return an error.
-
-2002-05-17 JP Rosevear <jpr@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_setup_view_menus): set the view
- to the current view
-
-2002-05-16 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/gnome-cal.c (client_cal_opened_cb): added support for
- CAL_CLIENT_OPEN_PERMISSION_DENIED error code.
- (permission_error): new function to display 'Permission Denied'
- error message when opening the calendar.
-
- * gui/e-tasks.c: likewise.
-
- * idl/evolution-calendar.idl: added PERMISSION_DENIED to Listener's
- OpenStatus enumeration.
-
- * cal-client/cal-client.c (cal_opened_cb): added code for retrieving
- 'Permission Denied' errors, and convert it to CalClientOpenStatus
- values.
-
- * pcs/cal-factory.c (open_backend): added code for informing of
- 'Permission Denied' errors.
-
-2002-05-16 Rodrigo Moya <rodrigo@ximian.com>
-
- * idl/evolution-calendar.idl: added PermissionDenied exception and
- make it be raised in open, updateObjects and removeObject.
-
- * pcs/cal-backend.h: added CAL_BACKEND_OPEN_PERMISSION_DENIED to
- CalBackendOpenStatus enumeration, added CalBackendResult enumeration.
-
- * pcs/cal.c:
- * pcs/cal-backend.c:
- * pcs/cal-backend-file.c: adapted to changes in update_objects and
- remove_object methods.
-
- * cal-client/cal-client.[ch]: added CalClientResult enumeration.
- (cal_client_update_object, cal_client_update_objects,
- cal_client_remove_object): changed to return a CalClientResult.
-
- * conduits/calendar/calendar-conduit.c:
- * calendar/conduits/todo/todo-conduit.c:
- * importers/icalendar-importer.c:
- * gui/dialogs/comp-editor.c:
- * gui/calendar-model.c:
- * gui/e-calendar-table.c:
- * gui/e-day-view.c:
- * gui/e-itip-control.c:
- * gui/e-week-view.c:
- * gui/comp-util.c:
- * gui/e-tasks.c:
- * gui/tasks-migrate.c: adapted to changes in cal_client_update_object(s)
- and cal_client_remove_object.
-
-2002-05-15 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c (create_object): Pass NULL as
- @request_quit_fn.
-
-2002-05-14 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/schedule-page.c (schedule_page_construct): set the
- working hours for the meeting time selector
-
-2002-05-14 JP Rosevear <jpr@ximian.com>
-
- * cal-util/cal-component.h: make the range datetime member a
- struct not a pointer
-
- * cal-util/cal-component.c (cal_component_get_recurid): take a
- pointer to a range
- (cal_component_set_recurid): ditto
-
- * gui/itip-utils.c (comp_minimal): get/set the recurrence id
- properly
-
-2002-05-09 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/e-itip-control.c (get_servers): use
- GNOME_Evolution_Storage__get_folderList instead of
- GNOME_Evolution_Storage_getFolderList since I have now changed
- that to be an attribute instead of a method.
-
-2002-05-07 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (start_calendar_server): start a server a
- uri
- (start_default_server): start a default server
- (get_servers): get all clients for all folders of the given
- type(s)
- (find_server): locate a server for a particular uid
- (init): get_servers, listen for object_requested signal
- (destroy): destroy all clients
- (write_html): put options is there own cell
- (get_publish_options): place selector in if param is true
- (get_request_options): ditto
- (get_real_item): only try and look up the item if we know its in
- the server
- (show_current_event): find the server (if any) for the current
- comp
- (show_current_todo): ditto
- (update_attendee_status): if there is no server for the comp, it
- doesn't exist
- (remove_item): ditto
- (button_selected_cb): get a client for the selected folder
- (object_requested_cb): draw the folder button in
-
- * gui/calendar-config.h: new protos
-
- * gui/calendar-config.c (calendar_config_default_tasks_folder):
- get default tasks uri
- (calendar_config_default_calendar_folder): get default calendar
- uri
-
- * cal-client/cal-client.c (get_default_uri): use
- cal_util_expand_uri
-
- * cal-util/cal-util.h: new proto
-
- * cal-util/cal-util.c (cal_util_expand_uri): tack on the file name
- if its a file uri
-
-2002-05-03 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-tasks.c (e_tasks_delete_selected):
- (e_tasks_complete_selected): show progress messages
- on the status bar.
-
-2002-05-02 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/query.c: #include <gtk/gtkmain.h> to avoid warnings.
-
-2002-05-02 JP Rosevear <jpr@ximian.com>
-
- * gui/e-week-view.c (free_view_popup): only discard the popup if
- we created one
-
-2002-05-02 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/query.c: refactored a bit, to not do things in idle loops.
-
-2002-05-01 JP Rosevear <jpr@ximian.com>
-
- * gui/print.c (print_day_details): modify the start and end hours
- to accomodate all the events in the day
-
- * gui/e-day-view.c (free_view_popup): only discard the popup if we
- created one
-
-2002-04-30 JP Rosevear <jpr@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_construct): remove setup_widgets
- from here
- (gnome_calendar_init): move setup_widgets back here
-
-2002-04-26 Jeffrey Stedfast <fejj@ximian.com>
-
- * gui/Makefile.am: Don't link to libibex anymore!!
-
-2002-04-24 JP Rosevear <jpr@ximian.com>
-
- * gui/e-day-view.c (e_day_view_on_pilot_settings): launch pilot
- settings capplet
-
- * gui/e-week-view.c (e_week_view_on_pilot_settings): ditto
-
-2002-04-24 JP Rosevear <jpr@ximian.com>
-
- * gui/e-week-view.c (free_view_popup): free the view popup
- (e_week_view_show_popup_menu): add the view popup to the
- "main_item" menu and listen for destruction
-
- * gui/e-day-view.c (free_view_popup): as above
- (e_day_view_on_event_right_click): as above
-
- * gui/e-week-view.h: add class member
-
- * gui/e-day-view.h: add a class member
-
- * gui/gnome-cal.h: new protos
-
- * gui/gnome-cal.c (set_view): set the instance view id properly
- when switching views
- (gnome_calendar_setup_view_popup): generate a view popup
- (gnome_calendar_discard_view_popup): destroy a view popup
-
-2002-04-22 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal.c (impl_Cal_get_alarms_in_range): raise an exception if the
- backend's method returns NULL, since we can't send a NULL pointer to
- ORBit.
-
-2002-04-19 Anna Marie Dirks <anna@ximian.com>
-
- * gui/dialogs/cal-prefs-dialog.glade: Collapsed notebook into two pages
- and added accelerators for everything, as part of my config dialog
- polishing project
-
-2002-04-18 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/recurrence-page.c (simple_recur_to_comp): properly
- handle -ve recurrence values
- (month_num_submenu_selection_done_cb): track the current date in
- use
- (make_recur_month_num_submenu): make a submenu of dates
- (make_recur_month_num_menu): make the date/relation option menu
- (month_num_menu_selection_done_cb): update the date properly and
- keep both option menus consistent
- (month_day_menu_selection_done_cb): keep both option menus
- consistent
- (make_monthly_special): listen for selection done signal
- (make_recurrence_special): destroy old month_num_menu
- (recurrence_page_fill_widgets): properly handle -ve recurrence
- values
-
-2002-04-18 JP Rosevear <jpr@ximian.com>
-
- * gui/e-day-view.c (e_day_view_on_settings): show the settings
-
- * gui/e-week-view.c (e_week_view_on_settings): ditto
-
- * gui/calendar-commands.c (control_util_show_settings): show the
- settings dialog
-
- * gui/calendar-commands.h: new proto
-
- * gui/control-factory.c (control_factory_new_control): set the
- control as object data on the calendar
-
-2002-04-17 Christopher James Lahey <clahey@ximian.com>
-
- * gui/e-calendar-table.c, gui/e-day-view.c, gui/e-week-view.c,
- gui/dialogs/meeting-page.c: Updated these to match the new
- EPopupMenu.
-
-2002-04-05 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal-backend.[ch] (cal_backend_get_query): new method.
-
- * pcs/cal-backend-file.c (cal_backend_file_get_query): new method.
-
- * pcs/cal.c (impl_Cal_get_query): call the CalBackend's implementation
- instead of calling query_new directly.
-
- * pcs/query.[ch]: fixed headers.
-
-2002-04-10 Dan Winship <danw@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_open): Fix this: Rodrigo's patch
- used one of the functions I just removed. :)
-
-2002-04-10 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_open): use the default uri for
- tasks (as stored in the configuration) when the calendar URI is not
- a local one (connector, etc).
-
-2002-04-10 Dan Winship <danw@ximian.com>
-
- * cal-client/cal-client.c (get_default_uri): Use new-and-improved
- default folder URI config paths.
-
- * gui/calendar-config.c (calendar_config_{get,set}_default_uri,
- calendar_config_{get,set}_default_tasks_uri): Remove these. The
- shell owns this information now. (Weren't being used anyway.)
-
- * gui/component-factory.c (get_data_uri): Fix another place that
- hardcoded tacking foo.ics on to the end of URLs.
-
-2002-04-08 Dan Winship <danw@ximian.com>
-
- * gui/component-factory.c (create_view): Add view_info arg. If the
- view_info is non-empty and this is a calendar folder, set the
- "view" property on the control's propertybag.
-
- * gui/control-factory.c (calendar_properties_init): Set up the
- "view" property.
- (get_prop, set_prop): handle the "view" property by
- getting/setting the GnomeCalendar's view. Unfortunately, this
- doesn't actually work. See #23208.
-
- * gui/calendar-commands.c (calendar_control_activate): Set the UI
- component's container before calling
- gnome_calendar_set_ui_component so that the search bar
- initialization will work.
-
-2002-04-06 JP Rosevear <jpr@ximian.com>
-
- * pcs/cal-backend-db.[hc]: Remove dead files.
-
-2002-04-06 JP Rosevear <jpr@ximian.com>
-
- * gui/GNOME_Evolution_Calendar.oaf.in: add config_item:type
-
-2002-04-01 Kjartan Maraas <kmaraas@gnome.org>
-
- * gui/e-itip-control.c: Fix a string.
-
-2002-04-01 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal-backend-db.c: simple fix for DB3 header inclusion in
- Mac OS X, by Max Horn <max@quendi.de>
-
-2002-03-31 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (clean_up): free the my_address member
- (find_my_address): fall back on a CN match if possible
- (change_status): handle changing the status of a non-existent
- address by adding a new attendee
- (update_attendee_status): if the attendee response is not from a
- user on the list of attendees, ask the user if they want to add
- the attendee any how (as an optional participant)
- (ok_clicked_cb): if we are suppose to rsvp and the status was ok,
- but the attendee address is not known, find it
-
-2002-03-29 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/GNOME_Evolution_Calendar.oaf.in: Set a priority for the
- config item. Rename to "Calendar and Tasks".
-
-2002-03-29 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/Makefile.am: s/libversit.la/libversit.a/
-
- * conduits/todo/Makefile.am: ditto
-
-2002-03-29 JP Rosevear <jpr@ximian.com>
-
- * gui/e-calendar-table.c: implement new pop up menu items for
- "Save as", "Print", "Assign Task", "Forward as iCalendar"
-
- * gui/e-day-view.c: similarly, also "Publish Free/Busy
- Information" and "New Meeting" and "New Task"
-
- * gui/e-week-view.c: ditto
-
- * gui/dialogs/task-editor.c (show_assignment): move the assignment
- page stuff here
- (task_editor_show_assignment): use it
- (assign_task_cmd): ditto
-
- * gui/dialogs/task-editor.h: new proto
-
- * gui/dialogs/comp-editor.c (save_as_cmd): use new e-util file
- selector function
-
- * meeting-mockup.glade: Remove old file
-
- * topic.dat
-
-2002-03-19 Dan Winship <danw@ximian.com>
-
- * cal-util/Makefile.am: s/libversit.la/libversit.a/
-
- * cal-client/Makefile.am: Likewise
-
- * gui/Makefile.am: Likewise
-
-2002-03-18 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/cal-search-bar.c: Removed `search_menu_items'.
- (cal_search_bar_menu_activated): Removed.
- (cal_search_bar_class_init): Don't install.
- (cal_search_bar_construct): No menu items here.
-
-2002-03-15 Jeffrey Stedfast <fejj@ximian.com>
-
- * gui/e-day-view.c: Updated to use new EPopupMenu API.
-
- * gui/e-week-view.c: Updated to use new EPopupMenu API.
-
- * gui/e-calendar-table.c: Updated to use new EPopupMenu API.
-
-2002-03-15 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/tasks-control.c (tasks_control_activate): Call
- `e_tasks_set_ui_component()' here to give it the
- BonoboUIComponent.
- (tasks_control_deactivate): Likewise, call it here to unset the
- BonoboUIComponent.
-
- * gui/e-tasks.c (e_tasks_set_ui_component): New.
-
- * gui/calendar-commands.c (calendar_control_activate): Call
- gnome_calendar_set_ui_component() here.
- (calendar_control_deactivate): ...And here, with a NULL
- BonoboUIComponent.
-
- * gui/gnome-cal.c (gnome_calendar_set_ui_component): New.
-
-2002-03-15 JP Rosevear <jpr@ximian.com>
-
- * gui/main.c: use bonobo exception macros to tidy
-
- * gui/itip-control-factory.c: ditto
-
- * gui/gnome-cal.c: ditto
-
- * gui/comp-editor-factory.c: ditto
-
- * gui/calendar-commands.c: ditto
-
-2002-03-14 JP Rosevear <jpr@ximian.com>
-
- * idl/evolution-calendar.idl: add all day event editor mode
-
- * gui/component-factory.c: clean up exception handling
- (sc_user_create_new_item_cb): support the all day event id
- (create_object): add a user creatable all day appointment item
-
- * gui/comp-editor-factory.c (get_default_event): get a default
- event either all day or starting at the top of the hour
- (get_default_task): get a default task
- (edit_new): support the all day event mode
-
- * gui/calendar-commands.c: remove unused functions/verbs
-
-2002-03-13 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/GNOME_Evolution_Calendar.oaf.in: Add an
- "evolution:config_item:icon_path" attribute so we get an icon for
- the calendar preferences.
-
-2002-03-12 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/dialogs/cal-prefs-dialog.glade: Add <visible>False</visible>
- to cal-prefs-dialog so it doesn't get shown when we load the Glade
- file with libglade.
-
- * gui/component-factory.c (owner_set_cb): Register the
- ConfigControl factory.
-
- * gui/tasks-control.c: Removed verb "TaskSettings".
- (tasks_control_settings_cmd): Removed.
-
- * gui/calendar-commands.c: Removed verb "CalendarSettings".
- (settings_cmd): Removed.
-
- * gui/dialogs/cal-prefs-dialog.c: Renamed `CalPrefsDialogPrivate'
- to `DialogData'. Replace `dialog' member with a `page' member.
- Remove `toplevel_notebook' member.
- (init_widgets): Renamed from `cal_prefs_dialog_init_widgets'.
- Just get a DialogData.
- (get_widgets): Get a DialogData pointer.
- (cal_prefs_dialog_destroy): Removed.
- (config_control_destroy_callback): New, signal handler for
- ::destroy for ConfigControl.
- (cal_prefs_dialog_new): Create a new DialogData, connect all the
- signal handlers.
- (create_time_edit): Renamed from
- `cal_prefs_dialog_create_time_edit'.
- (cal_prefs_dialog_show): Removed.
- (cal_prefs_dialog_button_clicked): Removed.
- (show_task_list_config): Get a DialogData.
- (show_config): Renamed from `cal_prefs_dialog_show_config'.
- Likewise.
- (update_task_list_config): Likewise.
- (update_config): Renamed from
- `cal_prefs_dialog_update_config'. Likewise.
- (color_set_callback): New callback, makes the dialog report
- changes when the setting in any of the color widgets is changed.
- (widget_changed_callback): New callback, makes the dialog report
- changes when any of the widgets changes status.
- (connect_changed): New utility function to connect this callback
- to all the widgets.
- (setup_widgets): Connect all the widgets.
- (cal_prefs_dialog_new): Call `setup_widgets'.
-
- * gui/config-control-factory.c: New.
- * gui/config-control-factory.h: New.
-
- * gui/GNOME_Evolution_Calendar.oaf.in: Add
- OAFIID:GNOME_Evolution_Calendar_ConfigControl and
- OAFIID:GNOME_Evolution_Calendar_ConfigControlFactory.
-
-2002-03-06 Rodrigo Moya <rodrigo@ximian.com>
-
- Should fix #21240
-
- * gui/alarm-notify/alarm-notify.c: replaced use of GnomeVFSURI
- with EUri, to allow non-registered methods.
-
-2002-03-05 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-itip-control.c (e_itip_control_set_data): reverted my last
- change of adding the METHOD property to the incoming request.
-
- * gui/itip-utils.c (comp_string): added extra
- X-MICROSOFT-CDO-REPLYTIME property for broken Outlook. Should fix
- #20783.
-
-2002-03-04 Dan Winship <danw@ximian.com>
-
- * gui/itip-utils.c (comp_compliant): Reset the DTSTAMP of the new
- component. (RFC2245 says DTSTAMP corresponds to the time the
- particular iCalendar representation of the object was created.)
- Fixes #21198.
-
-2002-03-05 JP Rosevear <jpr@ximian.com>
-
- * gui/print.c: remove unneeded parameter from print_text_size
- everywhere
- (get_font_for_size): calculate a font size based on the available
- height
- (print_text): calculate the top of where the font should be drawn
- (print_text_size): use get_font_for_size
- (print_day_background): use get_font_for_size
-
-2002-03-05 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-time-sel-item.c
- (e_meeting_time_selector_item_draw): pass the real table
- to e_meeting_model_etable_view_to_model_row
- (e_meeting_time_selector_item_paint_busy_periods): ditto
-
- * gui/dialogs/meeting-page.c (right_click_cb): ditto
-
- * gui/e-meeting-model.h: update protos
-
- * gui/e-meeting-model.c
- (e_meeting_model_etable_model_to_view_row): take in to account the
- fact the table used the without model
- (e_meeting_model_etable_view_to_model_row): ditto
-
-2002-03-04 Damon Chaplin <damon@ximian.com>
-
- * gui/tasks-control.c: added support for printing the Tasks table.
- I hacked it a bit so the user could choose portrait or landscape mode.
- This is bug #9677. ETable printing has a few issues, though, and it
- isn't very pretty.
-
-2002-03-04 Dan Winship <danw@ximian.com>
-
- * gui/itip-utils.c (comp_subject): Prefix the subject with an
- indicator like "Accepted" or "Cancelled" explaining what the
- action is, since Outlook doesn't display any of that information
- inline like we do. (20780)
-
-2002-02-28 Rodrigo Moya <rodrigo@ximian.com>
-
- * calendar/gui/e-itip-control.c (e_itip_control_set_data): added the
- METHOD property to the top level component we create.
-
-2002-02-26 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/control-factory.c (set_prop):
- * gui/tasks-control.c (tasks_control_set_property): display an error
- message if the call to gnome_calendar_open or e_tasks_open does not
- return TRUE. Fixes #20346.
-
-2002-02-25 Dan Winship <danw@ximian.com>
-
- * gui/itip-utils.c (itip_send_comp): use
- GNOME_Evolution_Composer_setBody rather than _setMultipartType and
- _attachData now, to send a message containing just a text/calendar
- part. Fixes 14705. Mostly.
- (comp_content_type): Include the filename here since we can't add
- a Content-Disposition now.
-
-2002-02-24 Chris Toshok <toshok@ximian.com>
-
- * gui/cal-search-bar.c (cal_search_bar_class_init): change
- query_changed to search_activated.
- (cal_search_bar_search_activated): rename
- cal_search_bar_query_changed to this.
-
-2002-02-21 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c (add_creatable_item): New helper
- function.
- (create_object): Add icons for the various user creatable items.
-
-2002-02-19 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (send_item): pass extra itip_send_comp
- params
- (send_freebusy): ditto
- (ok_clicked_cb): ditto, including the timezones culled from the
- component
-
- * gui/e-week-view.c: pass extra itip_send_comp params
-
- * gui/calendar-commands.c: ditto
-
- * gui/e-day-view.c: ditto
-
- * gui/dialogs/task-editor.c: ditto
-
- * gui/dialogs/event-editor.c: ditto
-
- * gui/dialogs/comp-editor.c: ditto
-
- * gui/itip-utils.h (itip_send_comp): update proto
-
- * gui/itip-utils.c (foreach_tzid_callback): check the passed in
- zones, then the builtin time zones then the client
-
-2002-02-19 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (find_my_address): strip the ical value and
- do a case insensitive compare
- (find_attendee): ditto
- (change_status): put the error message here
- (ok_clicked_cb): don't update the item or rsvp unless
- change_status was successful, trip the ical value and do a case
- insensitive compare
-
- * gui/itip-utils.c (get_address): strip the incoming address
- (itip_strip_mailto): use g_strncasecmp
- (comp_limit_attendees): strip the ical value and do a case
- insensitive compare
-
-2002-02-14 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-model.c: use new column enums
- (set_value_at): emit pre-change/cell change signals
- (destroy): destroy refresh_queue and refresh_data
- (init): init new elements
- (refresh_queue_add): if the attendee is being refreshed already,
- possibly update the start/end times to look for and update the
- callback info, otherwise add it to the queue
- (refresh_queue_remove): remove a refreshing attende from the queue
- (process_callbacks): make all the callbacks and remove the
- attendee from the queue
- (process_free_busy): process the callbacks immediately if parsing
- fails or on successful completion of processing
- (async_close): process free busy
- (cursor_cb): we're only looking for one at a time now
- (refresh_busy_periods): idle callback to start processing the queue
- (e_meeting_model_refresh_all_busy_periods): add every row to the queue
- (e_meeting_model_refresh_busy_periods): add a single row to the queue
-
- * gui/e-meeting-model.h: new protos, enum the columns
-
- * gui/e-meeting-time-sel.c: use new compare time function
- (e_meeting_time_selector_construct): listen for a cell changed
- signal and use separate callbacks for rows_inserted and
- rows_deleted
- (e_meeting_time_selector_refresh_free_busy): util function to
- refresh free busy info
- (e_meeting_time_selector_on_update_free_busy): use above
- (rows_inserted_cb): refresh free busy on the new rows
- (cell_changed_cb): refresh free busy on the row when the address
- changes
- (rows_deleted_cb): redraw
-
- * gui/e-meeting-utils.[hc]: a holding spot for a meeting time
- comparison function
-
- * gui/Makefile.am: compile new files
-
-2002-02-13 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/control-factory.c (set_prop): don't append 'calendar.ics'
- to the URI.
- (get_prop): finished.
-
- * gui/tasks-control.c (tasks_control_set_property): don't append
- 'tasks.ics' to the URI.
- (tasks_control_get_property): finished.
-
- * gui/gnome-cal.c (gnome_calendar_open):
- * gui/e-tasks.c (e_tasks_open): append $filename.ics to the uri to be
- opened if the uri is local. Leave intact in other cases.
-
-2002-02-08 Damon Chaplin <damon@ximian.com>
-
- * gui/comp-util.c (cal_comp_util_compare_event_timezones): check if
- the CalComponentDateTime values are set before trying to use them.
- Possibly fixes bug #18529.
-
- * importers/icalendar-importer.c: added vCalendar importer and
- intelligent GnomeCalendar importer code here, as it shares a lot of
- code with the iCalendar importer.
-
- NOTE: check_folder_type() needs to be finished at some point.
- It needs a new shell Corba call so it can decide whether to import
- events or tasks into the folder. Currently it just imports both.
-
- * importers/main.c (importer_factory_fn): create vCalendar importer
- or GnomeCalendar importer if required.
-
- * importers/evolution-calendar-importer.h: added declarations for
- creating a vCalendar importer and intelligent Gnome Calendar importer.
-
- * importers/Makefile.am: added -DEVOLUTION_SOUNDDIR so the importer
- knows what filename to use for audio alarms in vCalendar files.
- Added libicalvcal-evolution to LDADD.
-
- * importers/GNOME_Evolution_Calendar_Importer.oaf.in: added vCalendar
- importer and intelligent Gnome Calendar importer.
-
- * gui/comp-util.c (cal_comp_util_compare_event_timezones): return TRUE
- if the event uses UTC. We don't want to flag all events from Outlook,
- which use UTC.
-
-2002-02-08 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/task-details-page.glade: change custom widget
- creator to e_url_entry_new
-
- * gui/dialogs/task-details-page.c (get_widgets): get the url entry
- and its entry
-
-2002-02-08 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/task-details-page.glade: add a custom widget created
- with e_url_button_new
-
- * gui/dialogs/task-details-page.c (task_details_page_init): init
- url_button member to NULL
- (init_widgets): set the url button entry
- (get_widgets): get the url button
-
- * gui/calendar-commands.c (pixmaps): use new all day event icon
-
-2002-02-07 JP Rosevear <jpr@ximian.com>
-
- * gui/e-day-view.c: pass meeting boolean for
- gnome_calendar_edit_object and gnome_calendar_new_appointment_for
-
- * gui/e-week-view-event-item.c: ditto
-
- * gui/e-week-view.c: ditto
-
- * gui/tasks-control.c (confirm_expunge): kill warning
-
- * gui/calendar-commands.c (new_meeting_cb): show a new meeting
- dialog
- (new_event_cb): pass new param
-
- * gui/gnome-cal.c (gnome_calendar_edit_object): take meeting
- boolean and show meeting page if true
- (gnome_calendar_new_appointment_for): takeing meeting param and
- pass to above
- (gnome_calendar_new_appointment): add new param
-
- * gui/gnome-cal.h: update proto
-
- * gui/component-factory.c (create_component): take a comp editor
- mode, determine vtype
- (sc_user_create_new_item_cb): check for meeting user creatable
- item
- (create_object): add meeting as user creatable item
-
- * gui/comp-editor-factory.c (edit_new): get a comp editor mode
- now, determine vtype and show meeting page if required
- (queue_edit_new): get comp editor mode
- (impl_editNew): ditto, plus queue the mode directly instead of
- determining the vtype
-
- * gui/dialogs/event-editor.c (show_meeting): new internal util
- function to show meeting page
- (event_editor_show_meeting): show the meeting
- (schedule_meeting_cmd): use show_meeting
-
- * gui/dialogs/event-editor.h: new proto
-
- * idl/evolution-calendar.idl: editNew takes a mode rather than a
- type now
-
- * cal-util/Makefile.am: fix includes
-
-2002-02-07 Christopher James Lahey <clahey@ximian.com>
-
- * gui/e-tasks.c (e_tasks_setup_view_menus), gui/gnome-cal.c
- (gnome_calendar_setup_view_menus): Made these use the new
- GalViewMenus stuff.
-
-2002-02-06 Damon Chaplin <damon@ximian.com>
-
- * cal-util/cal-recur.c (cal_recur_from_icalproperty): convert months
- from 1-12 to 0-11. Fixes bug #19235.
-
-2002-02-04 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/todo-conduit.c (e_todo_gui_new): new gui routines
- for conduit settings
- (e_todo_gui_fill_config): ditto
- (e_todo_gui_fill_widgets): ditto
- (e_todo_gui_destroy): ditto
- (e_todo_context_destroy): destroy new_cfg and gui properly
- (local_record_from_comp): set the priority to the default setting
- if none is set on the icalendar object
- (fill_widgets): fill gui widgets
- (create_settings_window): create gui
-
-2002-01-30 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (write_html): if this is a reply, print the
- attendee status
-
-2002-01-25 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/alarm-options.glade: Use 1 instead of zero as the
- minimum value for the repetitions spin button as we use a check
- box to specify whether the alarm has repetitions or not. Fixes
- bug #19054.
-
-2002-01-24 Ettore Perazzoli <ettore@ximian.com>
-
- * importers/Makefile.am (evolution_calendar_importer_LDADD):
- Ooops. Forgot to use EVOLUTION_CALENDAR_LIBS here.
-
-2002-01-24 Ettore Perazzoli <ettore@ximian.com>
-
- * conduits/calendar/Makefile.am: Use
- EVOLUTION_CALENDAR_CONDUIT_LIBS and
- EVOLUTION_CALENDAR_CONDUIT_CFLAGS.
- * conduits/todo/Makefile.am: Likewise.
-
- * cal-client/Makefile.am: Use EVOLUTION_CALENDAR_LIBS and
- EVOLUTION_CALENDAR_CFLAGS.
- * cal-util/Makefile.am: Likewise.
- * gui/alarm-notify/Makefile.am: Likewise.
- * gui/Makefile.am: Likewise.
-
-2002-01-23 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c (create_object): Pass a NULL @icon to
- `evolution_shell_component_add_user_creatable_item()'.
-
-2002-01-21 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/todo-conduit.c (todoconduit_load_configuration):
- return a new configuration struct, load default priority setting
- (todoconduit_save_configuration): save default priority setting
- (e_todo_context_new): dupe configuration
-
- * conduits/calendar/calendar-conduit.c (e_calendar_context_new):
- set ps to NULL
-
-2002-01-17 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/alarm-page.c (get_alarm_string): save the alarm string
- in the correct variable (str), so it actually gets shown for alarms
- with specific trigger times. Fixes bug #18801.
-
-2002-01-15 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/dialogs/task-page.c (task_page_fill_widgets): default component
- classification to PUBLIC. Fixes internal bug #1066
-
-2002-01-14 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c: move all functions here,
- get rid of header files, use e-pilot-settings to display gui
-
- * conduits/todo/todo-conduit.c: as above
-
-2002-01-14 JP Rosevear <jpr@ximian.com>
-
- * gui/gnome-cal.c (get_current_time): use icaltimetype_to_tm
-
-2002-01-14 JP Rosevear <jpr@ximian.com>
-
- * gui/e-week-view-main-item.c (e_week_view_main_item_draw_day):
- figure out when today is and highlight if it is not selected
-
- * gui/e-week-view.h: enum the "today" color
-
- * gui/e-week-view.c (e_week_view_realize): init the "today" color
-
-2002-01-13 JP Rosevear <jpr@ximian.com>
-
- * gui/alarm-notify/save.h: add protos
-
- * gui/alarm-notify/save.c (save_blessed_program): records a
- program as blessed
- (is_blessed_program): checks to see if a program is blessed
-
- * gui/alarm-notify/alarm-queue.c (procedure_notification_dialog):
- popup a dialog notifying the user that is a program and let them
- not see the dialog about this program again
- (procedure_notification): use above
-
-2002-01-11 Damon Chaplin <damon@ximian.com>
-
- * gui/e-timezone-entry.c:
- * gui/e-itip-control.c (write_label_piece):
- * gui/calendar-config.c (on_timezone_set): translate timezone names
- when displayed. Fixes bug #6544.
-
-2002-01-03 JP Rosevear <jpr@ximian.com>
-
- * gui/tasks-control.c (tasks_control_complete_cmd): new verb
- callback
- (sensitize_commands): set sensitivity of mark complete command
-
- * gui/e-tasks.h: new proto
-
- * gui/e-tasks.c (e_tasks_complete_selected): mark selected tasks
- in the table as complete
-
- * gui/e-calendar-table.h: new proto
-
- * gui/e-calendar-table.c (e_calendar_table_complete_selected):
- mark selected rows as complete
-
-2002-01-03 JP Rosevear <jpr@ximian.com>
-
- * gui/tasks-control.c (confirm_expunge): only need one warning
- message now
-
- * gui/e-tasks.c (create_sexp): change the logic to expunge all
- completed tasks not just hidden ones
-
-2002-01-03 JP Rosevear <jpr@ximian.com>
-
- * gui/tasks-control.c (confirm_expunge): confirm expunging of the
- tasks
- (tasks_control_expunge_cmd): verb callback
-
- * gui/calendar-config.c (config_read): read confirm expunge value
- (calendar_config_write): write confirm expunge value
- (calendar_config_write_on_exit): ditto
- (calendar_config_get_confirm_expunge): get value
- (calendar_config_set_confirm_expunge): set value
-
- * gui/calendar-config.h: new proto
-
- * gui/e-itip-control.c (start_calendar_server): kill warning
-
- * gui/e-tasks.c (e_tasks_init): init query member to NULL
- (set_status_message): util function to set status message
- (e_tasks_open): use above
- (cal_opened_cb): ditto
- (create_sexp): create sexp of items to be deleted
- (query_obj_updated_cb): remove any items found
- (query_eval_error_cb): bail out on error
- (query_query_done_cb): tidy when done
- (e_tasks_delete_completed): set up query
-
- * gui/e-tasks.h: new proto
-
- * gui/calendar-model.c (query_query_done_cb): use g_warning
- instead of printing to stderr
- (query_eval_error_cb): ditto
- (update_query): clear the status message if we can't create the
- query
-
- * gui/tag-calendar.c (resolve_tzid_cb): make this static
-
-2001-12-21 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/comp-editor.c: remove needs send signal related
- cruft
- (save_comp_with_send): with send_component_dialog, indicate if the
- meeting info is newly created or not
- (real_edit_comp): remember if the dialog initially needs a send
-
- * gui/dialogs/send-comp.c (send_component_dialog): take a "new"
- parameter indicating whether the dialog should intimate if the
- component to be sent is a new meeting or not
-
- * gui/dialogs/send-comp.h: update proto
-
- * gui/dialogs/comp-editor.c: remove no longer used needs_send
- notification and signal
-
- * gui/dialogs/comp-editor.h: remove proto
-
- * gui/e-day-view.c (e_day_view_on_main_canvas_drag_data_received): add new
- param to send_component_dialog
- (e_day_view_finish_long_event_resize): ditto
- (e_day_view_finish_resize): ditto
- (e_day_view_on_editing_stopped): ditto
- (e_day_view_on_top_canvas_drag_data_received): ditto
-
- * gui/e-week-view.c (e_week_view_on_editing_stopped): add new
- param to send_component_dialog
-
-2001-12-21 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/comp-editor.h: inherit from bonobo window
-
- * gui/dialogs/comp-editor.c: inherit from bonobo window
- (comp_editor_key_press_event): Look for an escape key press and
- close the window if found
-
-2001-12-20 Ettore Perazzoli <ettore@ximian.com>
-
- [Fixes #17377, Evolution doesn't work on multi-depth displays.]
-
- * gui/main.c (main): Push GdkRGB visual and colormap.
-
-2001-12-19 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (check_for_slow_setting):
- go slow and clear the map if the last uri and the current uri do
- not match
- (post_sync): save the last uri
-
- * conduits/calendar/calendar-conduit-config.h: handle a last uri
- config option
-
- * conduits/todo/todo-conduit-config.h: ditto
-
- * conduits/calendar/calendar-conduit.c (start_calendar_server):
- use the open_default_calendar method
-
- * conduits/todo/todo-conduit.c (start_calendar_server): same as above
-
- * cal-client/Makefile.am: link with bonobo conf
-
- * cal-client/cal-client.h: new protos
-
- * idl/evolution-calendar.idl: make sure open method raises
- appropriate exceptions
-
- * gui/e-itip-control.c (start_calendar_server): use
- cal_client_open_default_* calls
-
- * cal-client/cal-client.c (real_open_calendar): do the real work
- of loading
- (cal_client_open_calendar): use above
- (get_fall_back_uri): get the basic local uri
- (get_default_uri): get the default uri from the config db
- (cal_client_open_default_calendar): open the default uri or the
- fallback if the method is unsupported
- (cal_client_open_default_tasks): same for tasks
-
-2001-12-17 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (send_item): use get_real_item
- (get_refresh_options): uncomment out
- (get_real_item): obtain the real object which has the uid of the
- item received
- (show_current_todo): use get_refresh_options for refresh method
- and provide the description and summary from the real component
- since its not in the reply
- (show_current_event): ditto
- (send_item): use get_real_item
-
-2001-12-17 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (comp_limit_attendees): can't remove properties
- in an iteration loop, so remove them outside the loop
- (comp_minimal): don't set a recurid if there isn't one, add the x
- properties to the clone
- (comp_compliant): unref the clone for DECLINECOUNTER
-
- * gui/e-itip-control.c (get_refresh_options): make function
- available again
- (show_current_event): use it here
- (ok_clicked_cb): can't remove properties in an iteration loop, so
- remove them outside the loop
-
- * cal-util/cal-component.c (free_icalcomponent): properly free the
- attendee list
- (cal_component_rescan): don't destroy the alarm hash
-
-2001-12-13 Damon Chaplin <damon@ximian.com>
-
- * zones.h: new file to contain all timezone names for translation.
- We won't be using the translations in 1.0.1, but it gives translators
- time before we do use them in 1.0.2.
-
- * Makefile.am: added zones.h to EXTRA_DIST.
-
-2001-12-12 JP Rosevear <jpr@ximian.com>
-
- * gui/e-day-view.c (e_day_view_on_top_canvas_button_release):
- ungrab the pointer before calling
- e_day_view_finish_long_event_resize
- (e_day_view_on_main_canvas_button_release): ditto
- (e_day_view_finish_long_event_resize): ask if the meeting should
- be sent
- (e_day_view_finish_resize): ditto
- (e_day_view_on_editing_stopped): ditto
- (e_day_view_on_top_canvas_drag_data_received): ditto
- (e_day_view_on_main_canvas_drag_data_received): ditto
-
-2001-12-11 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-model.c (process_free_busy_comp): properly convert
- the dtstart and dtend times if they are UTC
- (cursor_cb): if we don't have anybody to get f/b info for, process
- the callbacks immediately
- (e_meeting_model_refresh_busy_periods): take start/end times,
- calculate the timet values with object timezone
- (e_meeting_model_etable_model_to_view_row): proper cast
- (e_meeting_model_etable_view_to_model_row): ditto
- (async_open): bail out if we couldn't open properly
-
- * gui/e-meeting-time-sel.c
- (e_meeting_time_selector_on_update_free_busy): use defines for
- determining the number of days before and after of free busy to
- request
- (e_meeting_time_selector_update_dates_shown): use defines for the
- number of days shown
-
- * gui/e-meeting-model.h: update proto
-
-2001-12-10 Damon Chaplin <damon@ximian.com>
-
- * gui/control-factory.c (control_factory_new_control): removed code
- that connects to GnomeCalendar's "dates_shown_changed" signal.
-
- * gui/calendar-commands.c (gcal_calendar_dates_change_cb):
- (calendar_control_activate): moved it here, so it gets reconnected
- whenever the control is activated. Fixes bug #15798.
-
-2001-12-10 Damon Chaplin <damon@ximian.com>
-
- * importers/GNOME_Evolution_Calendar_Importer.oaf.in: fixed executable
- name. Fixes bug #16880.
-
-2001-12-08 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (local_record_from_comp):
- if we have an alarm that can be represented on the pilot, set the
- appointment fields appropriately, if the duration has values for
- minutes and/or hours and/or days, use the lowest common
- denominator
- (comp_from_remote_record): if the appointment on the pilot has an
- alarm, find the first alarm an item currently had that is relative
- to the start and with a negative duration and update it (or create
- a new one if no valid ones exist)
-
- * cal-util/cal-component.c (cal_component_get_alarm_uids): build
- list in the order they appear in the component so we get
- consisting order for the gui and for the pilot
-
-2001-12-08 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/calendar-config.c (calendar_config_get_default_uri):
- (calendar_config_get_default_tasks_uri): s/%/%s
-
-2001-11-09 Federico Mena Quintero <federico@ximian.com>
-
- (committed by Damon)
-
- Fix bug #14699.
-
- * pcs/query.c (QueryState): Added a state QUERY_WAIT_FOR_BACKEND
- to indicate that the query is not populated as we are waiting for
- the backend to be opened.
- (query_init): Start in the QUERY_WAIT_FOR_BACKEND state.
- (query_destroy): Only disconnect from the backend if we are in a
- state that implies that we are connected to its signals.
- (query_construct): If the backend is already loaded, immediately
- set the state to QUERY_START_PENDING.
- (backend_opened_cb): Disconnect from the backend's "opened"
- signal. Set the state to QUERY_START_PENDING.
- (match_component): We can now only match components if the query
- is in progress or if it is done. Assert to that effect, and do
- not ensure_sexp().
- (match_component): Do not check for a nonexistent component using
- g_return_if_fail(). Also, there is no need to ref/unref the
- component.
- (backend_obj_updated_cb): Assert to the effect of our state.
- (backend_obj_removed_cb): Likewise.
- (parse_sexp): Renamed from ensure_sexp(). Assert that the query
- has not started. Do not disconnect from the backend's signals
- here, since we have no connections.
- (start_query_cb): Set the state to QUERY_IN_PROGRESS here instead
- of in populate_query().
-
-2001-12-07 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/calendar-config.c (calendar_config_get_default_uri):
- (calendar_config_get_default_tasks_uri): if the key in the config
- database does not exist, just return the local URIs, but never
- return NULL
-
-2001-12-06 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/dialogs/event-page.c (event_page_fill_widgets): default
- component classification to PUBLIC
-
-2001-12-06 Jon Trowbridge <trow@ximian.com>
-
- * gui/dialogs/event-editor.c (event_editor_destroy): Explicitly
- destroy the EMeetingModel. This is a hack to work around problems
- with the reference counting; we are still leaking the
- EMeetingModels.
-
- * gui/e-meeting-time-sel.c
- (e_meeting_time_selector_construct): Ref our EMeetingModel.
- (e_meeting_time_selector_destroy): Unref the model.
-
- * gui/e-meeting-model.c (destroy): Properly destroy
- corba_select_names with a call to bonobo_object_release_unref.
- (Fixes 14002)
-
-2001-12-05 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/dialogs/event-page.glade: added entry for the LOCATION field
-
- * gui/dialogs/event-page.c: added support for the new LOCATION entry
- added in the Event editor.
-
-2001-12-05 Zbigniew Chyla <cyba@gnome.pl>
-
- * gui/itip-utils.c (comp_subject, comp_description):
- Marked strings for translation.
-
-2001-12-03 Damon Chaplin <damon@ximian.com>
-
- * gui/e-meeting-model.c:
- * gui/calendar-model.c: make sure we call e_table_model_pre_change()
- before changing the model.
-
- * gui/calendar-config.c (calendar_config_configure_e_calendar_table):
- removed call to e_table_model_changed(). calendar_model_refresh()
- results in that anyway.
-
-2001-12-03 Damon Chaplin <damon@ximian.com>
-
- * gui/e-calendar-table.etspec: disabled 'Alarms', 'End Date' and
- 'Show Time As' fields, as these are not useful for tasks. We may want
- to reenable them later if we add a table view of calendar events.
-
-2001-12-02 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/calendar-offline-handler.c (backend_cal_opened): connect to
- "cal_set_mode" signal before calling cal_client_set_mode. Also,
- s/cal_mode_set/cal_set_mode
- (backend_go_offline): connect to "cal_opened" signal before calling
- cal_client_open_calendar
-
-2001-11-30 Damon Chaplin <damon@ximian.com>
-
- * gui/e-itip-control.c (remove_item): only show the dialog if we
- created it. Hopefully fixes bug #15774.
- Also ifdef'ed out a lot of code that isn't currently used, including
- code to use a label which is never created. The unused code was there
- to support handling multiple iTIP objects in a message, but was never
- updated when we switched to use HTML for the control. Fixes bug #16232.
-
-2001-11-28 Federico Mena Quintero <federico@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_new_task): Set the category of
- the new task to that of the search bar. Fixes bug #15533.
-
-2001-11-27 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-itip-control.c (update_attendee_status):
- * gui/itip-utils.c (comp_to_list): fixed typos in translatable
- strings. Fixes Ximian #15456
-
-2001-11-14 Damon Chaplin <damon@ximian.com>
-
- * gui/print.c: Substituted gnome_font_get_width_string() with
- gnome_font_get_width_utf8() and gnome_font_get_width_string_n()
- with gnome_font_get_width_utf8_sized(). Fixes calendar part of #15379.
-
-2001-11-14 Federico Mena Quintero <federico@ximian.com>
-
- * gui/calendar-model.c (date_value_to_string): Convert the buffer
- to UTF8.
- (calendar_model_value_to_string): Do not convert the string fields
- to UTF8 again; they are already in UTF8. Fixes the UTF8-related
- bits of bug #15304.
-
-2001-11-14 Damon Chaplin <damon@ximian.com>
-
- * gui/calendar-model.c:
- * cal-util/cal-component.h: #ifdef'ed out the LOCATION field for now,
- since it wasn't supported everywhere, or in the .etspec file.
-
-2001-11-14 Damon Chaplin <damon@ximian.com>
-
- * gui/e-calendar-table.c: don't abort when e_table_selected_count()
- returns odd values. There seems to be a bug in ETable. This is to
- avoid bug #13843.
-
-2001-11-13 Federico Mena Quintero <federico@ximian.com>
-
- (committed to CVS by Damon)
- Fixes bug #15137.
-
- * gui/e-day-view.c (e_day_view_on_delete_appointment): Do not try
- to operate on the event if it gets deleted while stopping the
- edition.
- (e_day_view_on_event_double_click): Likewise.
- (e_day_view_on_long_event_button_press): Likewise.
- (e_day_view_on_event_button_press): Likewise.
- (e_day_view_on_long_event_click): Likewise.
- (e_day_view_on_event_click): Likewise.
-
- * gui/e-week-view.c (e_week_view_on_text_item_event): Likewise.
-
-2001-11-14 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (pre_sync): remove silly
- debug warning
-
-2001-11-13 Damon Chaplin <damon@ximian.com>
-
- * gui/alarm-notify/config-data.c (ensure_inited):
- * gui/calendar-config.c (config_read):
- * conduits/todo/todo-conduit.c (get_default_timezone):
- * conduits/calendar/calendar-conduit.c (get_default_timezone):
- make the timezone default to UTC. Fixes bug #14362.
-
-2001-11-13 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-week-view.c (selection_received): only change the day,
- month and year for the start date, for not screwing up the start
- time, which was being set to midnight always (Fixes Ximian #5287)
- Also, deal correctly with VCALENDAR components
-
- * gui/e-day-view.c (selection_received): dela correctly with
- VCALENDAR components being pasted
-
-2001-11-11 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/save.c (get_calendars_to_load): The last
- argument to the bonobo_config_get_XXX_with_default() is a gboolean
- *, not a CORBA_Environment *. Fixes bug #14655.
-
-2001-11-11 JP Rosevear <jpr@ximian.com>
-
- * pcs/cal-backend-file.c (free_busy_instance): recurrence
- expansion callback for free/busy
- (create_user_free_busy): expand recurrences and use date/time
- values for dtstart and dtend
-
-2001-11-11 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-model.h: new protos
-
- * gui/e-meeting-model.c (e_meeting_model_get_zone): accessor
- (e_meeting_model_set_zone): ditto
- (init): init to the calendar default zone
- (process_free_busy_comp): take the zone to convert to as a param
- (e_meeting_model_refresh_busy_periods): redraw properly
-
- * gui/dialogs/schedule-page.c (update_time): set the zone of the
- model
-
-2001-11-09 Damon Chaplin <damon@ximian.com>
-
- * gui/e-week-view.c (e_week_view_key_press): don't subtract a day
- from DTEND. For DATE values we don't include the entire day now.
- Fixes bug #14842.
-
-2001-11-09 Damon Chaplin <damon@ximian.com>
-
- * gui/e-week-view-layout.c (e_week_view_layout_events): fix buffer
- overflow. Fixes bug #10285 (the printing of lines & dates in the
- printout of the month view).
-
-2001-11-09 Zbigniew Chyla <cyba@gnome.pl>
-
- * gui/dialogs/meeting-page.c
- (meeting_page_fill_widgets): Convert strings to GTK+ encoding.
- (meeting_page_destroy): Free allocated strings before freeing the list
- itself.
-
-2001-11-08 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-time-sel.c
- (e_meeting_time_selector_timeout_handler): don't let an empty
- event occur for all days when auto scrolling
-
-2001-11-08 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal-backend-file.c
- (cal_backend_file_compute_changes_foreach_key): don't leak the
- string returned by cal_component_get_as_string nor the temporary
- CalComponent we create
-
-2001-11-08 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (ok_clicked_cb): don't add the item, remove
- it if declining (in case it was added before)
- (remove_item): Since we can't discern between an item not found
- and another error, always say the removal is complete
-
-2001-11-07 Zbigniew Chyla <cyba@gnome.pl>
-
- * gui/e-cell-date-edit-text.c (ecd_get_text):
- Convert generated string to UTF-8.
-
-2001-11-07 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-time-sel.c
- (e_meeting_time_selector_on_start_time_changed): emit changed
- signal
- (e_meeting_time_selector_on_end_time_changed): emit changed
- signal, if end time is now before start time and all day event,
- make sure a whole day is still selected
- (e_meeting_time_selector_drag_meeting_time): calculate the first
- and last_time's in whole days for all day events
- (e_meeting_time_selector_timeout_handler): calculate the drag time
- to be whole days for all day events and scroll the canvas even if
- we don't update the time so the user can see where they're headed
-
-2001-11-06 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/event-editor.c (event_editor_edit_comp): make sure
- to remove all attendees from the model when we edit a new comp,
- append the pages if they are needed and we weren't showing them
- before
-
- * gui/dialogs/task-editor.c (task_editor_edit_comp): same as above
-
- * gui/dialogs/comp-editor.c (comp_editor_remove_page): check for a
- return value indicating the page was not found and return if so
-
-2001-11-05 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/dialogs/e-delegate-dialog.c: #include
- "Evolution-Addressbook-SelectNames.h", not
- "../Evolution-Addressbook-SelectNames.h". Grrr.
-
-2001-11-05 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-time-sel.c (e_meeting_time_selector_class_init):
- add a changed signal
- (e_meeting_time_selector_construct): emit changed signal
- (e_meeting_time_selector_set_meeting_time): ditto
- (e_meeting_time_selector_set_all_day): set the all day setting
- (e_meeting_time_selector_autopick): emit changed signal
- (e_meeting_time_selector_find_nearest_interval): find proper
- interval when in all day mode
- (e_meeting_time_selector_find_nearest_interval_backward): ditto
- (e_meeting_time_selector_drag_meeting_time): for all day events,
- move the time when past the 12 hour mark, and and always make sure
- 1 full day is selected, emit changed signal when appropriate
- (e_meeting_time_selector_update_start_date_edit): set date and
- time of day together
- (e_meeting_time_selector_update_end_date_edit): ditto, and adjust
- display time if all day event
-
- * gui/e-meeting-time-sel-item.c
- (e_meeting_time_selector_item_draw): remove unused variable
- (e_meeting_time_selector_item_button_press): for all day mode,
- make the interval a whole day
-
- * gui/dialogs/schedule-page.c (update_time): set the meeting time
- selector setting instead of manual mucking with the e-date-edit
- widgets
- (init_widgets): listen to the changed signal of the meeting time
- selector instead of propagating multiple events as it updates
-
- * gui/dialogs/event-page.c (update_time): block time zone change
- signals
-
-2001-11-05 Damon Chaplin <damon@ximian.com>
-
- * gui/calendar-model.c (dup_date_edit_value): removed ';' in the wrong
- place. Fixes bug #14421.
-
-2001-11-05 Dan Winship <danw@ximian.com>
-
- * gui/alarm-notify/Makefile.am (evolution_alarm_notify_LDFLAGS):
- -export-dynamic for libglade custom widget.
-
-2001-11-04 Damon Chaplin <damon@ximian.com>
-
- * gui/comp-editor-factory.c (get_default_component): use TZID from the
- builtin timezone, instead of using the location name.
-
-2001-11-02 Federico Mena Quintero <federico@ximian.com>
-
- * cal-util/cal-util.c (compute_alarm_range): Short-circuit the
- calculation of the repeat time if there are zero repetitions.
- (compute_alarm_range): I'm a moron. De-reference alarm_start when
- subtracting stuff from it! Fixes bug #14209.
-
-2001-10-31 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/dialogs/Makefile.am: Added rules to generate
- `Evolution-Addressbook-SelectNames.h'.
-
- * gui/dialogs/comp-editor-util.h: #include
- "Evolution-Addressbook-SelectNames.h" from this directory.
-
-2001-10-31 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/alarm-options.c: #include <string.h>
-
-2001-10-31 Federico Mena Quintero <federico@ximian.com>
-
- * gui/gnome-cal.c (dn_query_obj_updated_cb): If a query is not in
- progress, just retag the whole thing. An event may change dates
- and tag_calendar_by_comp() would not know how to untag the old
- dates. Fixes bug #10220.
-
- * pcs/query.c (start_query_cb): Connect to the backend's
- "obj_updated" and "obj_removed" signals here instead of in
- query_construct(). If a query is started while another one is
- notifying of an update, these signal connections would get appened
- to the running signal (the one that triggered the notification
- about an update) and the new signal handlers would also get
- called. We are really not interested in updates before we
- populate the query, because we'll catch the changes anyways.
-
-2001-10-31 Federico Mena Quintero <federico@ximian.com>
-
- Fix bug #13723.
-
- * gui/gnome-cal.h (GnomeCalendarClass): New signals
- "calendar_focus_change", "taskpad_focus_change", and
- "taskpad_selection_changed". Renamed "selection_changed" to
- "calendar_selection_changed".
-
- * gui/gnome-cal.c (gnome_calendar_get_num_tasks_selected): New
- function.
- (setup_widgets): Connect to the focus event signals of the task
- pad and the calendar view widgets.
- (gnome_calendar_delete_selection): Renamed from
- gnome_calendar_delete_event().
- (gnome_calendar_cut_clipboard): Handle the current focus location.
- (gnome_calendar_copy_clipboard): Likewise.
- (gnome_calendar_paste_clipboard): Likewise.
- (gnome_calendar_delete_selection): Likewise.
- (table_selection_change_cb): New callback.
-
- * gui/calendar-commands.c (sensitize_calendar_commands): Take in
- whether we should unconditionally disable everything.
- (sensitize_taskpad_commands): Analogous function to the above.
- (gcal_calendar_focus_change_cb): New callback, used for calendar
- views.
- (gcal_taskpad_focus_change_cb): New callback, used for the
- taskpad.
-
- * gui/e-day-view.c (e_day_view_key_press): Use a better test for
- keys that should start editing. Fixes bug #6447.
-
- * gui/e-week-view.c (e_week_view_key_press): Likewise.
-
-2001-10-31 Christopher James Lahey <clahey@ximian.com>
-
- * gui/calendar-model.c: Make the pre_changes and changes match
- here.
-
-2001-10-31 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (itip_send_comp): send as mixed rather than
- alternative
-
-2001-10-31 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/alarm-notify/save.c (KEY_CALENDARS_TO_LOAD):
- Removed.
- (KEY_NUM_CALENDARS_TO_LOAD): New key, containing the number of
- calendars to load.
- (BASE_KEY_CALENDAR_TO_LOAD): New base key name for the URIs of the
- calendars to load.
- (save_calendars_to_load): Rewrote to not use a sequence, to work
- around an ORBit bug that causes bonobo-moniker-xmldb to crash.
- (get_calendars_to_load): Likewise.
-
-2001-10-30 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/comp-editor.c (comp_editor_remove_page): disconnect
- signals added in append_page(). Fixes Gtk-Critical warning about
- GtkAccelGroup being added twice to a window.
-
-2001-10-30 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (itip_send_comp): set a body for the message
-
-2001-10-30 Dan Winship <danw@ximian.com>
-
- * gui/itip-utils.c (itip_send_comp): call
- GNOME_Evolution_Composer_setMultipartType to get a
- multipart/alternative.
-
-2001-10-30 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-time-sel.c
- (e_meeting_time_selector_on_start_time_changed): don't overwrite
- memory
- (e_meeting_time_selector_on_end_time_changed): ditto
-
-2001-10-30 Damon Chaplin <damon@ximian.com>
-
- * gui/calendar-model.c (dup_date_edit_value): return NULL if passed
- NULL. Should fix bug #14048.
-
-2001-10-30 Federico Mena Quintero <federico@ximian.com>
-
- * gui/calendar-config.c (config_read): Do not ignore the
- exceptions of the cases that do not have defaults.
-
-2001-10-30 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-time-sel.c
- (e_meeting_time_selector_drag_meeting_time): if we are doing all
- day stuff, make the drag increment 1 day at a time
-
-2001-10-30 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/meeting-page.c (meeting_page_fill_component): Add
- _() to a string that was missing it.
-
-2001-10-30 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/meeting-page.c (table_canvas_focus_out_cb): Commit
- the ETable click-to-add for if the dialog is being destroyed.
- Should fix bug #13959.
-
-2001-10-30 Federico Mena Quintero <federico@ximian.com>
-
- * gui/itip-utils.c (itip_send_comp): Allocate enough space for the
- string! (was missing the null terminator) Possibly fixes #13924.
- Thanks a *LOT* to Michael Zucchi for running this through Purify.
-
-2001-10-30 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-time-sel-item.c
- (e_meeting_time_selector_item_button_press): move in whole day
- increments if we are in all day mode
-
- * gui/e-meeting-time-sel.c
- (e_meeting_time_selector_on_start_time_changed): get rid of
- localtime call
- (e_meeting_time_selector_on_end_time_changed): ditto
- (e_meeting_time_selector_update_start_date_edit): set the date
- editor using the meeting time fields directly
- (e_meeting_time_selector_update_end_date_edit): ditto
-
- * gui/dialogs/schedule-page.c (update_time): do the set_show_time
- stuff first
-
- * conduits/calendar/calendar-conduit.c (process_multi_day): don't
- adjust the time, set the default timezone for date values
-
-2001-10-30 Dan Winship <danw@ximian.com>
-
- * gui/alarm-notify/Makefile.am (INCLUDES):
- s/BONOBO_HTML_GNOME_LIBS/BONOBO_HTML_GNOME_CFLAGS/
-
-2001-10-30 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-model.c (e_meeting_model_count_actual_attendees):
- count the actual attendees (doesn't include people delegating
-
- * gui/e-meeting-time-sel.c: use
- e_meeting_model_count_actual_attendees (renamed)
-
- * gui/e-meeting-time-sel-item.c: use
- e_meeting_model_etable_view_to_model_row calls instead of calling
- on the model directly, use e_meeting_model_count_actual_attendees
-
- * gui/e-meeting-model.c
- (e_meeting_model_etable_model_to_view_row): get the real mapping
- (e_meeting_model_etable_view_to_model_row): ditto
- (get_key): e-table-without callback
- (duplicate_key): ditto
- (free_gotten_key): ditto
- (free_duplicated_key): ditto
- (init): create without model
- (e_meeting_model_etable_from_model): build etable from without
- model
-
- * gui/e-meeting-model.h: update protos
-
- * gui/dialogs/meeting-page.c (right_click_cb): convert row from
- view to model row
-
-2001-10-30 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/task-page.c (task_page_fill_widgets): set to the default
- timezone for DATE values, in case the user switches to a DATE-TIME.
-
-2001-10-30 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/task-page.c: handle DATE values for Start and Due dates.
-
-2001-10-30 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/schedule-page.c:
- * gui/dialogs/event-page.c:
- * gui/dialogs/comp-editor-util.c: updated code to handle DATE values.
-
- * gui/gnome-cal.c (gnome_calendar_new_appointment_for):
- * gui/e-day-view.c (e_day_view_key_press): updated DATE code.
-
- * gui/e-cell-date-edit-text.c:
- * gui/calendar-model.c: updated to support DATE values.
-
- * cal-util/cal-recur.c (cal_recur_generate_instances_of_rule): updated
- to use DATE values in same way as Outlook - i.e. the DTEND date is
- not included entirely. Though I did make it so that if the DTSTART
- and DTEND used the same DATE value, it includes the entire day.
- So 1-day events should be the same. Long All-Day events will be
- 1 day shorter.
-
- * cal-util/cal-component.c (cal_component_get_start_plus_duration):
- don't subtract a day from the end date.
-
- * gui/tasks-control.c: updated the EPixmap paths for Cut/Copy etc.
- Removed Print & Print Preview paths, since we don't have menu commands
- for these any more.
-
-2001-10-30 Federico Mena Quintero <federico@ximian.com>
-
- Fix bug #10016.
-
- * gui/dialogs/comp-editor.c (comp_editor_merge_ui): Use
- bonobo_ui_util_set_ui() instead of doing things by hand. Hmmm, if
- only that function had a way of telling us whether it failed so
- that we could avoid setting the verb list...
-
- * gui/dialogs/event-editor.c (event_editor_init): Do not pass the
- filename with the full path so that Bonobo can find it in a smart
- way.
-
- * gui/dialogs/task-editor.c (task_editor_init): Likewise.
-
-2001-10-30 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/delete-comp.c (delete_component_dialog): Use an
- EMessageBox instead of a gnome_dialog_question so that the label
- gets line breaking. Fixes bug #11260.
-
-2001-10-29 Federico Mena Quintero <federico@ximian.com>
-
- Fix bug #13649.
-
- * gui/calendar-config.c
- (calendar_config_get_use_default_reminder): New function.
- (calendar_config_set_use_default_reminder): New function.
- (calendar_config_get_default_reminder_interval): New function.
- (calendar_config_set_default_reminder_interval): New function.
- (calendar_config_get_default_reminder_units): New function.
- (calendar_config_set_default_reminder_units): New function.
- (config_read): Get the options for default reminders.
- (calendar_config_write): Set the options for default reminders.
-
- * gui/dialogs/cal-prefs-dialog.c (cal_prefs_dialog_show_config):
- Set the default reminder widgets from the config values.
- (cal_prefs_dialog_update_config): Set the config values from the
- widgets.
-
- * gui/comp-util.c (cal_comp_event_new_with_defaults): New
- function; creates a VEVENT component with the default alarm.
-
- * gui/e-day-view.c (e_day_view_key_press): Use
- cal_comp_event_new_with_defaults ();
-
- * gui/e-week-view.c (e_week_view_key_press): Likewise.
- * gui/calendar-model.c (calendar_model_append_row): Likewise.
- * gui/comp-editor-factory.c (get_default_component): Likewise.
- * gui/gnome-cal.c (gnome_calendar_new_appointment_for): Likewise.
-
- * cal-util/cal-component.c (ensure_alarm_properties_cb): Ensure we
- have a DESCRIPTION property.
- (cal_component_commit_sequence): Ensure we have the mandatory
- alarm properties.
-
-2001-10-30 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-model.c (process_section): process an individual
- section here
- (select_names_ok_cb): call above
- (get_select_name_dialog): listen for ok:dialog signal
-
-2001-10-29 Damon Chaplin <damon@ximian.com>
-
- * importers/Makefile.am (evolution_calendar_importer_LDADD):
- * gui/Makefile.am (evolution_calendar_LDADD):
- * cal-util/Makefile.am (test_recur_LDADD):
- * cal-client/Makefile.am (client_test_LDADD): use libical-evolution.la
-
- * gui/dialogs/schedule-page.c: save the timezone passed in for the
- start time, so if our times are changed we use this. Also, if the
- end time was passed in in a different timezone, convert it.
- Also hide the time fields for DATE values. Note that DATE values still
- do not work.
-
- * gui/dialogs/meeting-page.glade: changed "Invite Others" to
- "Invite Others..." to be consistent with the other page.
-
- * gui/dialogs/event-page.c (times_updated):
- (all_day_event_toggled_cb): set is_date if appropriate.
-
- * gui/e-itip-control.c (write_label_piece): convert all UTC times to
- the current timezone. Outlook sends simple, non-recurring, events as
- UTC times, which isn't very useful.
-
-2001-10-29 Federico Mena Quintero <federico@ximian.com>
-
- * gui/main.c (launch_alarm_daemon): Launch the alarm daemon as
- soon as the calendar component is started. Fixes bug #13867;
- we can't really do much better than this.
-
-2001-10-29 Federico Mena Quintero <federico@ximian.com>
-
- * gui/tasks-control.c (pixmaps): Fix the verb names for the
- pixmaps in the Edit menu; they were out of synch with the XML
- UI description.
-
-2001-10-29 Chris Toshok <toshok@ximian.com>
-
- * pcs/cal-factory.c (cal_factory_dump_active_backends): new
- function.
- (dump_backend): new function.
-
- * pcs/cal-factory.h: add prototype for
- cal_factory_dump_active_backends.
-
-2001-10-29 Federico Mena Quintero <federico@ximian.com>
-
- Fix bug #12163.
-
- * cal-util/cal-util.c (compute_alarm_range): Take alarm
- repetitions into account.
- (add_alarm_occurrences_cb): Add alarm repetitions.
- (generate_absolute_triggers): Likewise.
- (generate_absolute_triggers): Oops, absolute triggers are in UTC,
- so convert them as such. Also, pay attention to the timezones of
- the dtstart and dtend properties.
-
-2001-10-29 JP Rosevear <jpr@ximian.com>
-
- * importers/Makefile.am: include the header as a source so it gets
- dist'ed.
-
-2001-10-29 Ettore Perazzoli <ettore@ximian.com>
-
- * importers/Makefile.am (INCLUDES):
- s/BONOBO_CFLAGS/BONOBO_GNOME_CFLAGS/.
-
-2001-10-29 Rodrigo Moya <rodrigo@ximian.com>
-
- * importers/icalendar-importer.c (load_file_fn): fixed URI
- construction, which was preventing importing into the root
- calendar (~/evo/local/Calendar/)
-
-2001-10-29 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (is_all_day): handle date
- values
-
-2001-10-29 Rodrigo Moya <rodrigo@ximian.com>
-
- * importers/: added evolution-calendar-importer binary, starting
- with an iCalendar file importer
-
-2001-10-29 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/todo-conduit-config.h
- (todoconduit_load_configuration): get the management object by id
-
- * conduits/calendar/calendar-conduit-config.h
- (calconduit_load_configuration): ditto
-
-2001-10-29 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/calendar-config.[ch] (calendar_config_get_default_uri):
- (calendar_config_set_default_uri):
- (calendar_config_get_default_tasks_uri):
- (calendar_config_set_default_tasks_uri): new functions for setting
- and retrieving the default calendar URIs
-
- * gui/e-itip-control.c (init): don't use
- hard-coded URI, but use the default calendar URI, as returned
- by calendar_config_get_default_uri
- (start_calendar_server): added a "gboolean tasks" parameter, so
- that the local tasks.ics file is used if the calendar to be
- started is for tasks when no default tasks URI is found in
- the configuration
-
-2001-10-28 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (add_record): unref the
- comp when finished
-
- * conduits/todo/todo-conduit.c (add_record): ditto
-
-2001-10-28 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/task-page.c (task_page_fill_widgets): added break
- statements after each case, when setting the classification.
- Fixes bug #13772.
-
-2001-10-28 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-client/cal-client.c (destroy_wombat_client): removed this
- function, as we don't need to unref at all the WombatClient
- object, since it is aggregated to the CalListener object, which
- will take care of unrefing it (Fixes Ximian #12001)
- (cal_client_open_calendar): create the WombatClient here
-
-2001-10-28 Damon Chaplin <damon@ximian.com>
-
- * gui/print.c (print_todo_details): get the tasks directly from the
- CalendarModel, so we get the filtering & sorting for free. Fixes
- bug #10280. Hmm. This seems too easy. It isn't going to work is it...
-
- * gui/gnome-cal.c (gnome_calendar_get_task_pad): new function to get
- the TaskPad ECalendarTable, for printing.
-
- * gui/calendar-model.c:
- * gui/calendar-config.c (calendar_config_get_hide_completed_tasks_sexp):
- split this out from calendar-model.c so we could use it for printing,
- but ended up doing that a different way.
-
- * gui/dialogs/task-page.c (init_widgets): removed a duplicated signal
- connected to field_changed_cb().
-
-2001-10-27 Damon Chaplin <damon@ximian.com>
-
- * gui/print.c (print_week_view):
- (range_selector_new): when the week start day is set to Sunday, we
- have to be careful to make sure we print the correct week, since
- the previous Saturday is actually printed first. Fixes bug #13687.
- (print_week_summary): always set compress_weekend to true if
- multi_week_view is FALSE (i.e. we are printing the week view).
- Fixes bug #13688.
-
- * gui/e-itip-control.c (send_freebusy): use the timezones from the
- DTSTART and DTEND.
- (write_label_piece): output the date-time and the timezone after it.
- Note that we may want to convert it to the current timezone and display
- that as well. Also converted COMPLETED to the current timezone.
- And fixed all uses of old timezone functions.
-
- * gui/dialogs/comp-editor.c (commit_all_fields): added function to
- set the focus in the window to NULL, so all fields lose their focus,
- so they emit "changed" signals and update their values if needed.
- We call this when most menu commands are used, e.g. 'Save and Close',
- 'Print' etc. Fixes bug #11434. In future we should also check fields
- are valid and show dialogs if they are not.
-
- * gui/calendar-model.c (get_completed): use the completed value
- properly. Fixes bug #13694.
-
- * cal-util/timeutil.c (icaltimetype_to_tm_with_zone): don't check
- from_zone and to_zone != NULL. A NULL zone is valid, it is for
- floating times.
-
-2001-10-27 Federico Mena Quintero <federico@ximian.com>
-
- * gui/e-day-view.c (e_day_view_on_text_item_event): Cancel editing
- if the user presses Escape.
-
- * gui/e-week-view.c (e_week_view_on_text_item_event): Likewise.
-
- * gui/cal-search-bar.c: #include <string.h>
-
-2001-10-27 Federico Mena Quintero <federico@ximian.com>
-
- * gui/e-day-view.c (e_day_view_on_editing_stopped): Delete
- appointments with empty summaries. Fixes Ximian bug #780.
-
- * gui/e-week-view.c (e_week_view_on_editing_stopped): Likewise.
-
- * gui/dialogs/delete-comp.c (delete_component_dialog): Added an
- argument to specify whether we unconditionally want single
- components to be considered as not having a summary.
-
- * gui/comp-util.c (cal_comp_confirm_delete_empty_comp): New
- function.
-
- * gui/misc.[ch]: New files with miscellaneous utility functions;
- moved string_is_empty() over from calendar-model.c.
-
- * gui/calendar-model.c: Use the string_is_empty()
- function from misc.c.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Added misc.[ch] to
- the list of sources.
-
-2001-10-27 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/todo-conduit.c (local_record_from_comp): touch on
- lookup
- (check_for_slow_setting): write touched only if slow sync
- (match): touch on lookup
-
- * conduits/calendar/calendar-conduit.c (local_record_from_comp):
- touch the record on lookup
- (check_for_slow_setting): write touched only if slow sync
- (pre_sync): don't touch on lookup
- (match): touch on lookup
-
-2001-10-26 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/e-calendar.conduit.in: remove the merges as
- valid sync types
-
- * conduits/todo/e-todo.conduit.in: as above
-
- * conduits/calendar/calendar-conduit.c (pre_sync): write out only
- the touched records if we are doing copies
-
- * conduits/todo/todo-conduit.c: as above
-
- * conduits/calendar/calendar-conduit-config.h
- (calconduit_load_configuration): get the sync type
-
- * conduits/todo/todo-conduit-config.h: as above
-
-2001-10-26 Damon Chaplin <damon@ximian.com>
-
- * gui/e-itip-control.c (write_label_piece): convert the formatted
- date to UTF-8.
-
- * cal-util/cal-recur.c (CAL_OBJ_DEBUG): turn off debug functions.
-
- * gui/dialogs/comp-editor-util.c (parse_contact_string): handle UTF8
- correctly. Bug #4450. Good enough for 1.0.
-
- * gui/e-week-view-event-item.c (e_week_view_draw_time): set the gc
- color before drawing. Should fix bug #11469.
-
- * gui/dialogs/task-editor.c (task_editor_edit_comp): show or hide the
- meeting page as appropriate. Note this may be called more than once,
- if the task gets updated somewhere else and the user clicks 'Update
- the object'. Hopefully fixes bug #12930.
-
- * gui/print.c (print_comp_item): printed more fields and made a little
- prettier. Fixes bug #9352.
- (print_date_label): used the correct timezones for each date field.
-
- * *.c: removed several debug messages.
-
-2001-10-26 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (check_for_slow_setting):
- make debug output more accurate
-
- * conduits/todo/todo-conduit.c (check_for_slow_setting): ditto
-
-2001-10-26 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/todo-conduit.c (pre_sync): remove the uid from the
- map if was archived and is now deleted
-
- * conduits/calendar/calendar-conduit.c: ditto
-
-2001-10-26 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-calendar_table.c (delete_selected_components):
- (selection_received): added status bar messages
-
- * gui/e-day-view.c (e_day_view_cut_clipboard):
- (selection_received): likewise
-
- * gui/e-week-view.c (e_week_view_cut_clipboard):
- (selection_received): likewise
-
-2001-10-26 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.h: modify fields
-
- * conduits/todo/todo-conduit.h: as above
-
- * conduits/calendar/calendar-conduit.c (print_remote): free the
- struct after use
- (e_calendar_context_new): explicitly init context fields
- (e_calendar_context_destroy): free local records and properly free
- changed hash elements
- (start_calendar_server_cb): tidy
- (start_calendar_server): ditto
- (free_local): free a local record
- (local_record_to_pilot_record): use a static buffer to avoid leaks
- (local_record_from_comp): only copy over alarm stuff from the
- original record, we sync everything else
- (local_record_from_uid): unref the comp when we are done
- (pre_sync): free change_id
- (post_sync): ditto
- (for_each): track locals
- (for_each_modified): ditto
- (free_match): use free_local
-
- * conduits/todo/todo-conduit.c: as above
-
-2001-10-26 Federico Mena Quintero <federico@ximian.com>
-
- * pcs/cal.c (cal_construct): Get a fresh CORBA_Environment for
- every CORBA call. Hopefully will fix #11978, but I'm not sure
- about what else could be happening.
- (cal_get_password): Free the exception.
-
-2001-10-25 Damon Chaplin <damon@ximian.com>
-
- * gui/e-itip-control.c: used functions to get PUBLISH_OPTIONS etc.,
- so we can translate them.
-
-2001-10-25 Damon Chaplin <damon@ximian.com>
-
- * cal-util/cal-recur.c (cal_obj_bysetpos_filter): subtract 1 from
- any positive BYSETPOS value, since our array is 0-based.
-
- * gui/dialogs/recurrence-page.c (simple_recur_to_comp):
- (recurrence_page_fill_widgets): Outlook (2000) will not accept monthly
- recurrences like BYDAY=2TU. Instead it uses BYDAY=TU;BYSETPOS=2.
- So to be compatable with it we now do the same, although we still
- accept and convert the old format.
-
- * cal-client/cal-client.c (cal_client_get_component_as_string): new
- function to return a complete VCALENDAR string containing a VEVENT
- or VTODO with all the VTIMEZONEs it uses.
-
- * gui/dialogs/comp-editor.c (save_as_ok): use above function so we
- save the VTIMEZONE data with the VEVENT/VTODO. Fixes bug #8626.
- Also made sure we output "METHOD:PUBLISH" since Outlook (2000) will
- not import it otherwise.
-
- * gui/dialogs/comp-editor.c (page_mapped_cb):
- (page_unmapped_cb): install/uninstall the GtkAccelGroup for the page.
- (comp_editor_append_page): connect to the map/unmap signals to
- install/uninstall the accelerators. (This is all for bug #11609,
- though of course it doesn't work too well in GTK+ 1.2 anyway.)
-
- * gui/dialogs/task-page.c (get_widgets):
- * gui/dialogs/task-details-page.c (get_widgets):
- * gui/dialogs/schedule-page.c (get_widgets):
- * gui/dialogs/recurrence-page.c (get_widgets):
- * gui/dialogs/meeting-page.c (get_widgets):
- * gui/dialogs/event-page.c (get_widgets):
- * gui/dialogs/alarm-page.c (get_widgets): got the GtkAccelGroup from
- the original window, ref'ed it and placed it in the CompEditorPage
- struct.
-
- * gui/dialogs/comp-editor-page.c (comp_editor_page_destroy): unref
- any GtkAccelGroup for the page.
-
- * gui/dialogs/task-page.glade: changed '_Confidential' to
- 'Con_fidential' as it clashed with '_Contacts'. It now matches the
- event editor as well.
-
- * gui/dialogs/event-page.glade:
- * gui/dialogs/task-page.glade: Set CAN_FOCUS to TRUE for the custom
- EDateEdit widgets, and set them as the accel targets of the labels.
-
-2001-10-25 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/dialogs/comp-editor.c (save_comp): show an error message when
- we can't update the object on the calendar server
-
-2001-10-25 Federico Mena Quintero <federico@ximian.com>
-
- * gui/control-factory.c: Ifdef-ed out the PersistFile bits.
-
- * gui/GNOME_Evolution_Calendar.oaf.in: The tasks folder does not
- support the PersistFile interface; removed it. Removed it as well
- from the calendar folder since it is aggregated but not actually
- implemented.
-
-2001-10-25 Federico Mena Quintero <federico@ximian.com>
-
- * gui/component-factory.c (xfer_folder): Handle tasks folders as
- well; was always using "calendar.ics" as the filename.
-
-2001-10-24 Damon Chaplin <damon@ximian.com>
-
- * gui/GNOME_Evolution_Calendar.oaf.in: added sections for Tasks
- factory and control. I hope someone checks these!
-
-2001-10-24 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c (xfer_folder): Fixed to only copy the
- `calendar.ics' and `calendar.ics~' files.
-
-2001-10-24 Damon Chaplin <damon@ximian.com>
-
- * pcs/cal-backend-file.c (cal_backend_file_update_objects): when
- iterating over the subcomponents, use 'subcomp' rather than 'icalcomp'.
- That meant it wasn't working at all well when an entire VCALENDAR
- was passed in.
-
- * cal-util/cal-component.c: handle DURATION property used instead of
- DTEND or DUE. In cal_component_get_dtend/due we will return DTSTART
- + DURATION if necessary. In set_dtend/due we remove any DURATION
- property. Fixes bug #11262.
-
- * gui/e-meeting-model.c (build_etable):
- * gui/e-calendar-table.c (e_calendar_table_init): use U_ for the
- ECellCombo popdown strings, as it expects UTF-8 strings.
-
-2001-10-24 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-time-sel.c (e_meeting_time_selector_construct):
- track the spacer vbox
- (e_meeting_time_selector_style_set): make sure the rows are the
- correct size for the style
-
- * gui/e-meeting-time-sel-item.c
- (e_meeting_time_selector_item_paint_day_top): slight adjustments
- to where the text is drawn
-
- * gui/e-meeting-time-sel.h: new member
-
- * gui/e-meeting-model.c (build_etable): ensure uniform row height
-
- * conduits/todo/todo-conduit.c (comp_from_remote_record): mark
- status as completed in appropriate places and don't overwrite
- legitimate percentages and such
-
-2001-10-24 Federico Mena Quintero <federico@ximian.com>
-
- Fixes bug #5282.
-
- * cal-util/timeutil.c (icaltimetype_to_tm_with_zone): New function
- to avoid copying the same code all over the place.
- (icaltimetype_to_tm): Also set the tm.tm_wday.
-
- * gui/alarm-notify/alarm-queue.c (queue_midnight_refresh): Use
- time_day_end_with_zone().
- (load_alarms_for_today): Likewise. And oops, we were only
- computing the times and not loading the alarms.
- (obj_updated_cb): Likewise.
- (load_alarms): Removed assertion that is no longer valid because
- we may load the alarms for a client in two stages.
-
- * gui/dialogs/alarm-page.c (get_alarm_string): Convert absolute
- trigger times to the local timezone.
-
- * gui/alarm-notify/alarm-notify-dialog.c (write_html_heading):
- Convert the times to the local timezone.
- (alarm_notify_dialog): Likewise, for the window title.
- (alarm_notify_dialog): Set the window layer to WIN_LAYER_ONTOP.
-
- * gui/e-cell-date-edit-text.c (ecd_get_text): Use
- icaltimetype_to_tm_with_zone().
-
- * gui/alarm-notify/save.c (get_config_db): Made public.
- (discard_config_db): Made public.
-
- * gui/alarm-notify/config-data.[ch]: New files with functions to
- fetch the calendar configuration data used by the alarm daemon.
-
-2001-10-23 Damon Chaplin <damon@ximian.com>
-
- * cal-util/cal-component.c (cal_component_event_dates_match): make sure
- we free all the CalComponentDateTime's when we are finished.
-
- * gui/gnome-cal.c (gnome_calendar_notify_dates_shown_changed): just
- return if no time range is set.
-
-2001-10-23 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-time-sel.c
- (e_meeting_time_selector_table_vadjustment_changed): adjust the
- display canvas when the table scrolls
- (e_meeting_time_selector_construct): listen for table scrolling
-
-2001-10-23 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-model.c (build_etable): no longer set the
- scrollbar policy here
-
- * gui/e-meeting-time-sel.c
- (e_meeting_time_selector_update_main_canvas_scroll_region): add an
- extra row to the height so the click to add row can be properly
- seen
- (e_meeting_time_selector_construct): set the scrollbar policy for
- the etable scrolled
-
-2001-10-23 JP Rosevear <jpr@ximian.com>
-
- * cal-util/timeutil.c (icaltimetype_to_tm): convert an
- icaltimetype to a tm
- (tm_to_icaltimetype): vice versa
-
- * cal-util/timeutil.h: new protos
-
- * conduits/calendar/calendar-conduit.c: replace all mktime and
- localtime calls (except for debugging calls)
-
- * conduits/todo/todo-conduit.c: ditto
- (comp_from_remote_record): make sure the completed time is in UTC
-
-2001-10-23 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-client/cal-query.c (cal_query_construct) set priv->corba_query
- to CORBA_OBJECT_NIL if there was an error
-
-2001-10-22 Damon Chaplin <damon@ximian.com>
-
- * idl/evolution-calendar.idl: added setDefaultTimezone() method.
-
- * pcs/cal-backend.c (cal_backend_get_default_timezone):
- (cal_backend_set_default_timezone): new functions to call class
- methods.
-
- * pcs/cal-backend-file.c: lots of changes to handle the default
- timezone and use it.
-
- * pcs/query.c: use the default timezone.
-
- * gui/dialogs/task-details-page.c (date_changed_cb): initialized
- completed_tt.
-
- * gui/dialogs/event-page.c: changed it to handle DATE values. The
- 'All Day Event' checkbox is only set now when the DTSTART and DTEND
- are DATE values.
-
- * gui/dialogs/comp-editor-util.c (comp_editor_free_dates): free the
- CalComponentDateTime structs as well.
-
- * gui/e-tasks.c: set the default timezone on the server.
-
- * gui/tag-calendar.c:
- * gui/gnome-cal.c:
- * gui/e-week-view.c:
- * gui/e-day-view.c: updates to handle DATE values.
-
- * gui/e-calendar-table.c (date_compare_cb): updated to use the new
- ECellDateEditValue values, so it now works.
- (percent_compare_cb): updated to use GPOINTER_TO_INT values.
- (e_calendar_table_init): use an ECellPercent for the percent field
- and an ECellDateEditText for the date fields.
-
- * gui/comp-util.c (cal_comp_util_compare_event_timezones): return TRUE
- if the DTSTART or DTEND is a DATE value. We don't want to show the
- timezone icons for DATE values.
-
- * gui/comp-editor-factory.c (resolve_pending_requests): set the default
- timezone on the server.
-
- * gui/calendar-model.c: major changes to support sorting properly.
- For date and percent fields we now use subclasses of ECellText, so
- we don't use a char* as the model value. For the percent field we now
- use a GINT_TO_POINTER. For the date fields we now use a
- ECellDateEditValue* as the value.
-
- * gui/calendar-config.c (calendar_config_configure_e_cell_date_edit):
- set the timezone and use_24_hour flags of the new ECellDateEditText.
-
- * conduits/todo/todo-conduit.c (pre_sync):
- * conduits/calendar/calendar-conduit.c (pre_sync): set the default
- timezone on the server.
-
- * cal-util/timeutil.c (time_days_in_month): removed debug message.
-
- * cal-util/test-recur.c: try to handle timezones in the iCalendar
- file properly, and updated to pass default timezone.
-
- * cal-util/cal-util.c (cal_util_generate_alarms_for_comp):
- (cal_util_generate_alarms_for_list): added default timezone argument.
-
- * cal-util/cal-recur.c: changed many of the functions to take a default
- timezone, to use to resolve DATE and floating DATE-TIME values.
-
- * cal-client/cal-client.c (cal_client_set_default_timezone): new
- function to set the default timezone.
- (cal_client_ensure_timezone_on_server): new function to ensure that
- a given timezone is on the server.
-
- * gui/e-cell-date-edit-text.c: new subclass of ECellText to display
- and edit a date value.
-
- * cal-util/cal-recur.c (cal_obj_byday_expand_monthly): changed week_num
- to -week_num when calculating the weeks to go back from the end of the
- month for things like BYDAY=-2WE. Fixes bug #11525.
- (cal_recur_generate_instances_of_rule): only go up to MAX_YEAR (2037).
- We can't really handle anything past that anyway.
- (cal_recur_ensure_rule_end_date): initialize cb_date.end_date to 0,
- so if the RULE doesn't generate COUNT instances we save 0 as the
- time_t.
-
-2001-10-22 Federico Mena Quintero <federico@ximian.com>
-
- * gui/tasks-control-factory.c (tasks_control_factory_fn): Put up a
- warning dialog box if we failed to create the tasks control.
- Fixes bug #13033.
-
-2001-10-22 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (set_date_label): write out the correct
- time in the control
-
- * pcs/cal.c (build_fb_seq): utility function to build sequences of
- f/b data
- (impl_Cal_get_free_busy): use above so we never return a NULL
-
- * conduits/calendar/calendar-conduit-config.h
- (calconduit_save_configuration): fix c/p error
- (calconduit_load_configuration): ditto
-
-2001-10-22 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/meeting-page.c (meeting_page_destroy): we don't need
- to save the state
-
- * gui/e-meeting-time-sel.c (e_meeting_time_selector_destroy):
- ditto
-
- * gui/e-meeting-model.c (build_etable): listen for the etable
- being destroyed
- (table_destroy_cb): save the state when the etable is destroyed
-
-2001-10-21 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/schedule-page.c (init_widgets): listen for changes
- in the date editors
- (schedule_page_set_dates): update the times when they change
- elsewhere
- (update_time): set the time in the dialog
- (time_changed_cb): notify of changed times
-
- * gui/dialogs/comp-editor.c (page_dates_changed_cb): don't call
- the set dates function on the page that noted the change
- (page_summary_changed_cb): same for set summary function
-
- * gui/dialogs/event-page.c (update_time): move time setting stuff
- to util function
- (event_page_set_dates): use it
- (event_page_fill_component): ditto
-
- * gui/e-meeting-time-sel.h: fix comment
-
-2001-10-19 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/alarm-notify.c (add_uri_to_load): Do not assert
- if we fail to load the URI list. This would of course have been a
- bonobo-conf activation problem.
- (remove_uri_to_load): Likewise.
-
- * gui/alarm-notify/notify-main.c (load_calendars): Likewise.
-
- * gui/alarm-notify/alarm-queue.c (load_missed_alarms): Make the
- time range half-open so that we do not display the last alarm
- twice.
-
-2001-10-19 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/calendar-model.c (calendar_model_set_status_message): make
- it a public function
-
- * gui/e-tasks.c (e_tasks_open): display progress messages
- (cal_opened_cb): clean up status bar messages
-
- * gui/gnome-cal.c (gnome_calendar_open): display progress messages
- (client_cal_opened_cb): clean up status bar messages
-
-2001-10-19 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/calendar-model.c (set_status_message): new function
- (update_query): call set_status_message
- (query_query_done_cb):
- (query_eval_error_cb): clean up status bar messages
- (get_location, set_location): new functions for setting and
- retrieving the location in the calendar model
-
-2001-10-19 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/component-factory.c (owner_set_cb): keep a reference to the
- EvolutionShellClient component
-
- * gui/e-week-view.c (e_week_view_set_status_message): new function
- (update_query): call e_week_view_set_status_message
- (query_query_done_cb):
- (query_eval_error_cb): clean up status bar messages
-
- * gui/e-day-view.c (e_day_view_set_status_message): new function
- (update_query): call e_day_view_set_status_message
- (query_query_done_cb):
- (query_eval_error_cb): clean up status bar messages
-
- * gui/Makefile.am: added EVOLUTION_IMAGESDIR to CFLAGS
-
-2001-10-18 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-time-sel.c
- (e_meeting_time_selector_on_invite_others_button_clicked): call
- the invite others dialog in the model
-
- * gui/e-meeting-attendee.c (e_meeting_attendee_get_atype): pick
- attendee type based on role and cutype
-
- * gui/e-meeting-attendee.h: remove proto
-
- * gui/Makefile.am: compile select names idl
-
- * gui/e-meeting-model.h: new proto
-
- * gui/dialogs/meeting-page.c: remove invite others dialogs bits
- from here
-
- * gui/e-meeting-model.c (e_meeting_model_invite_others_dialog):
- and put them here
-
- * gui/dialogs/Makefile.am: compile corba bits in parent dir
-
- * gui/dialogs/comp-editor-util.h: reflect above in includes
-
- * gui/dialogs/e-delegate-dialog.c: ditto
-
- * gui/dialogs/schedule-page.c: ditto and clean includes
-
-2001-10-18 Larry Ewing <lewing@ximian.com>
-
- * gui/alarm-notify/alarm-notify-dialog.c: add html widget
- (url_requested_cb): add function to load images from file as they
- are requested.
- (write_html_heading): convert to using html.
- (alarm_notify_dialog): convert to use html display.
- (make_html_display): this is the function the custom widget in the
- galde file uses to create the html widget.
-
- * gui/alarm-notify/alarm-notify.glade: add placeholder for the
- custom html widget.
-
- * gui/alarm-notify/Makefile.am: add flags for gtkhtml and gal.
-
-2001-10-18 Federico Mena Quintero <federico@ximian.com>
-
- Adds session management for the alarm daemon. Also makes it store
- a list of calendars to be monitored. Those calendars will all be
- loaded when the alarm daemon starts up.
-
- * idl/evolution-calendar.idl (AlarmNotify): Removed the ::die()
- method. The alarm daemon now handles termination via the session
- manager's commands.
-
- * gui/alarm-notify/notify-main.c (set_session_parameters): New
- function, sets some parameters so that the session manager can
- restart the daemon via the evolution-alarm-client program. Also,
- sets up the "die" signal so that the daemon can terminate when the
- session ends.
- (load_calendars): New function to load the calendars on startup.
- (main): Set the session parameters. Load the calendars on startup.
-
- * gui/alarm-notify/alarm-notify.c (alarm_notify_add_calendar): New
- function, moved over from the impl_ function. Added a
- load_afterwards argument to indicate whether the calendar should
- just be loaded or if it should also be added to the list of
- calendars to load on startup.
- (AlarmNotify_addCalendar): Use alarm_notify_add_calendar().
- (AlarmNotify_removeCalendar): Remove the calendar from the list of
- calendars to load on startup.
-
- * gui/alarm-notify/save.c (save_calendars_to_load): New function,
- saves a sequence of the URIs to load.
- (get_calendars_to_load): New function, loads a sequence of
- calendars to load.
-
- * gui/alarm-notify/alarm.h: Removed stale prototype for alarm_init().
-
- * gui/component-factory.c (remove_folder): Ask the alarm daemon to
- stop monitoring alarms for the folder that is being deleted.
-
-2001-10-18 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-time-sel.c
-
- * gui/e-meeting-time-sel-item.c
- (e_meeting_time_selector_item_paint_day_top): use 12 or 24 hour
- settings
-
- * gui/e-meeting-time-sel.c: strings for 12 hour setting
- (e_meeting_time_selector_construct): increase width slightly
-
- * gui/e-meeting-time-sel.h: extern the new char array
-
-2001-10-18 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-util/cal-component.[ch] (cal_component_get_location):
- (cal_component_set_location): new functions
-
-2001-10-18 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-model.c (process_callbacks): util routine to
- handle calling back
- (async_close): use above
- (e_meeting_model_refresh_busy_periods): ditto
-
-2001-10-17 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/todo-conduit.c (local_record_from_comp): translate
- 1-5 priorites to 1-9 priorities better
- (comp_from_remote_record): ditto
-
-2001-10-17 JP Rosevear <jpr@ximian.com>
-
- * idl/evolution-calendar.idl: allow some decent exceptions
-
-2001-10-17 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/query.c (match_component): there may be cases when the backend
- will return an invalid component from a valid UID (an UID returned
- by the get_uids method), so don't abort if that's the case
-
-2001-10-15 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/cal-prefs-dialog.glade: removed Help button. Do we have
- any others?
-
-2001-10-15 Larry Ewing <lewing@ximian.com>
-
- * gui/dialogs/comp-editor.c (set_icon_from_comp): remove warnings.
-
-2001-10-15 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (process_multi_day):
- function to break up multi day events into single events for both
- evo and the pilot and create new CalClientChange structures
- (pre_sync): call above function, and adjust changed list if
- necessary
-
-2001-10-15 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (is_all_day): util function
- to determine if event is all day
- (local_record_from_comp): use new util function
- (comp_from_remote_record): kill use of deprecated time functions
-
-2001-10-13 Larry Ewing <lewing@ximian.com>
-
- * gui/dialogs/comp-editor.c (real_edit_comp): call
- set_icon_from_comp.
- (set_icon_from_comp): set the window icon from the comp.
- (make_icon_from_comp): get the icon path based on comp type.
-
- * gui/dialogs/Makefile.am (iconsdir): EVOLUTION_ICONSDIR bits.
-
-2001-10-13 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/task-editor.c (task_editor_send_comp): send
- cancellation comp if necessary
-
-2001-10-12 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/alarm-page.c: return fill_component success
-
- * gui/dialogs/task-page.c: ditto
-
- * gui/dialogs/task-details-page.c: ditto
-
- * gui/dialogs/schedule-page.c: ditto
-
- * gui/dialogs/recurrence-page.c: ditto
-
- * gui/dialogs/event-page.c: ditto
-
- * gui/dialogs/meeting-page.c: use e_notice instead of
- duplicate_error
- (meeting_page_get_cancel_comp): duh, deleted_attendees is an array
- now
- (meeting_page_fill_component): spew gui errors if there is no
- organizer or no attendees, return success
-
- * gui/dialogs/event-editor.c (event_editor_send_comp): always call
- parent method and don't send the cancellation comp if the method
- is publish
- (refresh_meeting_cmd): use the orginal comp to refresh
- (forward_cmd): prompt the user for the version they want to send
- (current, original)
-
- * gui/dialogs/task-editor.c (forward_cmd): as above
- (refresh_task_cmd): ditto
-
- * gui/dialogs/comp-editor-page.c
- (comp_editor_page_fill_component): return boolean of whether the
- component could be filled or not
-
- * gui/dialogs/comp-editor-page.h: update proto
-
- * gui/dialogs/comp-editor.c (prompt_to_save_changes): take a param
- on whether to try and send or not
- (comp_editor_get_current_comp): only fill component if its changed
- (comp_editor_save_comp): prompt user as well
-
- * gui/dialogs/comp-editor.h: change proto
-
- * gui/itip-utils.c: replace error_dialog with e_notice
- (comp_content_type): specify charset
-
-2001-10-11 Larry Ewing <lewing@ximian.com>
-
- * gui/e-itip-control.c: large reworking of i18n tagging and now
- uses gtk_html_stream write and U_ where appropriate. More to
- come.
-
-2001-10-10 Larry Ewing <lewing@ximian.com>
-
- * gui/e-itip-control.c (init): set the default character set to
- utf-8.
-
-2001-10-10 Federico Mena Quintero <federico@ximian.com>
-
- * pcs/cal-factory.c (lookup_backend): Return the original key in
- the hash table if requested.
- (backend_last_client_gone_cb): Use lookup_backend() so that we
- have the URI mangling done for us.
- (impl_CalFactory_open): The type should be GtkType *, not GtkType!
-
-2001-10-10 JP Rosevear <jpr@ximian.com>
-
- * cal-client/cal-client.c (cal_set_mode_cb): remove unneeded
- assertions
-
-2001-10-10 JP Rosevear <jpr@ximian.com>
-
- * pcs/cal-factory.c (add_uri): fix logic checks
-
- * gui/dialogs/event-editor.c (event_editor_init): init the
- exisiting_org boolean
- (set_menu_sens): base sensitivity on existing_org boolean
- (event_editor_edit_comp): set exisiting_org boolean
-
- * gui/dialogs/task-editor.c: same as above
-
- * gui/calendar-offline-handler.c (add_connection): handle the
- protocol or host being unknown
-
- * cal-util/cal-component.c (cal_component_has_organizer):
- implement
-
-2001-10-09 Federico Mena Quintero <federico@ximian.com>
-
- Fixes bug #884.
-
- * gui/alarm-notify/save.[ch]: New files with functions to
- save/load the last notification time.
-
- * gui/alarm-notify/alarm-queue.c (alarm_trigger_cb): Save the last
- notification time.
- (alarm_queue_init): Load the last notification time when the
- daemon is inited.
- (alarm_queue_add_client): Load the alarms that we missed while the
- alarm daemon was not running.
- (cal_opened_cb): Likewise.
-
- * gui/alarm-notify/Makefile.am (evolution_alarm_notify_SOURCES):
- Added save.[ch] to the list of sources.
-
-2001-10-09 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (get_address): util function to get address
- (itip_addresses_get_default): get only the default address
- (itip_address_free): free single address
- (itip_addresses_free): use above
- (comp_limit_attendees): limit the number of attendees to one, the
- user
- (comp_sentby): set the sentby parameter if the user is not the
- organizer
- (comp_minimal): remove extraneous info for send (for refresh and
- declinecounter)
- (comp_compliant): remove all alarms, do various things to make the
- components comply with itip spec based on method
- (itip_send_comp): use comp_compliant method
-
- * gui/itip-utils.h: new protos
-
- * gui/e-itip-control.c: rescan the component when necessary
- (get_next): don't get stuck in infinite loop if there are no
- viewable components
- (e_itip_control_set_data): if there are no viewable components,
- spit an error message
-
- * gui/dialogs/meeting-page.h: tidy
-
- * gui/dialogs/meeting-page.c (meeting_page_fill_widgets): use
- organizer's cn if possible
- (other_clicked_cb): no longer doing the sent by stuff directly,
- hide more widgets
-
- * pcs/query.c: use bonobo exception stuff
-
- * cal-util/cal-component.c (cal_component_rescan): have the comp
- rescan its libical component (for when you change things directly)
- (free_icalcomponent): take a param on whether to free the
- component or just clean up the mappings
- (cal_component_has_attendees): util function
-
- * cal-util/cal-component.h: new protos
-
-2001-10-09 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal-factory.c (lookup_backend, add_backend): deal correctly with
- URIs to be inserted into the hash table, so that we don't add the same
- backend over and over because the URI strings were different (although
- refering to the same backend)
-
- * pcs/cal-backend-file.c (mail_account_*): moved to a common place
- (cal_backend_file_open): check if "uristr != NULL" and not
- "uri != NULL"
-
- * pcs/cal-backend-util.c: moved to here
-
- * gui/e-day-view.c: add missing header file
-
-2001-10-09 Dan Winship <danw@ximian.com>
-
- * gui/e-meeting-model.c (process_free_busy_comp): Fix incorrect
- variable name check.
-
-2001-10-03 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (itip_send_comp): refactor functionality into
- several function
- (comp_string): if we are publishing, empty the attendee list
-
- * gui/dialogs/event-editor.c (schedule_meeting_cmd): when we
- schedule a new meeting, mark the event editor as changed
-
- * pcs/cal.c (cal_class_init): get correct parent class
-
- * gui/dialogs/comp-editor.c (comp_editor_merge_ui): use the
- generated ui component name
-
-2001-10-03 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/component-factory.c:
- * gui/calendar-offline-handler.c:
- * gui/comp-editor-factory.c: replace use of gnome_vfs_uri with e_uri
-
- * gui/e-meeting-model.c (start_addressbook_server): make it return void,
- since the return value does not mind
-
- * pcs/cal.c:
- * pcs/cal-factory.c:
- * pcs/cal-backend.[ch]: don't use GnomeVFS for URI management
-
- * pcs/cal-backend-file.c: ditto, only use GnomeVFS for internal
- operations
-
- * cal-client/cal-client.c (cal_client_open_calendar): don't CORBA_exception_free
- before checking for exceptions
-
-2001-10-03 Christopher James Lahey <clahey@ximian.com>
-
- * gui/e-calendar-table.etspec: Added priorities to a bunch of
- these columns. Fixes Ximian bug #7158.
-
-2001-10-03 Damon Chaplin <damon@ximian.com>
-
- * gui/comp-util.c (cal_comp_util_add_exdate): save the EXDATE as a
- DATE-TIME value, since we know the exact time. Fixes bug #11278.
- (Before we were setting is_date, but icaltime_from_timet_with_zone()
- didn't convert it properly. We need to figure out how to handle DATEs
- when using time_t's.)
-
- * gui/dialogs/recurrence-page.c (get_exception_string): use
- e_time_format_date_and_time() so we show the time as well, if the
- exception is a DATE-TIME value.
-
- * cal-util/timeutil.c: removed time_add_month(), time_year_begin(),
- time_month_begin() & time_week_begin() - old pre-timezone functions
- which we no longer use.
-
- * cal-util/cal-recur.c (cal_recur_from_icalproperty): set
- ir.until.is_date to FALSE before converting to a time_t.
- Hopefully fixes bug #5034.
-
-2001-10-02 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/dialogs/comp-editor.c (setup_widgets): Use
- `bonobo_ui_component_new_default()', not
- `bonobo_ui_component_new()'.
-
-2001-10-02 JP Rosevear <jpr@ximian.com>
-
- * cal-client/cal-query.c: use bonobo-exception to tidy
-
-2001-10-02 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (nth_weekday): handle -1 as
- well
- (comp_from_remote_record): fix monthly by day recurrences and
- handle "last" day type
-
-2001-10-01 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/comp-editor.c (comp_editor_destroy): unref the page
- objects here, instead of in close_dialog(). (This was fixed a while
- ago, but accidentally reverted.) Fixes bug #7543.
-
-2001-10-01 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/alarm-notify-dialog.c (alarm_notify_dialog):
- Set the window state to sticky. Thanks to Peter Teichman for the
- suggestion.
-
-2001-10-01 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (local_record_from_comp):
- Convert the comp exceptions to the pilot record
- (comp_from_remote_record): record exceptions on the desktop and
- use time zone stuff on recurrence end date
-
-2001-10-01 JP Rosevear <jpr@ximian.com>
-
- * pcs/cal-backend-file.c (cal_backend_file_compute_changes):
- strdup the uid to avoid double free, write out only after
- everything is done
-
-2001-10-01 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_open): don't use
- gnome_vfs_uri_is_local on URIs created with
- gnome_vfs_uri_new_private
-
-2001-09-28 Damon Chaplin <damon@ximian.com>
-
- * gui/print.c (print_comp_item): use bound_text to print the summary,
- so it wraps instead of being clipped to 1 line. Fixes part 3 of bug
- #10285, I think.
-
- * gui/dialogs/alarm-page.glade: left-aligned the Date/Time label.
- Also set the width of the Summary & Date/Time labels to 10, and set
- expand to TRUE, to make sure that the dialog doesn't keep getting
- wider as the summary text on the main page gets longer. Could possibly
- use an EClippedLabel here instead, so we get a '...' at the end if it
- is clipped.
-
- * gui/dialogs/recurrence-page.glade: changed Summary & Date/Time
- widths as above.
-
- * gui/print.c (print_calendar): use landscape mode for the month
- preview.
- (print_border_with_triangles): use EPSILON to account for floating
- point errors. Hopefully fixes part 2b of bug #10285.
-
-2001-09-28 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (local_record_from_comp):
- Handle the fields and category we don't sync by making sure we
- don't overwrite them
- (local_record_to_pilot_record): use local record category
- (pre_sync): track db info
-
- * conduits/calendar/calendar-conduit.h: db info field
-
- * conduits/todo/todo-conduit.[hc]: same as above
-
- * pcs/cal-backend-file.c
- (cal_backend_file_compute_changes_foreach_key): create a dummy
- component of the right type and strdup the uid
- (cal_backend_file_compute_changes): sync the db hash after each
- change and free the uid
-
-2001-09-28 JP Rosevear <jpr@ximian.com>
-
- * cal-client/cal-client.c (cal_client_open_calendar): init the
- execption rather than freeing it
-
-2001-09-28 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-client/cal-client.c (cal_client_construct): use bonobo-exception
- for exceptions
- (cal_client_open_calendar): likewise
-
-2001-09-27 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/calendar-commands.c (pixmaps): Update pixmap menu paths;
- /menu/ComponentToolsPlaceholder/Tools ->
- /menu/Tools/ComponentPlaceholder .
- * gui/tasks-control.c: Likewise.
-
-2001-09-27 Rodrigo Moya <rodrigo@ximian.com>
-
- * idl/evolution-calendar.idl: added InvalidURI and UnsupportedMethod
- exceptions to the CalFactory interface
-
- * pcs/cal-factory.c (impl_CalFactory_open): raise InvalidURI exception on
- URI errors and UnsupportedMethod when we don't support the method for
- a given URI
-
-2001-09-26 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-client/cal-client.c: added support for using multiple calendar
- factories
- (cal_client_uri_list): use the list of factories loaded for this
- CalClient
-
-2001-09-26 Damon Chaplin <damon@ximian.com>
-
- * gui/e-calendar-table.c (date_compare_cb):
- (percent_compare_cb):
- (priority_compare_cb): added comparison functions for these special
- cell types. But the date and percent ones don't work yet due to the
- use of static text buffers for return cell values.
- (e_calendar_table_init): added the comparison functions to the
- ETableExtras. NOTE: task_compare_cb() never seems to be called.
- I'm not sure why it is there.
-
- * gui/e-calendar-table.etspec: set the comparison function names for
- the date/percent/priority fields.
-
- * cal-util/cal-util.c (cal_util_priority_to_string):
- (cal_util_priority_from_string): new utility functions.
-
- * gui/calendar-model.c (get_priority):
- (set_priority): used above utility functions, and removed the warning
- dialog which isn't useful now that the field isn't editable.
-
- * gui/dialogs/event-page.c (times_updated): handle timezones and for
- all-day events make sure it stays an all-day event after adjusting.
- Fixes bugs #5945 and #10222.
-
- * gui/calendar-commands.c (pixmaps): fixed the E_PIXMAP paths - the
- edit items were moved beneath 'EditPlaceholder'. This gets rid of
- those long Bonobo warnings! (and we get the icons back)
-
- * gui/dialogs/comp-editor.c (pixmaps): removed the PrintPreview toolbar
- icon, since it doesn't appear in the xml file. Gets rid of warning.
-
- * gui/dialogs/event-page.c (notify_dates_changed): new function to
- emit the notification signal when the dates are changed. It also
- handles timezones now.
-
- * gui/dialogs/comp-editor-page.h (CompEditorPageDates): used
- CalComponentDateTime for start/end/due so we have the timezone as well
- as the time.
-
- * gui/dialogs/comp-editor-util.c (comp_editor_dates): updated to get
- the timezones as well as the times.
- (comp_editor_free_dates): new function needed to free all the structs.
-
- * gui/dialogs/recurrence-page.c (recurrence_page_set_dates): added call
- to preview_recur() to make sure the preview gets updated.
-
- * gui/dialogs/alarm-page.c (alarm_page_fill_widgets): free the
- CompEditorPageDates struct after use.
-
- * gui/tag-calendar.c (tag_calendar_by_comp): added 'comp_is_on_server'
- argument. If FALSE, we try to use builtin timezones first. This is
- needed for the recurrence page of the event editor, because the
- timezones may not have been added to the server yet. This and the
- changes to the notification stuff should fix bug #5034.
-
- * gui/gnome-cal.c (dn_query_obj_updated_cb): call above
- tag_calendar_by_comp() with TRUE since the events will be on the
- server in this case.
-
- * gui/e-day-view-layout.c:
- * gui/e-day-view.c: made sure an event always takes up at least one
- row, even when the start & end times are the same. Fixes bug #5944.
- I don't know if we should try to also handle events with the end time
- before the start time.
-
- * gui/e-week-view.c (e_week_view_style_set): check that the small font
- is actually smaller than the normal font. If it isn't, don't use it.
- Hopefully fixes bug #6876.
- (e_week_view_on_new_appointment): if only one day is selected, then
- we set the initial time of the event to 1/2-hour from the start of the
- working day, to differentiate 'New Appointment' from 'New All Day
- Event'. Fixes bug #8892.
-
- * gui/e-day-view.c (e_day_view_on_new_appointment): do the same as the
- above.
-
-2001-09-26 Federico Mena Quintero <federico@ximian.com>
-
- Fixes the GUI part of bug #7892.
-
- * gui/dialogs/alarm-page.c (get_alarm_duration_string): Return
- NULL if the duration is zero.
- (get_alarm_string): Handle duration of zero. Also, hopefully
- make the strings be more l10n-friendly.
-
- * gui/alarm-notify/alarm.c (alarm_ready_cb): I am a moron. Fix
- reversed test.
-
-2001-09-26 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/comp-editor.c (comp_editor_destroy): disconnect
- signals first thing
-
-2001-09-26 Dan Winship <danw@ximian.com>
-
- * gui/Makefile.am (evolution_calendar_LDFLAGS): Add
- -export-dynamic to make glade custom widgets work on non-Linux.
-
-2001-09-26 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-util/cal-util.h: added CAL_MODE_INVALID to CalMode enum
-
-2001-09-26 JP Rosevear <jpr@ximian.com>
-
- * pcs/cal.h: new proto
-
- * pcs/cal.c (impl_Cal_set_mode): implement set mode method
- (cal_class_init): set setMode function in epv
- (cal_notify_mode): notify listener of mode change
-
- * pcs/cal-factory.c (add_uri): deal with UriType renaming
-
- * pcs/cal-backend.h: add new virtual methods and protos
-
- * pcs/cal-backend.c (cal_backend_class_init): init new virtual
- methods to null
- (cal_backend_set_mode): sets mode
- (cal_backend_get_mode): gets mode
-
- * pcs/cal-backend-file.c (cal_backend_file_class_init): overide
- get_mode and set_mode methods
- (cal_backend_file_get_mode): return mode
- (notify_mode): have listeners notified of the set mode call
- (cal_backend_file_set_mode): set the mode by indicating not
- supported
-
- * cal-client/cal-listener.h: update proto
-
- * cal-client/cal-listener.c (impl_notifyCalSetMode): implement set
- mode callback
- (cal_listener_construct): take set mode callback
- (cal_listener_new): ditto
-
- * cal-client/cal-client.h: update protos, add signal proto
-
- * cal-client/cal-client.c (cal_client_class_init): add
- cal_set_mode signal
- (cal_set_mode_cb): handle set mode callback from listener
- (cal_client_open_calendar): pass additional param to cal_listener_new
- (cal_client_set_mode): wrapper to set the calendar mode
-
- * idl/evolution-calendar.idl: make UriType into CalMode, add
- SetModeStatus enum and notifyCalSetMode method to the listener
-
- * gui/calendar-offline-handler.c (create_connection_list): fetch
- the uri list ourselves
- (impl_prepareForOffline): reflect param change of
- create_connect_list
- (update_offline): ditto
- (backend_cal_set_mode): set mode call back
- (backend_cal_opened): cal opened call back, set mode to local
- (impl_goOffline): reflect UriType renaming
-
- * cal-util/cal-util.h: rename UriType to CalMode
-
-2001-09-25 Federico Mena Quintero <federico@ximian.com>
-
- Warning fixes courtesy of Chris Lahey <clahey@ximian.com>.
-
- * gui/e-itip-control.c (write_html): Warning fixes. Also, don't
- strdup() more than necessary.
-
- * gui/e-meeting-time-sel.c (e_meeting_time_selector_refresh_cb):
- Warning fixes.
-
- * gui/itip-utils.c (itip_addresses_get): Warning fixes.
-
- * gui/print.c (print_day_background): Warning fixes.
-
- * gui/dialogs/alarm-options.c (alarm_to_aalarm_widgets): Warning
- fixes.
- (alarm_to_palarm_widgets): Likewise.
-
- * gui/dialogs/delete-comp.c: #include "../calendar-config.h"
-
-2001-09-25 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/alarm.c (alarm_ready_cb): Check that the
- timeout is not set up before we create a new one; the alarm_fn
- callback may cause the alarm system to re-enter and add a new
- alarm. Fixes bug #10840.
- (pop_alarm): Assert that there is at least one alarm in the queue.
-
-2001-09-25 JP Rosevear <jpr@ximian.com>
-
- * pcs/cal.c: use bonobo-exception stuff to clean code
-
- * pcs/cal-factory.c (add_uri): add uri to the list if the type
- matches
- (impl_CalFactory_uriList): implement uriList method
-
- * pcs/cal-backend.h: new virtual function member
-
- * pcs/cal-backend.c (cal_backend_is_remote): call virtual function
-
- * pcs/cal-backend-file.c (cal_backend_file_class_init): override
- virtual function
- (cal_backend_file_is_remote): new virtual function, always return
- FALSE
-
- * idl/evolution-calendar.idl: uriList factory call, with flags for
- types to get
-
- * gui/dialogs/comp-editor.c (comp_editor_destroy): cast to remove
- warning
-
- * gui/e-itip-control.c (write_label_piece): kill warnings by take
- const char *
-
- * gui/component-factory.c (create_object): aggregate offline
- interface
-
- * gui/Makefile.am: compile new files
-
- * calobj.[hc]: Remove obsolete files
-
- * cal-util/cal-util.h: enum URI types for uriList call
-
- * cal-client/cal-client.c (build_uri_list): build list from string
- sequence
- (cal_client_uri_list): factory call to get uri list
-
- * cal-client/cal-client.h: new proto
-
- * cal-client/cal-client.c: use bonobo exception stuff to clean
- code
-
- * gui/calendar-offline-handler.[hc]: Start some skeleton routines
- for online/offline handling
-
- * pcs/cal-factory.c (launch_backend_for_uri): use accessor and
- remove FIXME
-
-2001-09-23 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (set_date_label): base text on component
- type
-
-2001-09-20 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/component-factory.c: don't use gnome_vfs_uri_new_private
- (fixes Ximian #10544)
-
-2001-09-20 Federico Mena Quintero <federico@ximian.com>
-
- * gui/component-factory.c: #include a few files we were missing
- from libgnomevfs.
-
-2001-09-20 JP Rosevear <jpr@ximian.com>
-
- * pcs/cal-backend-file.c (load_db): gets a config db
- (cal_backend_file_destroy): release config db
- (cal_backend_file_init): use load_db
- (mail_account_get): gets a mail account by number
- (mail_account_get_default): gets the default mail account
- (mail_account_is_valid): looks to see if any accounts have the
- given address
- (create_user_free_busy): modularize so we can call multiple times
- if necessary, set organizer
- (cal_backend_file_get_free_busy): if the list of users is null,
- use the default account otherwise get the same info for each
- address that is an identity in the mailer
-
- * gui/itip-utils.c (itip_addresses_get): s/gint/glong/ for bonobo
- conf returns
-
- * gui/calendar-commands.c (publish_freebusy_cmd): fix problems
- from a merge so that we publish 6 weeks of free/busy information
- again
-
-2001-09-20 Larry Ewing <lewing@ximian.com>
-
- * gui/dialogs/recurrence-page.c (recurrence_page_destroy): make
- sure to release the ref on priv->comp.
-
- * gui/dialogs/comp-editor.c (real_edit_comp): make sure to release
- the ref on priv->comp.
-
-2001-09-19 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/alarm-queue.c (audio_notification): Display a
- notification message always, in addition to playing the sound.
- (procedure_notification): Present a confirmation dialog before
- actually running the alarm's program.
- (procedure_notification): Use gnome_execute_shell() instead of
- gnome_execute_async() so that we handle multiple arguments
- properly. Plus, it is most likely what the user expects.
- (mail_notification): Display a message about unsupported email
- reminders instead of blindly dropping the alarm.
-
- * gui/dialogs/alarm-options.glade: Added an explanatory message
- about mail alarms not being supported.
-
- * gui/dialogs/alarm-page.glade: Removed the "Send an email"
- option.
-
- * gui/dialogs/alarm-page.c (action_map): Removed CAL_ALARM_EMAIL.
-
-2001-09-19 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/task-editor.c (init_widgets): listen for model
- changes
- (task_editor_edit_comp): add the attendees to the model and notify
- of need send
- (row_count_changed_cb): mark as changed when row added/deleted
- (model_row_changed_cb): mark as changed when row changes
-
- * gui/dialogs/event-editor.c (init_widgets): listen for model
- changes
- (event_editor_init): flip page order
- (event_editor_edit_comp): set needs send value
- (schedule_meeting_cmd): flip page order
- (row_count_changed_cb): mark as changed when row added/deleted
- (model_row_changed_cb): mark as changed when row changes
-
- * gui/dialogs/schedule-page.c: remove model change notification
- stuff
- (schedule_page_fill_widgets): no need to do the needs_send here
- because the editor handles this since it owns the model
-
- * gui/dialogs/event-editor.c (init_widgets): listen for model
- changes
- (event_editor_init): flip page order
- (event_editor_edit_comp): set needs send value
- (schedule_meeting_cmd): flip page order
- (row_count_changed_cb): mark as changed when row added/deleted
- (model_row_changed_cb): mark as changed when row changes
-
- * gui/dialogs/meeting-page.c (meeting_page_fill_widgets): no need
- to do the needs_send here because the editor handles this since it
- owns the model
- (invite_entry_changed): ditto
-
- * gui/dialogs/comp-editor.c (comp_editor_set_changed): new
- accessor
- (comp_editor_get_changed): ditto
- (comp_editor_set_needs_send): ditto
- (comp_editor_get_needs_send): ditto
-
- * gui/dialogs/comp-editor.h: new protos
-
- * gui/itip-utils.c (itip_addresses_get): reflect configuration
- path changes in the mailer
-
- * gui/e-meeting-model.c: remove commented out code, ifdef one
- section for later
-
-2001-09-19 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal-factory.c (cal_factory_oaf_register): add a new parameter
- (const char *iid) to specify the OAFIID of the factory being
- registered
-
-2001-09-19 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-model.c (e_meeting_model_refresh_busy_periods):
- remove silly debug #if 0
-
- * gui/calendar-commands.c (publish_freebusy_cmd): g_list_free
- rather than g_free
-
- * gui/e-itip-control.c (write_html): eliminate code path that
- caused double freed memory
-
-2001-09-18 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/schedule-page.*: A page that shows the meeting time
- selector and free/busy data for attendees
-
- * gui/dialogs/meeting-page.c: use the meeting model to track/edit
- attendees, remove table value conversion routines and simple table
- routines
- (set_attendees): take a pointer array
- (meeting_page_destroy): destroy the pointer array, save state
- (meeting_page_init): new pointer array
- (meeting_page_fill_widgets): don't null the deleted attendees
- field
- (popup_delegate_cb): array add
- (popup_delete_cb): array add
- (cleanup_attendees): iterate over the array to unref now
- (meeting_page_fill_widgets): don't null out fields, no need to add
- attendees here
- (invite_entry_changed): use e_meeting_attendee routines
- (popup_delegate_cb): ditto
- (popup_delete_cb): ditto
- (meeting_page_new): take new arg and pass it to construct
- (meeting_page_construct): take new arg, use e-meeting-model
- routines to construct table
-
- * gui/dialogs/task-editor.c (task_editor_init): new meeting model
- (task_editor_destroy): unref the model
-
- * gui/dialogs/event-editor.c (event_editor_init): make new model
- and pass it to meeting and schedule pages
- (event_editor_set_cal_client): virtual function, set meeting model
- client
- (event_editor_edit_comp): add the attendees to the model
- (event_editor_destroy): unref model
-
- * gui/dialogs/comp-editor.h: add virtual function
- * gui/dialogs/comp-editor.c (comp_editor_set_cal_client): make
- set_cal_client a virutal function
-
- * gui/e-meeting-types.h: generally useful type defines
-
- * gui/e-meeting-time-sel*.[hc]: Move here and use an e-table for
- the attendee list and extract display information from the new
- meeting model and attendees
-
- * gui/e-meeting-time-sel.etspec: spec for the table
-
- * gui/e-meeting-attendee.[hc]: meeting attendees for the model,
- with to/from conversions for CalComponentAttendee structure, emits
- changed signal and allows getting and setting of free busy
- periods
-
- * gui/e-meeting-model.[hc]: move the model out on its own
-
- * gui/e-itip-control.c (write_error_html): clean up warnings
-
-2001-09-18 Federico Mena Quintero <federico@ximian.com>
-
- Fixes bug #6350.
-
- * gui/component-factory.c (remove_folder): Use a simplified method
- for removing our folder data; we just need to remove calendar.ics
- or tasks.ics and the corresponding backup files.
-
-2001-09-18 Federico Mena Quintero <federico@ximian.com>
-
- Fixes bug #2830.
-
- * gui/calendar-config.c (calendar_config_get_confirm_delete): New
- function.
- (calendar_config_set_confirm_delete): New function.
- (config_read): Get the default value for the ConfirmDelete option.
- (calendar_config_write): Set the value of ConfirmDelete.
-
- * gui/dialogs/delete-comp.c (delete_component_dialog): Handle the
- configuration option for confirmation.
-
- * gui/dialogs/cal-prefs-dialog.c (CalPrefsDialogPrivate): Added
- the fields for the Other page.
- (get_widgets): Handle the new widgets.
- (cal_prefs_dialog_show_config): Likewise.
- (cal_prefs_dialog_update_config): Likewise.
-
-2001-09-18 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-client/cal-client-multi.[ch]: new class for managing multiple
- calendars, with an API very similar to the CalClient one,
- for ease of transition from one to the other
-
- * gui/component-factory.c (xfer_folder, remove_folder, create_folder):
- reworked to be able to manage folders for any calendar backend, and
- not only the file: one
-
-2001-09-18 Rodrigo Moya <rodrigo@ximian.com>
-
- * idl/evolution-calendar.idl: changed signature for the getFreeBusy
- method, to return a sequence of CalObj's, and added sequence of users
- as a new parameter to that method
-
- * cal-client/cal-client.c (cal_client_get_free_busy): adapted to new
- IDL method signature, by adding a new "GList *users" parameter, for
- callers to be able to specify a list of users
-
- * pcs/cal-backend.[ch] (cal_backend_get_free_busy):
- * pcs/cal-backend-file.c (cal_backend_file_get_free_busy): add the
- "GList *users" parameter. In cal_backend_file_get_free_busy, call
- lookup_component to get the CalComponent for each uid, instead
- of calling cal_backend_get_object, which meant converting the
- component to a string and then parsing it again.
-
- * cal-client/client-test.c (cal_opened_cb):
- * gui/e-itip-control.c (send_freebusy):
- * gui/calendar-commands.c (publish_freebusy_cmd): adapted to
- new getFreeBusy method signature
-
-2001-09-17 Damon Chaplin <damon@ximian.com>
-
- * gui/calendar-model.c: added a timeout to refresh the list every
- 10 minutes. Not ideal, as the user may be editing a task when it gets
- refreshed.
- (adjust_query_sexp): use the 'completed-before?' operator to filter
- out tasks according to the config settings.
-
- * gui/dialogs/task-details-page.c (task_details_page_fill_widgets):
- added support for the 'Completed' date. This code must have got lost
- somewhere, as it used to work.
- (date_changed_cb): set the priv->updating flag while updating the other
- widgets.
-
- * pcs/cal-backend-file.c (cal_backend_file_update_objects): made sure
- we freed the components.
-
- * pcs/query.c (func_completed_before): added 'completed-before?'
- operator.
-
- * gui/calendar-config.c (calendar_config_configure_e_cell_date_edit):
- don't set the lower & upper hour. Use 0-24 like the EDateEdit does.
-
- * gui/dialogs/cal-prefs-dialog.c (cal_prefs_dialog_show_config): set
- the 12/24-hour time format options sensitive only if we support both.
-
- * gui/calendar-config.c (config_read): if the locale doesn't define
- 'am' and 'pm' strings then we must use 24-hour format.
-
- * gui/calendar-commands.c (calendar_set_folder_bar_label): don't
- translate the '%d' as it doesn't make much sense. Resolves bug #8027.
-
-2001-09-17 Federico Mena Quintero <federico@ximian.com>
-
- * gui/component-factory.c (owner_set_cb): Do not call
- calendar_config_init() here.
-
- * gui/main.c (main): Call calendar_config_init() here.
-
-2001-09-17 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/alarm.c (queue_alarm): Duh, only setup the
- timeout if the list was empty.
- (alarm_ready_cb): Notify with the ID of the original alarm.
- (alarm_remove): Likewise.
-
-2001-09-17 Federico Mena Quintero <federico@ximian.com>
-
- Switch the alarm system from using SIGALRM to normal glib timers.
- Also, use a more robust de-queueing mechanism.
-
- * gui/alarm-notify/alarm.c (alarm_init): Removed.
- (alarm_done): Remove the glib timeout instead of closing the pipes
- and the signal handler.
- (alarm_add): Allow adding alarms that happen before right now.
- (queue_alarm): Use a glib timer instead of a signal.
- (alarm_remove): Adjust the timeout as appropriate.
-
- * gui/alarm-notify/notify-main.c (main): There is no need to
- initialize the alarm system now.
-
- * gui/main.c (main): Likewise.
-
-2001-09-17 JP Rosevear <jpr@ximian.com>
-
- * gui/calendar-model.c (calendar_model_init): get itip addresses
- (calendar_model_destroy): destroy same
- (calendar_model_value_at): do more thorough checking on whether to
- use recurring, assigned, assigned to or regular task icons
-
-2001-09-17 JP Rosevear <jpr@ximian.com>
-
- * cal-util/cal-component.c (for_each_remove_all_alarms): for each
- call back, removes the alarms
- (cal_component_remove_all_alarms): remove all alarms from the
- component
-
- * cal-util/cal-component.h: new proto
-
- * gui/e-itip-control.c (write_error_html): writes error messages
- rather than normal html
-
- * gui/itip-utils.c (itip_send_comp): remove all alarms if the
- method warrants it
-
-2001-09-16 Christopher James Lahey <clahey@ximian.com>
-
- * gui/dialogs/meeting-page.c (build_etable): Updated this to match
- the new ETableSimple interface.
-
-2001-09-14 Ettore Perazzoli <ettore@ximian.com>
-
- [Automake 1.5 fixes pointed out by Richard Boulton
- <richard@tartarus.org>, as per #9258.]
-
- * cal-client/Makefile.am: Set CLEANFILES directly instead of using
- `+='.
- * gui/Makefile.am: Likewise.
- * gui/alarm-notify/Makefile.am: Likewise.
- * pcs/Makefile.am: Likewise.
-
-2001-09-14 Damon Chaplin <damon@ximian.com>
-
- * gui/e-itip-control.c (ok_clicked_cb): added space after 'identities'
- in the message. Fixes bug #9896.
-
-2001-09-14 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/e-calendar.conduit.in: remove translation
- marker for now
-
-2001-09-13 JP Rosevear <jpr@ximian.com>
-
- * cal-util/cal-component.h: use ical partstat, role, cutypes
- directly
-
- * cal-util/cal-component.c: ditto
-
- * gui/e-itip-control.c (find_my_address): set my addresses if the
- addresses match
- (find_attendee): strstr returns non-null on a match
- (write_html): use new icon, select the name displayed (organizer
- or attendee) based on method,
- (ok_clicked_cb): when rsvp'ing strip off all but the attendee
- being replied for as is specified in the spec
- (find_attendee_partstat): new util function to extract the
- partstat of an attendee
- (update_attendee_status): updates the partstat of a specific
- attendee in the reply message
-
- * gui/dialogs/meeting-page.c: use ical partstat, role, cutypes
- directly
- (popup_delegate_cb): if we delegate, notify of needs send and
- changed
- (popup_delete_cb): notify of needs send and changed for each
- deletion
-
-2001-09-12 JP Rosevear <jpr@ximian.com>
-
- * gui/calendar-commands.c (publish_freebusy_cmd): send 6 weeks of
- free busy info starting with the UTC start of day
-
- * gui/itip-utils.c (get_label): create a text representation of
- the given icaltime
- (itip_send_comp): if the summary is empty, set the subject based
- on the type of component, put the right extension on free/busy
- components and base descriptions on type of component, include
- start/end for free/busy info
-
-2001-09-11 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/alarm-queue.c (display_notification): Added an
- use_description argument so that other alarms can fall back to
- this type.
- (audio_notification): Implemented.
- (remove_comp): Call remove_queued_alarm() here; there is no longer
- a destroy notification function for alarms so must we do this
- manually.
- (alarm_trigger_cb): Do not pass the alarm to the notification
- functions so that we can free it ourselves before all the alarms
- in the component get freed.
- (display_notification): Get the alarm here instead of getting it
- as an argument.
- (procedure_notification): Implemented.
-
-2001-09-11 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/meeting-page.c (invite_entry_changed): free the
- destination vector when we finish with it, if we actually add
- anyone, notify listeners of the needs send and changed info. Fixes
- bug #8632.
-
-2001-09-10 Zbigniew Chyla <cyba@gnome.pl>
-
- * gui/print.c
- (format_date): Convert string generated by strftime to UTF-8.
- (print_week_view_background): Ditto.
- (print_month_summary): Ditto.
- (print_month_small): Use U_() instead of _().
- (print_day_background): Ditto.
- (print_todo_details): Ditto.
- (print_date_label): Convert generated string to UTF-8.
-
-2001-09-10 Federico Mena Quintero <federico@ximian.com>
-
- * cal-util/cal-component.c (cal_component_alarm_get_attach):
- Handle the new icalattach type instead of struct icalattachtype.
- (cal_component_alarm_set_attach): Likewise.
-
- * gui/dialogs/alarm-options.c (alarm_to_aalarm_widgets): Likewise.
- (alarm_to_palarm_widgets): Likewise.
- (aalarm_widgets_to_alarm): Likewise.
- (palarm_widgets_to_alarm): Likewise.
-
-2001-09-05 Ettore Perazzoli <ettore@ximian.com>
-
- [Fix #958, ShellComponents should not be created by factories, for
- the calendar.]
-
- * gui/GNOME_Evolution_Calendar.oaf.in: Remove the
- ShellComponentFactory.
-
- * gui/component-factory.c (create_object): Renamed from
- `component_fn'. Don't get any args.
- (component_factory_init): Create the component using
- `create_object()' and register it into OAF.
- (COMPONENT_FACTORY_ID): Removed.
- (COMPONENT_ID): New.
-
-2001-09-04 Federico Mena Quintero <federico@ximian.com>
-
- * gui/component-factory.c (sc_user_create_new_item_cb):
- Implemented.
-
- * gui/main.c (component_editor_factory_init): New function to
- create the factory for the comp_editor_factory.
-
- * gui/comp-editor-factory.c: Finished implementation.
-
- * gui/alarm-notify/alarm-queue.c (edit_component): Implemented the
- Edit command.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Added
- comp-editor-factory.[ch] to the list of sources.
-
-2001-09-03 Damon Chaplin <damon@ximian.com>
-
- * gui/calendar-commands.c (calendar_control_activate):
- * gui/tasks-control.c (tasks_control_activate): don't call
- calendar_config_check_timezone_set() now, since the startup wizard
- handles that.
-
- * gui/e-tasks.c (e_tasks_class_init): changed selection_changed signal
- to GTK_RUN_LAST. It has no reason to be GTK_RUN_FIRST.
-
- * gui/gnome-cal.c:
- * gui/e-week-view.c:
- * gui/e-day-view.c: added "selection_changed" signal,
- XX_delete_event() and XX_get_num_events_selected().
-
- * gui/e-day-view-top-item.c (e_day_view_top_item_draw): fix the shadow
- around the dates at the top - it was 1 pixel off.
-
- * gui/calendar-commands.c: added sensitize_commands(), similar to in
- tasks-control.c, so we only make Cut/Copy/Delete sensitive when an
- event is selected. Also added delete_event_cmd().
-
- * gui/dialogs/task-page.c (task_page_set_summary):
- * gui/dialogs/event-page.c (event_page_set_summary): do nothing,
- since the summary only gets changed on the main event/task page now.
- Fixes bug #6939.
-
- * gui/e-day-view.c (e_day_view_on_main_canvas_drag_data_received):
- (e_day_view_on_top_canvas_drag_data_received): check that we are
- dragging an event from the same EDayView. We currently don't support
- DnD from other widgets.
- (e_day_view_update_top_canvas_drag): only get the summary if we
- actually have an event. Fixes bug #5162.
-
- * gui/e-day-view.c (e_day_view_on_editing_stopped): if the text hasn't
- changed we need to call e_day_view_update_event_label() to show the
- times again if necessary. Fixes bug #1813.
-
- * gui/dialogs/comp-editor.c (comp_editor_destroy): destroy the
- CompEditorPage objects here rather than in close_dialog(), after the
- widgets have been destroyed. We do this because the widgets have lots
- of signal handlers connected with the CompEditorPage objects as the
- signal data, so we want to ensure that the data pointer is always
- valid. (Alternatively we could disconnect all the handlers when the
- CompEditorPage objects are destroyed, or use connect_while_alive()).
- Fixes bug #7543.
-
- Note: there is still a small bug in that if you type in a time and
- then hit 'Save and Close', the time won't be saved. I'm not sure
- where this should be fixed - should the actions which close the
- dialog grab the focus to the toplevel, so any widgets currently
- being edited finish the edit and emit 'changed'?
-
- * gui/dialogs/recurrence-page.c (append_exception): use
- gtk_clist_set_row_data_full() so freeing is handled automatically by
- the GtkClist. This helps avoid problems at destroy-time.
- (exception_delete_cb): just call gtk_clist_remove() now. No need to
- free the row data as GtkCList now handles it.
- (recurrence_page_destroy): no need to free the data in the clist.
-
- * gui/dialogs/alarm-page.c: ditto.
-
- * gui/dialogs/meeting-page.c: ditto.
- (etable_destroy_cb): save the ETable state in this new handler cb
- rather than in the destroy method, since the widget will already be
- destroyed by then.
-
-2001-08-31 Damon Chaplin <damon@ximian.com>
-
- * gui/e-itip-control.c: changed 3 occurrences of 'Replyed' to 'replied'
-
-2001-08-31 Zbigniew Chyla <cyba@gnome.pl>
-
- * gui/e-itip-control.c (write_html):
- Marked strings for translation (with U_).
-
- * gui/itip-utils.c (itip_send_comp):
- Ditto.
-
-2001-08-31 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/comp-editor-util.c (comp_editor_contacts_to_widget):
- (comp_editor_contacts_to_component): fix debugging messages so they
- use "" rather than NULL. Fixes bug #8559.
-
-2001-08-29 Federico Mena Quintero <federico@ximian.com>
-
- * pcs/cal-backend-file.c (cal_backend_file_remove_object): See if
- the set of categories changed by using the removed_categories hash
- table.
- (cal_backend_file_init): Create a table of removed categories.
- This allows us to notify if and only if the set of category
- changes when an object is updated/removed, instead of
- unconditionally notifying if an object is updated.
- (cal_backend_file_update_objects): Only notify if the set of
- categories really changed.
- (update_categories_from_comp): Shuffle the categories between the
- priv->categories and priv->removed_categories lists.
-
-2001-08-28 Federico Mena Quintero <federico@ximian.com>
-
- Fixes bug #7879, a query may receive an update notification from
- the backend before the query itself gets populated.
-
- * pcs/query.c (ensure_sexp): New function; ensures that the esexp
- is created and notifies of parse errors. It is the bulk of
- start_query_cb() but put in a separate function so that we can
- share it elsewhere.
- (start_query_cb): Use ensure_sexp().
- (process_component_cb): Oops, notify of a successfully finished
- query.
- (match_component): Call ensure_sexp(). This function can be
- called by the backend notification callbacks before the query is
- populated, so we need to make sure the esexp exists here.
-
-2001-08-22 Federico Mena Quintero <federico@ximian.com>
-
- * gui/cal-search-bar.c (cal_search_bar_construct): Set the
- "category is" criterion as the default for the calendar and tasks.
-
-2001-08-22 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/recurrence-page.c (recurrence_page_fill_widgets):
- Unset the priv->updating flag before returning in the case the
- component has no recurrence information. Fixes bug #6850.
-
-2001-08-22 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/alarm-queue.c (QueuedAlarm): Added a snooze
- flag to differentiate snoozed alarms from real occurrences.
- (add_component_alarms): Do not specify a destroy function for the
- alarm trigger. We handle this in the callbacks now.
- (alarm_trigger_cb): Just remove the alarms for the unimplemented
- notification types.
- (create_snooze): Implemented snooze.
- (notify_dialog_cb): Snooze as appropriate.
-
-2001-08-22 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (foreach_tzid_callback): call back to add
- timezones to the top level
- (itip_send_comp): call icalcomponent_foreach_tzid
-
-2001-08-22 Dan Winship <danw@ximian.com>
-
- * gui/gnome-cal.c: #include <libgnomevfs/gnome-vfs-types.h> so
- this will compile against gnome-vfs 1.0.1.
-
-2001-08-22 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_open): open the tasks folder
- associated with the calendar being opened, and not always the local
- tasks.ics file
-
- * pcs/cal-factory.c (open_fn): use gnome_vfs_uri_new_private when
- parsing the URI to allow non-registered URIs
-
-2001-08-21 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/alarm-options.c (alarm_to_palarm_widgets): Handle
- the case where there is no attachment. Fixes bug #7257.
-
-2001-08-21 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (write_html): strip the mailto bit for the
- email address if we display it
-
-2001-08-21 Damon Chaplin <damon@ximian.com>
-
- * pcs/query.c (func_is_completed): added new e-sexp operator. We
- don't currently use it though.
-
- * gui/dialogs/cal-prefs-dialog.glade: Changed '_Overdue' to 'O_verdue'
- since we have an '_Other' notebook tab. Added '_Hide' accel.
-
- * gui/dialogs/cal-prefs-dialog.c: hooked up config options to dialog.
-
- * gui/calendar-config.c: added config options for hiding completed
- tasks.
-
- * gui/e-week-view-event-item.c (e_week_view_event_item_draw):
- * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event):
- * gui/e-day-view.c (e_day_view_reshape_long_event): added 2 pixels
- extra space between icons and text for long events, and 1 pixel space
- between icons in all events.
- (e_day_view_realize): changed the background color to match the
- EGrayBar in the shell.
-
-2001-08-21 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal-backend-util.[ch]: new files to contain utility functions
- for calendar backends
-
- * pcs/cal-backend.c (cal_backend_add_cal): implement it here, and not in
- the calendar backends. Add a "cal_added" signal, so that backends are
- notified when a new Cal is added, if they need to
- (cal_backend_get_type_by_uid): implement it here
-
- * pcs/cal-backend-file.c (fill_alarm_instances_seq): moved to
- cal-backend-util.c
- (cal_backend_file_add_cal): removed
- (cal_backend_file_init): connect to the "cal_added" signal in the
- CalBackend class so that we can update categories when a new Cal is
- added
- (cal_backend_file_get_type_by_uid): removed
-
- * pcs/cal-backend-db.c (fill_alarm_instances_seq): moved to
- cal-backend-util.c
- (cal_backend_db_add_cal): removed
- (cal_backend_db_get_type_by_uid): removed
-
- * AUTHORS: added JP and Damon to list of authors
-
-2001-08-20 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-util/cal-util.[ch] (cal_util_generate_alarms_for_list):
- (cal_util_generate_alarms_for_comp):
- new functions moved from the CalBackendFile, to allow its use outside
- of it. The signature has changed a little bit, since these functions
- need a way to get the timezones from the callers, so a callback
- function to resolve the timezones has been added to the list of
- parameters
-
- * pcs/cal-backend-file.c (generate_alarms_for_list):
- (generate_alarms_for_comp): moved to cal-util, with all their related
- functions/structures
-
- * pcs/cal-backend-db.c: removed functions that were moved to cal-util
-
-2001-08-20 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/comp-editor.c (pixmaps): use Delete icon in menu, and
- change to bigger Save icon in toolbar.
-
- * gui/tasks-control.c:
- * gui/calendar-commands.c (pixmaps): used new_task-16.png and
- goto-16.png.
-
-2001-08-20 Damon Chaplin <damon@ximian.com>
-
- * gui/calendar-commands.c (pixmaps): added delete icons for menu
- and toolbar.
-
-2001-08-20 Damon Chaplin <damon@ximian.com>
-
- * gui/tasks-control.c: added Cut/Copy/Paste icons for toolbar.
-
-2001-08-20 Damon Chaplin <damon@ximian.com>
-
- * gui/tasks-control.c: uses new delete icons in menu & toolbar.
-
-2001-08-19 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c: Update the folder list to include a
- display name and a description.
-
-2001-08-20 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/comp-editor.c (pixmaps): use new delete icon for toolbar.
-
-2001-08-19 Damon Chaplin <damon@ximian.com>
-
- * gui/e-itip-control.c: fixed typo, 'send' -> 'sent'. Bug #7621.
-
-2001-08-18 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/cal-prefs-dialog.glade: added option to hide completed
- tasks after a given number of minutes/hours/days. Unfinished.
-
- * gui/dialogs/event-page.c (event_page_fill_component): initialize
- zone to NULL to avoid a warning.
- (contacts_clicked_cb): work around a bug in SelectNames by notifying
- that the page has changed when you click the 'Contacts' button.
- Otherwise it is easy to lose changes.
-
- * gui/dialogs/task-page.c (contacts_clicked_cb): ditto.
-
-2001-08-18 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/comp-editor.c (pixmaps): used new Save/Save As icons.
-
- * gui/tasks-control.c:
- * gui/calendar-commands.c (pixmaps): added new Cut/Copy/Paste icons,
- and changed the 'New Task' icon to use the bigger one I made.
-
-2001-08-05 Zbigniew Chyla <cyba@gnome.pl>
-
- * gui/dialogs/task-page.c (summary_changed_cb):
- Use e_dialog_editable_get instead of gtk_editable_get_chars (we need
- UTF-8 string).
-
-2001-08-18 Zbigniew Chyla <cyba@gnome.pl>
-
- * gui/calendar-config.c (locale_uses_24h_time_format): New.
- (config_read): Use locale's setting as default for
- /Calendar/Display/Use24HourFormat so that Europeans don't have to
- switch to 24-hour format manually.
-
-2001-08-17 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (destroy): destroy the addresses
- (clean_up): don't free the addresses, we need them
-
-2001-08-17 Damon Chaplin <damon@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_new_task): new function to open the
- task editor to add a new task.
-
- * gui/calendar-commands.c: added new_task_cb() to create a new task
- in the calendar folder, and added menu commands for it, and a toolbar
- button (I think that is what Ettore wanted. Maybe he just meant menu
- commands. Anyway, it is easy to take out.) Note that we don't have a
- decent icon for 'New Task' for the toolbar.
- Also added the new Goto button (but we don't have a similar one for
- the menu command).
-
-2001-08-16 Iain Holmes <iain@ximian.com>
-
- * gui/Makefile.am: Add the libetimezonedialog.a lib link
-
- * gui/calendar-config.c: Change the #include for the timezone dialog
-
- * gui/e-timezone-entry.c: Ditto.
-
- * gui/dialogs/Makefile.am: Remove the e-timezone-dialog stuff.
-
-2001-08-16 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/event-page.c: hide the timezone fields for all-day
- events. We will use DATE values for these eventually, and these
- don't have timezones associated with them. Currently we just use the
- default timezone for all-day events, as a workaround until we have
- DATE values working.
-
- * gui/dialogs/comp-editor-util.c (comp_editor_new_date_edit): added
- make_time_insensitive flag. Though we may not use it.
-
- * gui/dialogs/event-page.glade: made the 'All day event' toggle
- right-aligned, so it doesn't move when the other widgets are shown
- and hidden.
-
- * gui/e-timezone-entry.c (e_timezone_entry_set_default_timezone): new
- function to set the default timezone of the widget. If the current
- timezone setting matches the default then the entry field is hidden.
- Most people won't use timezones so this makes the GUI simpler.
-
- * gui/dialogs/event-page.c (init_widgets):
- * gui/dialogs/task-page.c (init_widgets): set the default timezone
- using the above function.
-
- * gui/dialogs/task-page.c (task_page_fill_widgets): if the start date
- or due date is not set, we use the default timezone, so the user
- doesn't have to set this each time they set the date.
-
-2001-08-16 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/alarm-page.c (alarm_page_fill_widgets): If the
- component has no alarms remember to set the priv->updating flag to
- FALSE before returning.
-
-2001-08-16 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/e-delegate-dialog.c
- (e_delegate_dialog_get_delegate_name): get the destinations
- property, not the text property
-
-2001-08-16 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/alarm-page.c (clear_widgets): Set the default-to-add
- notification to be display a message 15 minutes before the start
- of the appointment. Fixes bug #7175.
-
-2001-08-16 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/comp-editor-util.c (comp_editor_strip_categories):
- New function to strip surrounding whitespace from a string of
- categories entered by the user.
-
- * gui/dialogs/task-page.c (task_page_fill_component): Use
- comp_editor_strip_categories().
-
- * gui/dialogs/event-page.c (event_page_fill_component): Likewise.
-
-2001-08-16 Federico Mena Quintero <federico@ximian.com>
-
- * gui/calendar-config.c (calendar_config_configure_e_date_edit):
- Do not set the time popup range. We also want to be able to
- create appointments that are not within nine-to-five! Think of
- going to the movies! Fixes bug #7436.
-
- * gui/dialogs/cal-prefs-dialog.glade: "am/pm" is now "AM/PM".
- Fixes bug #7367.
-
-2001-08-16 Jon Trowbridge <trow@ximian.com>
-
- * gui/cal-search-bar.c: Changed to reflect my renaming of some of
- the more hideously-named functions in the ESearchBar API.
-
-2001-08-15 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/comp-editor.c (save_comp): only fill the component
- and save it if something has changed
- (save_comp_with_send): only try to send if something has changed
- and the editor needs a send
-
-2001-08-15 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/cal-prefs-dialog.glade: OK, re-added the default
- alarm options. Way too many people are asking for them.
-
-2001-08-15 Federico Mena Quintero <federico@ximian.com>
-
- * gui/component-factory.c (factory_fn): Add the user creatable
- items. The callback is not actually implemented yet; this is just
- to finalize the GUI.
-
- * gui/dialogs/cal-prefs-dialog.glade: Added an option to ask for
- confirmation when deleting items. Added underlined shortcuts
- (they may not all work currently).
-
-2001-08-14 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/task-page.c:
- * gui/dialogs/event-page.c: added support for the Contacts field.
- Note that I'm not sure what we should put in the iCalendar CONTACT
- properties. Currently we put "name <email>", but it isn't recognized
- as a contact when we reopen the dialog, so we may need more info here.
- Also we currently use a simple parser to parse the above format, and
- we should maybe use some camel function.
-
- * gui/dialogs/task-page.glade:
- * gui/dialogs/event-page.glade: replaced the GtkEntry fields for the
- Contacts with a GtkEventBox which we put the BonoboControl in at
- runtime.
-
- * gui/dialogs/meeting-page.c (invite_entry_changed): added FIXMEs
- since it doesn't seem to be freeing the EDestination stuff. JP?
-
- * gui/dialogs/comp-editor-util.c: added bunch of utility functions to
- handle the Contacts field in the main Event and Task pages.
-
- * gui/gnome-cal.c: added visible_start and visible_end fields, so we
- only emit the 'dates-shown-changed' signal when really necessary.
- Currently changing the folder title bar label results in a complete
- redraw of the Evolution window (silly GtkLabel queueing a resize),
- so we want to avoid that as much as possible.
- (gnome_calendar_new_appointment_for): only move the event's end time
- to the end of the day if it is not already 00:00:00.
-
- * gui/e-week-view-event-item.c:
- * gui/e-week-view.c:
- * gui/e-day-view.c: added support for double-clicking on an event to
- open it, and for double-clicking on the background to create a new
- event. There is still a minor problem to sort out, but it basically
- works.
-
- * cal-util/cal-component.c: added support for CONTACT properties,
- mainly by copying the code for COMMENT properties which are exactly
- the same type.
-
- * gui/e-day-view.c (e_day_view_realize): use the same color for the
- top canvas background as the shortcut bar, to make it look a little
- nicer (I think). Although we still have the theme problem with
- hard-coded colors.
-
-2001-08-14 Federico Mena Quintero <federico@ximian.com>
-
- * gui/e-calendar-table.etspec: Made the click-to-add message
- shorter. Fixes bug #7177.
-
-2001-08-14 Federico Mena Quintero <federico@ximian.com>
-
- * gui/calendar-commands.c (pixmaps): Added Tigert's new icons for
- Prev and Next.
-
-2001-08-14 Federico Mena Quintero <federico@ximian.com>
-
- * gui/cal-search-bar.c (make_suboptions): Make the "Any Category"
- item consistent with the one in the addressbook. Also, free the
- items correctly.
-
-2001-08-14 Federico Mena Quintero <federico@ximian.com>
-
- * gui/cal-search-bar.c (get_current_category): Handle an array of
- categories in the CalSearchBar instead of our own menu items.
- (notify_query_contains): Fetch the text from the search bar here
- instead of in regen_query().
- (regen_query): Handle category searches.
- (notify_category_is): New function.
- (cal_search_bar_construct): Do not create an option menu.
- (make_suboptions): New function to create the suboption items from
- the list of categories.
- (notify_query_contains): Do not include a category sexp here.
-
-2001-08-13 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (update_item): add dialog for feedback
- (remove_item): ditto
- (send_item): ditto
- (send_freebusy): ditto
-
-2001-08-13 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c: rewrite the gui to use gtkhtml
-
- * gui/Makefile.am: define the icon dir
-
-2001-08-12 Kjartan Maraas <kmaraas@gnome.org>
-
- * gui/e-itip-control.h: Remove #include <config.h> from here.
- * gui/itip-utilss.h: Same here.
-
-2001-08-11 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/tasks-control.c: Update the paths of the Tools menu
- according to the changes in the XML [i.e. things are moved to the
- ComponentToolsPlaceholder].
-
- * gui/calendar-commands.c: Likewise.
-
-2001-08-11 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/event-page.c (init_widgets):
- * gui/dialogs/task-page.c (init_widgets): turn on word-wrap for the
- description fields. Fixes bug #6821.
-
-2001-08-10 Jon Trowbridge <trow@ximian.com>
-
- * gui/cal-search-bar.c: Where we have ESearchBarItems, set their
- subitems to NULL.
-
-2001-08-09 Damon Chaplin <damon@ximian.com>
-
- * pcs/cal-backend.c (cal_backend_get_object_component): added new
- backend method to get the component given a UID.
-
- * pcs/cal-backend-file.c (cal_backend_file_get_object_component):
- added implementation of above virtual method.
-
- * pcs/query.c (match_component): use the new backend function to get
- the CalComponent rather than the string. This avoids converting all
- the calendar components to strings and parsing them back into
- components for every query! (That wasn't a good idea, was it ;)
-
- * gui/e-week-view.c:
- * gui/e-day-view.c: use a timeout handler to layout the events,
- to avoid doing a layout for each event we get from a query.
-
- * gui/print.c (print_day_add_event):
- * gui/e-day-view.c (e_day_view_add_event): set start_row_or_col and
- num_columns to 0. They are guint8's.
-
- * gui/e-week-view.c (e_week_view_free_events): hide all the jump
- buttons. Fixes bug #5946.
-
- * gui/calendar-commands.c (calendar_set_folder_bar_label): added the
- day numbers for the month view.
-
- * gui/dialogs/recurrence-page.glade: changed "_Delete" to "_Remove",
- since it clashed with "_Add". Also added underlined accelerators for
- the recurrence radio buttons. Note that none of these accelerators
- actually work at present, due to the way we are using .glade files
- for each notebook page. I need to add a bug about this.
- Also, the "_Action" menu doesn't popup when I press Alt+A, even though
- the "_File" menu does popup when I press Alt+F. Strange.
-
- * pcs/cal-backend-file.c (cal_backend_file_get_timezone_object):
- removed debug msgs.
-
-2001-08-09 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event):
- * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event):
- * gui/e-week-view-event-item.c (e_week_view_event_item_draw_icons):
- unref the GdkPixmap and GdkBitmap returned by the function
- e_categories_config_get_icon_for ()
-
-2001-08-09 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/task-page.*: Remove progress frame
-
- * gui/dialogs/task-details-page.*: Put in progress frame, remove
- basics frame
-
- * gui/dialogs/task-editor.c (set_menu_sens): util function to set
- menu sensitivity based on state
- (task_editor_init): add meeting page
- (task_editor_edit_comp): show page if necessary
- (task_editor_destroy): unref meeting page
- (assign_task_cmd): bring up meeting page
- (refresh_task_cmd): save before sending
- (forward_cmd): ditto
-
- * gui/dialogs/comp-editor.c (save_cmd): implement new save command
-
-2001-08-09 Federico Mena Quintero <federico@ximian.com>
-
- * gui/e-itip-control.c (destroy): Chain to the destroy handler in
- the parent class!
-
- * gui/dialogs/comp-editor-page.c (comp_editor_page_destroy):
- Likewise. Sigh.
-
- * gui/cal-search-bar.c (cal_search_bar_destroy): Whoops, added a
- destroy handler.
-
-2001-08-08 Damon Chaplin <damon@ximian.com>
-
- * gui/goto-dialog.glade: removed underlined accelerator key from
- "_Go To Today" button. GnomeDialog doesn't actually support underlined
- accelerator keys for buttons. We could hack it, like Glade does, if
- we really need to. Fixes bug #6418.
-
-2001-08-08 Federico Mena Quintero <federico@ximian.com>
-
- * gui/e-day-view.c (update_query): Stop editing any event. Fixes
- bug #5949.
-
-2001-08-08 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/alarm-page.c (alarm_page_fill_component): Duuuh, set
- the alarm_copy on the component, not the original alarm. Fixes
- bug #5214.
-
-2001-08-08 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/meeting-page.c (set_attendees): set the attendees of
- a component
- (meeting_page_fill_component): use above
- (meeting_page_get_cancel_comp): return a comp with the attendees
- to be cancelled
-
- * gui/dialogs/meeting-page.h: get a component that will be sent as
- a cancellation
-
- * gui/dialogs/event-editor.c (event_editor_class_init): override
- send_comp class method
- (event_editor_send_comp): send cancellation notices to deleted
- attendees
- (refresh_meeting_cmd): save before send
- (forward_cmd): ditto
-
- * gui/dialogs/comp-editor.c (comp_editor_class_init): set default
- send_comp method
- (real_send_comp): do the real work
- (comp_editor_send_comp): call class method
- (save_comp): don't do any sending
- (save_comp_with_send): save and send here
- (prompt_to_save_changes): use above
- (save_close_cmd): ditto
-
- * gui/dialogs/comp-editor.h: add virtual function
-
-2001-08-08 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-week-view-event-item.c
- (e_week_view_event_item_draw_icons): don't use a NULL mask in the
- call to gdk_gc_set_clip_mask
-
- * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event):
- ditto
-
- * gui/e-day-view-main-item.c
- (e_day_view_main_item_draw_day_event): ditto
-
-2001-08-08 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit-config.h: fix pre-processor
- macros
-
- * conduits/calendar/calendar-conduit.h: ditto
-
- * conduits/todo/todo-conduit-config.h: fix pre-processor macros
-
- * conduits/todo/todo-conduit.h: ditto
-
-2001-08-07 Federico Mena Quintero <federico@ximian.com>
-
- * cal-client/cal-listener.c (cal_listener_stop_notification): New
- function to stop further notification from happening.
- (impl_notifyCalOpened): Do not notify if requested.
- (impl_notifyObjUpdated): Likewise.
- (impl_notifyObjRemoved): Likewise.
- (impl_notifyCategoriesChanged): Likewise.
- (CalListenerPrivate): Do not keep a reference to the server-side
- Cal. This would create a circular reference since the server
- keeps a reference to the listener.
- (cal_listener_destroy): Likewise.
- (impl_notifyCalOpened): Likewise.
-
- * pcs/cal.c (cal_destroy): bonobo_object_release_unref() the listener.
-
- * cal-client/cal-client.c (cal_client_destroy): Ask the listener
- to stop notifications. Also, do not unref it as the server does
- that itself when we unref the Cal.
-
-2001-08-07 Federico Mena Quintero <federico@ximian.com>
-
- * gui/calendar-model.c (calendar_model_free_value): Only unref the
- FIELD_COMPONENT if it is non-NULL. We return a NULL for that
- field from ::initialize_value(), after all. Fixes bug #6098.
-
-2001-08-07 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (itip_send_comp): Make calendar.ics the
- suggested name when attaching the ical object
-
-2001-08-06 Damon Chaplin <damon@ximian.com>
-
- * gui/e-week-view.h:
- * gui/e-day-view.h: added 'different_timezone' fields to EDayViewEvent
- and EWeekViewEvent, to note that the event is in a different timezone.
- We now compute this once when we add the event to the array, rather
- than each time we draw the event. If it is set, we will draw the
- timezone icon next to the event.
-
- * gui/e-day-view-main-item.c: take transparency into account when
- drawing the blue vertical bars to represent busy time.
-
- * gui/tag-calendar.c: take transparency into account when tagging
- the mini calendar.
-
- * gui/e-calendar-table.c (e_calendar_table_init): removed the "None"
- options for transparency and classification, since these properties
- have defaults anyway, so we may as well use those to keep it simple.
- Also use "Free" and "Busy" for transparency, rather than "Transparent"
- and "Opaque".
-
- * gui/calendar-model.c: updated classification & transparency code
- as above.
-
- * gui/e-calendar-table.etspec: changed "Transparency" to "Show Time As"
- since people have a chance of understanding that.
-
- * gui/e-week-view.c:
- * gui/e-day-view.c:
- * gui/gnome-cal.c: added functions to get the visible time range.
-
- * gui/calendar-commands.c: finished stuff to set the folder bar
- label to the dates currently displayed.
-
- * gui/control-factory.c (control_factory_new_control): connected
- signal to update the folder title bar label when the dates shown
- are changed. I had to connect it here since we need the BonoboControl
- in the callback, and I don't know how to get the control from the
- widget.
-
- * gui/tasks-control.c (tasks_control_activate): clear the folder bar
- label. We could display something here at some point.
-
- * gui/dialogs/recurrence-page.glade: changed "_Add" to "A_dd", since
- we have an "_Actions" menu. (These also use Alt+key, right?)
-
- * gui/dialogs/event-page.glade:
- * gui/dialogs/event-page.c: added 'Show Time As' field, which is
- really the TRANSP property but with a better name!
- Also changed one of the "_Confidential" to "Con_fidential" since we
- already have "_Contacts" using the same 'C' key.
-
- * pcs/cal-backend-file.c (cal_backend_file_get_free_busy): skip
- events that are TRANSPARENT. Also added comment as this code looks
- inefficient.
-
- * cal-util/cal-component.c: removed stuff for comparing timezones.
-
- * gui/comp-util.c (cal_comp_util_compare_event_timezones): moved the
- above function here, and updated it to compare the UTC offsets of the
- times as well as the TZIDs.
-
-2001-08-06 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/cal-prefs-dialog.glade: In process of fixing bug
- #6005. The "Calendar" page is now "Display", and it has no
- frames. The "Task list" page has colons between the labels and
- the color pickers, and it has no frame.
-
-2001-08-06 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-client/cal-client.c (destroy_wombat_client): added check for
- NULL pointers. Maybe fixes #5203 (I can't reproduce it, so I'm not
- sure)
-
-2001-08-03 Federico Mena Quintero <federico@ximian.com>
-
- * cal-client/query-listener.c (query_listener_stop_notification):
- New function; stops further notification from happening. This is
- needed since the listener is destroyed asynchronously from the
- Wombat and the corresponding CalQuery may already have died.
- (impl_notifyObjUpdated): Do not notify if requested.
- (impl_notifyObjRemoved): Likewise.
- (impl_notifyQueryDone): Likewise.
- (impl_notifyEvalError): Likewise.
-
- * cal-client/cal-query.c (cal_query_destroy): Use
- query_listener_stop_notification().
-
- * cal-client/cal-listener.c (cal_listener_destroy): Nullify the
- pointers to the callback functions.
-
- * gui/e-day-view.c (update_query): Commit our state of no longer
- having a query before unrefing it. We may reenter from the ORBit
- main loop and we *really* want this information to be committed.
-
- * gui/e-week-view.c (update_query): Likewise.
-
- * gui/calendar-model.c (update_query): Likewise.
-
- * gui/tag-calendar.c (tag_calendar_by_comp): Added a "clear_first"
- argument that indicates whether the ECalendar should be cleared of
- any marks first.
-
- * gui/calendar-commands.c (calendar_control_activate): Removed
- ifdefed-out view buttons code from the Gnomecal days.
-
- * gui/gnome-cal.c (client_categories_changed_cb): Merge the
- categories of the calendar and tasks clients so that we can
- display the categories in both sets.
- (gnome_calendar_construct): Connect to "categories_changed" on
- both clients.
- (gnome_calendar_on_date_navigator_selection_changed): Removed call
- to gnome_calendar_update_view_buttons().
- (gnome_calendar_update_view_buttons): Removed. We cannot have
- this until Bonobo supports radio toolbar items.
- (gnome_calendar_set_view_buttons): Removed.
- (gnome_calendar_dayjump): Do not use priv->day_button.
- (GnomeCalendarPrivate): Removed the {day,work_week,week,month}_button
- fields.
- (gnome_calendar_set_query): Start a retagging process of the date
- navigator so that it reflects the current query.
- (update_query): New function to restart a query for the date navigator.
- (initial_load): Use update_query() instead of tagging the date
- navigator directly.
- (gnome_calendar_on_date_navigator_date_range_changed): Likewise.
- (client_cal_opened_cb): Use update_query() instead of initial_load().
- (initial_load): Removed.
- (client_obj_updated_cb): Removed.
- (client_obj_removed_cb): Removed.
- (gnome_calendar_new_appointment_for): Set the default category of
- the new component.
- (search_bar_category_changed_cb): Set the default category for the
- calendar views.
-
- * gui/cal-search-bar.c (cal_search_bar_set_categories): Sort the
- categories before creating the menu.
-
- * gui/e-day-view.c (adjust_query_sexp): Return NULL instead of
- "#f" if the time range is not set yet.
- (update_query): Do not start a query if the time range is not set.
- (e_day_view_set_default_category): New function.
- (e_day_view_key_press): Set the default category on the new
- component.
-
- * gui/e-week-view.c (adjust_query_sexp): Analogous to the above.
- (update_query): Analogous to the above.
- (e_week_view_set_default_category): Analogous to the above.
- (e_week_view_key_press): Analogous to the above.
-
-2001-08-03 Federico Mena Quintero <federico@ximian.com>
-
- Fixes bug #1407.
-
- * gui/dialogs/cal-prefs-dialog.glade: Removed the alarm
- preferences page, since we decided it was unnecessary.
-
-2001-08-03 Zbigniew Chyla <cyba@gnome.pl>
-
- I18n fixes.
-
- * gui/dialogs/event-page.c (summary_changed_cb):
- Use e_dialog_editable_get instead of gtk_editable_get_chars (we need
- UTF-8 string).
-
- * gui/itip-utils.c:
- Added missing #include <config.h>
-
-2001-08-02 Jon Trowbridge <trow@ximian.com>
-
- * gui/Makefile.am: Added camel dependency (now needed by ebook).
-
-2001-08-01 Federico Mena Quintero <federico@ximian.com>
-
- * gui/calendar-model.c (calendar_model_value_is_empty): If the
- default category is the same as the value passed in to this
- function, return TRUE. This could be a hack or not, but it
- prevents two items from being added to the table if a category is
- selected.
-
- * gui/e-tasks.c (setup_widgets): Allow the search bar to shrink
- horizontally.
-
- * gui/dialogs/task-page.c (clear_widgets): Pass valid values to
- e_dialog_option_menu_set(); these need to come from the status map.
-
-2001-08-01 Damon Chaplin <damon@ximian.com>
-
- * cal-client/cal-client.c: removed debugging messages.
-
-2001-08-01 Federico Mena Quintero <federico@ximian.com>
-
- The calendar search bar widget now includes a drop-down menu of
- available categories.
-
- * pcs/query.c (func_has_categories): Handle one and only one #f
- value as meaning "unfiled", for components that have no categories
- at all.
-
- * pcs/cal-backend-file.c (open_cal): Duh, do not notify here about
- changed categories since at this point we don't have any clients
- bound to us yet.
- (create_cal): Likewise.
- (cal_backend_file_add_cal): Notify here.
-
- * gui/cal-search-bar.h (CalSearchBarClass): New signal
- "category_changed".
-
- * gui/cal-search-bar.c (cal_search_bar_construct): Add a drop-down
- menu for the list of categories.
- (search_option_items): Removed the "Has category" option, since we
- now have the drop-down menu instad and it would be confusing to
- have both options.
- (regen_query): Likewise. Also, this function is now the old
- cal_search_bar_query_changed() and is shared by that very function
- and by the callback from the drop-down menu.
- (notify_query_contains): Include the sub-sexp for the categories.
- (cal_search_bar_set_categories): New function.
- (cal_search_bar_get_category): New function.
- (categories_selection_done_cb): Emit the "category_changed" signal.
-
- * gui/e-tasks.c (obj_updated_cb): Removed function since it did
- not do anything; all updates are handled by the CalendarModel.
- (obj_removed_cb): Likewise.
- (ETasksPrivate): Removed the fields for the categories option
- menu, since now it is in the ESearchBar.
- (search_bar_sexp_changed_cb): Use calendar_model_set_query()
- directly here, as we do not need to frob the sexp anymore.
- (update_query): Removed.
- (client_categories_changed_cb): New callback.
- (search_bar_category_changed_cb): New callback.
- (e_tasks_new_task): Set the default category on the component to
- the one that is selected in the search bar.
- (e_tasks_on_filter_selected): Removed.
- (e_tasks_on_categories_changed): Removed.
- (e_tasks_rebuild_categories_menu): Removed.
- (e_tasks_add_menu_item): Removed.
- (e_tasks_setup_view_menus): Sanitized not to sink objects wildly.
- (e_tasks_discard_view_menus): New function.
-
- * gui/calendar-model.h (CalendarModelClass): Removed the
- "categories_changed" signal since this is handled in the Wombat
- now.
-
- * gui/calendar-model.c (calendar_model_get_categories): Removed.
- (calendar_model_set_value_at): Do not collect the categories.
- (query_obj_updated_cb): Likewise.
- (calendar_model_collect_categories): Removed.
- (calendar_model_set_default_category): Constify.
-
- * gui/tasks-control.c (tasks_control_deactivate): Call
- e_tasks_discard_view_menus().
-
- * gui/gnome-cal.c (search_bar_category_changed_cb): Set the
- default category for the task pad's model.
-
-2001-07-31 Federico Mena Quintero <federico@ximian.com>
-
- The Wombat now keeps track of which categories are present in the
- objects of a calendar. It will notify the clients of changes in
- this set. This is to make the category drop-down menus in the
- calendar/tasks views be always up to date.
-
- * idl/evolution-calendar.idl (Listener): Added a
- notifyCategoriesChanged() method. The Wombat now keeps track of
- the categories within a calendar.
-
- * cal-client/cal-listener.[ch]: Switched it to use BonoboXObject.
- Also added the notifyCategoriesChanged implementation.
-
- * cal-client/cal-client.[ch]: Added a "categories_changed" signal.
-
- * pcs/cal-backend-file.c: Maintain a list of the live categories.
- (update_categories_from_comp): New function to maintain the set of
- live categories.
- (add_component): Update the set of categories.
- (remove_component): Likewise.
- (open_cal): Notify about changes in the set of categories.
- (create_cal): Likewise.
- (cal_backend_file_update_objects): Likewise.
- (cal_backend_file_remove_object): Likewise.
- (notify_categories_changed): New function to notify the clients
- about the current set of categories.
-
- * pcs/cal.c (cal_notify_categories_changed): New function.
-
-2001-07-31 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view.c (selection_received):
- * gui/e-week-view.c (selection_received): yes, set the end date, but
- correctly calculated, not by using the component's duration, which
- may not exist. Now really fixes #5836
-
-2001-07-31 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view.c (selection_received):
- * gui/e-week-view.c (selection_received): don't set the end date
- for the pasted components, since it will be recalculated when the start
- date is set, thus keeping the same duration than the original
- cut/copied component. Fixes #5836
-
-2001-07-30 Damon Chaplin <damon@ximian.com>
-
- * gui/gnome-cal.c:
- * gui/calendar-commands.c (clear_folder_bar_label): started some code
- to show the currently displayed dates in the folder title bar.
- Unfinished.
-
- * gui/e-itip-control.c (set_date_label):
- * conduits/todo/todo-conduit.c (local_record_from_comp):
- * conduits/calendar/calendar-conduit.c (local_record_from_comp): free
- the CalComponentDateTimes. (Note the iTIP control needs updating for
- timezone support.)
-
- * cal-util/cal-component.c: Changed CalComponentDateTime so that the
- TZID is malloc'ed and freed rather than being a pointer to a static
- string. This was causing problems as sometimes we were freeing the
- string that was being pointed to, so we got corrupted TZIDs.
-
- * gui/comp-util.c (cal_comp_util_add_exdate): set TZID to NULL.
- DATE values do not have timezones.
-
- * gui/e-week-view.c:
- * gui/e-day-view.c: Moved 'Paste' after the New Appointment commands,
- since I think they are more commonly-used. Also added underlined
- accelerator keys.
-
- * gui/e-calendar-table.c: changed 'Edit this task' to 'Open' in the
- popup menu to be consistent with other folders, and separated from the
- clipboard commands. Also changed to use EPopupMenu so the accelerators
- work, and the masks may be useful at some point.
-
- * gui/dialogs/recurrence-page.c: use DATE values for UNTIL, since
- that makes it simpler. Fixes bug #5034.
-
- * gui/calendar-config.c (calendar_config_set_timezone): strdup the
- location string. Fixes bug #4990.
-
- * gui/tag-calendar.c (tag_calendar_cb): take 1 off iend as the times
- don't include the end time.
-
- * gui/e-week-view-layout.c (e_week_view_layout_event): fixed
- days_shown. Fixes bug #5709.
-
- * cal-client/cal-client.c (cal_client_get_timezone): took out some
- debugging messages.
-
-2001-07-30 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/cal-prefs-dialog.glade: added Help button. Though of
- course it doesn't do anything yet.
-
-2001-07-30 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/meeting-page.c: Mark strings for translation
-
-2001-07-30 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-client/client-test.c (cal_opened_cb): call
- cal_client_get_free_busy for testing the new method
-
- * pcs/cal-backend-file.c (cal_backend_file_get_free_busy): implemented
-
-2001-07-28 Federico Mena Quintero <federico@ximian.com>
-
- Fixes bug #5352.
-
- * gui/dialogs/cal-prefs-dialog.c (cal_prefs_dialog_show): Added a
- `page' argument so that we can select which page to show when
- popping up the dialog.
- (cal_prefs_dialog_construct): Added the `page' argument as well.
- (cal_prefs_dialog_new): Likewise.
-
- * gui/calendar-commands.c (settings_cmd): Set the page to the main
- calendar settings one.
-
- * gui/tasks-control.c (tasks_control_settings_cmd): Implemented
- callback for the "Task Settings" command.
- (verbs): Added the "TasksSettings" verb.
- (pixmaps): Added an icon for the tasks settings command.
-
-2001-07-27 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (local_record_from_comp):
- recur is always in UTC
-
-2001-07-27 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c: handle timezones
- everywhere
- (get_timezone): new function to get a timezone based
- on a tzid
- (get_default_timezone): get default timezone
-
- * conduits/calendar/calendar-conduit.h: time zone field for the
- context
-
- * conduits/calendar/Makefile.am: link to bonobo conf
-
- * conduits/todo/todo-conduit.c: handle timezones
- everywhere
- (get_timezone): new function to get a timezone based
- on a tzid
- (get_default_timezone): get default timezone
-
- * conduits/todo/todo-conduit.h: time zone field for the
- context
-
- * conduits/todo/Makefile.am: link to bonobo conf
-
-2001-07-27 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event):
- * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event):
- * gui/e-week-view-event-item.c (e_week_view_event_item_draw_icons):
- initialize to NULL some pointers
-
- * e-calendar-table.c (selection_received): deal correctly with
- VCALENDAR objects
- (e_calendar_table_copy_clipboard): g_strdup the value returned by
- icalcomponent_get_as_ical_string
-
-2001-07-27 Federico Mena Quintero <federico@ximian.com>
-
- * gui/gnome-cal.c (gnome_calendar_set_query): Constify and set the
- query sexp on the task pad's model as well.
-
-2001-07-27 Federico Mena Quintero <federico@ximian.com>
-
- * gui/cal-search-bar.[ch]: New files with a derivative of
- ESearchBar that generates sexps for calendar queries directly.
-
- * gui/gnome-cal.c (setup_widgets): Use CalSearchBar instead of
- ESearchBar.
-
- * gui/e-calendar-table.h (ECalendarTable): Removed the ->colors
- array since it is handled by ETableExtras now.
-
- * gui/e-calendar-table.[ch]: Removed the subset_model. Now we use
- the live query facility to filter tasks. Removed the filter
- function stuff as well.
-
- * gui/e-tasks.c (e_tasks_construct): Use
- calendar_model_set_cal_client() directly instead of
- e_calendar_table_set_model().
- (setup_widgets): Create a calendar search bar for the tasks
- component.
- (search_bar_sexp_changed_cb): Set the query sexp on the table model.
- (e_tasks_on_filter_selected): Regenerate the query from the
- selected category and the current sexp.
- (update_query): New convenience function to recompute the real
- query sexp.
-
- * gui/gnome-cal.c (gnome_calendar_construct): Likewise.
-
- * gui/e-calendar-table.c (e_calendar_table_set_cal_client):
- Removed function; people are now supposed to get the model from
- the calendar table and operate on it.
-
- * gui/calendar-commands.c (verbs): Consistency fixes with the XML
- file.
- (pixmaps): Likewise.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Added
- cal-search-bar.[ch] to the list of sources.
-
-2001-07-20 Federico Mena Quintero <federico@ximian.com>
-
- * idl/evolution-calendar.idl (CompEditorFactory): New interface to
- a centralized factory for calendar component editors. Has
- editExisting() and editNew() methods to edit an existing component
- from a URI/UID pair, and to create a new component in a calendar
- that is in a particular URI, respectively.
-
- * gui/comp-editor-factory.[ch]: Implementation files for the
- component editor factory.
-
- * gui/GNOME_Evolution_Calendar.oaf.in: Added the CompEditorFactory
- stuff.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Added
- comp-editor-factory.[ch] to the list of sources.
-
-2001-07-26 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/meeting-page.c (invite_entry_changed): when an entry
- has changed, iterate over the elements of the entry and add them
- to the list if need be
- (get_select_name_dialog): add a Chair Persons section
-
- * gui/itip-utils.c (itip_send_comp): send the empty string as
- subject if there is no summary
-
-2001-07-26 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c (itip_send_comp): send the empty string as
- subject if there is no summary
-
- * gui/dialogs/meeting-page.c (cleanup_attendees): free a list of
- attendees
- (meeting_page_fill_widgets): clean up attendee lists and fix typo
- (find_match): add ability to return pos of match
- (popup_delete_cb): if deletion happens, make sure to tidy up
- delegation chain
-
- * gui/dialogs/e-delegate-dialog.c (e_delegate_dialog_construct):
- use the destination rather than text property
- (e_delegate_dialog_get_delegate): ditto
- (e_delegate_dialog_new): take name/address pair for dialog default
-
- * gui/dialogs/e-delegate-dialog.h: update protos
-
- * gui/e-itip-control.c (clean_up): only unref the object if we
- have one
-
- * gui/itip-control-factory.c (stream_read): make sure we null
- terminate the final buffer
-
- * gui/itip-utils.c (itip_send_comp): strip the mailto: from the
- organizer address if necessary
-
-2001-07-26 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/recurrence-page.c (exception_select_row_cb): check that
- the row passed in is valid. Sometimes we get the "row-selected"
- signal for row 0 when there are no rows in the list. Fixes bug #4266.
-
- * cal-client/cal-client.c (cal_client_get_object): prefetch all the
- timezone data needed by the object, to try to avoid making Corba
- calls all over the place. They can cause problems because they call
- the GTK+ main loop recursively. This currently leads to an assertion
- failure in the GnomeCanvas occasionally.
-
-2001-07-25 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (e_itip_control_set_data): gracefully
- handle the lack of a method
-
-2001-07-25 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view.c (selection_received_cb): check type of component
- before actually pasting.
- Deal with VCALENDAR components also (fixes bug #5140)
-
- * gui/e-week-view.c (selection_received_cb): ditto
-
- * cal-client/cal-client.c (cal_client_update_object): check the return
- value from cal_component_get_as_string and don't call
- GNOME_Evolution_Calendar_Cal_updateObjects if NULL
-
-2001-07-25 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/comp-editor.c (pixmaps): used the new print preview icon.
-
- * gui/print.c (range_selector_new): changed the 'Current day/week...'
- strings to 'Selected day/week...' to make a little less confusing.
- Fixes bug #5451.
-
-2001-07-25 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/meeting-page.c (is_duplicate): see if the address is
- already in the list of attendees
- (duplicate_error): throw up an error dialog
- (popup_delegate_cb): if the attendee has already delegated, delete
- the old delegatee
- (value_at): cast to kill warnings
- (append_row): don't add the new attendee if they are already in
- the list
-
-2001-07-24 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/recurrence-page.c (get_exception_string): calculate
- tmp_tm.tm_wday ourselves. strftime has a habit of crashing if you
- have weird values here. I think this fixes bug #4574.
-
-2001-07-24 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/meeting-page.c (value_at): stip the delto and
- delfrom
- (popup_delegate_cb): show a delegate dialog and add the new
- delegatee and update the delegator
- (add_section): listen for changes in a more direct manner
- (get_select_name_dialog): add_section now takes a limit argument
-
- * gui/dialogs/e-delegate-dialog.[hc]: New dialog to query the user
- for a person to delegate to
-
- * gui/dialogs/Makefile.am: build/install new files
-
- * gui/Makefile.am: add ldadd line for ebook
-
-2001-07-21 Damon Chaplin <damon@ximian.com>
-
- * gui/e-week-view-event-item.c (e_week_view_event_item_draw): fixed
- the test to see whether we should draw the icons.
-
-2001-07-22 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c (get_local_file_name_for_folder_type):
- New helper function.
- (remove_folder): Add a @type arg and handle it, by deleting
- "tasks.ics" instead of "calendar.ics" if the type is "tasks". If
- the type is not "tasks" or "calendar", report an
- `UNSUPPORTED_TYPE' error.
- (xfer_folder): Likewise.
-
-2001-07-21 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c: Make folders of type "calendar" and
- "tasks" user-creatable by setting `user_creatable' to %TRUE in the
- `EvolutionShellComponentFolderType's.
-
-2001-07-19 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/event-editor.h (event_editor_update_widgets):
- Removed unused prototype.
-
- * gui/dialogs/task-editor.h (task_editor_update_widgets):
- Likewise.
-
-2001-07-19 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (clean_up): free various data related
- settings
- (destroy): use cleanup and unref the clients
- (e_itip_control_set_data): clean up before setting the data and
- store the timezones in a top level component
- (update_item): use cal_client_update_objects and our top level
- (including the timezones)
-
-2001-07-19 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/comp-editor.c (pixmaps):
- * gui/calendar-commands.c (pixmaps): updated to use new print icon.
-
-2001-07-17 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/recurrence-page.c (init_widgets): don't show the time
- in the EDateEdit widget for adding EXDATEs.
-
- * cal-util/cal-component.c (cal_component_alarm_set_trigger): don't
- set t.time.is_date to -1. It is a boolean flag, 0 or 1. We probably
- don't want a date value, so we leave it at 0.
-
-2001-07-18 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event):
- do not discard drawing icon if mask is NULL
-
- * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event):
- ditto
-
-2001-07-17 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (get_next): find the next displayable
- component
- (get_prev): find the previous displayable component
- (e_itip_control_set_data): use above
- (prev_clicked_cb): ditto
- (next_clicked_cb): ditto
-
-2001-07-17 Federico Mena Quintero <federico@ximian.com>
-
- Really fixes #4380. The previous fix was necessary but not
- sufficient; it worked for me because my system timezone happens to
- match the Evolution timezone --- if they don't match, the bug
- would persist. Not matching is *not* an error; it is just a
- matter of Unix sucking a lot and XST not being finished :)
-
- * cal-util/timeutil.c (time_to_gdate_with_zone): New function. We
- cannot use g_date_set_time() anymore because it does not take
- timezones into account.
-
- * gui/gnome-cal.c (get_days_shown): Use the function above.
-
- * gui/e-day-view.c (e_day_view_find_work_week_start): Likewise.
-
- * gui/e-week-view.c (e_week_view_set_selected_time_range): Likewise.
-
-2001-07-17 Jon Trowbridge <trow@ximian.com>
-
- * gui/dialogs/meeting-page.c (invite_entry_changed): Print
- a g_message when the list of invited people changes
- in the SelectNames control.
- (add_section): #if 0/#endif out some (broken?) code.
- (get_select_name_dialog): Listen for changes in the
- SelectNames control.
-
-2001-07-17 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/e-timezone-dialog.c (e_timezone_dialog_destroy): destroy
- the dialog widget here. Fixes bug #4198.
-
-2001-07-16 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/task-page.c (task_page_fill_widgets):
- * gui/dialogs/event-page.c (event_page_fill_widgets): try to use
- builtin timezones before getting them from the server. When creating
- new events/tasks the timezones may not be on the server.
-
- * gui/dialogs/event-page.c (event_page_fill_widgets): for all-day
- events we subtract a day from the end date rather than add it.
-
- * gui/dialogs/e-timezone-dialog.c (on_map_leave): ignore the event
- if it isn't a GDK_CROSSING_NORMAL event. For some reason we are getting
- leave events when the button is pressed, which meant that selecting
- timezones in the map didn't work.
-
- * gui/dialogs/comp-editor-util.c (comp_editor_dates):
- * gui/print.c (print_date_label): only free icaltimetype if not NULL.
-
-2001-07-12 Taylor Hayward <taylorhayward@yahoo.com>
-
- * gui/goto-dialog.glade:
- * gui/meeting-mockup.glade:
- * gui/alarm-notifyålarm-notify.glade:
- * gui/dialogs/alarm-page.glade:
- * gui/dialogs/meeting-page.glade:
- * gui/dialogs/recurrence-page.glade: Added missing underlined
- shortcuts.
-
-2001-07-12 JP Rosevear <jpr@ximian.com>
-
- * cal-util/cal-util.h: new proto
-
- * cal-util/cal-util.c (cal_util_new_top_level): standard place to
- get your top level calendar component
-
- * pcs/cal-backend-file.c (create_cal): use it
-
- * gui/itip-utils.c (itip_send_comp): ditto
-
- * gui/e-calendar-table.c (e_calendar_table_copy_clipboard): ditto
-
-2001-07-12 JP Rosevear <jpr@ximian.com>
-
- * gui/e-calendar-table.c (e_calendar_table_copy_clipboard): fix
- typo breaking compilation
-
- * gui/dialogs/meeting-page.c: fix include
-
- * gui/dialogs/Makefile.am: build select names idl here
-
- * gui/Makefile.am: remove select names compilation from here
-
-2001-07-12 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/task-details-page.c (task_details_page_set_dates):
- guard against infinite loops with the updating boolean, fixes 4270
-
-2001-07-12 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-calendar-table.c: added support for multiple selections in
- cut/copy/paste. Also, it's now ready for the
- s/update_object/update_objects change (I think)
-
-2001-07-11 Damon Chaplin <damon@ximian.com>
-
- * idl/evolution-calendar.idl: renamed updateObject to updateObjects
- and removed the UID argument, since it can add/update multiple objects
- at once. (It can't yet, but it will!)
-
- * pcs/cal.c:
- * pcs/cal-backend.[hc]:
- * pcs/cal-backend-file.c: renamed update_object to update_objects and
- got rid of the UID arg.
-
- * cal-client/cal-client.c (cal_client_update_objects): new function to
- add/update multiple objects in one go, i.e for iTIP and for importing
- calendars.
-
- * gui/print.c (print_date_label): fixed type bug.
-
- * gui/e-week-view.[hc]:
- * gui/e-week-view-event-item.c: draw the timezone icons if the event's
- DTSTART or DTEND is in a different timezone to the current one.
- Note that we may want to change this so it compares the UTC offsets
- rather than the TZIDs, since currently it will draw the icons for all
- events coming from iTIP requests from other clients.
-
-2001-07-11 Federico Mena Quintero <federico@ximian.com>
-
- Fixes bug #4380 as well as some leftovers from the days of struct
- tm and some uninitialized values.
-
- * gui/gnome-cal.c
- (gnome_calendar_on_date_navigator_selection_changed): Initialize
- the icaltimetype structures completely.
- (gnome_calendar_init): Do not reset priv->zone to NULL here, since
- it was set by gnome_calendar_update_config_settings() from
- setup_widgets().
-
- * gui/calendar-model.c (set_completed): Do not set is_daylight.
-
- * gui/e-day-view.c (e_day_view_convert_grid_position_to_time):
- Likewise.
-
- * gui/e-week-view.c (e_week_view_set_timezone): Likewise.
-
- * cal-util/cal-recur.c (generate_instances_for_chunk): Likewise,
- and initialize start_tt and end_tt completely.
-
- * cal-util/timeutil.c (time_year_begin_with_zone): Likewise.
- (time_month_begin_with_zone): Likewise.
- (time_week_begin_with_zone): Likewise.
- (time_day_begin_with_zone): Likewise.
- (time_day_end_with_zone): Likewise.
- (time_from_isodate): Likewise.
-
- * gui/dialogs/task-page.c (task_page_fill_component): Initialize
- icaltime before using it.
-
- * gui/dialogs/event-page.c (event_page_fill_component): Likewise.
-
- * gui/dialogs/recurrence-page.c (simple_recur_to_comp): Removed an
- unused icaltimetype.
-
- * gui/dialogs/task-details-page.c
- (task_details_page_fill_component): Initialize icaltime before
- using it.
-
-2001-07-11 JP Rosevear <jpr@ximian.com>
-
- * gui/component-factory.c: fix the calendar not exiting with a
- gross hack because i don't have time to fix the ref counting right
- now
-
-2001-07-11 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/meeting-page.c: be careful about adding and
- stripping MAILTO:'s properly
-
- * gui/dialogs/meeting-page.etspec: add missing columns
-
- * gui/itip-utils.c (itip_strip_mailto): point to the real start of
- the email address
-
- * gui/itip-utils.h: add proto
-
- * gui/itip-control-factory.c: get rid of the my address property
-
- * gui/e-itip-control.c: use the users real identity to figure out
- which attendee they are
- (find_my_address): figure out who the user is among the attendees
-
- * gui/e-itip-control.h: remove protos
-
- * gui/dialogs/Makefile.am: extra dist etspecs
-
- * gui/Makefile.am: ditto
-
-2001-07-11 Kjartan Maraas <kmaraas@gnome.org>
-
- * gui/e-calendar-table.c: Added a hack to get the last
- string translated since xml-i18n-tools doesn't recognize
- _click-to-add-message="Click here to add a task".
-
-2001-07-10 Peter Williams <peterw@ximian.com>
-
- * gui/Makefile.am (BUILT_SOURCES): Move this higher so that
- Makefile properly depends on us. Fixes distcheck.
-
-2001-07-11 Jason Leach <jleach@ximian.com>
-
- [Fix bug #4389: ETableSpecification still in e-calendar-table.c
- file]
-
- * gui/e-calendar-table.etspec: New file containing the spec that
- was in e-calendar-table.c as a big string.
-
- * gui/e-calendar-table.c (e_calendar_table_init): Use the spec
- file instead of a string.
- (e_calendar_table_get_spec): Removed this function, we don't need
- it anymore.
-
- * gui/e-tasks.c (e_tasks_setup_menus): Don't load from string,
- from file instead.
-
- * gui/Makefile.am: Necessary changes to get the new .etspec file
- installed.
-
-2001-07-10 Jason Leach <jleach@ximian.com>
-
- [Fix bug #4388: ETableSpecification still in meeting-page.c file]
-
- * gui/dialogs/meeting-page.etspec: New file containing the spec
- that was previously in meeting-page.c as a string.
-
- * gui/dialogs/meeting-page.c: One line change to get it to use
- this spec file instead of a string.
-
- * gui/dialogs/Makefile.am: Necessary changes to get the new
- meeting-page.etspec installed.
-
-2001-07-10 Damon Chaplin <damon@ximian.com>
-
- * gui/calendar-model.c:
- * gui/e-calendar-table.c:
- * gui/e-day-view-main-item.c:
- * gui/e-day-view-top-item.c:
- * gui/e-day-view.[hc]:
- * gui/e-week-view.c:
- * gui/gnome-cal.c:
- * gui/print.c:
- * gui/dialogs/cal-prefs-dialog.c:
- * gui/dialogs/comp-editor-util.c:
- * gui/dialogs/event-page.c:
- * pcs/cal-backend-file.c:
- * pcs/query.c:
- * cal-util/cal-component.[hc]:
- * cal-util/cal-recur.c:
- * cal-util/timeutil.[hc]:
- * cal-client/cal-client.[hc]: more timezone updates. I'm pretty much
- done with the calendar code now, except for alarms and conduits,
- which Federico and JP know more about. And there are a couple of
- other minor things to fix. But it is still pretty buggy.
-
-2001-07-10 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/meeting-page.c: Add popup support so you can delete
- users from the list
-
- * gui/dialogs/comp-editor.c (setup_widgets): fix typo
-
-2001-07-10 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/alarm-queue.c (alarm_trigger_cb): Handle the
- different alarm actions.
- (display_notification): Do the alarm notification dialog here.
-
- * gui/alarm-notify/alarm-notify-dialog.c (make_heading): Take in a
- CalComponentVType, not a whole component.
- (alarm_notify_dialog): Take in a CalComponentVType and the final
- message instead of generating it ourselves.
-
-2001-07-09 Federico Mena Quintero <federico@ximian.com>
-
- * pcs/cal-backend-file.c (generate_alarms_for_comp): Pass the
- parent vCalendar component as the timezone closure of
- cal_recur_generate_instances().
-
- * gui/dialogs/alarm-page.c (get_alarm_string): Make the string
- consistent with the option menu text.
- (get_alarm_string): Removed extra spaces from the last part of the
- alarm string.
-
-2001-07-09 Federico Mena Quintero <federico@ximian.com>
-
- * gui/e-day-view.c (e_day_view_key_press): Use
- e_utf8_from_gtk_event_key() so that we can input utf8 text
- properly.
- (e_day_view_cut_clipboard): Constify.
- (e_day_view_on_cut): Constify.
- (e_day_view_reshape_long_event): Remove unused variable.
-
- * gui/e-week-view.c (e_week_view_key_press): Use
- e_utf8_from_gtk_event_key() so that we can input utf8 text
- properly.
- (e_week_view_cut_clipboard): Constify.
- (e_week_view_on_cut): Constify.
-
- * cal-client/cal-client.c (cal_client_resolve_tzid_cb): Fix the
- prototype so that this matches CalRecurResolveTimezoneFn. Also
- renamed it so that it is clear that it is supposed to be a
- callback.
-
-2001-07-06 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/meeting-page.c (init_widgets): connect to the entry
- not the combo
-
- * gui/dialogs/event-editor.c (set_menu_sens): set menu
- sensitivities based on whether or not the meeting page is shown
- (event_editor_init): call above
- (event_editor_edit_comp): ditto
- (schedule_meeting_cmd): ditto
-
- * gui/dialogs/comp-editor.h: new proto
-
- * gui/dialogs/comp-editor.c (comp_editor_set_ui_prop): new
- function to allow for set of ui props (esp. "sensitive")
-
-2001-07-06 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/meeting-page.c (clear_widgets): actually clear some
- widgets and hide/show widgets in the default setup
- (meeting_page_destroy): destroy the address lists
- (meeting_page_fill_widgets): allow the user to select among their
- identities as a new organizer, or show the existing organizer as
- label
- (meeting_page_fill_component): set the "MAILTO:" bit of the
- organizer to match spec, set CN properly if we know it
- (get_widgets): load new widgets
- (other_clicked_cb): handle "Other Organizer" click
- (change_clicked_cb): handle "Change Organizer" click
- (init_widgets): listen for clicks on new buttons
-
- * gui/dialogs/comp-editor.c (comp_editor_remove_page): remove the
- page from our internal list and unref it
-
- * gui/itip-utils.c (itip_addresses_get): get the configure mail
- identities
- (itip_addresses_free): free a list of identities returned by
- itip_addresses_get
-
- * gui/itip-utils.h: remove obsolete protos, and new protos
-
- * gui/gnome-cal.html: Remove ancient file
-
-2001-07-04 Federico Mena Quintero <federico@ximian.com>
-
- Fixes bug #4018 and what would be the analogous bugs for the other
- component editors.
-
- * gui/dialogs/comp-editor-page.h (CompEditorPageClass): New
- virtual method "::focus_main_widget()".
-
- * gui/dialogs/comp-editor-page.c
- (comp_editor_page_focus_main_widget): New function.
-
- * gui/dialogs/comp-editor.c (comp_editor_append_page): If we are
- inserting the main page, ask it to focus its main widget.
-
- * gui/dialogs/alarm-page.c (alarm_page_focus_main_widget):
- Implemented.
-
- * gui/dialogs/event-page.c (event_page_focus_main_widget):
- Implemented.
- #include "e-util/e-categories-config.h".
-
- * gui/dialogs/meeting-page.c (meeting_page_focus_main_widget):
- Implemented.
-
- * gui/dialogs/recurrence-page.c
- (recurrence_page_focus_main_widget): Implemented.
-
- * gui/dialogs/task-details-page.c
- (task_details_page_focus_main_widget): Implemented.
-
- * gui/dialogs/task-page.c (task_page_focus_main_widget):
- Implemented.
-
-2001-07-04 Federico Mena Quintero <federico@ximian.com>
-
- * gui/calendar-commands.c (clear_folder_bar_label): New function.
- (calendar_control_activate): Clear the folder bar label; we really
- don't have anything interesting to display.
-
-2001-07-03 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/meeting-page.c: Add new columns for information
- specification
- (meeting_page_destroy): save the table state
- (build_etable): load new table state
-
- * gui/dialogs/task-editor.c (task_editor_destroy): unref pages
-
- * gui/dialogs/event-editor.c (event_editor_destroy): unref pages
-
- * gui/dialogs/comp-editor.c (setup_widgets): kill warning
- (comp_editor_append_page): ref page passed in
- (close_dialog): unref pages
-
-2001-07-03 Damon Chaplin <damon@ximian.com>
-
- * gui/e-day-view.c (query_obj_updated_cb): fix warning, and added
- some debug messages.
-
- * gui/dialogs/comp-editor-util.c (write_label_piece):
- * gui/e-day-view-top-item.c (e_day_view_top_item_draw): call mktime()
- to set the weekday, though this is a temporary fix.
-
-2001-07-03 Damon Chaplin <damon@ximian.com>
-
- * pcs/cal-backend.[hc]: added virtual method to get a VTIMEZONE
- component given a TZID. We need this to resolve TZIDs when expanding
- an event using cal_recur_generate_instances() in query.c.
-
- * pcs/cal-backend-file.c (cal_backend_file_get_timezone): implemented
- virtual method.
- (cal_backend_file_update_object): fixed bug, kind -> child_kind.
-
- * pcs/query.c (func_occur_in_time_range): use the virtual method for
- resolving TZIDs. The other way didn't work anyway, as we didn't have
- the entire VCALENDAR with VTIMEZONEs in it.
-
- * gui/dialogs/recurrence-page.c (init_widgets):
- (make_ending_until_special): moved the call to
- e_date_edit_set_get_time_callback() from init_widgets to
- make_ending_until_special(), since that is where the widget gets
- created.
-
- * gui/e-timezone-entry.c (e_timezone_entry_set_timezone): handle zone
- being NULL.
-
-2001-07-02 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/alarm-options.[ch]: New files with the alarm options
- dialog; this configures the repeat/duration properties and the
- options specific to each alarm action type.
-
- * gui/dialogs/alarm-page.c (AlarmPagePrivate): Added the alarm
- options button. Also, keep an alarm structure which we are
- editing and an alarm options dialog.
- (init_widgets): Connect to the options button.
- (add_clicked_cb): Clone the component we are editing instead of
- creating a new one so that we preserve the data from the alarm
- options dialog.
- (button_options_clicked_cb): Pop up the alarm options dialog.
-
- * cal-util/cal-component.c (cal_component_alarm_new): Doh,
- initialize the other fields in the new alarm.
-
-2001-07-03 Damon Chaplin <damon@ximian.com>
-
- * cal-client/cal-client.[hc]
- * cal-util/cal-component.c
- * cal-util/cal-recur.[hc]
- * cal-util/test-recur.c
- * cal-util/timeutil.c
- * gui/calendar-config.c
- * gui/calendar-model.[hc]
- * gui/comp-util.[hc]
- * gui/e-calendar-table.c
- * gui/e-day-view-main-item.c
- * gui/e-day-view-top-item.c
- * gui/e-day-view.[hc]
- * gui/e-itip-control.c
- * gui/e-timezone-entry.[hc]
- * gui/e-week-view.[hc]
- * gui/gnome-cal.[hc]
- * gui/goto.c
- * gui/tag-calendar.[hc]
- * gui/dialogs/cal-prefs-dialog.c
- * gui/dialogs/comp-editor-page.[hc]
- * gui/dialogs/comp-editor-util.[hc]
- * gui/dialogs/comp-editor.c
- * gui/dialogs/e-timezone-dialog.[hc]
- * gui/dialogs/event-page.c
- * gui/dialogs/meeting-page.c
- * gui/dialogs/recurrence-page.c
- * gui/dialogs/task-details-page.c
- * gui/dialogs/task-details-page.glade
- * gui/dialogs/task-page.c
- * idl/evolution-calendar.idl
- * pcs/cal-backend-file.c
- * pcs/cal-backend.c
- * pcs/cal-backend.h
- * pcs/cal.c
- * pcs/query.c: timezone changes everywhere. There's still quite a
- few things to update, and its not working well at present.
-
-2001-07-02 JP Rosevear <jpr@ximian.com>
-
- * gui/calendar-commands.c (publish_freebusy_cmd): publish
- free/busy information for the currently viewed time range
-
-2001-07-02 Christopher James Lahey <clahey@ximian.com>
-
- * gui/Makefile.am (INCLUDES): Added $(BONOBO_CONF_CFLAGS).
- (evolution_calendar_LDADD): Added $(BONOBO_CONF_LIBS).
-
-2001-07-02 Federico Mena Quintero <federico@ximian.com>
-
- Support for ATTACH, DESCRIPTION properties in alarm components.
-
- * cal-util/cal-component.c (scan_alarm_property): Deal with
- ATTACH, DESCRIPTION properties.
- (cal_component_alarm_get_attach): New function. Libical is
- actually bogus; supposedly icalattachtype structures are
- refcounted but the property functions return them by value.
- (cal_copmonent_alarm_set_attach): New function.
- (cal_component_alarm_get_description): New function.
- (cal_component_alarm_set_description): New function.
-
-2001-07-02 Federico Mena Quintero <federico@ximian.com>
-
- Support for repeat/duration properties in alarm components.
-
- * cal-util/cal-component.h (CalAlarmRepeat): New structure that
- pairs the repeat/duration values of an alarm component, which must
- be set both together or not set at all.
-
- * cal-util/cal-component.c (CalComponentAlarm): Added fields for
- the repeat and duration properties.
- (scan_alarm_property): Scan the DURATION and REPEAT properties.
- (make_alarm): Nullify/initialize all the fields in the alarm.
- (cal_component_alarm_get_repeat): New function.
- (cal_component_alarm_set_repeat): New function.
-
- * gui/dialogs/alarm-page.glade: Changed the label of display
- alarms from "Show a dialog" to "Display a message".
-
-2001-07-02 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/task-details-page.c
- (task_details_page_fill_widgets): fill in delegated from field
-
-2001-07-02 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/dialogs/task-page.c (categories_clicked_cb):
- * gui/dialogs/event-page.c (categories_clicked_cb): use the new
- self-contained e_categories_config_open_dialog_for_entry() function
-
- * gui/e-week-view-event-item.c (e_week_view_item_draw_icons):
- * gui/e-day-view-top-item.c (e_day_view_reshape_long_event):
- (e_day_view_reshape_day_event): ditto
- * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event):
- use e_categories_config_get_icon_for() to retrieve the icon
- associated with each category
-
-2001-07-02 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (send_freebusy): implement
-
- * cal-util/cal-component.c (set_attendee_list): add the delto
- property rather than the delfrom property twice
-
- * gui/dialogs/task-editor.c (task_editor_edit_comp): show
- delegation info if appropriate
- (delegate_task_cmd): delegate command
- (cancel_task_cmd): cancel command
- (refresh_task_cmd): refresh command
-
- * gui/dialogs/task-details-page.c: Load new widgets
- (task_details_page_show_delegation): show/hide delegation info widgets
-
- * gui/dialogs/task-details-page.h: new proto
-
- * gui/dialogs/event-editor.c (event_editor_edit_comp): free
- attendee list when finished
-
- * gui/dialogs/comp-editor.c (setup_widgets): explicitly show the
- widgets, update pixmaps after the verbs have been added
- (comp_editor_focus): don't do a show all
-
-2001-07-02 Federico Mena Quintero <federico@ximian.com>
-
- Fixes bug #1406.
-
- * gui/calendar-config.c (config_read): Handle the options for the
- task list colors.
- (calendar_config_write): Ditto.
- (calendar_config_get_tasks_due_today_color): New function.
- (calendar_config_set_tasks_due_today_color): New function.
- (calendar_config_get_tasks_overdue_color): New function.
- (calendar_config_set_tasks_overdue_color): New function.
- (calendar_config_configure_e_calendar_table): Use
- e_table_model_changed() for the colors.
-
- * gui/dialogs/cal-prefs-dialog.glade: Updated the options for the
- task list and alarms.
-
- * gui/dialogs/cal-prefs-dialog.c (cal_prefs_dialog_show_config):
- Update the task list settings.
- (cal_prefs_dialog_update_config): Ditto.
-
- * gui/calendar-model.c (get_color): Deal with tasks for today as
- well as overdue tasks. Make it cleaner, even though we have to
- duplicate a chunk of is_overdue().
-
- * gui/calendar-commands.c (preferences_cmd): Renamed from
- properties_cmd().
-
-2001-07-01 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view-main-item.c
- (e_day_view_main_item_draw_day_event): draw icons per category
-
- * gui/e-day-view-top-item.c
- (e_day_view_top_item_draw_long_event): draw icons per category
-
- * gui/e-day-view.c
- (e_day_view_reshape_long_event):
- (e_day_view_reshape_day_event): calculate space for category icons
-
- * gui/e-week-view-event-item.c
- (e_week_view_event_item_draw_icons): draw icons per category
-
- * gui/e-week-view.c
- (e_week_view_reshape_event_span): calculate space for category icons
-
-2001-07-01 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view.c (e_day_view_*_clipboard): fixed clibpoard
- command activation from the menu entries. CTRL-C and CTRL-X don't
- work though, since it seems the key presses are being captured by
- the text item
-
- gui/e-week-view.c (e_week_view_*_clipboard): ditto
-
-2001-06-30 Federico Mena Quintero <federico@ximian.com>
-
- * gui/e-week-view-event-item.c
- (e_week_view_event_item_button_press): Only set the
- pressed_event_num and pressed_span_num if button 1 was pressed.
- Fix up return values a bit. This fixes bug #3780.
-
- * gui/gnome-cal.c
- (gnome_calendar_on_date_navigator_selection_changed): Doh, the
- call for the day view was supposed to be
- gnome_calendar_set_view(), not set_view(). Fixes bug #3779.
-
-2001-06-30 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/tasks-control.c (tasks_control_cut_cmd): call
- e_calendar_table_cut_clipboard with the correct object
-
- (tasks_control_copy_cmd): ditto
-
- (sensitize_commands): sensitize clipboard commands based on the
- number of selected tasks
-
-2001-06-28 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-calendar-table.[ch] (e_calendar_table_cut_clipboard),
- (e_calendar_table_copy_clipboard),
- (e_calendar_table_paste_clipboard): new functions for allowing the
- execution of clipboard-related commands
-
- * gui/tasks-control.c (tasks_control_cut_cmd),
- (tasks_control_copy_cmd), (tasks_control_paste_cmd): added
- callbacks for the new clipboard-related menu entries
-
-2001-06-28 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/component-factory.c: removed not-uses-anymore parameter in
- call to evolution_shell_component_new
-
- * gui/gnome-cal.[ch] (gnome_calendar_cut_clipboard),
- (gnome_calendar_copy_clipboard), (gnome_calendar_paste_clipboard):
- new functions for allowing execution of clipboard-related commands
-
- * gui/e-day-view.[ch] (e_day_view_cut_clipboard),
- (e_day_view_copy_clipboard), (e_day_view_paste_clipboard): ditto
-
- * gui/e-week-view.[ch] (e_week_view_cut_clipboard),
- (e_week_view_copy_clipboard), (e_week_view_paste_clipboard): ditto
-
-2001-06-27 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/calendar-commands.c (cut_event_cmd),
- (copy_event_cmd), (paste_event_cmd): added callbacks for the new
- clipboard-related menu entries
-
-2001-06-27 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c (factory_fn): Pass NULL as the
- @external_uri_schemas argument to
- `evolution_shell_component_new()'.
-
-2001-06-27 Peter Williams <peterw@ximian.com>
-
- * conduits/*/Makefile.am (INCLUDES): More srcdir != builddir
- fixes.
-
-2001-06-27 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-calendar-table.c (selection_received): fixed
- (e_calendar_table_on_copy): fixed
-
-2001-06-26 Federico Mena Quintero <federico@ximian.com>
-
- * idl/evolution-calendar.idl (CalAlarmInstance): Renamed the occur
- field to occur_start; added an occur_end field. This way we can
- present the complete times for the occurrence from the server.
-
- * cal-util/cal-component.h (CalAlarmInstance): Likewise.
-
- * pcs/cal-backend-file.c (add_alarm_occurrences_cb): Fill the new
- fields appropriately.
- (generate_absolute_triggers): Likewise; we use -1 in case the
- component has no DTSTART or DTEND because there are no meaningful
- occurrence dates here.
- (fill_alarm_instances_seq): Fill in the new fields.
-
- * cal-client/cal-client.c (build_alarm_instance_list): Likewise.
-
- * gui/alarm-notify/alarm-notify-dialog.c (alarm_notify_dialog):
- Take in both the occur_start and occur_end times.
-
- * gui/goto.c (goto_dialog): Free the dlg structure on the bail-out
- cases.
-
- * gui/dialogs/event-page.c (get_widgets): Do not assert if we
- cannot find the main widget; just return FALSE.
-
- * gui/dialogs/alarm-page.c (get_widgets): Likewise.
-
- * gui/dialogs/task-page.c (get_widgets): Likewise.
-
- * gui/dialogs/task-details-page.c (get_widgets): Likewise.
-
- * gui/dialogs/meeting-page.c (get_widgets): Likewise.
-
-2001-06-25 Peter Williams <peterw@ximian.com>
-
- * conduits/calendar/Makefile.am (INCLUDES): Fixes for
- srcdir != builddir. Link to the static libwombat.
-
- * conduits/todo/Makefile.am (INCLUDES): Here too.
-
-2001-06-24 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/notify-main.c (main): Initialize libglade.
-
- * pcs/cal-backend-file.c (compute_alarm_range):
- icaldurationtype_as_int() will now return a negative value if
- dur->is_neg is true, so we need to flip the sign of some
- operations here.
- (add_alarm_occurrences_cb): Likewise.
-
- * pcs/cal-backend-db.c (compute_alarm_range): Likewise.
- (add_alarm_occurrences_cb): Likewise.
-
-2001-06-24 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/alarm-notify.c: Converted to use BonoboXObject.
-
- * gui/gnome-cal.c (gnome_calendar_open): Ask the alarm
- notification service to add the calendar and tasks URIs.
- (add_alarms): New function.
-
- * gui/alarm-notify/notify-main.c (main): Doh, fixed typo in the
- OAFIID.
- (main): Initialize and shut down gnome-vfs.
-
- * gui/Makefile.am (IDLS): Added evolution-calendar.idl, sigh.
- (evolution_calendar_SOURCES): Added the files generated from the IDL.
-
- * gui/alarm-notify/alarm-queue.c (alarm_trigger_cb): New function
- used when an alarm is triggered.
-
- * gui/dialogs/Makefile.am: Removed the alarm-notify-dialog files;
- they are now in gui/alarm-notify.
-
- * gui/alarm-notify/Makefile.am: Added the alarm-notify-dialog
- files.
-
- * pcs/cal.c (cal_forget_password): This was incorrectly named
- cal_client_forget_password(); renamed it.
-
- * gui/main.c (main): Initialize and shut down gnome-vfs.
-
-2001-06-23 Federico Mena Quintero <federico@ximian.com>
-
- * gui/e-calendar-table.c (task_compare_cb): New function to
- compare tasks like the Pilot task list.
-
- * cal-util/cal-component.h (CalComponentField): Added a
- semi-hackish CAL_COMPONENT_FIELD_COMPONENT. In the ETable model,
- it is intended to return a pointer to the component itself.
-
- * gui/calendar-model.c (calendar_model_value_at): Return the
- component itself for CAL_COMPONENT_FIELD_COMPONENT. Be more
- paranoid about invalid columns.
- (calendar_model_set_value_at): Be more paranoid about invalid
- columns.
- (calendar_model_duplicate_value): Ref the component field.
- (calendar_model_initialize_value): Deal with the component field.
- (calendar_model_value_is_empty): Likewise.
- (calendar_model_value_to_string): Likewise.
-
-2001-06-22 Jeffrey Stedfast <fejj@ximian.com>
-
- * gui/Makefile.am: Added itip-control-factory.* to the build.
-
-2001-06-22 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal.[ch] (cal_get_password): new function for the backends to
- be able to call the getPassword method on the associated
- WombatClient
- (cal_forget_password): ditto for the forgetPassword method
-
-2001-06-22 Rodrigo Moya <rodrigo@ximian.com>
-
- * idl/evolution-calendar.idl: changed getFreeBusy method to return
- a CalObj instead of a sequence
-
- * cal-client/cal-client.[ch] (cal_client_get_free_busy): changed it to
- work like the cal_client_get_object function, that is, it does not
- return anymore a list of UIDs, but a CalClientGetStatus code, and
- added a new parameter for the caller to get the component back when
- this function returns
- (cal_client_open): aggregate WombatClient interface to the CalListener
- being used
-
- * pcs/cal-backend-db.c, pcs/cal-backend-file.c (..get_free_busy): set
- return value to "char *" as it will be returning a FreeBusy object,
- and not a list of UIDs
-
- * pcs/cal-backend.[ch] (cal_backend_get_free_busy): ditto
-
- * pcs/cal.c (cal_construct): queryInterface on the listener to obtain
- the WombatClient interface
-
-2001-06-21 JP Rosevear <jpr@ximian.com>
-
- * gui/main.c (main): update to new call
-
- * gui/e-itip-control.[hc]: break the widget bits out on their own
- into a proper object, basic stuff seems to be working again
-
- * gui/itip-control-factory.c: put the control specific bits here
- from e-itip-control.c
-
- * gui/itip-control-factory.h: new header
-
-2001-06-21 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/Makefile.am (gladedir): add include path
-
- * gui/dialogs/comp-editor.c (setup_widgets): remove buttons and
- use evolution's standard ui config
-
- * gui/print.c (print_comp_item): print description text
-
-2001-06-21 Rodrigo Moya <rodrigo@ximian.com>
-
- * cal-client/cal-client.[ch]:
- (cal_client_init): create a WombatClient when creating a CalClient
- object, so that we can receive authentication notifications from
- the wombat
- (cal_client_destroy): destroy the WombatClient object when dying
- (cal_client_set_auth_func): new function to set the authentication
- function to be called when a password is required by the calendar
- server (through the WombatClient object)
- (cal_client_get_free_busy): new function for calling the new IDL
- method Cal::getFreeBusy
-
- * gui/alarm-notify/Makefile.am: add libwombat to LDADD
-
- * gui/Makefile.am: add libwombat to LDADD
-
-2001-06-20 Dave Camp <dave@ximian.com>
-
- * gui/itip-utils.c (itip_send_comp): Changed attach_data
- to be a GNOME_Evolution_Composer_AttachmentData rather than a
- CORBA_char*.
-
-2001-06-20 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/comp-editor.c (print_cmd): print menu command
- (print_preview_cmd): ditto for print preview
- (print_setup_cmd): ditto for print setup
- (comp_editor_set_cal_client): listen for updated and removed
- signals
- (obj_updated_cb): if the item changes else where, query the user
- for the course of action
- (obj_removed_cb): ditto for removal
-
- * gui/print.c (print_setup): rudimentary page setup support
- (print_comp): rudimentary individual event/task printing support
-
- * gui/print.h: new protos
-
- * gui/dialogs/changed-comp.[hc]: dialog to query the user about
- what to do when a item is changed elsewhere
-
- * gui/dialogs/Makefile.am: build new files
-
- * gui/dialogs/send-comp.c (send_component_dialog): remove useless
- assignment
-
-2001-06-20 Rodrigo Moya <rodrigo@ximian.com>
-
- * idl/evolution-calendar.idl: added getFreeBusy method
-
- * pcs/cal.c (impl_Cal_get_free_busy): implementation of the new
- getFreeBusy added method
-
- * pcs/cal-backend.[ch]: added new virtual method to the CalBackend
- class (get_free_busy)
-
- * pcs/cal-backend-db.c (cal_backend_db_get_free_busy): new function,
- not implemented yet
-
- * pcs/cal-backend-file.c (cal_backend_file_get_free_busy): new funtion,
- not implemented yet
-
-2001-06-20 Damon Chaplin <damon@ximian.com>
-
- * gui/calendar-config.[hc]:
- * gui/gnome-cal.[hc]:
- * gui/tasks-control.c (tasks_control_activate):
- * gui/calendar-commands.c (calendar_control_activate): moved the
- function to check for a default timezone to calendar-config.c, and
- also used it in the tasks control.
-
- * gui/dialogs/e-timezone-dialog.h: #include <gtk/gtkwidget.h> fix.
-
-2001-06-20 Damon Chaplin <damon@ximian.com>
-
- * gui/calendar-commands.c (calendar_control_activate):
- * gui/gnome-cal.[hc]: added code to show the timezone dialog if the
- user hasn't set a default timezone yet.
-
- * gui/dialogs/e-timezone-dialog.c (e_timezone_dialog_add_timezones):
- set the "None" item string before adding it to the combo, to stop the
- combo putting "None" in the entry initially.
-
-2001-06-19 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-calendar-table.[ch]: added cut/copy/paste support. It works
- with single selections (a single component selected) and with
- multiple ones (several components selected)
-
-2001-06-19 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/event-page.c: if the timezones of the start and end of
- the event are the same, then if the start timezone is changed we
- change the end timezone as well, since that is what most users will
- want.
-
-2001-06-19 Damon Chaplin <damon@ximian.com>
-
- * pcs/cal.c:
- * idl/evolution-calendar.idl:
- * cal-client/cal-client.[hc]: removed stuff to get builtin timezone
- info from the server.
-
-2001-06-19 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/cal-prefs-dialog.c: added a 'Time zone' setting. Also
- rearranged a little, adding a new 'General' page, since we had too
- many settings on the 'Calendar' page.
-
- * gui/e-timezone-entry.[hc]:
- * gui/dialogs/e-timezone-dialog.[hc]:
- * gui/dialogs/comp-editor.c:
- * gui/dialogs/comp-editor-page.[hc]:
- * gui/dialogs/event-page.c:
- * gui/dialogs/task-details-page.c:
- * gui/dialogs/task-page.c: removed CalClient stuff. The timezone dialog
- now uses the timezone data directly from the client's libical library.
-
-2001-06-19 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/task-editor.c (task_editor_init): add ui
- (forward_cmd): implement forward command
-
- * gui/dialogs/comp-editor.c (save_as_ok): bug fix, seems to work
- now
-
-2001-06-19 JP Rosevear <jpr@ximian.com>
-
- * gui/control-factory.c (control_factory_init): add auto exit unref
-
- * gui/component-factory.c (destroy_cb): destroy our selves if we
- have no more shells
- (component_factory_init): add auto exit unref
-
-2001-06-19 JP Rosevear <jpr@ximian.com>
-
- * gui/Makefile.am: don't compile or install the old meeting edit
- stuff
-
- * gui/e-week-view.c: ditto
-
- * gui/e-day-view.c: Remove scheduling menu option
-
-2001-06-19 JP Rosevear <jpr@ximian.com>
-
- * gui/itip-utils.c: add some needed commas
- (itip_send_comp): if publishing, don't set the to list and show
- the message. unless publishing, just send the email
-
- * gui/Makefile.am: remove typo
-
-2001-06-19 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/send-comp.c: itip/imip send dialog
-
- * gui/dialogs/send-comp.h: new proto
-
- * gui/dialogs/recurrence-page.c (recurrence_page_set_dates): only
- use the weekday picker if visible
-
- * gui/dialogs/meeting-page.c: just show the meeting list
-
- * gui/dialogs/event-editor.c (event_editor_edit_comp): remove the
- meeting page if no attendees
- (schedule_meeting_cmd): schedule a meeting menu item
- (refresh_meeting_cmd): refresh meeting request menu item
- (cancel_meeting_cmd): ditto for cancel
- (forward_cmd): send as attachment
-
- * gui/dialogs/comp-editor.c (comp_editor_remove_page): remove page
- from dialog
- (comp_editor_show_page): show a given page
- (comp_editor_get_current_comp): return a cal component
- representing the current widget state
- (comp_editor_save_comp): save the cal component
- (comp_editor_delete_comp): delete the cal component
- (comp_editor_send_comp): send the cal component
- (comp_editor_merge_ui): merge xml in to the bonobo gui
- (setup_widgets): use a bonobo window instead of a gtk window, add menus again
- (save_as_cmd): save to file on disk - still broken
- (save_close_cmd): close menu command
- (save_close_cmd): save and close menu command
-
- * gui/dialogs/comp-editor.h: new protos
-
- * gui/dialogs/cancel-comp.c (cancel_component_dialog): itip/imip
- cancellation dialog
-
- * gui/dialogs/cancel-comp.h: new proto
-
- * gui/dialogs/Makefile.am: build new files
-
- * gui/dialogs/comp-editor-page.c
- (comp_editor_page_notify_needs_send): emit needs_send signal
-
- * gui/dialogs/comp-editor-page.h: new signal protos
-
- * gui/itip-utils.c (itip_send_comp): new function to send cal
- components
-
- * gui/itip-utils.h: new proto
-
- * gui/e-itip-control.c (pstream_load): trim using cal-component
- wrapper stuff
- (accept_button_clicked_cb): use itip_send_comp
- (tentative_button_clicked_cb): ditto
- (decline_button_clicked_cb): ditto
-
- * gui/Makefile.am: compile select name idl stuff
-
- * cal-util/cal-component.c (cal_component_get_organizer): get the organizer
- (cal_component_set_organizer): set the organizer
- (cal_component_get_recurid): get the recurrence id
- (cal_component_set_recurid): set the recurrence id
- (set_attendee_list): actually set the attendee list
- (get_attendee_list): build the attendee list
-
- * cal-util/cal-component.h: new protos
-
-2001-06-19 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/task-details-page.glade:
- * gui/dialogs/task-page.glade:
- * gui/dialogs/event-page.glade: added timezone fields. Also moved the
- 'All Day' flag into an alignment so it doesn't mess up the height of
- the other widgets.
-
- * gui/dialogs/task-details-page.c:
- * gui/dialogs/task-page.c:
- * gui/dialogs/event-page.c: added code to handle the timezone fields.
- This still needs to be hooked up when the libical code is finished.
-
- * gui/dialogs/e-timezone-dialog.c (on_map_leave): new function to
- clear the preview label and turn off the highlighted point on the
- map when you move the mouse outside it.
- (find_selected_point): new function to try to find the point
- corresponding to the text in the combo.
- (on_combo_changed): call the above function to update the selected
- point.
- (on_map_leave): turn off the preview point & label when the mouse
- leaves the map.
- (e_timezone_dialog_set_cal_client): changed it so that selecting "None"
- clears the entry.
-
- * gui/dialogs/comp-editor-page.[hc]: added set_cal_client() virtual
- method since some pages need to access the CalClient to get timezone
- information. Also added comp_editor_page_set_cal_client() to call
- the virtual method.
-
- * gui/dialogs/comp-editor.c (comp_editor_set_cal_client): called
- comp_editor_page_set_cal_client() on each page.
-
- * gui/calendar-config.c: added functions to get & set the timezone.
-
-2001-06-18 Eskil Heyn Olsen <eskil@eskil.dk>
-
- * conduits/calendar/calendar-conduit.c: (comp_from_remote_record),
- (check_for_slow_setting), (conduit_get_gpilot_conduit):
- * conduits/todo/todo-conduit.c: (check_for_slow_setting),
- (conduit_get_gpilot_conduit):
- Tweaked for some gnome-pilot api changes
-
-2001-06-15 Federico Mena Quintero <federico@ximian.com>
-
- * gui/calendar-view.[ch]: New files with the generic calendar view
- object. It sucks that we have to implement at least two classes
- to define a GalView and its factory.
-
- * gui/calendar-view-factory.[ch]: New files; factory for calendar
- views.
-
- * gui/gnome-cal.h (GnomeCalendarViewType): Moved from gnome-cal.c
- and renamed from ViewType. We no longer use strings to identify
- the view types.
-
- * gui/gnome-cal.c (gnome_calendar_get_view_type): New function.
- (set_view): Renamed from gnome_calendar_set_view_internal().
- (gnome_calendar_set_query): Made public; renamed from set_query().
- (gnome_calendar_setup_view_menus): New function to set up the view
- collection and the GalViewMenus.
- (gnome_calendar_discard_view_menus): New function to discard them.
-
- * gui/calendar-commands.c (calendar_control_activate): Set up the
- GalView menus.
- (calendar_control_deactivate): Discard the GalView menus.
-
- * gui/e-day-view.c: #include <gtk/gtkinvisible.h>
-
- * gui/dialogs/comp-editor.c (comp_editor_get_type): The type info
- structure should be static.
-
-2001-06-15 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view.c (selection_received): generate a new UID
- when pasting
-
- * gui/e-week-view.c (selection_received): ditto
-
-2001-06-15 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view.c (selection_received): finished implementation
- of Paste stuff
-
- * gui/e-week-view.c (selection_received): ditto
-
-2001-06-14 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view.[ch]: added popup menu items for cut/copy/paste
-
- * gui/e-week-view.[ch]: ditto
-
-2001-06-14 Damon Chaplin <damon@ximian.com>
-
- * gui/e-timezone-entry.[hc]: new widget to enter a timezone.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): added the above.
- * gui/Makefile.am (evolution_calendar_LDADD): had to move
- libcal-dialogs.a above libmiscwidgets.a to get it to compile.
-
-2001-06-14 Damon Chaplin <damon@ximian.com>
-
- * gui/dialogs/e-timezone-dialog.[hc]:
- * gui/dialogs/e-timezone-dialog.glade: new dialog for setting the
- time zone.
-
- * gui/dialogs/Makefile.am: added timezone dialog files.
-
- * idl/evolution-calendar.idl: added CalTimezoneInfo struct and seq,
- and getBuiltinTimezoneInfo method.
-
- * pcs/cal.c (impl_Cal_get_builtin_timezone_info): implemented method.
- (cal_class_init): added method to epv.
-
- * cal-client/cal-client.c (struct CalClientPrivate): added
- timezone_info array to contain cached info on builtin timezone city
- names and coordinates.
- (cal_client_get_builtin_timezone_info): new function to get the info
- about builtin timezones.
-
- * cal-client/cal-client.h: added CalTimezoneInfo struct, to contain
- the city names and coords of the builtin timezones.
-
-2001-06-13 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/comp-editor-util.c (comp_editor_date_label): remove
- unnecessary space
-
- * gui/dialogs/task-page.c (task_page_set_summary): indicate we are
- updating, Fixes #3307
-
-2001-06-13 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/task-details-page.c (task_details_page_set_dates):
- set the completed time in the date editor if appropriate
-
- * gui/dialogs/task-page.c (task_page_set_dates): if we are
- updating, return
- (complete_date_changed): don't returns if we are updating - the
- guards are done in the calling function
- (status_changed): indicate when we are updating and when we are
- finished, round the completion time to the nearest minute
- (percent_complete_changed): indicate when are updating and when we
- are finished
- (percent_complete_changed): notify of the date change after the
- option menu is updated
-
-2001-06-11 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/e-day-view.[ch]: added cut&paste support, by using a GtkInvisible
- widget to manage the clipboard selections.
-
- * gui/e-week-view.[ch]: ditto
-
-2001-06-08 Iain Holmes <iain@ximian.com>
-
- * gui/component-factory.c: Removed the executive-summary includes.
- (component_factory_init): Don't init the summary factory.
-
- * gui/calendar-summary.[ch]: Removed.
-
- * gui/Makefile.am: Remove executive-summary stuff, move some libs
- around a bit.
-
-2001-06-04 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/recurrence-page.c (recurrence_page_set_dates):
- update the blocked/selected days if the starting day of the
- appointment changes, fixes #2188
-
- * gui/dialogs/task-details-page.h: tidy proto
-
-2001-06-03 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/e-itip-control.c: #include <bonobo/bonobo-context.h> instead
- of <bonobo/bonobo-running-context.h>.
- * gui/tasks-control-factory.c: Likewise.
-
- * gui/Makefile.am (evolution_calendar_LDADD): Move `$(DB3_LDADD)'
- before libeutil.
-
-2001-06-01 JP Rosevear <jpr@ximian.com>
-
- * gui/Makefile.am: no longer build widget-util.*, the code has
- been moved
-
-2001-06-01 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/event-page.c (make_date_edit): use new func
-
- * gui/dialogs/task-details-page.c
- (task_details_page_create_date_edit): ditto
-
- * gui/dialogs/recurrence-page.c (make_ending_until_special): ditto
-
- * gui/dialogs/comp-editor-util.c (comp_editor_new_date_edit):
- rename date_edit_new function
-
- * gui/dialogs/comp-editor-util.h: new proto
-
- * gui/dialogs/task-page.c (task_page_set_summary): no longer any
- need to block/unblock the handler
- (task_page_create_date_edit): use new func
-
-2001-06-01 JP Rosevear <jpr@ximian.com>
-
- * gui/.cvsignore: Update
-
- * gui/evolution-calendar-control.c: Remove dead file
-
- * gui/*.vcf: Remove dead files
-
-2001-06-01 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/comp-editor-page.[hc]: renamed from editor-page for
- consistency, more complete implementation
-
- * gui/dialogs/comp-editor.[hc]: More complete implementation
-
- * gui/dialogs/*-page.*: The various pages needed to construct the
- event and task dialogs
-
- * gui/dialogs/comp-editor-util.[hc]: useful utility functions for the
- component editor pages to use
-
- * gui/dialogs/Makefile.am: Build and install new files
-
- * gui/event-editor*: Remove, obsoleted by the new comp-editor
- stuff
-
- * gui/dialogs/task-editor-dialog.glade: ditto
-
- * gui/e-calendar-table.c (open_task): update to use comp editor
- stuff
-
- * gui/e-tasks.c (e_tasks_new_task): ditto
-
- * gui/gnome-cal.c (gnome_calendar_edit_object): ditto
-
- * gui/Makefile.am: don't build non-existent files nor try to
- install them
-
-2001-06-01 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (e_itip_control_factory_init): ditto
-
- * gui/tasks-control-factory.c (tasks_control_factory_init):
- auto_exit_unref the factory
-
-2001-06-01 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/Makefile.am (evolution_calendar_LDADD): Add `$(DB3_LDADD)'.
-
-2001-05-29 Federico Mena Quintero <federico@ximian.com>
-
- * gui/e-tasks.c (e_tasks_get_calendar_table): New function.
-
- * gui/tasks-control.c (tasks_control_activate): Connect to the
- "selection_changed" signal of the tasks widget here, not in
- tasks_control_new(). Also, update the sensitivity of the commands
- here for the first time.
- (tasks_control_deactivate): Disconnect from the signal here since
- it only makes sense to monitor selection changes while the control
- is active.
- (selection_changed_cb): Removed hack that tested the presence of
- the remote UI container.
- (sensitize_commands): New function.
-
-2001-05-28 Damon Chaplin <damon@ximian.com>
-
- * gui/e-week-view-layout.[hc]:
- * gui/e-day-view-layout.[hc]: new files to contain layout code split
- off from EDayView an EWeekView, so we can use it for printing.
-
- * gui/print.c: rewritten to use the same layout code as the EDayView
- and EWeekView widgets.
-
- * gui/gnome-cal.c (gnome_calendar_get_task_pad_cal_client): added
- function so we can get the CalClient used for the TaskPad for printing.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): added
- e-day-view-layout.[hc] amd e-week-view-layout.[hc].
-
- * cal-util/timeutil.c (time_week_begin):
- (time_week_end): added week_start_day argument.
-
- * cal-util/cal-recur.c: added comments describing problems in it.
-
-2001-05-27 Rodrigo Moya <rodrigo@ximian.com>
-
- * gui/component-factory.c (remove_folder): implemented the
- 'remove_folder' function for the calendar shell component
- (xfer_folder): ditto for 'xfer_folder'
-
-2001-05-27 Dan Winship <danw@ximian.com>
-
- * gui/calendar-commands.c: #include
- "evolution-shell-component-utils.h" rather than "e-gui-utils.h"
- for e_pixmaps_update.
-
- * gui/tasks-control.c: Likewise.
-
-2001-05-25 Peter Williams <peterw@ximian.com>
-
- * gui/Makefile.am: Reference libeshell.la instead of libeshell.a.
-
-2001-05-23 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/recurrence-page.c: Finished porting from the old
- event-editor.c. Made it store a clone of the component for when
- we need to expand the recurrence set.
-
- * gui/dialogs/event-page.c (event_page_get_dates): New function.
-
- * gui/dialogs/editor-page.c (editor_page_set_dates): Renamed from
- editor_page_set_dtstart(); now sets both DTSTART and DTEND.
-
- * gui/dialogs/alarm-page.c (alarm_page_set_dates): Ahem, it is a
- label, not an entry.
-
-2001-05-21 Federico Mena Quintero <federico@ximian.com>
-
- Fix bug #2831; the tasks toolbar and menu now have a button to
- delete the selected tasks.
-
- * gui/e-calendar-table.c (e_calendar_table_delete_selected): New
- function.
- (delete_cb): Use e_calendar_table_delete_selected().
- (e_calendar_table_get_table): New function.
-
- * gui/tasks-control.c (tasks_control_new_task_cmd): Handle the
- delete command.
- (selection_changed_cb): Change the sensitivity of the TasksDelete
- command when the selection in the table changes.
-
- * gui/e-tasks.c (table_selection_change_cb): Notify upstream when
- the ETable selection changes.
-
-2001-05-18 Federico Mena Quintero <federico@ximian.com>
-
- Fix bug #2829.
-
- * gui/dialogs/delete-comp.c (delete_component_dialog): Allow the
- caller to specify whether just one or many components are to be
- deleted.
-
- * gui/e-calendar-table.c (tasks_popup_one): Popup menu definition
- for when one and only one task is selected.
- (tasks_popup_many): Likewise, for more than one task.
- (e_calendar_table_on_right_click): Do not create a structure for
- the closure data; we can simply pass the cal_table. Use a
- different menu depending on the number of selected tasks.
- (mark_as_complete_cb): Renamed; now iterates over the selected
- rows.
- (delete_selected_components): New function to delete all the
- selected components.
- (delete_cb): Adjusted for delete_component_dialog().
- (open_task): New function, simply open a CalComponent in the task
- editor.
- (open_task_by_row): Renamed; use open_task().
-
- * gui/e-week-view.c (e_week_view_on_delete_appointment): Updated
- for delete_component_dialog().
-
- * gui/e-day-view.c (e_day_view_on_delete_appointment): Likewise.
-
-2001-05-16 Duncan Mak <duncan@ximian.com>
-
- * gui/Makefile.am (evolution_calendar_SOURCES): removed
- editor-page.[ch] because they've now moved dialogs.
-
-2001-05-16 Federico Mena Quintero <federico@ximian.com>
-
- Split the event and task editors into different objects for the
- separate pages; this way they can be shared by both editors.
-
- * gui/dialogs/editor-page.[ch]: New abstract class for a page in a
- calendar component editor.
-
- * gui/dialogs/event-page.[ch]: Main page of an event editor.
-
- * gui/dialogs/alarm-page.[ch]: Alarm page of a calendar component
- editor.
-
- * gui/dialogs/recurrence-page.[ch]: Recurrence page of a calendar
- component editor.
-
- * gui/dialogs/event-page.c (event_page_fill_widgets): Eeek, this
- was missing a bunch of break statements.
- (event_page_fill_component): Use a temporary variable rather than
- allocating a struct icaltimetype.
-
- * gui/dialogs/alarm-page.c (get_alarm_string): Do not use
- fixed-size buffers.
- (alarm_page_fill_widgets): Use cal_obj_uid_list_free().
- (append_reminder): Now the list stores the plain CalComponentAlarm
- structures in the row data. We do *NOT* want to be frobbing the
- component's data directly. Rather, we clone the alarms from the
- component and maintain them on our own.
- (alarm_page_fill_component): Clone the alarms before adding them
- to the component so that we maintain the invariant that the alarm
- structures in the list did *not* come from the component.
-
- * cal-util/cal-component.c (cal_component_add_alarm): Added
- documentation.
- (cal_component_remove_alarm): Added documentation.
- (cal_component_remove_alarm): Do a lookup in our hash table of
- alarms instead of scanning the whole component.
- (CalComponentAlarm): Removed the `parent' field, since it was
- unused.
- (cal_component_free_alarm_uids): Removed function, since
- cal_component_get_alarm_uids() is documented so that the user will
- know that he must use cal_obj_uid_list_free().
- (cal_component_alarm_clone): New function.
-
-2001-05-09 Federico Mena Quintero <federico@ximian.com>
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Added
- editor-page.[ch] to the list of sources.
-
-2001-05-09 JP Rosevear <jpr@ximian.com>
-
- * gui/event-editor.c (reminder_add_cb): switch on the correct
- widget and map
-
-2001-05-08 JP Rosevear <jpr@ximian.com>
-
- * gui/e-itip-control.c (e_itip_control_factory): unref the
- property bag when we finish with it
-
- * gui/evolution-calendar-control.c (calendar_properties_init): ditto
-
- * gui/control-factory.c (calendar_properties_init): ditto
-
- * gui/calendar-summary.c (create_summary_view): ditto
-
-2001-05-08 JP Rosevear <jpr@ximian.com>
-
- * cal-util/cal-component.c (cal_component_alarm_free):
- (cal_component_alarm_free): free the alarm component if it doesn't
- have a parent, rather than if it does
-
- * gui/Makefile.am: sanitize LD_ADDS and CFLAGS so the libtool
- lines are shorter (fixes problem on solaries due to sed)
-
-2001-05-07 JP Rosevear <jpr@ximian.com>
-
- * pcs/cal-factory.[hc]: Convert to bonobo xobject
-
- * pcs/cal.[hc]: Convert to bonobo xobject
-
-2001-05-07 Gediminas Paulauskas <menesis@delfi.lt>
-
- * gui/event-editor.c (make_title_from_comp): conversion summary
- from utf8 here, use translated strings as is.
- (set_title_from_comp): reflect this, simplify.
-
- * gui/dialogs/task-editor.c: updated copies of above functions here.
-
- * gui/gnome-cal.c: use defines from widgets/misc/e-filter-bar.h for
- consistency in "Show all".
-
-2001-05-04 JP Rosevear <jpr@ximian.com>
-
- * gui/calendar-model.c (calendar_model_append_row): unref the
- calcomponent when we're done with it
-
- * cal-util/cal-component.c (cal_component_gen_uid): free the iso
- date string when we finish with it
-
-2001-04-27 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-edit.c (put_property_in_list): remove hardcoded
- values
- (edit_attendee): ditto, and there are only 4 roles now
-
- * gui/e-meeting-dialog.glade: tweak
-
- * gui/itip-utils.c: There shouldn't be an "other" role
-
-2001-04-26 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-edit.c (edit_attendee): use enums not hard code
- values
-
-2001-04-26 JP Rosevear <jpr@ximian.com>
-
- * gui/e-meeting-edit.c (add_button_clicked_cb):
- icalparameter_new_rsvp now takes an enum
-
-2001-04-26 JP Rosevear <jpr@ximian.com>
-
- * cal-util/cal-component.c (cal_component_alarm_set_trigger): the
- value type should be inited with ICAL_VALUE_* rather than
- ICAL_*_VALUE because it is a param argument.
-
-2001-04-26 Federico Mena Quintero <federico@ximian.com>
-
- * gui/calendar-model.c (get_is_overdue): Replace "<" by "<=" in
- the comparison for due dates against the current time. This makes
- tasks appear immediately as red when you click Now in the due date
- popup field.
-
- This is not a complete solution to the more general problem of
- tasks staying the same color even if they become overdue while the
- task list remains the same on the screen. This has been logged as
- bug #2399.
-
-2001-04-26 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/dialogs/Makefile.am (INCLUDES): Add `$(EXTRA_GNOME_CFLAGS)'.
-
-2001-04-26 Dan Winship <danw@ximian.com>
-
- * conduits/todo/Makefile.am (libetodo_conduit_la_LIBADD): Remove
- UNICODE_LIBS
-
- * cal-client/Makefile.am (client_test_LDADD): Remove -lunicode
-
-2001-04-24 Duncan Mak <duncan@ximian.com>
-
- * gui/alarm-notify/notify-main.c (funny_trigger_cb): Fixed
- Strftime so it uses the locale prefered way to display date/time.
- ("%x %X" instead of "%Y/%m/%d %H:%M:%S")
-
-2001-04-21 Gediminas Paulauskas <menesis@delfi.lt>
-
- * gui/calendar-summary.c: translate "Things to do" etc. and convert them
- to utf8. Changed some link from helixcode to ximian.
-
-2001-04-18 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/dialogs/Makefile.am (INCLUDES): Add
- `-I$(top_srcdir)/calendar/cal-client',
- `-I$(top_builddir)/calendar/cal-client'.
- * gui/Makefile.am (INCLUDES): Likewise.
-
- * cal-client/cal-query.h: #include "evolution-calendar.h".
-
-2001-04-17 Federico Mena Quintero <federico@ximian.com>
-
- * gui/event-editor.c (init_widgets): Connect to the "changed"
- signal of the categories entry so that they will be applied
- correctly.
- (EventEditorPrivate): Added fields for the contacts button and
- entry.
- (init_widgets): Disable the contacts widgets as we do not support
- them yet.
- (get_widgets): Get the contacts widgets.
-
- * gui/dialogs/task-editor.c (get_widgets): Get the contacts
- button, which was missing.
- (init_widgets): Disable the contacts widgets as we do not support
- them yet.
-
- * pcs/query.c (matches_text_list): Use e_utf8_strstrcasedecomp()
- instead of plain e_utf8_strstrcase().
- (matches_summary): Likewise.
-
-2001-04-17 JP Rosevear <jpr@ximian.com>
-
- * cal-util/cal-component.c (cal_component_alarm_set_action): the
- libical action stuff uses enums rather than strings to enumerate
- the various actions now
- (cal_component_alarm_get_action): ditto
-
-2001-04-17 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/alarm-notify/Makefile.am (evolution_alarm_notify_SOURCES):
- Add `$(CORBA_GENERATED)'.
-
-2001-04-16 Dan Winship <danw@ximian.com>
-
- * pcs/Makefile.am (INCLUDES): Add EXTRA_GNOME_CFLAGS, for gal.
-
-2001-04-15 Federico Mena Quintero <federico@ximian.com>
-
- * gui/gnome-cal.c (setup_widgets): Create the ESearchBar thingy.
- (search_bar_query_changed_cb): Build the different queries based
- on the type and string.
-
- * pcs/query.c (backend_obj_updated_cb): Ref the query while we are
- notifying the listener so that it will not disappear from under us.
- (backend_obj_removed_cb): Likewise.
- (process_component_cb): Likewise.
- (func_contains): New function to match text fields.
- (matches_comment): New function to match comment lists.
- (matches_description): New function to match description lists.
- (matches_summary): New function to match summaries.
- (matches_any): New function to match any text field.
- (func_has_categories): New function to match categories.
-
-2001-04-14 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/notify-main.c (main): Initialize the trigger
- and queue systems.
-
-2001-04-13 Dan Winship <danw@ximian.com>
-
- * cal-util/timeutil.c (time_from_isodate): Fix the syntactic bogon
- here, and attempt to fix the logical bogon too. (tm_gmtoff and
- timezone have opposite signs... I'm assuming Federico tested the
- Linux case, so I'm flipping the sign of the BSD case. But maybe he
- didn't and it's supposed to be the other way...)
-
-2001-04-12 Federico Mena Quintero <federico@ximian.com>
-
- * gui/e-day-view.c (update_query): New function to restart a query
- for the day view.
- (query_obj_updated_cb): Renamed from obj_updated_cb(); updated for
- queries instead of calendar clients.
- (query_obj_removed_cb): Likewise.
- (cal_opened_cb): Just update_query() instead of queueing reloading
- all the events.
- (e_day_view_set_cal_client): Likewise.
- (e_day_view_set_query): Likewise.
- (e_day_view_set_selected_time_range): Likewise.
- (e_day_view_set_days_shown): Likewise.
- (e_day_view_recalc_work_week): Likewise.
- (e_day_view_queue_reload_events): Removed function now that events
- are updated entirely by the query.
- (e_day_view_reload_events_idle_cb): Likewise.
- (e_day_view_reload_events): Likewise.
- (e_day_view_init): Use a pretty arrow instead of GDK_TOP_LEFT_ARROW.
-
- * gui/e-week-view.c: Analogous changes to the ones in e-day-view.c.
- (e_week_view_init): Use a pretty arrow instead of GDK_TOP_LEFT_ARROW.
-
- * cal-util/timeutil.c (isodate_from_time_t): Return a g_strdup()ed
- version of the string instead of a pointer to a static buffer.
- (time_from_isodate): Resurrected function. Polished up to our
- current standards of paranoia.
-
- * pcs/query.c (func_time_now): New function (time-now).
- (func_make_time): New function (make-time ISODATE).
- (func_time_add_day): New function (time-add-day TIME N).
- (func_time_day_begin): New function (time-day-begin TIME).
- (func_time_day_end): New function (time-day-end TIME).
- (func_occur_in_time_range): Use time_t values instead of ints.
- (match_component): Free the stringized component. Free the ESexp
- result value.
-
- * gui/e-day-view.h: Removed a couple of unused prototypes.
-
- * pcs/query.c (query_destroy): Oops, disconnect from the backend.
-
- * pcs/cal.c (Cal_get_query): Duplicate the query reference before
- we return it.
-
- * gui/calendar-commands.c (pixmaps): Fixed paths to image files.
-
-2001-04-11 JP Rosevear <jpr@ximian.com>
-
- * pcs/cal-backend-file.c (cal_backend_file_compute_changes):
- prepend to both changes and change_ids when different and mark as
- modified, not added
-
-2001-04-11 Christopher James Lahey <clahey@ximian.com>
-
- * gui/calendar-model.c (calendar_model_append_row): Fix this to
- just send the data to the wombat instead of inserting it
- ourselves.
-
-2001-04-11 Gediminas Paulauskas <menesis@delfi.lt>
-
- Display fixes, thanks to Kjartan for finding these.
-
- * gui/event-editor.c: use simple (not e_utf8_) gtk_clist_append for
- strings which are never in utf-8.
- * dialogs/delete-comp.c (delete_component_dialog): convert only
- summary from utf-8 to gtk charset. Translated values are in correct
- craset already.
-
-2001-04-04 Kjartan Maraas <kmaraas@gnome.org>
-
- * gui/calendar-commands.c: Fix headers.
- * gui/calendar-config.c: Same here.
- * gui/calendar-model.c: Same here.
- * gui/e-day-view-time-item.c: Same here.
- * gui/e-day-view-top-item.c: Same here.
- * gui/e-day-view.c: Same here.
- * gui/e-meeting-edit.c: Same here.
- * gui/e-week-view-main-item.c: Same here.
- * gui/e-week-view.c: Same here.
- * gui/event-editor.c: Same here.
- * gui/gnome-cal.c: Same here.
- * gui/goto.c: Same here.
- * gui/main.c: Same her.
- * gui/print.c: Same here.
-
-2001-04-02 Federico Mena Quintero <federico@ximian.com>
-
- * gui/e-tasks.c (e_tasks_setup_menus): Plug leak.
-
- * gui/event-editor.c (obj_updated_cb): Do nothing for now until we
- think of something sensible to do.
- (obj_removed_cb): Likewise.
-
- * gui/dialogs/task-editor.c (obj_updated_cb): Likewise.
- (obj_removed_cb): Likewise.
-
- * gui/event-editor.c (dialog_to_comp_object): Plug leak.
-
-2001-04-01 Federico Mena Quintero <federico@ximian.com>
-
- Client-side glue for the live query engine.
-
- * cal-client/query-listener.[ch]: New files with the
- implementation fo the QueryListener interface.
-
- * cal-client/cal-query.[ch]: New files with the client-side
- convenience object for live queries.
-
- * cal-client/cal-listener.h (CalListenerClass): Removed unused
- slots for signal handlers.
-
- * cal-client/Makefile.am (libcal_clientinclude_HEADERS): Now we
- install the evolution-calendar.h header. This sucks a bit.
-
-2001-04-01 Gediminas Paulauskas <menesis@delfi.lt>
-
- * gui/calendar-commands.c: use new pixmap cache. Added some menu icons
- and changed filenames of renamed icons.
- * gui/tasks-control.c: added icons for new task and print in menu.
-
-2001-03-29 Federico Mena Quintero <federico@ximian.com>
-
- Engine for live queries to calendars. A query object watches a
- CalBackend in the PCS and is otherwise completely separate from
- it; backends need to do nothing to support live queries. Right
- now we have the following functions:
-
- (get-vtype)
-
- Returns a string indicating the type of component
- (VEVENT, VTODO, VJOURNAL, VFREEBUSY, VTIMEZONE,
- UNKNOWN).
-
- (occur-in-time-range? START END)
-
- START - int, time_t start of the time range
- END - int, time_t end of the time range
-
- Returns a boolean indicating whether the component
- has any occurrences in the specified time range.
-
- * idl/evolution-calendar.idl (Cal::getQuery): New method that
- initiates a live query.
- (Query): New interface for a handle to a live query.
- (QueryListener): New interface for a listener to changes in a live
- query.
-
- * pcs/query.[ch]: New files with the live query engine.
-
- * pcs/cal-backend.h (CalBackendClass): Added notification signals
- so that the query system can catch them.
- (CalBackendClass): New virtual method ::get_load_state().
-
- * pcs/cal-backend.c (cal_backend_opened):
- (cal_backend_obj_updated):
- (cal_backend_obj_updated): New functions to emit the notification
- signals; to be used only by backend implementations.
- (cal_backend_get_load_state): New function.
-
- * pcs/cal-backend-file.c (notify_update): Call
- cal_backend_obj_updated().
- (notify_remove): Call call_backend_obj_removed().
- (open_cal): Free the icalcomp if it is not of the correct type.
- (cal_backend_file_get_load_state): Implemented new method.
-
- * pcs/cal-backend-db.c (cal_backend_db_update_object): Call
- cal_backend_obj_updated().
- (cal_backend_db_remove_object): Call cal_backend_obj_removed().
- (cal_backend_db_get_load_state): Implemented new method.
-
- * pcs/cal.c (Cal_get_query): Implementation of the ::getQuery()
- method.
-
-2001-03-27 Anna Marie Dirks <anna@ximian.com>
-
- * gui/e-itip-control.c: fixed button placement to comply
- with gnome standards.
-
-2001-03-27 Anna Marie Dirks <anna@ximian.com>
-
- * gui/e-itip-control.glade: fixed spacing and label alignment to
- comply with gnome standards. Also removed shadows from extraneous
- scrolled windows to avoid bevelitous. There are many more changes
- that need to happen to this viewer, but they all require a hacker
- to do some c-coding, so I will avoid committing them until after the
- .10 release.
-
-2001-03-26 Kjartan Maraas <kmaraas@gnome.org>
-
- * cal-client/client-test.c: Replace includes of <gnome.h>, <bonobo.h>
- and <gtk/gtk.h> with the needed headers to speed up compile.
- * cal-util/test-recur.c: Same here for <gtk/gtk.h>
- * gui/calendar-commands.c: Replace <bonobo.h> and remove
- <libgnorba/gnorba.h>
- * gui/calendar-summary.c: Replace <gnome.h> and <bonobo.h>
- * gui/calendar-summary.h: Added <bonobo/bonobo-generic-factory.h>
- * gui/component-factory.c: Remove <bonobo.h>
- * gui/control-factory.c: Replace <bonobo.h>
- * gui/e-calendar-table.c: Remove <gnome.h>
- * gui/e-itip-control.c: Replace <gnome.h> and <bonobo.h>
- * gui/e-meeting-edit.c: Replace <bonobo.h>
- * gui/e-tasks.c: Replace <gnome.h>
- * gui/e-tasks.h: Replace <bonobo.h>
- * gui/gnome-cal.h: Remove <bonobo.h>
- * gui/main.c: Replace <bonobo.h> and <glade/glade.h>
- * gui/tasks-control-factory.c: Replace <bonobo.h>
- * gui/tasks-control.c: Replace <gnome.h> and <bonobo.h>
- * gui/weekday-picker.c: Add <string.h> and <libgnome/gnome-defs.h>
- * gui/alarm-notify/client-main.c: Remove <gnome.h> and <bonobo.h>
- * gui/alarm-notify/notify-main.c: Replace <gnome.h> and <bonobo.h>
- * gui/dialogs/alarm-notify-dialog.c: Replace <gnome.h>
- * pcs/cal-backend.c: Replace <gtk/gtk.h>
-
-2001-03-25 Federico Mena Quintero <federico@ximian.com>
-
- * gui/e-calendar-table.c (e_calendar_table_init): The
- model_rows_{inserted,deleted} signals changed names; deal with it.
- (e_calendar_table_on_rows_inserted): Updated for new ETable API.
- (e_calendar_table_on_rows_deleted): Likewise.
-
- * gui/gnome-cal.h (GnomeCalendarOpenMode): Removed unused enum.
-
- * gui/gnome-cal.c (gnome_calendar_open): Constify.
-
- * gui/calendar-commands.c (calendar_set_uri): Removed function,
- since it was just calling gnome_calendar_open().
-
- * gui/control-factory.c (set_prop): Replace usage of
- calendar_set_uri() with gnome_calendar_open().
- (load_calendar): Likewise.
- (calendar_persist_init): Made static.
-
- * gui/e-tasks.c: #include "calendar-config.h"
- (e_tasks_update_all_config_settings): We are configuring a table,
- not a calendar! Use the appropriate function.
-
-2001-03-17 Miguel de Icaza <miguel@ximian.com>
-
- * gui/e-day-view.c (e_day_view_on_new_event,
- e_day_view_on_new_appointment): Simplifed this function to use the
- shared code.
-
- * gui/e-week-view.c (e_week_view_on_new_event,
- e_week_view_on_new_appointment): ditto.
-
- * gui/gnome-cal.c (gnome_calendar_new_appointment_for): New
- function used to launch editor components with a time range. A
- bunch of functions use this code now instead of duplicating code
- all over the place
-
- * gui/e-week-view.c (e_week_view_new_event): Moved functionality
- here from e_day_view_on_new_appointment. Allows setting for "full
- day" event.
- (e_week_view_on_new_full_day): New function for making a full day
- event.
- (e_week_view_on_goto_date): Go To support.
- (e_week_view_on_goto_today): Goto today support.
-
- * gui/e-day-view.c (e_day_view_new_event): Moved functionality
- here from e_day_view_on_new_appointment. Allows setting for "full
- day" event.
- (e_day_view_on_new_full_day): New function for making a full day
- event.
- (e_day_view_on_goto_date): Go To support.
- (e_day_view_on_goto_today): Goto today support.
-
- * main_items: Add New All Day Event; Go to Today; Go to Date.
-
-2001-03-07 Miguel de Icaza <miguel@ximian.com>
-
- * gui/control-factory.c (calendar_persist_init): New function:
- inits the BonoboPersistFile server.
-
- * gui/GNOME_Evolution_Calendar.oaf.in: Added BonoboPropertyBag to
- the list of supported interfaces that were supported but not
- reported. Add the new PersistFile.
-
- Add text/calendar mime type attribute.
-
-2001-03-15 Dan Winship <danw@ximian.com>
-
- * gui/e-week-view.c (e_week_view_start_editing_event):
- * gui/e-day-view.c (e_day_view_start_editing_event): Update
- arguments to e_canvas_item_grab_focus.
-
-2001-03-15 Gediminas Paulauskas <menesis@delfi.lt>
-
- * gui/*.xpm: moved to ../art.
- * gui/Makefile.am: removed *.xpm and oaf_DATA from EXTRA_DIST.
- * gui/e-calendar-table.c, gui/e-day-view.c, gui/e-week-view.c:
- #include "art/*.xpm".
-
-2001-03-09 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/Makefile.am: PISOCK_INCLUDEDIR has become
- PISOCK_CFLAGS in gnome-pilot.m4 and remove capplet foo
-
- * conduits/calendar/Makefile.am: ditto
-
-2001-03-08 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/component-factory.c (factory_fn): Specify a NULL
- `EvolutionShellComponentGetDndSelectionFn'.
-
-2001-02-27 Miguel de Icaza <miguel@ximian.com>
-
- * gui/e-day-view.c (e_day_view_on_event_right_click): Reorganize
- the menus to have entries always in a consistent fashion, as
- reported to the genepool mailing list.
- (e_day_view_on_event_right_click): Added a FIXME comment to the
- FIXME comment without a FIXME.
-
- Now we use e_popup_menu. This allows us to hide/show items on
- demand, and to sensitize/de-sensitize items depending on their
- state.
-
- This will also let us add icon support (when we get nice icons for
- this)
-
- * gui/e-week-view.c (e_week_view_show_popup_menu): Ditto.
-
- The files popup-menu.c and popup-menu.h can now be removed.
-
-2001-03-05 Damon Chaplin <damon@ximian.com>
-
- * gui/e-tasks.c: keep list of all Tasks folders so we can update the
- preference settings when necessary.
-
- * gui/gnome-cal.c: configure the TaskPad according to the settings.
-
- * gui/e-calendar-table.c: use ECellCombo and ECellDateEdit for fields,
- so the tasks folders is almost usable now.
-
- * gui/calendar-model.c: added support for the Status property.
-
- * gui/calendar-config.[hc]: added convenience functions to setup
- ECalendarTable and ECellDateEdit objects.
-
- * gui/calendar-commands.c: connected to "destroy" signal of calendars
- so we can remove them from all_calendars list.
-
- * gui/dialogs/cal-prefs-dialog.c (cal_prefs_dialog_update_config):
- call e_tasks_update_all_config_settings() to update all the settings
- in the Tasks folders as well.
-
- * cal-util/cal-component.h: added CAL_COMPONENT_FIELD_STATUS.
-
- * cal-util/cal-component.c (cal_component_get_transparency): fixed
- calls to strcasecmp so they check for '== 0'.
-
- Applied patch from Miguel...
-
-2001-02-27 Miguel de Icaza <miguel@ximian.com>
-
- * gui/e-day-view.c (e_day_view_on_event_right_click): Reorganize
- the menus to have entries always in a consistent fashion, as
- reported to the genepool mailing list.
- (e_day_view_on_event_right_click): Added a FIXME comment to the
- FIXME comment without a FIXME.
-
- Now we use e_popup_menu. This allows us to hide/show items on
- demand, and to sensitize/de-sensitize items depending on their
- state.
-
- This will also let us add icon support (when we get nice icons for
- this)
-
- * gui/e-week-view.c (e_week_view_show_popup_menu): Ditto.
-
- The files popup-menu.c and popup-menu.h can now be removed.
-
-2001-03-02 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/e-todo.conduit.in: update for new pilot foo
-
- * conduits/calendar/e-calendar.conduit.in: ditto
-
- * conduits/todo/Makefile.am: update sed script
-
- * conduits/calendar/Makefile.am: ditto
-
-2001-02-28 Federico Mena Quintero <federico@ximian.com>
-
- * gui/event-editor.c (recurrence_exception_select_row_cb): New
- function to set the EDateEdit's value when a row is selected in
- the exception date list. Fixes bug #1638.
- (append_exception): Set the value as well. Block/unblock signals
- from the clist as appropriate. Gotta love non-model/view widgets.
- (recurrence_exception_delete_cb): Be more paranoid about the
- contents of the list row's data.
- (recur_to_comp_object): Likewise.
- (fill_exception_widgets): Select the first row after we are done
- appending the exception dates.
-
-2001-02-26 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/Makefile.am (libalarm_a_SOURCES): Create a
- little stand-alone library for the low-level alarm trigger
- mechanism. This is so that the GUI parts of the calendar can use
- it in addition to the alarm daemon.
-
- * gui/main.c: #include "alarm-notify/alarm.h".
-
- * gui/calendar-summary.c: Likewise.
- (alarm_fn): Do not remove the previous alarm; it is removed
- automatically when it is triggered.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Removed alarm.[ch]
- from the sources.
-
- * gui/alarm.[ch]: Removed obsolete files.
-
-2001-02-23 Federico Mena Quintero <federico@ximian.com>
-
- * gui/alarm-notify/alarm-notify.c (AlarmNotify_addCalendar):
- Switched to using our own refcounted structure for loaded clients.
- (AlarmNotify_removeCalendar): Ditto. Also, do the full
- destruction of the client.
- (alarm_notify_destroy): Destroy each element in the hash table.
-
- * cal-client/cal-client.c (cal_client_construct): Test for
- exceptions from OAF when activating the Wombat calendar factory.
-
- * gui/alarm-notify/GNOME_Evolution_Calendar_AlarmNotify.oaf.in:
- New .oaf.in file.
-
- * gui/alarm-notify/Makefile.am (oaf_in_files): Updated.
-
- * gui/GNOME_Evolution_Calendar.oaf.in: Put all the servers here
- instead of in a million files.
-
- * gui/GNOME_Evolution_Calendar_Control.oaf.in: Removed file.
-
- * gui/GNOME_Evolution_Calendar_gnomecal.oaf.in: Removed *REALLY*
- obsolete file.
-
- * gui/Makefile.am (oaf_in_files): Updated.
-
-2001-02-23 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal-backend-db.c (add_history): fixed generation of history records
-
-2001-02-16 Federico Mena Quintero <federico@ximian.com>
-
- * pcs/cal-factory.c (CalFactoryPrivate): Added a `registered'
- field.
- (cal_factory_oaf_register): New function; now the factory performs
- its own registration with OAF.
- (cal_factory_destroy): Unregister from OAF if appropriate.
-
-2001-02-19 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/Makefile.am: Remove PISOCK_LIBDIR
-
- * conduits/calendar/Makefile.am: ditto
-
-2001-02-16 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/calbackend-db.c (cal_backend_db_destroy): close DB environment.
- Some compilation warnings removed
-
-2001-02-13 Christopher James Lahey <clahey@ximian.com>
-
- * gui/Makefile.am (evolution_calendar_LDADD): Added libmenus.la.
-
- * gui/e-calendar-table.c, gui/e-calendar-table.h
- (e_calendar_table_get_spec): Added this function.
-
- * gui/e-tasks.c, gui/e-tasks.h (e_tasks_setup_menus): Added this
- function.
-
- * gui/tasks-control.c (tasks_control_activate): Call
- e_tasks_setup_menus.
-
-2001-02-13 JP Rosevear <jpr@ximian.com>
-
- * gui/e-tasks.c (e_tasks_new_task): call task_editor_focus
-
-2001-02-13 JP Rosevear <jpr@ximian.com>
-
- * gui/calendar-commands.c (update_pixmaps): Set toolbar new
- appointment icon
- (set_pixmap): load files rather than create from xpm file
-
- * gui/*view.xpm: move to the art directory
-
-2001-02-13 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal-backend-db.c (cal_backend_db_get_alarms_for_object):
- implemented
-
-2001-02-13 JP Rosevear <jpr@ximian.com>
-
- * gui/calendar-commands.c (update_pixmaps): Set toolbar new command
-
- * gui/e-calendar-table.c: Add titles to pixbuf column for grouping
-
- * gui/calendar-model.c (calendar_model_class_init): override value
- to string virtual method
- (calendar_model_value_to_string): implement value to string for
- etable (necessary for group by)
-
-2001-02-12 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal-backend-file.c:
- cal_backend_db_update_object(): manage both updates and additions/add notification
- cal_backend_db_get_object(): don't use DB cursors
- cal_backend_db_get_type_by_uid(): don't use DB cursors
- cal_backend_db_remove_object(): don't use DB cursors/add notification
- cal_backend_db_get_alarms_in_range(): implemented
-
-2001-02-12 Kjartan Maraas <kmaraas@gnome.org>
-
- * gui/Makefile.am: Hook up the xml-i18n-tools + .oaf.in stuff.
- * gui/GNOME_Evolution_Calendar*.oaf.in: Marked strings for translation.
-
-2001-02-11 Rodrigo Moya <rodrigo@ximian.com>
-
- * pcs/cal-backend-db.c: added DB3 transactions support
- * pcs/cal-backend-db.[ch]: added the new DB3-based backend. This is just
- the beginning, there are some missing things still.
-
-2001-02-11 Gediminas Paulauskas <menesis@delfi.lt>
-
- Really use xml-i18n-tools.
-
- * conduits/calendar/e-calendar-conduit-control-applet.desktop,
- conduits/todo/e-todo-conduit-control-applet.desktop: removed.
-
- * conduits/calendar/e-calendar-conduit-control-applet.desktop.in,
- conduits/todo/e-todo-conduit-control-applet.desktop.in: added empty.
-
- * conduits/calendar/Makefile.am, conduits/todo/Makefile.am:
- reflect above changes, merge translations.
-
- * gui/*.glade.h, gui/dialogs/*.glade.h: removed, xml-i18n-extract
- takes care of strings itself.
-
- * gui/*.glade, gui/dialogs/*.glade: do not output_translatable_strings
-
- * gui/Makefile.am, gui/dialogs/Makefile.am: do not include removed
- files in EXTRA_DIST.
-
-2001-02-08 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/task-editor-dialog.glade: Oops, remove old widget
-
-2001-02-08 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/task-editor.c (fill_widgets): fill in new
- classification stuff properly
- (get_widgets): load new class. widgets
- (init_widgets): if the class. widgets change, mark the dialog
- dirty
- (dialog_to_comp_object): set the comp class. from the new widgets
-
- * gui/dialogs/task-editor-dialog.glade: Make more consistent,
- fixing bugs 1247 and 1249
-
- * gui/dialogs/task-editor.c (fill_widgets):
-
- * gui/event-editor-dialog.glade: Gui tidying
-
- * gui/event-editor.c: Remove old alarm cruft
-
- * cal-util/cal-component.c (cal_component_set_url): Don't try and
- write an empty string as a property
-
-
-2001-02-08 JP Rosevear <jpr@ximian.com>
-
- * pcs/cal-backend-file.c: Move the get_change code here
-
- * pcs/cal-backend.c: Remove get_changes related stuff and
- implement by calling the virtual method instead
-
- * pcs/cal-backend.h: New virtual method.
-
- * pcs/cal-backend-file.c (compute_alarm_range): Use
- icaldurationtype_as_int (replace _as_timet)
- (add_alarm_occurrences_cb): ditto
-
-2001-02-08 JP Rosevear <jpr@ximian.com>
-
- * pcs/cal-backend-file.c (compute_alarm_range): Use
- icaldurationtype_as_int (replace _as_timet)
- (add_alarm_occurrences_cb): ditto
-
- * gui/e-week-view.c (e_week_view_on_schedule_meet): new routine to
- throw up the meeting schedule dialog
- (e_week_view_show_popup_menu): add schedule meeting to the
- contextual menu where appropriate
-
-2001-02-08 JP Rosevear <jpr@ximian.com>
-
- * gui/event-editor.c: Remove assorted menu/bonobo stuff
-
- * gui/dialogs/task-editor.c: Remove assorted menu/bonobo stuff
- (task_editor_construct): no longer suck out the glade contents
- into a bonobo win, listen for apply and close signals
- (tedit_apply_event_cb): listen for apply signal and save object
- (tedit_close_event_cb): listen for close signal and prompt to save
- if need be
- (task_editor_focus): new function to bring the dialog to the front
-
- * gui/dialogs/task-editor.h: new prototype
-
- * gui/e-meeting-edit.c (schedule_button_clicked_cb): no need to
- update widgets in the event editor since the event editor won't be
- open
- (e_meeting_editor_new): don't need the event editor reference any
- more
-
- * gui/e-meeting-edit.h: Change prototype
-
- * gui/e-day-view.c (e_day_view_on_event_right_click): Make
- schedule meeting a new contextual menu item
- (e_day_view_on_schedule_meet): new routine to schedule a meeting
- from the contextual menu
-
- * gui/e-calendar-table.c (e_calendar_table_open_task): Call
- task_editor_focus
-
- * gui/event-editor-dialog.glade: Update to be a property box
-
- * gui/dialogs/task-editor-dialog.glade: Update to be a property
- box
-
-2001-02-07 Iain Holmes <iain@ximian.com>
-
- * gui/calendar-summary.c (create_summary_view): Add a setter to the
- property bag.
- (set_property): The setter.
- (generate_html_summary): Sort the UIDs accodring to time.
-
-2001-02-06 JP Rosevear <jpr@ximian.com>
-
- * gui/event-editor.c (fill_reminder_widgets): Match new
- append_alarm signature
- (reminder_to_comp_object): only add alarms tagged as new, no
- longer delete all alarms first
- (append_reminder): the row data is now of type ReminderData,
- rename from append_alarm
- (reminder_add_cb): math new append_alarm signature
- (reminder_delete_cb): if the alarm existed before the dialog was
- loaded, delete it immediately from the cal component
-
-2001-02-06 JP Rosevear <jpr@ximian.com>
-
- * gui/event-editor-dialog.glade: Gui tweaks for bugs 1248 and 1246
-
- * gui/dialogs/task-editor-dialog.glade: ditto
-
-2001-02-07 JP Rosevear <jpr@ximian.com>
-
- * gui/event-editor-dialog.glade: Fix spacing
-
-2001-02-06 JP Rosevear <jpr@ximian.com>
-
- * gui/event-editor-dialog.glade: Gui tweaks for bugs 1248 and 1246
-
- * gui/dialogs/task-editor-dialog.glade: ditto
-
-2001-02-06 JP Rosevear <jpr@ximian.com>
-
- * gui/e-week-view.c (e_week_view_show_popup_menu): Make the menus more
- consistent
-
- * gui/e-day-view.c (e_day_view_on_event_right_click): ditto
-
- * gui/e-calendar-table.c: ditto
-
-2001-02-06 JP Rosevear <jpr@ximian.com>
-
- * cal-util/cal-component.c (cal_component_set_categories): If the
- categories string is empty, remove the property
- (get_period_list): Fixes from clahey to handle the new rdate
- format in libical
- (set_period_list): ditto
-
-2001-02-05 JP Rosevear <jpr@ximian.com>
-
- * cal-util/cal-component.c (cal_component_alarm_set_trigger): Set
- the time and duration values in the trigger to null by default
- (cal_component_free_alarm_uids): properly free the list of alarm
- uids
-
-2001-02-05 JP Rosevear <jpr@ximian.com>
-
- * gui/event-editor.c (get_widgets): get the new reminder widgets
- (sync_entries): different callback data
- (summary_changed_cb): take different data and handle various cases
- (init_widgets): connect signals for the new widgets
- (get_alarm_duration_string): give a text string of the alarm
- duration
- (get_alarm_string): give a string representing the alarm
- (fill_widgets): make sure we don't loop infinitely and remove old
- alarm cruft
- (reminder_to_comp_object): dump alarm info in the gui into the cal
- component
- (append_alarm): add alarm to the clist
- (reminder_add_cb): create new alarm
- (reminder_delete_cb): remove the alarm from the list
-
- * gui/event-editor-dialog.glade: Update gui
-
- * gui/e-calendar-table.c: include gnome.h for all the menu stuff
-
- * gui/calendar-summary.c: for internationalization
-
- * gui/tasks-control.c: include gnome.h
-
- * gui/e-tasks.c: ditto
-
- * gui/e-itip-control.c: ditto
-
- * cal-util/cal-recur.c (cal_recur_set_rule_end_date): Update for
- libical changes
-
-2001-02-05 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/calendar-model.c: Fixed up these #includes.
-
-2001-02-03 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/save-comp.c (save_component_dialog):
- gnome_dialog_grab_focus() on the Yes button. Fixes bug #1242.
-
-2001-01-30 Kjartan Maraas <kmaraas@gnome.org>
-
- * gui/e-calendar-table.c: Mark a string for translation.
- * gui/e-itip-control.c: Mark a bunch of strings for translation.
-
-2001-01-30 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/print.c: #include <sys/time.h>.
-
-2001-01-29 Federico Mena Quintero <federico@ximian.com>
-
- * gui/calendar-config.c: <gnome.h> trimming to reduce compilation
- time.
- * gui/calendar-summary.c: Likewise.
- * gui/e-calendar-table.c: Likewise.
- * gui/e-day-view-time-item.c: Likewise.
- * gui/e-day-view.c: Likewise.
- * gui/e-itip-control.c: Likewise.
- * gui/e-meeting-edit.c: Likewise.
- * gui/e-meeting-edit.h: Likewise.
- * gui/e-tasks.c: Likewise.
- * gui/e-week-view.c: Likewise.
- * gui/event-editor.c: Likewise.
- * gui/gnome-cal.c: Likewise.
- * gui/goto.c: Likewise.
- * gui/itip-utils.h: Likewise.
- * gui/main.c: Likewise.
- * gui/popup-menu.c: Likewise.
- * gui/print.c: Likewise.
- * gui/tasks-control-factory.c: Likewise.
- * gui/tasks-control.c: Likewise.
- * gui/tasks-migrate.c: Likewise.
-
-2001-01-25 Federico Mena Quintero <federico@ximian.com>
-
- * cal-util/timeutil.c: <gnome.h> trimming to reduce compilation time.
- * gui/dialogs/task-editor.c: Ditto.
- * gui/dialogs/cal-prefs-dialog.c: Ditto.
- * gui/dialogs/save-comp.c: Ditto.
- * gui/dialogs/delete-comp.c: Ditto.
- * gui/calendar-commands.c: Ditto.
- * gui/calendar-model.c: Ditto.
-
-2001-01-26 Ettore Perazzoli <ettore@ximian.com>
-
- * gui/e-itip-control.c (itip_control_destroy_cb): Don't attempt to
- call `icalcomponent_remove_component()' on a NULL component or a
- NULL subcomponent.
-
-2001-01-25 Damon Chaplin <damon@ximian.com>
-
- * gui/tag-calendar.c: don't tag the calendar if no dates are shown.
- (e_calendar_item_get_date_range() now returns FALSE in this case.)
-
-2001-01-23 Damon Chaplin <damon@helixcode.com>
-
- * gui/calendar-model.c (ensure_task_complete): make sure the status
- is set to "Completed". Fixes bug #1253.
-
- * gui/e-tasks.c (e_tasks_open): load the ETable state after opening
- the tasks folder, since it relies on the folder uri, which isn't set
- now until you open the folder.
-
- * gui/calendar-model.c (obj_updated_cb): add the categories from the
- updated object to our tree, and emit the "categories-changed" signal
- if they have changed. Fixes bug #1255.
-
- * gui/e-tasks.c: removed debug messages.
-
-2001-01-23 JP Rosevear <jpr@ximian.com>
-
- * libical import cleanup
-
-2001-01-23 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/todo-conduit.c (local_record_from_comp): properly ref
- the cal component when we use it, prevents double free
-
- * conduits/calendar/calendar-conduit.c (local_record_from_comp): ditto
-
-2001-01-22 JP Rosevear <jpr@ximian.com>
-
- * gui/dialogs/Makefile.am: compile new stuff
-
- * gui/dialogs/task-editor.c (prompt_to_save_changes): use new
- standard dialog
-
- * gui/event-editor.c (prompt_to_save_changes): ditto
-
- * gui/dialogs/save-comp.h: new header
-
- * gui/dialogs/save-comp.c (save_component_dialog): shows the save
- dialog
-
-2001-01-22 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/todo-conduit.c (for_each_modified): remove duplicate
- message
-
- * conduits/calendar/Makefile.am: Remove vfs lib dependency
-
- * conduits/todo/Makefile.am: ditto
-
- * conduits/calendar/calendar-conduit.c: Remove alarm foo for now
- (for_each_modified): remove duplicate message
-
-2001-01-21 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (delete_record): Remove
- deleted records from the pilot map so we don't have dupes in the future
-
- * conduits/todo/todo-conduit.c (delete_record): ditto
-
-2001-01-21 Federico Mena Quintero <federico@ximian.com>
-
- * gui/dialogs/task-editor.c (file_delete_cb): Fix bug #1250; now
- we present a confirmation dialog before deleting the component.
-
-2001-01-20 Federico Mena Quintero <federico@ximian.com>
-
- * gui/event-editor-dialog.glade: Fix bug #1243. Turn on the Y
- expand/fill options for the date widgets in the General page.
- This makes them be vertically aligned with the "All day event"
- toggle so that they will get the focus in the proper order; the
- toggle would get the focus before them because it was a pixel or
- two above them.
-
-2001-01-19 Federico Mena Quintero <federico@ximian.com>
-
- * gui/weekday-picker.c (weekday_picker_init): Unset the
- GTK_CAN_FOCUS flag on the weekday picker. This will do until it
- supports being used with the keyboard.
-
-2001-01-19 JP Rosevear <jpr@ximian.com>
-
- * cal-util/cal-component.c (cal_component_alarm_new): create a new
- cal component alarm
- (cal_component_add_alarm): add alarm to the cal component
- (cal_component_remove_alarm): remove alarm from the cal component
- (remove_alarm): remove alarm from hash
-
- * cal-util/cal-component.h: new protos
-
- * conduits/calendar/calendar-conduit.c (comp_from_remote_record):
- add alarm information, still needs to be hacked to replace an already
- existing alarm. questions abound about the heuristic for doing this.
-
-2001-01-17 JP Rosevear <jpr@ximian.com>
-
- * gui/event-editor.c (dialog_to_comp_object): Properly set categories
- to NULL if there are none
-
-2001-01-18 Federico Mena Quintero <federico@ximian.com>
-
- * gui/tasks-migrate.[ch]: New files with a simple sequence to
- migrate the task components from the old calendar folder into the
- new tasks folder.
-
- * gui/component-factory.c (owner_set_cb): Call tasks_migrate()
- once evolution_dir is set. It sucks to have to do this here.
-
- * cal-client/cal-client.c (cal_client_get_uids): In the inline
- docs, indicate how to free the return value.
- (cal_opened_cb): Ahem, moved assertion to the right place. Also,
- ref() and unref() around our own signal emission because we are
- not inside a signal handler, rather a simple callback from the
- listener object; we want to have a chance to clean up even if the
- client is unrefed during the emission.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Added
- tasks-migrate.[ch] to the list of sources.
-
-2001-01-17 Federico Mena Quintero <federico@ximian.com>
-
- * gui/event-editor.c (init_widgets): Use
- e_calendar_item_set_max_days_sel() instead of setting GTK+ object
- arguments.
-
- * gui/e-day-view.c (e_day_view_set_cal_client): Oops, we had a
- reversed test for the client being loaded.
-
- * gui/tag-calendar.c (tag_calendar_by_client): Fixed similarly
- reversed test.
-
-2001-01-17 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-week-view*.c
- * gui/e-day-view*.c: don't use the theme colors at all within
- the graphical parts of the widgets, since they may clash with
- our colors. May make them configurable in future so people can tweak
- them to go with their theme. At least the calendars are usable in any
- theme now, even though the colors may not go well with the theme.
- Also set the font of all the EText items in style_set.
-
- * gui/e-week-view-event-item.c (e_week_view_event_item_draw): don't
- draw the icons if we are editing the event.
-
- * gui/e-day-view.c:
- * gui/e-week-view.c: reinstated the optimizations so we don't do a
- complete relayout if the event's dates haven't been changed.
- (Though we still do a re-layout when recurring events change, since
- comparing all the RDATES/RRULES/EXDATES/EXRULES is too much hassle.)
- A side-effect of this change is that the EWeekView won't crash so
- often - only recurring events will be a problem.
-
- * cal-util/cal-component.[hc]: added function to check if the start
- and end dates of a component match. Used for optimizing the updating
- of the EDayView & EWeekView.
-
-2001-01-17 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (start_calendar_server): Check
- for open error and handled
-
- * conduits/todo/todo-conduit.c (start_calendar_server): ditto
-
-2001-01-17 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/calendar-conduit.c (start_calendar_server): Check
- for open error and handled
-
- * pcs/cal-backend.c (cal_backend_compute_changes): Fix transposition
- of sync db location
-
-2001-01-17 Federico Mena Quintero <federico@ximian.com>
-
- * */*: Ximianified email addresses and copyrights.
-
- * idl/evolution-calendar.idl (CalFactory::open): Renamed from
- ::load(), and added an only_if_exists argument.
- (CalFactory::create): Removed method.
- (Listener::OpenStatus): Removed the IN_USE error and replaced it
- with a NOT_FOUND one; renamed the enum from LoadStatus.
- (Listener::notifyCalOpened): Renamed from notifyCalLoaded().
-
- * pcs/cal-backend.h (CalBackend): Removed the uri field.
- (CalBackendOpenStatus): Renamed from CalBackendLoadStatus and
- added a NOT_FOUND value.
- (CalBackendClass::open): Put in a slot for the open method.
-
- * pcs/cal-backend.c (cal_backend_create): Removed function.
-
- * pcs/cal-backend-file.c (cal_backend_file_open): Return the
- appropriate value when only_if_exists is TRUE.
- (create_cal): We are Ximian now, so set the PRODID property to
- the appropriate foo.
-
- * pcs/cal-factory.c (CalFactory_open): implemented, replacing
- CalFactory_load() and CalFactory_create().
- (CalFactory_open): Moved the queue_load_create_job() stuff to
- here, since we now only need to contemplate the open case instead
- of load/create ones.
- (open_backend): Do everything here; replaces load_backend() and
- create_backend().
-
- * cal-client/cal-listener.h (CalListenerClass::cal_opened):
- Renamed from cal_loaded.
- (CalListenerClass): Replaced the silly signals, which are
- gratuitous abstraction, by a set of function pointers in the
- instance structure.
-
- * cal-client/cal-listener.c (cal_listener_get_calendar): Removed
- unused function.
- (cal_listener_construct): Added the listener notification functions.
- (cal_listener_new): Ditto.
- (Listener_notifyCalOpened): Renamed to our new naming convention
- for servant implementations.
- (Listener_notifyObjUpdated): Ditto.
- (Listener_notifyObjRemoved): Ditto.
-
- * cal-client/cal-client.h (CalClientOpenStatus): Renamed from
- CalClientLoadStatus.
- (CalClientClass::cal_opened): Renamed from ::cal_loaded().
- (CalClientLoadState): New enum; basically make LoadState public so
- that users of this code do not have to maintain their own states.
-
- * cal-client/cal-client.c (cal_client_create_calendar): Removed
- function.
- (cal_client_open_calendar): Moved the functionality over from
- load_or_create(); now we do everything here.
- (*): Use the CalClientLoadState enum values instead of the old
- LoadState values.
- (cal_client_get_load_state): Renamed from cal_client_is_loaded(),
- and return the appropriate value.
- (CalClientPrivate): Added an uri field.
- (cal_client_init): Initialize priv->uri.
- (cal_client_destroy): Free the priv->uri.
- (cal_opened_cb): Maintain the priv->uri.
- (cal_client_open_calendar): Fill in the priv->uri.
- (cal_client_get_uri): New function.
-
- * gui/calendar-model.c (calendar_model_set_new_comp_vtype): New
- function to configure the type of calendar components to create
- when doing click-to-add. This makes the model usable for
- something other than task lists.
- (calendar_model_get_new_comp_vtype): New function.
-
- * gui/e-calendar-table.c (e_calendar_table_get_model): New function.
- (e_calendar_table_destroy): Unref the subset_model.
-
- * gui/gnome-cal.h (GnomeCalendarOpenMode): Removed enum.
-
- * gui/gnome-cal.c (LoadState): Removed enum; we now use the
- CalClientLoadState from the client objects.
- (GnomeCalendarPrivate): Removed the loading_uri and
- task_pad_loading_uri fields as well as the load_state and
- task_pad_load_state fields, as we can now query them directly from
- the CalClient.
- (open_error): Renamed from load_error().
- (create_error): Removed function.
- (gnome_calendar_open): Do not take in the mode parameter.
- (cal_opened_cb): Get rid of our beautifully-crafted state machine
- and replace it with simple code; all the loading smarts are in the
- Wombat now.
- (setup_widgets): Set the new component vtype of the table model to
- CAL_COMPONENT_TODO.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Removed
- gnome-month-item.[ch] from the list of sources.
-
- * gui/calendar-summary.c (CalSummary): Removed unused cal_loaded
- field.
- (create_summary_view): Do not check if the file exists; this is
- the job of the Wombat.
- (generate_html_summary): Fixed prototype.
- (alarm_fn): Fixed prototype.
- (property_dialog): Fixed prototype. Wonder if/how this ever
- worked.
- (create_summary_view): Cast the component and view as
- appropriate. Removed unused html variable.
-
- [Iain dude, are you compiling with -Wall?]
-
- * gui/e-itip-control.c (cal_opened_cb): Sigh, this function
- signature was *very* wrong. It was using CalClientGetStatus
- instead of CalClientOpenStatus.
-
- * gui/e-tasks.h (ETasksOpenMode): Removed enum.
-
- * gui/e-tasks.c (setup_widgets): Set the new component vtype of
- the table model to CAL_COMPONENT_TODO.
- (LoadState): Removed the state machine foo.
- (e_tasks_open): Removed the mode parameter.
- (initial_load): Removed function.
- (create_error): Removed function.
- (ETasksPrivate): Removed folder_uri field.
- (cal_opened_cb): Remove the state machine.
-
- * gui/component-factory.c: #include "tasks-control.h"
-
- * conduits/calendar/calendar-conduit.h (ECalConduitContext):
- Removed calendar_load_tried field.
-
- * conduits/calendar/calendar-conduit.c (start_calendar_server_cb):
- Sigh, fixed function prototype.
-
- * conduits/todo/todo-conduit.h (EToDoConduitContext): Removed
- calendar_load_tried field.
-
- * conduits/todo/todo-conduit.c (start_calendar_server_cb): Fixed
- function prototype.
-
-2001-01-16 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/todo-conduit.c (print_local): fix debug output
- (print_remote): ditto
-
-2001-01-15 JP Rosevear <jpr@ximian.com>
-
- * pcs/cal-backend.c (cal_backend_compute_changes): accomadate tasks
- in their new dir
-
- * conduits/todo/todo-conduit.c (start_calendar_server): ditto
-
-2001-01-15 JP Rosevear <jpr@ximian.com>
-
- * conduits/todo/todo-conduit.c (print_local): prevent segfaults and
- buffer overflows.
- (print_remote): ditto
-
- * conduits/calendar/calendar-conduit.c: as above
-
-2001-01-14 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-calendar-table.c (E_CALENDAR_TABLE_SPEC): changed the expansion
- values so that small text fields are 1.0, all the date fields and the
- URL field are 2.0, and the Summary is 3.0. Hopefully the user will
- resize the fields as desired, but at least this is a better start.
-
-2001-01-14 JP Rosevear <jpr@ximian.com>
-
- * conduits/calendar/Makefile.am: pass -module and -avoid-version to
- conduit linker
-
- * conduits/todo/Makefile.am: ditto
-
-2001-01-14 Damon Chaplin <damon@helixcode.com>
-
- * gui/dialogs/task-editor.[hc]: moved #include
- <cal-client/cal-client.h> to the .h file.
-
- * gui/e-tasks.c: load & save the Tasks folders' ETable layout.
- Added an option menu to filter tasks by category.
-
- * gui/gnome-cal.c: use the "Tasks" folder for the TaskPad.
- (We may make the actual tasks folder shown a per-calendar option.)
-
- * gui/tasks-control.c (tasks_control_new_task_cmd): added support for
- the New Task icon on the toolbar.
-
- * gui/e-calendar-table.[hc]: we now use an ETableSubsetVariable model
- to filter the tasks by a category. And tidied up a little.
-
- * gui/calendar-model.[hc]: added way to get all the categories used by
- the tasks, so we can show an option menu of them. Also a signal which
- is emitted when they are changed.
- Also allows a default category to be set, which is used to initialize
- the 'click-to-add' row.
- Also made sure the initialize_value()/get_value() functions don't
- return NULL since that can cause a SEGV.
-
- * gui/e-week-view.c:
- * gui/e-day-view.c: set the "fill_color_rgba" arg of the EText items
- to black since it doesn't seem to set up a default color properly.
- Hopefully this fixes the bug on Solaris where the items appear with
- strange colors.
-
- * gui/widget-util.c (date_edit_new): use the calendar_config function
- to set most of the options. It wasn't setting the 12/24 hour option
- before.
-
- * gui/dialogs/task-editor-dialog.glade: added "Undefined" priority.
-
-2001-01-12 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component-factory.c (factory_fn): Pass NULL as the
- @copy_folder_fn arg to `evolution_shell_component_new()'.
-
-2001-01-12 Miguel de Icaza <miguel@ximian.com>
-
- * gui/e-calendar-table.c: Add translation strings.
-
-2001-01-08 Iain Holmes <iain@helixcode.com>
-
- * gui/calendar-summary.c (create_summary_view): Add a PropertyControl
- interface to set whether or not to show tasks and appointments. Add
- a PersistStream to remember this.
-
-2001-01-09 Dave Camp <dave@helixcode.com>
-
- * gui/Makefile.am: Replaced e-meet-dialog.glade.h with
- e-meeting-dialog.glade in glade_messages.
-
- * gui/e-meeting-dialog.glade: Enabled the translatable string option.
-
- * gui/e-itip-control.glade: Likewise.
-
-2001-01-09 Federico Mena Quintero <federico@helixcode.com>
-
- * idl/evolution-calendar.idl (AlarmNotify): New interface for the
- alarm notification system.
-
- * gui/alarm-notify: New directory for the alarm notification
- daemon and its auxiliary stuff.
-
- * gui/alarm-notify/alarm.[ch]: Moved over from gui/alarm.[ch].
-
- * gui/alarm-notify/alarm-queue.[ch]: Moved over from
- gui/alarm-notify.[ch]. Renamed functions from alarm_notify_*() to
- alarm_queue_*().
-
- * gui/alarm-notify/alarm-notify.[ch]: Implementation of the
- GNOME::Evolution::Calendar::AlarmNotify interface.
-
- * gui/Makefile.am (evolution_calendar_LDADD): Removed the
- LINK_FLAGS variable and reordered the libraries to remove some
- duplicated ones.
- (SUBDIRS): Added the alarm-notify directory.
-
-2001-01-08 Iain Holmes <iain@helixcode.com>
-
- * gui/calendar-summary.c (generate_html_summary): Get the tasks
- correctly.
- (generate_html_summary): Mark the tasks as completed if so.
-
-2001-01-08 Damon Chaplin <damon@helixcode.com>
-
- * gui/Makefile.am: added new source files for the Tasks folders.
-
- * gui/e-tasks.[hc]: new widget to encapsulate the Tasks view.
-
- * gui/tasks-control.[hc]: new files to implement the Tasks control.
-
- * gui/tasks-control-factory.[hc]: new files to implement the factory
- for the Tasks controls. (I think the way I've split the code up is a
- lot cleaner than the GnomeCal implementation - the factory file just
- contains the factory functions and the control file contains all the
- control functions. Maybe we should make GnomeCal like this.)
-
- * gui/main.c: initialize the Tasks control factory.
-
- * gui/component-factory.c: added support for the Tasks control.
- Also added a "create_folder" function so we can now create new Tasks
- and Calendar folders within Evolution.
- I'm not a Bonobo expert so someone might want to check these over.
-
- * gui/calendar-config.[hc]: added convenience functions to configure
- the common settings of ECalendar and EDateEdit widgets.
-
- * gui/dialogs/task-editor.c (task_editor_create_date_edit):
- * gui/gnome-cal.c (gnome_calendar_update_config_settings):
- * gui/event-editor.c: used function to configure the ECalendars
- and EDateEdits.
-
- * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event):
- fixed minor bug in format strings.
-
-2001-01-06 Iain Holmes <iain@helixcode.com>
-
- * gui/calendar-summary.c (generate_html_summary): Neaten the HTML,
- and fix the time printing stuff. Add stuff the get Tasks.
- (alarm_fn): Set up an alarm for midnight everynight and regenerate
- the HTML for the new day.
-
-2001-01-05 JP Rosevear <jpr@helixcode.com>
-
- * gui/event-editor.c (get_widgets): get categories button
- (init_widgets): listen for button click
- (fill_widgets): fill in the categories area
- (dialog_to_comp_object): set the cal component categories
- (categories_clicked): throw up the categories dialog and update
- when ok is clicked
-
- * gui/event-editor-dialog.glade: Add categories and contacts buttons
- and fields
-
- * gui/dialogs/task-editor-dialog.glade: Rename button
-
-2001-01-05 JP Rosevear <jpr@helixcode.com>
-
- * gui/dialogs/task-editor.c (get_widgets): get categories button
- (init_widgets): listen for button click
- (fill_widgets): fill in the categories area
- (dialog_to_comp_object): set the cal component categories
- (categories_clicked): throw up the categories dialog and update
- when ok is clicked
-
- * gui/dialogs/task-editor-dialog.glade: Tweak to name the categories
- button and make it active
-
- * gui/calendar-model.c (get_categories): We can get the string list of
- categories directly now
-
- * cal-util/cal-component.c (cal_component_get_categories): new function
- to get the categories list as a string
- (cal_component_set_categories): same but for setting
- (free_icalcomponent): init the categories var
- (scan_categories): kill
- (scan_property): assign the prop to the categories var
- (cal_component_get_categories_list): deal with renaming var to categories
- (cal_component_set_categories_list): fix brokeness
-
-2001-01-03 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-commands.c (new_calendar): Handle the case where
- the calendar view cannot be created; present a warning dialog box.
- (new_calendar): Do not show the widget here, since we already show
- it in control-factory.c.
-
- * gui/control-factory.c (control_factory_new_control): Handle the
- case where the calendar view cannot be created.
-
- * gui/component-factory.c (create_view): Ditto.
-
- * gui/calendar-summary.h: Added prototype for
- calendar_summary_factory_init().
-
-2001-01-02 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/alarm-notify.c (add_component_alarms): If the component has
- no alarms, do not try to queue them.
- (remove_client_alarms): New function to remove all the queued
- alarms for a calendar client.
- (alarm_notify_remove_client): Remove the client's alarms.
-
-2001-01-02 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/dialogs/delete-comp.c (delete_component_dialog): Do not
- compose strings so that they can be localized correctly. Also,
- convert from UTF8 into the font's encoding. Fixes bug #1030.
-
- * gui/e-calendar-table.c (delete_component): Pass the widget
- argument to delete_component_dialog().
-
- * gui/e-day-view.c (e_day_view_on_delete_appointment): Likewise.
-
- * gui/e-week-view.c (e_week_view_on_delete_appointment): Likewise.
-
- * gui/event-editor.c (file_delete_cb): Likewise.
-
- * gui/calendar-commands.c: Use BONOBO_UI_VERB() instead of
- BONOBO_UI_UNSAFE_VERB(). Guess what, all of our handler
- signatures were wrong.
-
- * gui/event-editor.c: Likewise.
-
- * gui/dialogs/task-editor.c: Likewise.
-
- * gui/goto-dialog.glade: Added some spacing between the month/year
- widgets and the calendar widget.
-
-2001-01-01 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.c (gnome_calendar_destroy): Unconditionally remove
- the client from the alarm notification system.
- Removed all the obsolete alarm code.
-
- * gui/event-editor.c: Removed some crufty externs left over from
- Gnomecal.
-
- * gui/calendar-commands.c: #include "goto.h"
- Removed crufty variables left over from Gnomecal.
- (new_calendar): Do not take a full_name parameter.
- (init_username): Removed function.
- (init_calendar): Wheeeeeeee! Removed crufty function.
- (quit_cmd): Removed function.
-
- * gui/print.c (WEEK_STARTS_ON_MONDAY): Made it unconditionally
- FALSE because we do not use the configuration setting anyways.
- Sigh, all the printing code needs to be revamped.
-
-2000-12-26 Iain Holmes <iain@helixcode.com>
-
- * gui/calendar-summary.c (create_summary_view): Create a shared
- BonoboEventSource object.
-
-2000-12-25 Miguel de Icaza <miguel@helixcode.com>
-
- * gui/e-day-view.c (e_day_view_init): Set draw background to FALSE.
- (e_day_view_reshape_long_event): ditto.
- (e_day_view_reshape_day_event): ditto.
-
-2000-12-22 JP Rosevear <jpr@helixcode.com>
-
- * gui/dialogs/delete-comp.c (delete_component_dialog): Clean up
- translatable strings for translators, fixes bug 993
-
-2000-12-22 JP Rosevear <jpr@helixcode.com>
-
- * gui/goto.c (create_ecal): Make sure the current month is shown
- when the dialog pops up.
-
- * gui/goto-dialog.glade: Remove flicker
-
-2000-12-22 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal-backend-file.c (cal_backend_file_get_alarms_for_object):
- account for the case where there are no alarms, fixes crash
-
-2000-12-22 JP Rosevear <jpr@helixcode.com>
-
- * gui/goto.c (ecal_date_range_changed): New function to keep the
- ecal marked properly
- (create_ecal): move more creation code here, update marks
- (goto_dialog_init_widgets): listen for date_range_changed signal
- in the ecal
-
- * gui/calendar-commands.c (init_calendar): Remove ancient gnomecal
- cruft
-
- * gui/mark.[hc], gui/prop.c: Remove ancient gnomecal code that is
- no longer needed, last bit of bug 904
-
-2000-12-22 JP Rosevear <jpr@helixcode.com>
-
- * gui/goto-dialog.glade.h: translations
-
- * gui/goto-dialog.glade: new glade file for goto dialog
-
- * gui/gnome-cal.c (setup_widgets): Set date navigator attributes
-
- * gui/calendar-commands.h: remove prototype
-
- * gui/goto.h: Add prototype
-
- * gui/Makefile.am: Add glade file stuff
-
- * gui/gnome-cal.c (setup_widgets): Use accessors to configure the
- calendar item properly
-
-2000-12-21 Federico Mena Quintero <federico@helixcode.com>
-
- Alarm trigger queueing for the GUI part.
-
- * gui/alarm-notify.[ch]: New files with the high-level alarm
- notification system; mostly moved over from gnome-cal.c. The
- low-level timer stuff is still in alarm.[ch].
-
- * gui/alarm-notify.c (alarm_notify_init): New function to
- initialize the alarm notification system.
- (alarm_notify_done): New function to shut down the alarm
- notification system.
- (alarm_notify_add_client): New function to start monitoring a
- calendar client for alarm notification.
- (alarm_notify_remove_client): New function to stop monitoring a
- client.
-
- * gui/alarm.h (AlarmDestroyNotify): Also pass in the alarm ID so
- the callback may know which ID is being destroyed.
-
- * gui/alarm.c (clear_itimer): New function.
- (pop_alarm): Use clear_itimer().
- (alarm_done): New function to shut down the timer system.
- (alarm_add): Add some preconditions. Do not call the destroy
- notification function if we could not create the alarm.
- (alarm_ready): Pass the alarm ID to the destroy notify function.
- (alarm_remove): Likewise. Also, add some preconditions.
-
- * gui/gnome-cal.c: Removed the alarm notification functions from
- here since they are now in alarm-notify.c.
- (gnome_calendar_construct): Register the client with
- alarm_notify_add_client().
- (gnome_calendar_destroy): Use alarm_notify_remove_client() to
- unregister the client.
- (obj_updated_cb): Do not do any alarm-related stuff.
- (obj_removed_cb): Likewise.
-
- * gui/main.c (main): Shut down the alarm timer system.
- (main): Initialize and shut down the alarm notification system.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Added
- alarm-notify.[ch] to the list of sources.
-
- * gui/calendar-model.c (calendar_model_set_cal_client): Only
- connect to the "cal_loaded" signal if the client is not already
- loaded.
-
- * gui/e-day-view.c (e_day_view_set_cal_client): Likewise.
-
- * gui/e-week-view.c (e_week_view_set_cal_client): Likewise.
-
- * gui/e-itip-control.c (update_calendar): Connect to "cal_loaded"
- before issuing the load request.
-
-2000-12-21 Iain Holmes <iain@helixcode.com>
-
- * gui/calendar-summary.c: Updated for new executive summary.
-
- * gui/component-factory.c: Reenabled the summary.
-
- * gui/GNOME_Evolution_Calendar.oafinfo: Added the summary.
-
-2000-12-20 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.h: Fix erroneous documentation
-
- * conduits/todo/todo-conduit.c (comp_from_remote_record): if
- !is_empty_time rather than is_empty_time
- (e_todo_context_new): Return a pointer rather than fill in
- a parameter
- (e_todo_context_foreach_change): Free just the key
- (e_todo_context_destroy): Plug this enormous leakage. I had assumed
- i had done this earlier, which isn't too bright when anything beyond
- 2 minutes ago is fuzzy.
- (comp_from_remote_record): Kill warnings
- (post_sync): Destroy the map later
- (conduit_get_gpilot_conduit): Fix e_todo_context_new params
-
- * conduits/calendar/calendar-conduit.[hc]: Similar to above
-
-2000-12-19 JP Rosevear <jpr@helixcode.com>
-
- * conduits/calendar/calendar-conduit.c: Remove pointless comment
-
- * conduits/todo/todo-conduit.c (is_empty_time): add utility function
- (comp_from_remote_record): use it
-
-2000-12-19 JP Rosevear <jpr@helixcode.com>
-
- * conduits/calendar/calendar-conduit.c (local_record_from_comp):
- Convert cal component strings to pilot character set
- (comp_from_remote_record): vice versa
-
- * conduits/todo/todo-conduit.c: Same as above
-
-2000-12-19 Federico Mena Quintero <federico@helixcode.com>
-
- * pcs/cal-backend-file.c (compute_alarm_range): Fix confusion in
- the way the range is expanded.
-
- * cal-util/cal-component.c (cal_component_alarms_free): Doh,
- alarms->alarms is a list, not a generic pointer. Free it properly.
- (cal_component_free_pilot_id): Removed unused function.
- (cal_component_free_pilot_status): Likewise.
-
- * gui/main.c (init_bonobo): Use VERSION instead of a hardcoded
- string. Pass argc by value, not by reference. Test the return
- value of gnome_init_with_popt_table().
-
- * cal-client/cal-client.c (cal_client_free_alarms): Oops, missed
- implementing this function.
-
- * cal-util/timeutil.c (print_time_t): Better printing format.
- (isodiff_to_secs): Removed unused function.
- (isodiff_from_secs): Removed unused function.
- (time_day_end): Removed crufty part.
- (time_day_begin): Removed crufty part.
- (time_day_hour): Removed unused function.
- (format_simple_hour): Removed unused function.
- (get_time_t_hour): Removed unused function.
- (time_from_start_duration): Removed unused function.
-
- * cal-util/timeutil.h (parse_date): Removed unimplemented, unused
- function prototype.
-
-2000-12-19 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/gnome-cal.c: Removed prototype for setup_alarm to fix a
- warning.
-
-2000-12-18 Federico Mena Quintero <federico@helixcode.com>
-
- Alarm instance generation support for the Wombat.
-
- * idl/evolution-calendar.idl (Cal::CalAlarmInstance): Changed to
- have an alarm UID, the trigger time, and the actual occurrence
- time.
- (Cal::CalComponentAlarms): New structure to hold a pair of a
- component and its alarms that trigger in a particular range of
- time.
- (Cal::getAlarmsInRange): Changed to return a CalComponentAlarmsSeq.
-
- * cal-util/cal-component.h (CalAlarmInstance): New C-side
- structure to match the one on the IDL.
- (CalComponentAlarms): Ditto.
- (CalAlarmAction): Renamed from CalComponentAlarmAction.
- (CalAlarmTriggerType): Renamed from CalComponentAlarmTriggerType.
- Encoded the START and END parameters for the RELATED parameter in
- this enum, too. Added a NONE value for invalid or missing trigger
- specifications.
- (CalComponentAlarmTriggerRelated): Removed.
- (CalAlarmTrigger): Renamed from CalComponentAlarmTrigger. Renamed
- the duration/time fields to rel_duration/abs_time, respectively.
-
- * cal-util/cal-component.c (cal_component_alarm_get_trigger):
- Changed to use the new trigger structure.
- (cal_component_alarm_set_trigger): Likewise.
- (cal_component_alarm_free_trigger): Removed function.
- (cal_component_has_alarms): Count the elements in the
- alarm_uid_hash instead of trying to fetch the first alarm subcomponent.
- (cal_component_alarms_free): New function to free a
- CalComponentAlarms structure.
- (CalComponentAlarmPrivate): Added an uid property pointer.
- (scan_alarm_property): Scan for the our extension UID property.
- (cal_component_alarm_get_uid): New function.
-
- * pcs/cal-backend.h (CalBackendClass): Changed the signatures of
- the ::get_alarms_in_range() and ::get_alarms_for_object() methods.
-
- * pcs/cal-backend.c (cal_backend_get_alarms_in_range): Changed
- signature; use the new method.
- (cal_backend_get_alarms_for_object): Likewise.
-
- * pcs/cal-backend-file.c (compute_alarm_range): New spiffy
- function to compute a range of time for alarm occurrences.
- (add_alarm_occurrences_cb): New function to add alarms for a
- particular occurrence of the component.
- (generate_absolute_triggers): New function to add the absolute
- alarm triggers.
- (generate_alarms_for_comp): New function to generate all the alarm
- instances for a component.
- (cal_backend_file_get_alarms_in_range): Implemented.
-
- * pcs/cal.c (Cal_get_alarms_in_range): Use the new CalBackend API.
- (Cal_get_alarms_for_object): Likewise.
- (build_alarm_instance_seq): Removed old function.
-
- * cal-util/cal-util.c (cal_alarm_instance_list_free): Removed
- function.
-
- * cal-client/cal-client.c (build_component_alarms_list): New
- function to demarshal the component alarms sequence.
- (build_alarm_instance_list): New function to demarshal the alarm
- instances sequence.
- (cal_client_get_alarms_in_range): Updated for the new API.
- (cal_client_get_alarms_for_object): Updated for the new API.
-
- * gui/gnome-cal.c: Temporary #ifdef-ing out of alarm-related stuff
- to make it build.
-
-2000-12-15 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/timeutil.[ch] (time_from_isodate): Removed unused
- function, a relic from Gnomecal.
-
-2000-12-15 Dan Winship <danw@helixcode.com>
-
- * cal-util/timeutil.c (time_from_isodate): Fix the sign in the
- HAVE_TM_GMTOFF case
-
-2000-12-15 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Removed getdate.y.
- We no longer use it; it is a relic from Gnomecal.
-
- * gui/getdate.y: Removed file.
-
-2000-12-14 Federico Mena Quintero <federico@helixcode.com>
-
- Fixes bug #955.
-
- * gui/weekday-picker.c (WeekdayPickerPrivate): Added a field for
- the week_start_day, to be used in the same way as
- calendar-config.h defines it. Removed the week_starts_on_monday
- flag.
- (day_event_cb): Use the week_start_day.
- (colorize_items): Likewise.
- (configure_items): Likewise.
- (weekday_picker_set_week_start_day): New function.
- (weekday_picker_get_week_start_day): New function.
- (weekday_picker_set_week_starts_on_monday): Removed function.
- (weekday_picker_get_week_starts_on_monday): Removed function.
-
- * gui/widget-util.[ch]: New files with utilities for creating or
- configuring widgets.
-
- * gui/widget-util.c (date_edit_new): New function to create an
- EDateEdit configured with the calendar's preferences; moved over
- from event-editor.c.
-
- * gui/event-editor.c (make_recur_weekly_special): Use
- weekday_picker_set_week_start_day() and the corresponding function
- from calendar-config.h.
- (init_widgets): Likewise.
- (make_date_edit_with_time): Removed function.
- (make_recur_ending_until_special): Use date_edit_new().
- (make_date_edit): Likewise.
-
- * gui/dialogs/task-editor.c (task_editor_create_date_edit): Likewise.
-
- * gui/event-editor-dialog.glade: Removed references to
- make_date_edit_with_time(); replace them with make_date_edit().
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Added
- widget-util.[ch] to the list of sources.
-
-2000-12-14 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/e-calendar-table.c (E_CALENDAR_TABLE_SPEC): Reset the widths
- of the columns with pixbufs to the actual pixbufs' sizes; now
- ETable properly computes its column widths so we do not need to
- add extra padding here.
-
-2000-12-14 Dan Winship <danw@helixcode.com>
-
- * gui/calendar-model.c (_XOPEN_SOURCE): #define this to 500, not
- nothing. Also, move this bit after the other #includes to
- prevent potential messiness.
-
-2000-12-13 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (ensure_mandatory_properties): Even
- though icaltime_from_timet() now properly ignores the is_utc
- argument since time_t values *are* in UTC by definition, we were
- passing FALSE for that argument's value in a bunch of places. So
- although it is ignored, changed them to TRUE for consistency.
- Hopefully newer versions of libical will remove that argument
- entirely since it does not make sense to speak of non-absolute
- time_t values.
-
- * cal-util/cal-recur.c (cal_recur_set_rule_end_date): Likewise.
-
- * conduits/calendar/calendar-conduit.c (comp_from_remote_record): Likewise.
-
- * conduits/todo/todo-conduit.c (comp_from_remote_record): Likewise.
-
- * gui/dialogs/task-editor.c (dialog_to_comp_object): Likewise.
-
- * gui/e-day-view.c (e_day_view_on_new_appointment): Likewise.
- (e_day_view_on_delete_occurrence): Likewise.
- (e_day_view_on_unrecur_appointment): Likewise.
- (e_day_view_on_unrecur_appointment): Likewise.
- (e_day_view_finish_long_event_resize): Likewise.
- (e_day_view_finish_resize): Likewise.
- (e_day_view_key_press): Likewise.
- (e_day_view_on_top_canvas_drag_data_received): Likewise.
- (e_day_view_on_main_canvas_drag_data_received): Likewise.
-
- * gui/e-week-view.c (e_week_view_key_press): Likewise.
- (e_week_view_on_new_appointment): Likewise.
- (e_week_view_on_delete_occurrence): Likewise.
- (e_week_view_on_unrecur_appointment): Likewise.
-
- * gui/event-editor.c (simple_recur_to_comp_object): Likewise.
- (recur_to_comp_object): Likewise.
- (dialog_to_comp_object): Likewise.
-
- * gui/gnome-cal.c (gnome_calendar_new_appointment): Likewise.
-
-2000-12-13 Christopher James Lahey <clahey@helixcode.com>
-
- * cal-util/cal-recur.c: #if 0ed cal_obj_date_only_compare_func.
- (cal_object_get_rdate_end): Changed this function to get rid of a
- possible uninitialized error on the rdate function.
-
- * gui/calendar-model.c: Fixed some warnings involving the #define
- _XOPEN_SOURCE lines here.
-
- * gui/component-factory.c: #ifdef WANT_THE_EXECUTIVE_SUMMARYed out
- the summary_factory object since it's unused if
- WANT_THE_EXCUTIVE_SUMMARY is not defined.
-
- * gui/e-day-view.c: #if 0ed out e_day_view_remove_event_cb.
- (obj_updated_cb): #ifndef NO_WARNINGSed out a #warning.
-
- * gui/e-week-view-event-item.c (e_week_view_event_item_draw): Made
- it so that
-
- * gui/e-week-view.c (obj_updated_cb): #ifndef NO_WARNINGSed out a
- #warning.
-
-2000-12-13 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/Makefile.am: Revert federico's change for now
- because of libtool limitations with ldadding shared libtool
- libs
-
- * conduits/calendar/Makefile.am: ditto
-
-2000-12-12 JP Rosevear <jpr@helixcode.com>
-
- * gui/dialogs/task-editor.c (task_editor_set_todo_object): Use
- set_title_from_comp
- (save_todo_object): ditto
- (set_title_from_comp): Make sure the title is encoded properly (as in
- event-editor)
-
-2000-12-12 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (get_text_list): Constify for new
- libical API.
- (set_text_list): Likewise.
-
- * cal-util/cal-recur.c (cal_recur_get_rule_end_date): Likewise.
- (cal_recur_set_rule_end_date): Likewise.
-
- * gui/e-itip-control.c (find_attendee): Likewise.
- (pstream_load): Likewise.
-
- * gui/gnome-cal.c (released_event_object_cb): Removed unused function.
-
- * gui/dialogs/task-editor.c (status_string_map): Removed unused
- variable.
-
-2000-12-11 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/Makefile.am (test_recur_LDADD): Link to the libical
- shared library.
-
- * cal-client/Makefile.am (client_test_LDADD): Likewise.
-
- * conduits/calendar/Makefile.am (libecalendar_conduit_la_LIBADD):
- Likewise.
-
- * gui/Makefile.am (LINK_FLAGS): Likewise.
-
-2000-12-11 Federico Mena Quintero <federico@helixcode.com>
-
- This is to make things work with libical 0.21helix1 and later.
- Warnings remain because at last libical was constified; will take
- care of those tomorrow.
-
- * cal-util/timeutil.h: #include <ical.h> instead of <icaltypes.h>
-
- * gui/e-itip-control.c: Likewise.
-
- * gui/e-meeting-edit.c: Likewise.
-
- * gui/itip-utils.h: Likewise.
-
- * cal-util/cal-component.c (alarm_uid_from_prop): constify.
- (cal_component_get_status): Updated for new libical API.
- (cal_component_set_status): Likewise.
-
- * gui/calendar-model.c (ensure_task_complete): Removed unused
- status code.
- (ensure_task_not_complete): Update for new status API.
-
- * gui/dialogs/task-editor.c (status_string_to_value): Removed
- function.
- (status_value_to_string): Removed function.
- (status_string_map): Removed variable.
- (fill_widgets): Update for new status API.
- (dialog_to_comp_object): Likewise.
-
-2000-12-11 Damon Chaplin <damon@helixcode.com>
-
- * cal-util/cal-recur.c (generate_instances_for_chunk): updated the
- tests on the start & end time just before calling the callback. It
- was skipping occurrences that started before the required interval's
- start time, which was wrong. We want all occurrences that intersect
- the interval.
- (cal_obj_time_weekday): removed the CalRecurrence* argument, since it
- isn't needed.
-
-2000-12-11 Damon Chaplin <damon@helixcode.com>
-
- * gui/event-editor.c: added changed flags and added calls to a new
- function event_editor_set_changed() to set & reset this flag.
- Added prompt_to_save_changed() which is called when the user
- selects File/Close or the window's close button.
- Fixed the 'All day event' toggle button.
- Made the 'Alarm' page sensitive as appropriate when filling widgets.
- (Though note that the alarm widgets are not being set yet.)
-
- * gui/dialogs/task-editor.c: added changed flag as above.
-
- * gui/event-editor-dialog.glade: used good names for all the
- classification radio buttons so we can access them in the code.
-
- * gui/event-editor.c (init_widgets): use the "show week numbers" config
- option in the recurrence preview calendar.
-
- * gui/e-day-view.c (e_day_view_update_event_label): use 9:00 instead
- of 09:00 in the main view, as we do everywhere else now. It means the
- times won't line up, but they are easier to read which I think is
- better.
- Added support for Page Up/Down, though I think it should move the
- selection rather than just scroll the canvas.
-
- * cal-util/cal-recur.c (generate_instances_for_chunk): removed the
- end parameter since we should be using the chunk end time now.
- Added single_rule parameter for when we are generating the
- occurrences of a single RRULE, in which case the event's start date is
- not included in the occurrences output (unless it results from the
- RRULE expansion). Both of these fix problems when using COUNT.
-
- * gui/gnome-cal.c (gnome_calendar_on_date_navigator_selection_changed):
- fixed bug when checking if the new start day starts on the week start
- day. If you select a complete week it should now show the Week view.
-
-2000-12-08 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (dialog_to_comp_object): Free the strings we
- get from the editables.
-
- * gui/dialogs/task-editor.c (dialog_to_comp_object): Likewise.
- This sucks; this code should be shared between the two dialogs.
-
-2000-12-08 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (fill_widgets): Free the dates we get from
- the component.
-
-2000-12-08 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-calendar-table.c (e_calendar_table_init): Attach signal
- handlers to the e_scrolled_table's etable rather than to the
- e_scrolled_table directly
- (e_calendar_table_on_double_click): This signal provides more
- params now
-
-2000-12-07 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/e-calendar-table.c: Got rid of code referencing the
- ETableScrolled proxy functions.
-
-2000-12-07 JP Rosevear <jpr@helixcode.com>
-
- * conduits/calendar/calendar-conduit.c (post_sync): Ugly hack for syncing
- until pcs can be altered (longer term)
-
- * conduits/todo/todo-conduit.c (post_sync): ditto
-
-2000-12-07 Chris Toshok <toshok@helixcode.com>
-
- * cal-client/Makefile.am (client_test_LDADD): add
- EXTRA_GNOME_LIBS.
-
-2000-12-07 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal-backend.c (cal_backend_compute_changes_foreach_key): Create
- an empty cal component if the object has been deleted.
-
- * idl/evolution-calendar.idl: Bit shift the change type constants
- properly
-
-2000-12-07 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-client/cal-client.c (cal_client_generate_instances): Unref
- the component from the objects list; it got referenced as many
- times as appropriate for the instances list.
-
-2000-12-06 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (file_delete_cb): Confirm before deleting the
- event.
-
-2000-12-06 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-week-view.c (e_week_view_init): unref the pixbuf when
- finished with it
-
-2000-12-06 Federico Mena Quintero <federico@helixcode.com>
-
- Fixes bug #920.
-
- * gui/e-calendar-table.c (delete_component): New function.
- (e_calendar_table_on_delete_task): Use delete_component().
- (e_calendar_table_on_key_press): Likewise. Also, mark the event
- as handled.
-
- * gui/calendar-model.c (calendar_model_get_component): Renamed
- function from calendar_model_get_cal_object().
- (calendar_model_delete_task): Removed function.
-
- * gui/dialogs/delete-comp.[ch]: New files with the dialog for
- deleting a calendar component.
-
- * gui/e-day-view.c (e_day_view_on_delete_appointment): Confirm
- before actually deleting the appointment.
-
- * gui/e-week-view.c (e_week_view_on_delete_appointment): Likewise.
-
- * gui/dialogs/Makefile.am (libcal_dialogs_a_SOURCES): Added
- delete-comp.[ch] to the list of sources.
-
- * cal-util/cal-component.c (cal_component_destroy): Free the alarm
- UID hash.
-
-2000-12-06 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal.c (build_change_seq): kill
- (Cal_get_changes): return the corba sequence directly
-
- * pcs/cal-backend.h: update prototype
-
- * pcs/cal-backend.c (cal_backend_compute_changes_foreach_key): Build
- the corba struct rather than the old calobjchange thing
- (cal_backend_compute_changes): ditto. build and return the actual
- corba sequence rather than the list of calobjchanges
- (cal_backend_get_changes): return the corba sequence
-
- * cal-util/cal-util.h: Remove CalObjChange cruft
-
- * cal-util/cal-util.c (cal_obj_change_list_free): Kill
-
-2000-12-06 JP Rosevear <jpr@helixcode.com>
-
- * cal-util/cal-util.c:
-
- * conduits/calendar/calendar-conduit.c (map_name): Update so as not to conflict
- with calendar
- (next_changed_item): update to use CalClientChange instead of CalObjChange
- (compute_status): ditto
- (pre_sync): ditto
- (for_each_modified): since we now have the cal component we can call
- local_record_from_comp directly
-
- * conduits/todo/todo-conduit.c: same as above
-
- * pcs/cal-backend.c: Remove much logging cruft
- (cal_backend_compute_changes): Calculate the changes based on the
- hashed database
- (cal_backend_get_changes): call cal_backend_compute_changes
- (cal_backend_compute_changes_foreach_key): hash callback for
- calculating deletions
-
- * pcs/cal-backend.h: update protype, remove logging cruft from
- object
-
- * pcs/cal.c (build_change_seq): dup the calobj rather than the uid
- now
- (Cal_get_changes): rename from Cal_get_changed_uids
- (cal_get_epv): reflect name change in epv
-
- * cal-util/cal-util.c (cal_obj_change_list_free): update assertion
-
- * cal-util/cal-util.h: CalObjChange now returns the entire ical
- component, update the change types. This should all go away shortly
-
- * idl/evolution-calendar.idl: getChangedUIds -> getChanges.
- CalObjChange now contains the calobj rather than the uid, update
- the change types
-
- * cal-client/cal-client.c (cal_client_get_changes): rename from
- cal_client_get_changed_uids to make idl and addressbook
-
- * cal-client/cal-client.h: Update prototype
-
- * cal-client/cal-client.c (build_change_list): Build a list of
- CalClientChange instead of CalObjChange
-
- * cal-client/cal-client-types.c (cal_client_change_list_free): Free
- a glist of CalClientChanges
-
- * cal-client/cal-client-types.h: New file. Declarations for
- CalClientChange.
-
- * cal-client/Makefile.am: Build new files
-
-2000-12-06 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/Makefile.am: Fix my build stupidty READ THE MACRO
-
- * conduits/calendar/Makefile.am: ditto
-
-2000-12-04 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-day-view-time-item.c (e_day_view_time_item_get_column_width):
- Initialize max_large_digit_width to 0 to prevent crazy sizing issues.
-
-2000-12-04 Dan Winship <danw@helixcode.com>
-
- * gui/e-itip-control.c: Remove mysterious #include inserted by
- mmeeks to break the build.
-
-2000-12-01 Federico Mena Quintero <federico@helixcode.com>
-
- Fixes bug #918.
-
- * gui/weekday-picker.c (WeekdayPickerPrivate): Added a field for a
- set of blocked days.
- (weekday_picker_set_blocked_days): New function to configure a set
- of days that cannot be modified by the user.
- (weekday_picker_get_blocked_days): Query function for the above.
- (day_event_cb): Block the appropriate days from being modified.
-
- * gui/event-editor.c (get_start_weekday_mask): New function to
- compute a day mask for the start day of a calendar component.
- (set_recur_special_defaults): New function to set sane defaults
- for the recurrence special widgets.
- (fill_recurrence_widgets): Use set_recur_special_defaults().
- (make_recur_weekly_special): Block the appropriate days.
-
-2000-12-01 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/control-factory.c (set_prop): Removed debugging message.
- (control_factory_init): Ditto.
-
- * gui/calendar-commands.c (calendar_set_uri): Ditto.
-
- * gui/main.c (main): Ditto.
-
- * gui/event-editor.c (set_title_from_comp): New function to
- generate a title and convert it from UTF8 before setting it on the
- window.
- (save_event_object): Uset set_title_from_comp().
- (event_editor_set_event_object): Likewise.
-
-2000-11-30 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c: Debug message cleanups
- (comp_from_remote_record): Properly set the ical description field
-
- * conduits/calendar/calendar-conduit.c (is_empty_time): New utility
- functions that look for all 0's in a struct tm
- (comp_from_remote_record): use above
- (local_record_from_comp): Correctly set the repeatForever value so
- that we repeat forever instead of a really long time
- (comp_from_remote_record): Only set the cal component recurrence
- until field when repeatForever is 0
-
-2000-11-30 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-itip-control.c: fixed a bug that caused the calendar to
- segfault when the iTip control was destroyed.
-
-2000-11-30 JP Rosevear <jpr@helixcode.com>
-
- * conduits/calendar/calendar-conduit.c (local_record_from_comp): Empty
- by_day entries are no longer indicated by ICAL_RECURRENCE_ARRAY_MAX not
- SHRT_MAX. Calculate weekly and monthly by date recurrences properly
- (get_pilot_day): Convert ical day to corresponding integer for pilot day
-
-2000-11-30 JP Rosevear <jpr@helixcode.com>
-
- * conduits/calendar/calendar-conduit.c: Debug message cleanups
- (get_ical_day): Fix off-by-one error which affected weekly occurences.
- (comp_from_remote_record): Monthly by day and by date were reversed
- (nth_weekday): function taken from event-editor.c that encodes BYDAY
- values - this needs to be in libical really.
- (comp_from_remote_record): Don't set the description if the pilot note
- is null. Rejig so that we don't have to free objects.
-
-2000-11-28 Federico Mena Quintero <federico@helixcode.com>
-
- Upgrade of the alarm framework. We now access alarms by a unique
- identifier. This UID is added as an extension property to alarm
- subcomponents when their parent components are scanned by
- CalComponent.
-
- * cal-util/cal-component.c (CalComponentPrivate): Added a hash
- table of alarm UIDs -> alarm properties.
- (cal_component_init): Initialize priv->alarm_uid_hash.
- (free_icalcomponent): Free the elements in the
- priv->alarm_uid_hash.
- (scan_alarm): New function to add scan an alarm subcomponent and
- ensure that it has an alarm UID extension property so that we can
- add it to our mapping table.
- (cal_component_get_first_alarm): Removed function.
- (cal_component_get_next_alarm): Removed function.
- (cal_component_get_alarm_uids): New function.
- (cal_component_get_alarm): New function.
-
-2000-11-28 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c (local_record_to_pilot_record): Return
- a struct rather than a pointer to a struct
- (compare): local_record_to_pilot_record now returns a struct
- (prepare): ditto
- (free_prepare): remove as per gnome-pilot changes
- (conduit_get_gpilot_conduit): don't listen for free_prepare signal
-
- * conduits/calendar/calendar-conduit.c: Same as above
-
-2000-11-28 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/e-calendar-table.c (E_CALENDAR_TABLE_SPEC): Reformatted the
- table spec to make it easier to read.
-
- * gui/tag-calendar.c: Oops, Damon wrote this, not me. Fixed the
- Authors line.
-
-2000-11-28 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-day-view*.[hc]:
- * gui/e-week-view*.[hc]: finished 12-hour support and tried to tidy
- up & comment the drawing code in places. Also fixed a couple of bugs I
- spotted. All the options on the 'Calendar' page should now work.
-
-2000-11-28 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-meeting-edit.c: removed some debugging code that I had,
- which might have caused problems.
-
-2000-11-27 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/calendar-model.c: added a preliminary change to have
- Assigned To-Do items have a corresponding icon.
-
-2000-11-27 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c (free_prepare): Ditto
-
- * conduits/calendar/calendar-conduit.c (free_prepare): Adjust
- free_prepare to the correct signal parameters. Don't actually
- do anything - there is a semantic discrepancy that needs to be
- resolved.
-
-2000-11-26 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-day-view.c (e_day_view_set_days_shown): == instead of =.
-
-2000-11-26 Damon Chaplin <damon@helixcode.com>
-
- * gui/gnome-cal.c: added more support for config settings.
-
- * gui/e-week-view.[hc]:
- * gui/e-day-view.[hc]: added support for setting - show event end
- times, week start day and 12-hour format (unfinished).
-
- * gui/e-day-view-time-item.c: started 12-hour support.
-
- * gui/tag-calendar.c (prepare_tag): use end_day + 1 since we want to
- include the last day.
-
- * gui/event-editor.c (set_all_day): minor change when turning all_day
- off - set the event end to one hour after the event start if it is on
- or before the start time. Also added more comments to make it a bit
- clearer.
-
- * cal-util/cal-recur.c (cal_obj_time_add_days): use a gint for day
- rather than a guint since we now support -ve days.
- Also fixed bug with weekly recurrences.
-
- * gui/dialogs/task-editor.c (task_editor_create_date_edit): use
- config settings.
-
- * gui/dialogs/cal-prefs-dialog.c (cal_prefs_dialog_update_config):
- updated EDateEdit calls.
-
-2000-11-24 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/e-calendar-table.c (e_calendar_table_init): Unref the ETable
- extras.
-
-2000-11-24 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (free_icalcomponent): DOH, fixed
- reversed test for the presence of the icalcomp's parent. This was
- causing memory leaks in the Wombat and elsewhere.
-
- * pcs/cal-backend.c (cal_backend_set_node_timet): Plug leak.
-
-2000-11-24 Federico Mena Quintero <federico@helixcode.com>
-
- * pcs/cal-backend-file.c (scan_vcalendar): Use the new libical
- external iterators (icalcomponent_begin_component() and friends);
- the internal iterators are deprecated.
-
- * cal-util/test-recur.c (generate_occurrences): Likewise.
-
- * gui/e-itip-control.c (pstream_load): Likewise.
-
- * gui/e-meeting-edit.c (e_meeting_edit): Likewise.
-
- * pcs/cal-backend.c (cal_backend_log_entry): Plug leak.
- (cal_backend_log_sync): Free the entry->uid.
-
- * util/icalendar-save.[ch]:
- * util/icalendar-test.c:
- * util/icalendar.[ch]: Removed obsolete files.
-
-2000-11-21 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/task.xpm: Remove the check because it makes it look like the
- task is already completed. This fixes bug #819.
-
- * gui/task-recurring.xpm: Make it use a prettier overlaid icon.
-
- * gui/task-*.xpm: Made the things look like little spiral-bound
- notebooks.
-
- * gui/e-calendar-table.c (E_CALENDAR_TABLE_SPEC): Make the default
- column order be icon/completed/summary. You may need to erase
- your ~/evolution/config/TaskPad for this to appear.
-
-2000-11-21 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-model.c (calendar_model_is_cell_editable): The icon
- column is not editable!
-
- * gui/calendar-commands.c (todo_properties_changed): Removed.
- (time_format_changed): Removed.
- (colors_changed): Removed.
-
- * gui/calendar-commands.h:
- * gui/prop.c (prop_apply):
- * gui/calendar-commands.c (init_calendar): Removed the old to-do
- list crap.
-
- * gui/gncal-todo.[ch]: Removed obsolete files.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Removed gncal-todo.[ch].
-
- * gui/gnome-cal.c (gnome_calendar_todo_properties_changed): Removed.
- (gnome_calendar_time_format_changed): Removed.
- (gnome_calendar_colors_changed): Removed.
-
-2000-11-21 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-itip-control.c: fixed the stupid Bonobo widget size
- allocation bug that had been vexing me.
-
- * gui/e-itip-control.glade: I removed some hacks that were
- necessary for said size bug.
-
-2000-11-16 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-itip-control.c, gui/e-meeting-edit.c: added cancellation
- code to our program; people can cancel meetings, which is the best
- thing to do for most meetings.
-
-2000-11-13 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-itip-control.c: made the REPLY code actually work.
-
-2000-11-13 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/itip-utils.[ch]: I created this file to store some commonly used enumeration to
- string mappings and functions.
-
- * gui/Makefile.am: this was changed to reflect the addition of the above file.
-
- * gui/e-itip-control.c: added code to take action on a REPLY message.
-
- * gui/e-meeting-edit.c: bug fixes.
-
-2000-11-12 Federico Mena Quintero <federico@helixcode.com>
-
- OK, bugzilla bug #829 is fixed and that does not redeem me from
- extreme procrastination. Wheeeeeeeeeeeeeeee!
-
- * gui/event-editor-dialog.c: Changed the "Rule view" label to
- "Preview"
-
-2000-11-12 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (make_recur_ending_count_special): Misspelled
- "occurrences".
- (fill_recurrence_widgets): Sensitize the "Custom recurrence" radio
- button as appropriate.
- (sensitize_recur_widgets): Resurrected the recurrence custom
- warning label.
- (get_widgets): Load the recurrence custom warning bin.
-
- * gui/event-editor-dialog.glade: Add an empty alignment for the
- recurrence custom warning label.
-
-2000-11-12 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (recur_preview_date_range_changed_cb): New
- function; re-tag the calendar when its date range changes.
- (init_widgets): Connect to "date_range_changed" on the recurrence
- preview calendar.
- (make_recur_weekly_special): Connect to "changed" on the weekday
- picker.
- (recur_weekday_picker_changed_cb): New function; re-tag the calendar.
- (month_day_menu_selection_done_cb): Re-tag the calendar.
- (recur_month_index_value_changed_cb): Likewise.
- (recur_ending_until_changed_cb): Likewise.
- (recur_ending_count_value_changed_cb): Likewise.
- (make_recur_monthly_special): Connect to "value_changed" on the
- adjustment of the month index.
- (make_recur_ending_until_special): Connect to "changed" on the
- ending-until date picker.
- (make_recur_ending_count_special): Connect to "value_changed" on
- the ending-count adjustment.
- (init_widgets): Set to zero the maximum number of selectable days
- in the recurrence preview calendar. Set the week_start_day from
- the calendar's configuration.
-
-2000-11-12 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (clear_widgets): Block the signals as appropriate.
- (fill_ending_date): Ditto.
- (fill_recurrence_widgets): Ditto.
- (recurrence_type_toggled_cb): Only sensitize the widgets and
- preview the recurrence if the toggle button is active.
-
-2000-11-12 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (recur_to_comp_object): Clear the rdate and
- exrule lists from the component if we are setting a simple
- recurrence.
- (recur_to_comp_object): Set the exdate list here instead of in
- dialog_to_comp_object().
- (preview_recur): New function to tag the recurrence preview
- calendar based on the information from the dialog box.
- (fill_exception_widgets): Fill the exception widgets here; moved
- over from fill_widgets().
- (fill_recurrence_widgets): Call preview_recur(). Also, call
- fill_exception_widgets() first of all.
- (recurrence_type_toggled_cb): Call preview_recur().
- (recur_interval_selection_done_cb): Likewise.
- (recur_ending_selection_done_cb): Likewise.
- (recurrence_exception_add_cb): Likewise.
- (recurrence_exception_modify_cb): Likewise.
- (recurrence_exception_delete_cb): Likewise.
- (date_changed_cb): Likewise.
- (recur_interval_value_changed_cb): Likewise, new function.
-
- * gui/tag-calendar.[ch]: New files with utilities for tagging
- calendars. mark.[ch] should go away some day.
-
- * gui/tag-calendar.c (tag_calendar): Moved over from
- gnome_calendar_tag_calendar(). Take in a CalClient instead of a
- GnomeCalendar. Added API docs.
- (tag_calendar_by_comp): New function to tag a calendar based on a
- single calendar component instead of a whole client.
-
- * gui/gnome-cal.c (initial_load): Use tag_calendar_by_client().
- (obj_updated_cb): Likewise.
- (obj_removed_cb): Likewise.
- (gnome_calendar_on_date_navigator_date_range_changed): Likewise.
- (editor_closed_cb): Free the closure.
- (destroy_editor_cb): Renamed from free_uid(). Do not free the
- UID; just unref the event editor. Our destroy handler to it will
- free things properly. This will also cause the corresponding
- calendar client to be unrefed.
- (editor_closed_cb): Use a flag on the GnomeCalendar to decide
- whether to remove the editor from the hash table. This is sort of
- icky.
-
- * gui/calendar-model.c (obj_updated_cb): If the object is new, we
- have to use e_table_model_row_inserted(), not row_changed().
- Thanks to JP Rosevear for reporting this.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Added
- tag-calendar.[ch] to the list of sources.
-
-2000-11-11 Matt Bissiri <bissiri@eecs.umich.edu>
-
- * gui/evolution-calendar.oafinfo:
- Update the remaining "IDL:Evolution*" to "IDL:GNOME/Evolution*"
- to sync up with yesterday's IDL re-scoping.
-
-2000-11-10 Michael Meeks <michael@helixcode.com>
-
- * gui/Makefile.am ($(IDL_GENERATED)): sort include order.
-
- * pcs/Makefile.am (idl_flags): ditto.
-
-2000-11-10 JP Rosevear <jpr@helixcode.com>
-
- * conduits/calendar/calendar-conduit.c (for_each_modified): Inc the
- iterator before finding the next changed item.
-
- * conduits/todo/todo-conduit.c (for_each_modified): ditto
-
-2000-11-09 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-itip-control.c: I wrote the code so that recipients of meeting requests
- can reply appropriately.
-
-2000-11-09 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-meeting-edit.c: fixed a bug that would make the calendar segfault
- if the meeting editor were called up twice without first saving the
- component.
-
-2000-11-08 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-itip-control.c, gui/e-itip-control.glade: updated the GUI
- to allow the user to add PUBLISHed events to his calendar, and created
- unworking buttons for meeting requests.
-
-2000-11-08 Federico Mena Quintero <federico@helixcode.com>
-
- These changes fix bugzilla bugs #874 and #875.
-
- * cal-util/cal-component.c (cal_component_get_exdate_list): Return
- a list of CalComponentDateTime instead of simple struct
- icaltimetype objects. Exception date properties *can* contain a
- timezone parameter, so we need to include those if they are
- present.
- (cal_component_set_exdate_list): On the input, handle a list of
- CalComponentDateTime structures. On the internals, handle a list
- of struct datetime instead of plain properties.
- (cal_component_free_exdate_list): Handle a list of
- CalComponentDateTime structures.
- (scan_exdate): Create a list of struct datetime structures.
- (free_icalcomponent): Free the exdate_list properly.
-
- * cal-util/cal-recur.c (generate_instances_for_chunk): Use the
- proper types for exception dates.
-
- * gui/comp-util.h:
- * gui/comp-util.c: New files with utilities for manipulating
- calendar component objects.
- (cal_comp_util_add_exdate): New function.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Added
- comp-util.[ch] to the list of sources.
-
- * gui/e-day-view.c (add_exdate): New convenience function to add
- an exception date to a calendar component.
- (e_day_view_on_unrecur_appointment): Use cal_comp_util_add_exdate().
- (e_day_view_on_delete_occurrence): Likewise.
-
- * gui/e-week-view.c (e_week_view_on_delete_occurrence): Likewise.
- (e_week_view_on_unrecur_appointment): Likewise.
-
- * gui/event-editor.c (nth_weekday): Be paranoid about valid
- position values.
- (fill_widgets): Use the proper types for exdates.
- (dialog_to_comp_object): Likewise.
-
-2000-11-08 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (adjust_day_index_spin): Adjust the valid
- range of the month index spin button depending on the selection of
- the day/weekday menu.
-
-2000-11-07 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-itip-control.c, gui/e-itip-control.glade: changed the GUI,
- and added some extra feedback for the user.
-
-2000-11-07 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/weekday-picker.h (WeekdayPickerClass): Added a "changed"
- signal to notify of changes to the set of selected days.
-
- * gui/weekday-picker.c (weekday_picker_class_init): Create the
- "changed" signal.
- (weekday_picker_set_days): Emit the "changed" signal.
-
-2000-11-06 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-itip-control.c, gui/e-itip-control.glade: changed to GUI to
- accomodate dynamically generated buttons, which will be tailored to
- the type of iTip message that is incoming.
-
- * gui/e-meeting-dialog.glade gui/e-meeting-edit.c: added a new button
- to publish events, in addition to requesting meetings.
-
-2000-11-05 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor-dialog.glade: Removed the old recurrence page.
- Wheeeeeeeeee!
-
- * gui/event-editor.c (make_recurrence_special): Clear the monthly
- widgets.
- (make_recur_monthly_special): Create the monthly widgets.
- (clear_widgets): Clear the monthly values.
- (simple_recur_to_comp_object): Fill in the monthly values.
- (fill_recurrence_widgets): Fill in the monthly and yearly source
- values.
- (dialog_to_comp_object): Take in a CalComponent instead of using
- the event editor's directly.
- (recur_to_comp_object): Likewise.
- (simple_recur_to_comp_object): Likewise.
- (EventEditorPrivate): Removed the widgets from the old recurrence
- page.
- (get_widgets): Likewise.
- (clear_widgets): Likewise.
- (dialog_to_comp_object): If the description or summary are empty,
- just clear the description list or summary property, respectively,
- instead of saving empty ones.
- (simple_recur_to_comp_object): Set the week_start field.
-
- * gui/main.c: Fix includes, and add calendar-config.h.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): The glade messages
- file should not be in SOURCES.
-
-2000-11-05 Christopher James Lahey <clahey@helixcode.com>
-
- * doc/.cvsignore, doc/C/.cvsignore: Removed unnecessary .cvsignore
- files.
-
-2000-11-03 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (check_all_day): Block signals from the
- toggle button.
- (date_changed_cb): Merged check_dates() and check_times() into
- this function; provide better behavior as well.
- (check_dates): Removed function.
- (check_times): Removed function.
- (init_widgets): Connect to the "changed" signal on the start_time
- and end_time widgets.
- (check_all_day): Use a better test.
-
- * gui/Makefile.am: Clean the idl-generated sources properly.
- * cal-client/Makefile.am: Likewise.
-
-2000-11-03 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-itip-control.c: added some checks for the type of an
- incoming iCal component before passing it off to the CalComponent
- routines.
-
-2000-11-02 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/dialogs/task-editor.c (init_widgets): The date editor's
- signal is now "changed".
- (completed_changed): Renamed callback to reflect the name of the
- signal.
-
-2000-11-01 Gediminas Paulauskas <menesis@delfi.lt>
-
- * gui/main.c: (main): added call to bindtextdomain and textdomain, so
- all calendar gui shows up localized.
-
-2000-10-31 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (count_by_xxx): Hmmm. SHRT_MAX changed to
- ICAL_RECURRENCE_ARRAY_MAX in libical. Deal with it.
- (fill_recurrence_widgets): Likewise.
- (simple_recur_to_comp_object): Fixed incorrect assertion. The
- weekday picker is not the immediate child of the recurrence
- special container.
- (fill_recurrence_widgets): Call make_recurrence_special() after
- setting the recurrence period type.
- (fill_ending_date): Call make_recurrence_ending_special(). This
- would be so much nicer if GTK+ were model/view all over.
-
-2000-10-31 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.h: Remove add/del/mod hashes and
- add changed_hash.
-
- * conduits/calendar/calendar-conduit.h: ditto
-
- * conduits/todo/todo-conduit.c (next_changed_item): Utility function
- to get the next "really" changed item (changed status can be cleared now)
- (compute_status): Compute status based on changed_hash
- (pre_sync): Fill changed_hash and counts adds/mods/dels
- (set_status_cleared): New callback handler - avoid double syncing
- (for_each_modified): Use next_changed_item to iterate
- (add_archive_record): kill
- (delete_archive_record): kill
- (archive_record): New callback handler - mark/unmark archive status
- (conduit_get_gpilot_conduit): Adjust signal connects
-
- * conduits/calendar/calendar-conduit.c: ditto
-
-2000-10-30 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (sensitize_recur_widgets): New function. We
- split it from the radio callback so that we can call it explicitly
- from fill_recurrence_widgets().
- (fill_recurrence_widgets): Call sensitize_recur_widgets() as
- appropriate.
-
-2000-10-30 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-commands.c (new_calendar): Removed the geometry and
- hidden arguments. This code is ancient.
- (all_calendars): Made static. This sucks; configuration should be
- notification-based instead of "let's iterate through all open
- calendars".
- (active_calendars): Removed. Functions can check the length of
- the all_calendars list if they are interested.
-
- * gui/event-editor.c (sync_entries): Do not take in an extra data
- pointer.
- (summary_changed_cb): Use a single call back to sync both entries.
- (sync_date_edits): New function to sync two EDateEdit widgets.
- (init_widgets): Connect the general and recurrence starting date
- widgets.
-
-2000-10-27 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (sync_entries): New function.
- (general_summary_changed_cb): Sync the general summary to the
- recurrence summary widget.
- (recurrence_summary_changed_cb): Vice-versa.
- (init_widgets): Hook to the summaries.
-
- * event-editor-dialog.glade: Do not expand/fill the start and end
- date so that the "all day event" button is not pushed all the way
- to the right.
- Decrease the spacing between the recurrence sentence widgets.
- Remove a spurious empty label that was lurking around the
- recurrence widgets.
- Make the alarm widgets expand the right way.
- Delete old recurrence widgets.
-
-2000-10-27 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (init_widgets): Connect to the recurrence
- ending menu.
- (recur_ending_selection_done_cb): Implemented.
- (make_recurrence_ending_special): Implemented.
- (make_recur_ending_until_special): Implemented.
- (fill_ending_date): Implemented.
- (make_recur_ending_count_special): Implemented.
- (simple_recur_to_comp_object): Fill in the ending date.
- (clear_widgets): Clear the recurrence ending widgets.
-
- * gui/event-editor-dialog.glade: Moved the recurrence type radio
- buttons to a single hbox to save space.
- Fixed the lower value of the recurrence interval spin button.
- Removed the stale widgets from the recurrence ending date part.
-
-2000-10-27 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-meeting-edit.c: fixed problems in which I allocated CORBA
- strings of 0 length, but then didn't NULL terminate them.
-
-2000-10-27 <jpr@helixcode.com>
-
- * conduits/calendar/calendar-conduit.c (check_for_slow_setting):
- Check boundary case of fast sync
-
- * conduits/todo/todo-conduit.c (check_for_slow_setting): ditto
-
-2000-10-27 <jpr@helixcode.com>
-
- * conduits/calendar/calendar-conduit.c (add_archive_record): Remove
- invalid test.
- (local_record_from_comp): If the event is all day, mark it as timeless
- (comp_from_remote_record): Timeless events take up all day
-
- * conduits/todo/todo-conduit.c (add_archive_record): ditto
-
-2000-10-27 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c (add_archive_record): Take proper
- number of parameters
-
- * conduits/calendar/calendar-conduit.c (add_archive_record): ditto
-
-2000-10-26 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (EventEditorPrivate): Integrate Anna's new
- recurrence page. Replace the old widget pointers with the new
- ones. Modified the relevant functions accordingly and added
- plenty of new ones.
- (event_editor_get_cal_client): New function.
- (fill_recurrence_widgets): This is *THE* tricky function for you.
- It has to discriminate whether we get a recurrence we support for
- editing or not. And this is not trivial. Sigh.
- (event_editor_update_widgets): Added preconditions and API docs.
-
- * event-editor-dialog.glade: Fixed all the spacings/
- paddings/packing options so that the widgets will look right if
- the dialog box is resized. Also fixes some misaligned widgets.
-
- * cal-util/cal-component.c (cal_component_set_rdate_list): Removed
- incorrect assertion.
-
-2000-10-26 Michael Meeks <michael@helixcode.com>
-
- * pcs/cal-factory.c (str_tolower): unsigned chars to isalpha
-
- * cal-util/calobj.c (weekdaylist, weekdaynum): ditto.
-
-2000-10-25 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-meeting-edit.c: brushed up some code to deal with
- the organizer entry, and solidified the CORBA memory-freeing
- issues.
-
-2000-10-25 Jesse Pavel <jpavel@helixcode.com>
-
- * removed the Evolution-Composer generated files, due
- to a tip on how we do things.
-
-2000-10-25 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-meeting-edit.c: I fixed a bunch of memory-deallocation
- bugs, and finished the initial integration with the mailer.
-
- * gui/Makefile.am: made the build us the Evolution-Composer.idl
- from the composer directory.
-
-2000-10-25 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/Evolution-Composer.idl: added this from the composer IDL sources
-
- * gui/Makefile.am: changed to reflect the above IDL and the associated
- orbit-idl generated files.
-
- * gui/Evolution-Composer.h,
- gui/Evolution-Composer-common.c,
- gui/Evolution-Composer-stubs.c,
- gui/Evolution-Composer-skels.c:
- the generated files, as per the above description.
-
- * gui/e-meeting-edit.c: more work towards mailer integration.
-
-2000-10-24 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-meeting-edit.c: I've added code to interact with the mailer's
- CORBA interfaces, though it's not yet working.
-
-2000-10-23 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c (local_record_from_comp): Use
- new e-pilot-map lookup function
- (match): ditto
-
- * conduits/calendar/calendar-conduit.c (local_record_from_comp): Use
- new e-pilot-map lookup function
- (match): ditto
-
-2000-10-23 Dan Winship <danw@helixcode.com>
-
- * pcs/Makefile.am (INCLUDES):
- * gui/dialogs/Makefile.am (INCLUDES):
- * gui/Makefile.am (INCLUDES):
- * cal-util/Makefile.am (INCLUDES):
- * cal-client/Makefile.am (INCLUDES): Update GNOMELOCALEDIR.
-
-2000-10-23 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.h: Use new libeconduit calls and
- abstraction
-
- * conduits/calendar/calendar-conduit.c: ditto
-
- * conduits/calendar/calendar-conduit.h: ditto
-
- * conduits/todo/todo-conduit.c: ditto
-
- * conduits/calendar/Makefile.am: Add libeconduit-static.la
-
- * conduits/calendar/calendar-conduit.c (post_sync): Use e_pilot_map_write
- (pre_sync): Use e_pilot_map_read
-
-2000-10-23 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/Makefile.am: Add libeconduit-static.la
-
- * conduits/todo/todo-conduit.c (post_sync): Use e_pilot_map_write
- (pre_sync): Use e_pilot_map_read
-
-2000-10-21 Damon Chaplin <damon@helixcode.com>
-
- * gui/dialogs/cal-prefs-dialog.c
- (cal_prefs_dialog_use_24_hour_toggled): removed debug message.
-
- * gui/e-calendar-table.c (e_calendar_table_save_state): new function
- to save the state of the table to a given file.
-
- * gui/e-calendar-table.h (struct _ECalendarTable): added etable field
- so we can access it to save the state.
-
- * gui/gnome-cal.c (gnome_calendar_destroy): call
- e_calendar_table_save_state() to save the state of the TaskPad.
- (setup_widgets): load the state of the TaskPad.
-
- * gui/calendar-config.c: added support for the default view.
-
- * gui/gnome-cal.c (gnome_calendar_construct):
- (gnome_calendar_set_view_internal): use/set the default view setting.
-
-2000-10-20 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-meeting-editor.c: added more (working) integration with the
- meeting schedular.
-
-2000-10-20 Jesse Pavel <jpavel@helixcode.com>
-
- * cal-utils/cal-component.c: in set_datetime(), I put an #if 0'd portion
- of the code back into operation, because the icalproperty_remove_parameter()
- function is now implemented.
-
- * gui/e-meeting-editor.c: added more (unworking) integration with the
- meeting schedular.
-
-2000-10-20 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal-backend.c (cal_backend_destroy): New destroy
- handler to properly stop the timer, sync the log and unref
- the URI.
- (cal_backend_last_client_gone): Just emit the signal,
- clean up work is done in cal_backend_destroy now.
-
- * pcs/cal-backend-file.c (cal_backend_file_load): Unref the
- uri we are replacing NOT the new uri.
-
-2000-10-20 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/Makefile.am: Fix build
-
- * conduits/calendar/Makefile.am: Fix build
-
-2000-10-20 JP Rosevear <jpr@helixcode.com>
-
- * conduits/calendar/calendar-conduit.c (delete_archive_record):
- Don't throw an error
-
- * conduits/todo/todo-conduit.c (delete_archive_record): ditto
-
-2000-10-20 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit-control-applet.c: Add defines
-
- * conduits/todo/todo-conduit-config.h: put #ifdefs around functions
- can't make this a public interface in the usual way as then the
- symbols would be exported
-
- * conduits/todo/todo-conduit.c: Kill warnings. clahey will be
- happy! Add some defines to include only the necessary config functions.
- (conduit_get_gpilot_conduit): Hook up archive signals
-
- * conduits/calendar/calendar-conduit.c: Same as above
-
- * conduits/calendar/calendar-conduit-control-applet.c: ditto
-
- * conduits/calendar/calendar-conduit-config.h: ditto
-
-2000-10-20 Michael Meeks <michael@helixcode.com>
-
- * gui/calendar-commands.h: s/BonoboUIHandler/BonoboUIComponent/
-
- * gui/calendar-commands.c (properties_cmd): ditto.
-
-2000-10-20 Damon Chaplin <damon@helixcode.com>
-
- * gui/calendar-model.c (calendar_model_value_at): use
- cal_component_has_alarms().
-
-2000-10-20 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-calendar-table.c (E_CALENDAR_TABLE_SPEC): added
- _click-to-add-message, though I'm not sure if i18n will work.
-
- * cal-util/cal-recur.c (cal_obj_time_add_hours):
- (cal_obj_time_add_minutes):
- (cal_obj_time_add_seconds): updated to handle -ve args.
-
- * cal-util/timeutil.c (time_add_day): set tm_isdst to -1 before calling
- mktime().
-
- * cal-util/cal-recur.c (generate_instances_for_chunk): don't call the
- callback if the event ends exactly on the interval start time.
-
- * gui/e-week-view.c (e_week_view_reshape_event_span):
- * gui/e-week-view-event-item.c (e_week_view_event_item_draw_icons):
- * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event):
- * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event):
- * gui/e-day-view.c (e_day_view_reshape_long_event):
- (e_day_view_reshape_day_event): use cal_component_has_alarms().
-
- * cal-util/cal-component.[hc]: added cal_component_has_alarms().
-
-2000-10-16 Damon Chaplin <damon@helixcode.com>
-
- * gui/calendar-config.c (config_read): set default MonthVPanePosition
- to 1 rather than 0, so if you move the hpane you'll see the date
- navigator.
-
-2000-10-19 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/event-editor.[ch]: added a public function which causes the
- event editor to reload its widgets to the associated CalComponent.
-
- * gui/e-meeting-edit.c: added rudimentary support for the phat
- e-meeting-time-selector widget, though it has no effect on the
- component yet.
-
- * gui/Makefile.am: the meeting editor depends on the meeting widget
- library, now.
-
- * gui/e-itip-control.glade: I added another toolbar button that summons
- from the hoary deep the meeting time widget.
-
-2000-10-19 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/Makefile.am: Add `event-editor-dialog.glade.h'.
- (EXTRA_DIST): Add `$(glade_messages)'.
-
-2000-10-19 Michael Meeks <michael@helixcode.com>
-
- * gui/calendar-commands.c (tb_print_cb): remove; redundant.
-
- * gui/event-editor.c (create_menu, create_toolbar): kill.
- (event_editor_destroy): upd.
- (event_editor_construct): update to new UI handler, cast
- priv->general_summary to a widget not an object.
-
-2000-10-18 Michael Meeks <michael@helixcode.com>
-
- * gui/dialogs/task-editor.c (create_menu, create_toolbar): die.
- (debug_xml_cb): add debugging hook.
-
- * gui/dialogs/Makefile.am: add EVOLUTION_DATADIR
-
- * gui/dialogs/task-editor.c (task_editor_construct): upd for new UI.
-
-2000-10-17 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit-control-applet.c: Add defines
-
- * conduits/todo/todo-conduit-config.h: put #ifdefs around functions
- can't make this a public interface in the usual way as then the
- symbols would be exported
-
- * conduits/todo/todo-conduit.c: Kill warnings. clahey will be
- happy! Add some defines to include only the necessary config functions.
- (conduit_get_gpilot_conduit): Hook up archive signals
-
- * conduits/calendar/calendar-conduit.c: Same as above
-
- * conduits/calendar/calendar-conduit-control-applet.c: ditto
-
- * conduits/calendar/calendar-conduit-config.h: ditto
-
-2000-10-16 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-itip-control.c: You can now add incoming iTip
- messages to your calendar store.
-
- * gui/e-itip-control.glade: added a progress bar dialog
- in case the calendar loading takes a long time.
-
-2000-10-16 JP Rosevear <jpr@helixcode.com>
-
- * cal-client/cal-client.h: Remove pilot cruft. All pilot stuff
- is in the conduits now and uses the logging facility.
-
- * pcs/cal-backend-file.c: ditto
-
- * pcs/cal-backend.h: ditto
-
- * pcs/cal-backend.c: ditto
-
- * pcs/cal.c: ditto
-
- * pcs/cal.h: ditto
-
- * idl/evolution-calendar.idl: ditto
-
- * cal-util/cal-component.h: ditto
-
- * cal-util/cal-component.c: ditto
-
- * cal-client/cal-client.c: ditto
-
- * conduits/calendar/calendar-conduit.c (local_record_from_comp):
- Take a stab at storing recurrence stuff on the pilot properly
-
- * pcs/cal-backend.c (cal_backend_update_object): Don't log the
- event until after the update in case its a new item
-
-2000-10-16 Tuomas Kuosmanen <tigert@helixcode.com>
-
- * gui/dayview.xpm, gui/workweekview.xpm, gui/weekview.xpm
- gui/monthview.xpm gui/yearview.xpm: Updated icons, let me know
- if you like these or not, I might work on these some more but
- I wanted to put these versions up anyway to get feedback..
-
-2000-10-15 Dan Winship <danw@helixcode.com>
-
- * gui/Makefile.am: Remove CPPFLAGS def since the -D there was
- already in INCLUDES
-
-2000-10-14 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/evolution-calendar.oafinfo: Added an
- "evolution:shell-component-icon" attribute.
-
-2000-10-12 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-itip-control.{c,glade}: Made the control much more
- relavent to the function at hand.
-
-2000-10-12 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-calendar-table.c (E_CALENDAR_TABLE_SPEC): set the 2 icon
- columns to a min width of 18 and resizable to FALSE.
-
-2000-10-12 Damon Chaplin <damon@helixcode.com>
-
- * gui/calendar-commands.c (calendar_control_activate):
- (update_pixmaps):
- (set_pixmap): set the pixmaps of the toolbar buttons for the views,
- and removed a lot of old unused stuff. We'll use plain buttons for
- the view buttons for now, until Bonobo toolbars support radio buttons.
-
- * gui/gnome-cal.c (gnome_calendar_dayjump): check day_button is not
- NULL before using it.
- (gnome_calendar_update_view_buttons): check button is not NULL.
-
-2000-10-11 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-day-view-time-item.c (e_day_view_time_item_draw): got 12/24
- hour format the wrong way round.
-
-2000-10-12 JP Rosevear <jpr@helixcode.com>
-
- * conduits/calendar/calendar-conduit.c (comp_from_remote_record):
- Store recurrence stuff on the desktop properly
- (get_ical_day): Utility function
-
-2000-10-12 Iain Holmes <iain@helixcode.com>
-
- * gui/component-factory.c: Disable the executive summary.
-
-2000-10-11 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal-backend.c (cal_backend_log_entry): Take CalObjType
- as a param because its impossible to determine after a delete.
- (cal_backend_remove_object): Calculate CalObjType and pass
- it to cal_backend_log_entry
- (cal_backend_update_object): ditto
-
- * conduits/todo/todo-conduit.c (local_record_from_comp): Kill
- unused variables.
- (add_archive_record): Don't kill the sync if this happens
- (update_record): Kill old function
- (replace_record): New function to handle replace_record signal
- (conduit_get_gpilot_conduit): Listen for replace record signal
- (add_record): Always add a new record, never replace
- (replace_record): Always replace an existing record
-
- * conduits/calendar/calendar-conduit.c: Same as above
-
-2000-10-10 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-itip-control.c: set a default size for the control.
-
-2000-10-10 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/evolution-calendar.oafinfo: Added information about the
- text/calendar MIME type, so that the evolution-calendar is called
- to deal with iMIP attachments.
-
- * gui/e-itip-control.[ch]: These files implement a Bonobo
- control that will eventually deal with iMIP/iTIP messages from
- the mailer. Right now, it's not working.
-
- * gui/e-itip-control.glade: The Glade GUI for the above-mentioned
- control.
-
- * gui/Makefile.am: added references to the files I created.
-
- * gui/main.c: called the initialization function of the Bonobo
- control factory.
-
-2000-10-11 Tuomas Kuosmanen <tigert@helixcode.com>
-
- * gui/task-assigned-to.xpm gui/task-assigned.xpm
- gui/recur.xpm gui/task-recurring.xpm gui/task.xpm:
- New versions of the icons for the tasklist/pad.
-
-2000-10-11 Damon Chaplin <damon@helixcode.com>
-
- * gui/component-factory.c (owner_unset_cb): don't free evolution_dir
- as we need it to save the config settings.
-
-2000-10-11 Damon Chaplin <damon@helixcode.com>
-
- * gui/main.c (main): call calendar_config_write_on_exit() to write
- out some special config settings (as the mail component does).
-
- * gui/calendar-commands.c (properties_cmd): changed to use the new
- preferences dialog.
- (update_all_config_settings): new function to iterate over all the
- calendars and update the config settings.
-
- * gui/dialogs/cal-prefs-dialog.glade: preferences dialog.
-
- * gui/dialogs/cal-prefs-dialog.[hc]: new files for the preferences
- dialog.
-
- * gui/calendar-config.[hc]: new files to handle loading/saving config
- settings.
-
- * cal-util/cal-recur.c: fixed bug in YEARLY when no filters were set,
- plus minor changes.
-
- * cal-util/test-recur.c: updated.
-
- * gui/e-day-view-time-item.c:
- * gui/popup-menu.c: update to #include <gal/widgets/e-gui-utils.h>
-
- * gui/component-factory.c (owner_set_cb): called calendar_config_init.
- (owner_set_cb):
- (owner_unset_cb): updated the prototypes.
-
- * gui/main.c (main): added call to calendar_config_write_on_exit().
-
- * gui/component-factory.h:
- * gui/component-factory.c (owner_set_cb): added global evolution_dir
- just like the mail component, so we know we to store config stuff.
-
-2000-10-11 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/e-calendar-table.c: Fixed the column elements here.
-
-2000-10-11 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/e-calendar-table.c: Updated to use the new ETable
- specification stuff.
-
-2000-10-11 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c (map_sax_start_element): The
- element is "pilot_id" not "pilotid". Update both maps
- (compute_pid): Utility function to set a local records pid
- (local_record_from_comp): Compute the pid and status here,
- no longer use the old cal_component pilot interfaces
- (free_match): Its a *local not a **local
-
- * conduits/calendar/calendar-conduit.c: same as above
-
- * conduits/todo/todo-conduit.h: Have both a uid and pid map
-
- * conduits/todo/calendar-conduit.h: same as above
-
-2000-10-09 JP Rosevear <jpr@helixcode.com>
-
- * conduits/*: Adjust to using gnome-pilot-sync-abs conduit which
- is based on the latest pilot link changes.
-
-2000-10-09 Iain Holmes <iain@helixcode.com>
-
- * Makefile.am: Added the executive-summary library and cflags
-
- * gui/evolution-calendar.oafinfo: Added oaf servers for the
- executive summary and executive summary factory.
-
- * gui/calendar-summary.[ch]: New files to create the summary.
-
- * gui/component-factory.c (summary_fn): Create the executive
- summary component.
- (component_factory_init): Start the summary factory as well.
-
-2000-10-06 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/weekday-picker.[ch]: New widget to pick weekdays.
-
-2000-10-05 Michael Meeks <michael@helixcode.com>
-
- * gui/calendar-commands.c: upd.
- (calendar_control_activate): upd.
- (calendar_control_deactivate): upd.
-
-2000-10-05 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-day-view.c:
- * gui/e-week-view.c: when the user types in a new event, don't create
- it until the user hits Return or switches focus. Removed the
- editing_new_event flags.
-
- * cal-util/test-recur.c: rewritten to work on ics files. Now I can
- start testing the recurrence code.
-
- * cal-util/cal-recur.c: a few fixes.
-
- * gui/e-day-view.c (e_day_view_check_if_new_event_fits): fixed to
- return TRUE for long events, not FALSE.
-
-2000-10-04 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/print.c (print_todo_details): As a temporary solution to the
- to-do printing, just print the summaries. We'll use the ETable
- printing stuff later.
-
- * gui/print.c (print_day_summary_cb): Use g_list_append() correctly.
- (print_todo_details_cb): Likewise.
- (print_day_summary): Initialize psi.events. This code was
- obviously never tested.
- (print_todo_details): Likewise.
- (print_day_details): Initialize pdi.slots.
-
- * gui/print.c (range_selector_new): Fix strftime() %a versus %b
- confusion. Fixes bugzilla #644.
- (range_selector_new): Fix the whole localization mess by making
- better use of strftime(). Now we generate whole date strings at a
- time and compose them later. Fixes bugzilla #643.
-
-2000-10-02 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-meeting-edit.c: added support for the ROLE and RSVP parameters
- in both the GUI and underlying iCal.
-
-2000-09-29 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-meeting-edit.c: added support for organizers in the meeting
- scheduler.
-
-2000-09-29 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/e-meeting-edit.c: added code that makes changes to the underlying
- iCAL structure of an event, when the user changes meeting information.
-
- * gui/e-meeting-dialog.glade: this is the Glade UI for the meeting dialog
- and accoutrements.
-
-2000-09-29 Damon Chaplin <damon@helixcode.com>
-
- * cal-util/cal-recur.c: updated to support RDATE end times or
- durations. Note that if you have two RDATEs with the same start times,
- but with different end dates/durations set, the results are
- unpredictable. So the event editor dialog should check for this.
-
- * gui/e-week-view-main-item.c (e_week_view_main_item_draw_day):
- make strftime() strings translatable, and changed the formats a bit.
-
- * NOTE: someone needs to check print.c to make sure strftime strings
- are OK for i18n.
-
- * gui/e-day-view.h: Changed EDayViewDateFormat enum. We now try to
- include the weekday if possible. Also changed EDayView struct so we
- store the month & weekdays with the longest names rather than the
- actual widths. This helps i18n.
-
- * gui/e-day-view.c (e_day_view_recalc_cell_sizes): used _() for
- strftime strings, tried to see if weekday fits, and rearranged a
- bit to make i18n easier.
-
- * gui/e-day-view-top-item.c (e_day_view_top_item_draw): used _() for
- strftime strings, and updated to use new formats.
-
- * gui/calendar-model.c: added use_24_hour_format boolean to
- CalendarModelPrivate so we can display dates in 12-hour format if
- requested. This meant adding a CalendarModel argument to a few
- functions. Also added get/set functions to set use_24_hour_format.
- I suppose ideally we should have an ECellDate renderer and this option
- should go there.
-
-2000-09-27 Jesse Pavel <jpavel@helixcode.com>
-
- * gui/event-editor.c: changed a menu entry so that it will invoke
- my meeting editor.
-
- * gui/e-meeting-edit.[ch]: added these files to provide preliminary
- support for iTIP meeting scheduling. Currently, only the GUI works;
- there is not yet any backend support.
-
- * gui/Makefile.am: added entries for e-meeting-edit.[ch]
-
-2000-09-24 Damon Chaplin <damon@helixcode.com>
-
- * gui/dialogs/task-editor-dialog.glade: set the height of the scrolled
- window for the description field, since the default window height
- doesn't seem to be working.
-
- * cal-util/cal-component.h: added functions to get the actual
- icalproperty lists for RRULE and EXRULE properties.
-
- * cal-util/cal-recur.[hc]: added support for COUNT, though I need to
- test it a bit. Also fixed the call to generate_instances_for_year() so
- it uses the chunk dates.
-
-2000-09-20 Damon Chaplin <damon@helixcode.com>
-
- * gui/event-editor.c: got rid of 1 '_' in '__Formatting'.
-
-2000-09-22 Michael Meeks <michael@helixcode.com>
-
- * gui/calendar-commands.c (calendar_control_activate): upd.
-
-2000-09-21 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-commands.c (verbs): Removed the "about calendar"
- command, since we don't want to have both "About Evolution" and
- "About Calendar".
-
-2000-09-21 Michael Meeks <michael@helixcode.com>
-
- * gui/calendar-commands.c (calendar_control_activate): _UIHandler
- update.
-
-2000-09-20 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c (pre_sync): Don't fail if there
- is no map file.
-
-2000-09-20 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.h: Add since field to context
-
- * conduits/todo/todo-conduit.c (map_set_node_timet): New utility
- function
- (map_sax_start_element): Look for the map timestamp as well
- (map_write): Write the map timestamp
- (pre_sync): Use the map time stamp when looking for changed entries
-
- * pcs/cal-backend.c (cal_backend_log_sax_start_element): Make sure
- we are in a valid timestamp
-
-2000-09-20 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal-backend.c (cal_backend_log_name): Make the log file
- name relevant to the actual calendar file, rather than just the
- directory.
-
-2000-09-20 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal-backend.c (cal_backend_get_log_entries): Oops
-
-2000-09-20 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal-backend.c (cal_backend_get_log_entries): Use a local
- sax handler.
-
- * conduits/todo/todo-conduit.c (pre_sync): Use xmlSAXParseFile
- (map_sax_parse): Delete
-
-2000-09-20 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal-backend.c (cal_backend_log_sax_start_element): Properly
- assign the CalObjChange type.
- (cal_backend_log_sax_parse): Delete
- (cal_backend_get_log_entries): Use xmlSAXUserParseFile
-
-2000-09-19 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal-backend.c (cal_backend_set_uri): New utility function
- (cal_backend_load): use above
- (cal_backend_create): use above
- (cal_backend_log_name): Take a uri instead of a backend param
-
- * pcs/cal-backend-file.c: Get rid of useless hash functions
- (cal_backend_file_load): Check to make sure path exists and is
- local
- (cal_backend_file_load): Unref the current uri if there is one
- (cal_backend_file_create): ditto
-
- * pcs/cal-backend.c (cal_backend_last_client_gone): Sync before
- shooting ourselves in the foot
-
- * pcs/cal-backend-file.c (save): Fully implement backing up the
- calendar before writing out the new entry.
-
-2000-09-19 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c (check_for_slow_setting): Add some
- other cases where a slow sync is in order
- (pre_sync): Pre load the uids, the map and the add/mod/del lists
- (match_record): Use the map hash to match records
- (iterate): Iterate using the pre-loaded uid list
- (iterate_specific): Iterate using the add/mod/del lists
- (purge): Delete all entries in the del list
- (set_status): Set status by adding to an appropriate list
- (set_pilot_id): Set pilot_id by updating map hash
-
- * conduits/todo/todo-conduit.h: Add lists for added, modified and
- deleted objects
-
- * conduits/todo/todo-conduit.c (map_name): Get the pilot_id->uid map
- file name
- (map_sax_start_element): SAX handler to extract a pilot_id->uid
- mapping
- (map_sax_parse): Parse the given file and build a pilot_id->uid hash
- (map_write_foreach): Write out individual mapping elements
- (map_write): Write out the pilot_id->uid mapping
- (start_calendar_server_cb): Rename from gnome_calendar_load_cb
-
- * conduits/todo/todo-conduit-config.h: Rename pilotID to pilot_id
-
- * conduits/todo/e-todo.conduit.in: A little renaming
-
- * conduits/todo/Makefile.am: Fix build slightly
-
- * pcs/cal.c (build_change_seq): Build a corba sequence out of a list
- of CalObjChanges
- (Cal_get_objects_in_range): Implement new corba function
-
- * pcs/cal-backend.c (cal_backend_init): Intiliaze to NULL
- (cal_backend_load): Track the uri so we can write the log file
- to the same place
- (cal_backend_log_name): Figure out the log filename/path based on
- the calendar uri
- (cal_backend_set_node_timet): Set an xml node property value from
- a time_t
- (cal_backend_log_entry): Adds a log entry to list waiting to be written
- out
- (cal_backend_log_sync): Syncs the log entries to disk
- (cal_backend_log_sax_start_element): SAX callback for reading in
- log entries
- (cal_backend_log_sax_end_element): ditto
- (cal_backend_log_sax_parse): Main SAX parser call to parse the log
- file looking for particular log entries and creating a CalObjChange
- hash with the last change for each object
- (cal_backend_get_log_entries): Returns a hash of objects of a given
- type changed since the given time
- (cal_backend_update_object): Add appropriate log entries
- (cal_backend_remove_object): ditto
- (cal_backend_get_changed_uids): Implement new idl interface call
- (cal_backend_foreach_changed): Convert CalObjChange hash into a list
-
- * pcs/cal-backend-imc.[hc]: Remove crufty files
-
- * pcs/cal-backend-file.c (cal_backend_file_get_type_by_uid): New
- function that returns the CalObjType for a uid.
-
- * cal-client/cal-client.h: Update prototypes.
-
- * cal-client/cal-client.c (build_change_list): Build a list
- of CalObjChange items from a corba sequence.
- (cal_client_get_changed_uids): New accessor method for the
- similarly named addition to the idl file.
-
- * cal-util/cal-util.h: Update prototypes and add CalObjChangeType
- enum.
-
- * cal-util/cal-util.c (cal_obj_change_list_free): New utility
- method to free a list of CalObjChange objects.
-
- * idl/evolution-calendar.idl: Add get_changed_uids method
- and associated types.
-
-2000-09-18 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/Makefile.am: Added $(EXTRA_GNOME_CFLAGS) and
- $(EXTRA_GNOME_LIBS). Removed unneeded libraries.
-
- * gui/calendar-model.h, gui/e-calendar-table.c, gui/e-day-view.c,
- gui/e-week-view-event-item.c, gui/e-week-view.c,
- gui/event-editor.c, gui/gncal-todo.c, gui/gnome-cal.c, gui/main.c,
- gui/print.c, gui/dialogs/task-editor.c: Fixed the #include lines
- to deal properly with gal.
-
- * gui/check-filled.xpm: New file since we can't include it from
- e-table anymore.
-
-2000-09-16 Michael Meeks <michael@helixcode.com>
-
- * gui/Makefile.am (INCLUDES): add datadir
-
- * gui/calendar-commands.c (calendar_control_activate): use it.
-
-2000-09-14 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/.cvsignore: Shush
-
-2000-09-14 JP Rosevear <jpr@helixcode.com>
-
- * Add headers with GPL notice and credit copyright to those appropriate
-
- * conduits/todo/todo-conduit-control-applet.c (doHelp): Update name,
- authors, copyright for about dialog.
- (activate_sync_type): Tidy
-
- * conduits/todo/Makefile.am: Rename binaries and libs to e-todo*
- to avoid conflicts.
-
- * conduits/todo/e-todo.conduit.in: Reflect binary/lib name changes
-
- * conduits/todo/e-todo-conduit-control-applet.desktop: ditto
-
- * conduits/todo/todo.conduit.in: Removed
-
- * conduits/todo/todo-conduit-control-applet.desktop: Removed
-
- * conduits/todo/todo-conduit-config.h (todoconduit_load_configuration):
- The config file will now be called e-todo-conduit
- (todoconduit_save_configuration): ditto
-
- * conduits/todo/todo-conduit.c: Some renaming to keep consistent.
- (pre_sync): Remove commented out function that does not exist.
-
- * conduits/todo/todo-conduit-control-applet.c: ditto
-
- * conduits/todo/todo-conduit-config.h: ditto
-
- * conduits/todo/todo-conduit.h: ditto
-
-
-2000-09-07 Michael Meeks <michael@helixcode.com>
-
- * gui/calendar-commands.c: Re-write most UI handler code.
-
-2000-09-13 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-model.c (obj_updated_cb): Removed an unused
- variable.
-
- * gui/calendar-model.c (obj_updated_cb): See if the new object
- matches the type of objects we were told to deal with.
- (load_objects): Likewise.
-
-2000-09-13 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal-backend-file.c (remove_component): Only remove the pilot
- item from the hash if it exists in the first place.
-
-2000-09-12 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal-backend-file.c (add_component): plug leakage
-
-2000-09-12 JP Rosevear <jpr@helixcode.com>
-
- * conduits/calendar/calendar-conduit.c: Hack to compile for distcheck.
-
- * conduits/calendar/calendar-conduit.h: Remove calobj.h dependency
-
-2000-09-12 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal-backend-file.c (cal_backend_file_load): Use g_int_*
- for now
- (cal_backend_file_create): ditto
-
- * conduits/todo/todo-conduit.c (local_record_from_compobject): Make
- this actually fill in the todo record.
- (find_record_in_repository): Add debug stuff
- (iterate_specific): Use the already exisiting utility function
-
- * pcs/cal-backend-file.c (cal_backend_file_update_pilot_id): correct
- the status and id types. g_strdup the uid since this is not a
- constified return
- (cal_backend_file_get_uid_by_pilot_id): correct the id type
-
-2000-09-12 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/Makefile.am: Remove `ui.xml' stuff.
-
- * pcs/cal-backend.c: Dont' #include calobj.h anymore as it's gone.
-
-2000-09-12 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.c (gnome_calendar_construct): Connect to the
- "cal_loaded" signal of the client here.
- (connect_load): Removed function.
- (disconnect_load): Removed function.
- (cal_loaded_cb): Store the URI we are loading in the GnomeCal
- structure instead of in a weird closure. This gets rid of the
- connect/disconnect mess as well.
- (gnome_calendar_open): Store the URI in the GnomeCal.
-
-2000-09-11 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/e-day-view.c: Fixed a warning (removed unused variable
- gfloat width from e_day_view_get_event_position.)
-
-2000-09-11 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c: Handle renaming, header cleanup
-
- * conduits/todo/todo-conduit.h: Rename GCalLocalRecord to
- EToDoLocalRecord, header cleanup
-
-2000-09-11 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c (comp_from_remote_record): Use
- description list instead of comment list for pilot todo note
- (transmit): Check for null cal component properties, set priority
- correctly, use description list instead of comment list. Make
- pilot record private when appropriate.
-
-2000-09-10 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c (comp_from_remote_record): Only
- set the due date only if it exists
-
-2000-09-10 JP Rosevear <jpr@helixcode.com>
-
- * gui/calendar-model.c (get_is_complete): Relying on the status
- field is somewhat faulty since it is related to group scheduling
-
-2000-09-10 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c (update_calendar_entry_in_repository):
- Make log output a little more sensible
- (comp_from_remote_record): Minor correction when making a CalComponent
- from scratch.
- (update_record): Use comp_from_remote_record for new items, rather
- than repeating the code here.
-
-2000-09-10 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c: Remove catch_ret_val function
- since its no longer useful. Fix naming of various fields from
- the header changes. Use GnomePilotRecord* stuff instead of
- ICAL_PILOT_SYNC_*
- (e_todo_context_new): Rename from gcalconduit_new_context. Now takes
- a pilot id and loads the configuration here
- (e_todo_context_destroy): Rename from gcalconduit_destroy_context.
- Unref the client and destroy the configuration if they exist here
- (start_calendar_server): Change the default calendar name
- (local_record_from_comp_uid): Rename from local_record_from_ical_uid
- (local_record_from_compobject): Rename from
- local_record_from_icalobject. Properly do the pilot id and status.
- (comp_from_remote_record): Rename from ical_from_remote_record.
- Handle due, complete, classification and pilot stuff properly
- (pre_sync): Remove some old stuff. We need to figure out how to
- set some of the field values.
- (set_status): Reflect pilot status changes from above
- (conduit_destroy_gpilot_conduit): Remove cleanup stuff that is
- now done by e_todo_context_destroy
- (conduit_get_gpilot_conduit): Only set the context as object
- data of the conduit.
-
- * conduits/todo/todo-conduit.h: Rename GCalConduitContext to
- EToDoConduitContext. Remove some unused struct fields.
- For GCalLocalRecord, rename ical to comp.
-
-2000-09-11 Damon Chaplin <damon@helixcode.com>
-
- * gui/dialogs/task-editor.c: changed to use EDateEdit.
-
- * gui/dialogs/task-editor-dialog.glade: added "None" option to
- Classification option menu, and used custom widgets for the date
- entries so we can use EDateEdit widgets.
-
- * gui/event-editor.c: changed to use EDateEdit. Note that this needs
- to be fixed at some point to handle invalid dates, i.e. when
- e_date_edit_get_time returns -1.
-
- * gui/calendar-model.c (ensure_task_complete):
- (ensure_task_not_complete): new functions to set the related properties
- to make sure a task is marked as complete on not, i.e. "Date Completed"
- "Status" and "Percent" properties.
-
-2000-09-08 Damon Chaplin <damon@helixcode.com>
-
- * gui/calendar-model.c (get_is_complete): use the status field rather
- than the completed date, as it is more reliable.
- (get_is_overdue): use get_is_complete().
- (calendar_model_mark_task_complete): check if it is already complete,
- and if so don't update it.
-
- * cal-util/cal-component.c (cal_component_get_status):
- (cal_component_set_status): added functions to support the STATUS
- property. Also added the property to CalComponentPrivate and set it
- to NULL in free_icalcomponent(). Someone should check my code as I've
- mainly done a Cut & Paste job.
-
-2000-09-10 JP Rosevear <jpr@helixcode.com>
- * conduits/todo/todo-conduit.c: Convert "//" style comments
- (local_record_from_ical_uid): Remove iCalObject cruft
- (ical_from_remote_record): ditto
- (free_match): Properly unref the CalComponent
-
-2000-09-10 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c (local_record_from_icalobject): Use
- cal component pilot stuff properly
- (find_record_in_repository): Remove cruft
- (ical_from_remote_record): Remove cruft
- (update_record): Set the vtype immediately after creation. Remove cruft
-
- * conduits/todo/todo-conduit.h: Remove iCalObject stuff
-
- * conduits/todo/todo-conduit-config.h: Move all the config stuff
- here, I need to kill the warnings at some point
-
- * conduits/todo/todo-conduit-control-applet.c (doRevertSettings):
- Set all the state variables correctly on a revert
- (doSaveSettings): Update original state
- (doHelp): Rename from about_cb
- (main): Destroy configurations when done
-
- * conduits/todo/Makefile.am: Tidy
-
- * pcs/cal-backend-file.c (cbf_pilot_hash): Function for hashing
- pilot ids
- (cbf_pilot_equal): For hash table of pilot ids
- (cal_backend_file_destroy): Destroy pilot id hash
- (add_component): Insert the uid into the pilot hash
- (remove_component): Remove the uid from the pilot hash
- (cal_backend_file_load): Create the pilot hash
- (cal_backend_file_create): ditto
- (cal_backend_file_get_uid_by_pilot_id): Implement using the pilot hash
- (cal_backend_file_update_pilot_id): ditto
-
- * cal-util/cal-component.h: Update prototypes
-
- * cal-util/cal-component.c (cal_component_get_pilot_id): Implement
- using ical X properties
- (cal_component_set_pilot_id): ditto
- (cal_component_get_pilot_status): ditto
- (cal_component_set_pilot_status): ditto
- (cal_component_free_pilot_id): Free a pilot id
- (cal_component_free_pilot_status): Free a pilot status
-
-2000-09-09 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/dialogs/Makefile.am (INCLUDES): Add
- `-I$(top_builddir)/libical/src/libical' so that we get
- `icalversion.h' from the build directory instead of taking it from
- the installation directory, which is of course Wrong (tm).
- * gui/Makefile.am (INCLUDES): Likewise.
-
-2000-09-08 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.c (cal_loaded_cb): New function with the
- loading/creation state machine. It is carefully modelled after
- the state machine that started the Universe, so bow before it.
- (gnome_calendar_construct): Do not connect to cal_loaded here.
- (connect_load): The closure for the cal_loaded callback is a bit
- tricky, so provide a function to create it and connect to the
- signal.
- (disconnect_load): Disconnect from the signal and free the
- closure.
- (gnome_calendar_load_cb): Removed obsolete buggy function.
- (gnome_calendar_open): Use the new mechanism.
-
- * gui/control-factory.c (set_prop): The default filename is now
- calendar.ics.
-
-2000-09-08 JP Rosevear <jpr@helixcode.com>
-
- * conduits/calendar/calendar-conduit.c (transmit): Use
- icaltime_as_timet
-
-2000-09-08 Christopher James Lahey <clahey@helixcode.com>
-
- * cal-util/cal-recur.c, gui/e-day-view.c, gui/e-week-view.c,
- gui/event-editor.c, gui/getdate.y, gui/gncal-todo.c,
- gui/gnome-cal.c, gui/dialogs/task-editor.c: Fixed some warnings.
-
-2000-09-08 JP Rosevear <jpr@helixcode.com>
-
- * conduits/calendar/Makefile.am: Tidy
-
- * conduits/todo/Makefile.am: Tidy
-
-2000-09-08 Federico Mena Quintero <federico@helixcode.com>
-
- Fall equinox cleanup!
-
- OK, I know the equinox is not here yet, but weather has changed
- enough to warrant it.
-
- Sigh. This place is definitely not the tropics.
-
- * gui/gnome-cal.c (obj_updated_cb): Renamed from
- gnome_calendar_object_updated_cb(); fixed prototype.
- (obj_removed_cb): Renamed from gnome_calendar_object_removed_cb();
- fixed prototype.
- (GnomeCalendarPrivate): Moved all the GnomeCalendar fields to a
- private structure so I don't have to rebuild the whole calendar
- GUI directory every time something changes in the object.
- (GnomeCalendarPrivate): Removed the property bag and the control
- fields; they are local to the control-factory now.
- (gnome_calendar_update_view_buttons): Remove the
- ignore_view_button_clicks mess and just block the signal.
- (gnome_calendar_set_view): Added a "focus" argument to indicate
- whether we want the main widget in the specified view to grab the
- focus.
- (gnome_calendar_set_view_internal): Handle the focus argument here.
- (gnome_calendar_set_view_buttons): Temporary hack to notify the
- calendar about its buttons.
- (gnome_calendar_get_selected_time_range): New function.
- (gnome_calendar_get_cal_client): New function.
-
- * gui/control-factory.c (calendar_properties_init): Keep the
- property bag local to here; it does not need to be in the calendar
- object yet.
- (control_factory_fn): Renamed from control_factory(). Just use
- control_factory_new_control().
- (control_factory_new_control): Moved the stuff over from
- create_control(), and keep the control local to here. Check the
- return value of bonobo_control_new().
-
- * gui/calendar-commands.c (show_day_view_clicked): Remove the
- ignore_view_button_clicks mess.
- (new_calendar): Removed the useless "page" argument.
- (calendar_control_activate): Use gnome_calendar_set_view_buttons()
- for now.
-
-2000-09-07 Lauris Kaplinski <lauris@helixcode.com>
-
- * cal-client/Makefile.am: Added -lunicode
-
- * gui/dialogs/task-editor.c: More UTF-8 wrappers
- (priority_index_to_value): Kill warning, add assertion
-
-2000-09-06 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event):
- Use new cal_component_has_recurrences convenience function
-
- * gui/e-week-view.c (e_week_view_show_popup_menu): ditto
-
- * gui/e-week-view-event-item.c (e_week_view_event_item_draw_icons):
- ditto
-
- * gui/calendar-model.c (calendar_model_value_at): ditto
- (calendar_model_value_at): ditto
-
- * gui/e-day-view.c (e_day_view_on_event_click): ditto
- (e_day_view_on_event_right_click): ditto
- (e_day_view_on_top_canvas_motion): ditto
- (e_day_view_on_top_canvas_motion): ditto
- (e_day_view_on_main_canvas_motion): ditto
- (e_day_view_on_main_canvas_motion): ditto
- (e_day_view_reshape_day_event): ditto
-
- * gui/e-day-view-top-item.c (e_day_view_top_item_draw_long_event):
- ditto
-
- * gui/e-day-view.c (e_day_view_on_long_event_click): ditto
-
-2000-09-06 JP Rosevear <jpr@helixcode.com>
-
- * cal-util/cal-recur.c (cal_recur_generate_instances): Use
- new convenience functions and only get the recurrence
- stuff if needed. Free the recurrence stuff if used.
-
-2000-09-05 JP Rosevear <jpr@helixcode.com>
-
- * cal-util/cal-component.h: Add new prototypes
-
- * cal-util/cal-component.c (cal_component_has_exrules): Utility
- function to determine whether a cal component has any exrules
- (cal_component_has_exdates): Ditto for exdates
- (cal_component_has_exceptions): Utility function to determine
- whether a cal component has any exception rules
- (cal_component_has_recurrences):Utility function to determine
- whether a cal component has any recurrence rules
-
-2000-09-05 JP Rosevear <jpr@helixcode.com>
-
- * gui/event-editor.c (dialog_to_comp_object): Kill all exdates if
- there are no dates in the box
-
- * cal-util/cal-recur.c (generate_instances_for_year): Add a special
- case for when there are exceptions but no rrules or rdates.
- (cal_obj_remove_exceptions): Use date only compare func
- (cal_obj_date_only_compare_func): New compare function that
- compares the date only, not the time.
-
- * gui/event-editor.c (dialog_to_comp_object): Need a break for the
- yearly recurrence type
- (dialog_to_comp_object): We need to allocate icaltimetypes for the
- exdate list
- (fill_widgets): Handle a weekly recurrence with no particular day set
- (dialog_to_comp_object): Kill all rrules if "None" is selected as
- the recurrence type by the user
-
-2000-09-06 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-calendar-table.c (e_calendar_table_open_task): uses the new
- TaskEditor dialog.
-
- * gui/dialogs/task-editor.[hc]:
- * gui/dialogs/task-editor-dialog.glade: updated. Still need to fix the
- 'Status' property (CalComponent doesn't support it yet), and use a
- replacement for GnomeDateEdit, since we need to support setting 'None'
- as the date.
-
-2000-09-04 Damon Chaplin <damon@helixcode.com>
-
- * gui/event-editor.c (obj_updated_cb):
- (obj_removed_cb): compare the updated object's uid with the one we
- are editing, and just return if it doesn't match.
-
-2000-09-01 Damon Chaplin <damon@helixcode.com>
-
- * gui/gnome-cal.c (gnome_calendar_tag_calendar): added check to see
- if the client has loaded successfully. Gets rid of a few warnings.
-
-2000-09-05 JP Rosevear <jpr@helixcode.com>
-
- * cal-util/cal-recur.c (generate_instances_for_year): The exdate
- and rdate lists are a list of icaltimetypes, not CalComponentPeriods
-
- * gui/e-day-view.c (e_day_view_on_delete_occurrence): The exdate list
- is a list of icaltimetypes, not CalComponentDateTimes
-
-2000-09-05 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-day-view.c (e_day_view_on_delete_occurrence): Append
- the exdate to the list AFTER we create the date value.
-
-2000-09-05 JP Rosevear <jpr@helixcode.com>
-
- * cal-util/cal-component.c (cal_component_free_recur_list): Free
- the data, not the list element.
-
-2000-09-05 JP Rosevear <jpr@helixcode.com>
-
- * cal-util/cal-recur.c (cal_recur_generate_instances): Compute
- the event duration using the event start/end times, not the
- interval times.
-
-2000-09-05 JP Rosevear <jpr@helixcode.com>
-
- * cal-util/cal-recur.c (cal_recur_from_icalrecurrencetype): Check
- to see if r->enddate is (time_t)-1 and set to 0 if so
-
-2000-09-02 Ettore Perazzoli <ettore@helixcode.com>
-
- * conduits/calendar/Makefile.am (INCLUDES): Add libical include
- directories and `$(BONOBO_GNOME_CFLAGS)'.
- * conduits/todo/Makefile.am (INCLUDES): Likewise.
-
-2000-09-02 Lauris Kaplinski <lauris@helixcode.com>
-
- * gui/event-editor.c: e_utf8 wrappers
-
- * gui/gncal-todo.c: e_utf8_wrappers
-
-2000-09-02 Christopher James Lahey <clahey@helixcode.com>
-
- * conduits/calendar/calendar-conduit.c,
- conduits/todo/todo-conduit.c, gui/e-week-view.c, gui/gnome-cal.c:
- Fixed some warnings.
-
-2000-09-01 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.c (gnome_calendar_new): Use
- gnome_calendar_construct() so that we can check for proper
- creation of the client.
- (gnome_calendar_destroy): Check that the client exists before we
- unref it.
- (gnome_calendar_construct): Do the CalClient creation here. Bind
- the views to it here as well instead of in setup_widgets().
- (gnome_calendar_init): Call setup_widgets() here.
-
- * gui/e-calendar-table.c (e_calendar_table_destroy): Unref the
- model.
-
-2000-09-01 JP Rosevear <jpr@helixcode.com>
-
- * conduits/todo/todo-conduit.c: Update for new libical.
- Conduits should atleast compile now.
-
- * conduits/calendar/calendar-conduit.c: ditto
-
- * Makefile.am: Build the conduits only when they've been
- enabled.
-
-2000-09-01 JP Rosevear <jpr@helixcode.com>
-
- * gui/event-editor.c: Make toolbar save and close button.
- We should put a similar menu option in sometime.
-
-2000-08-31 JP Rosevear <jpr@helixcode.com>
-
- * cal-util/cal-recur.c (array_to_list): Use
- ICAL_RECURRENCE_ARRAY_MAX instead of MAX_SHORT
-
-2000-08-31 JP Rosevear <jpr@helixcode.com>
-
- * gui/event-editor.c (file_delete_cb): Implement delete option
- (dialog_to_comp_object): Set the weekday start value and use
- local not UTC time
-
-2000-08-31 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (file_delete_cb): No need to spit a warning
- if removal fails.
- (event_editor_destroy): Free the exception clist data. Unref the
- calendar client here.
- (close_dialog): Just call gtk_object_destroy() on the event
- editor; the destroy handler will free everything else.
-
- * cal-client/cal-client.c (cal_client_object_exists): Removed
- function; this is not useful because we operate asynchronously.
-
- * gui/e-day-view.c (e_day_view_on_delete_appointment): No need to
- spit a warning if removal fails.
-
- * gui/e-week-view.c (e_week_view_on_delete_appointment): Likewise.
-
- * gui/calendar-model.c (calendar_model_delete_task): Likewise.
-
-2000-08-31 JP Rosevear <jpr@helixcode.com>
-
- * gui/event-editor.c (file_delete_cb): Implement delete option
- (recurrence_toggled): Make an ugly hack to get the recurrence
- pages showing properly since we don't yet implement all of the
- recurrence rule stuff.
-
- * cal-client/cal-client.c (cal_client_object_exists): New function
- to see if an object exists and is obtainable from the backend
-
- * cal-client/cal-client.h: Add prototype
-
-2000-08-31 JP Rosevear <jpr@helixcode.com>
-
- * gui/gnome-cal.c (editor_closed_cb): Event editor destroyed
- callback to do hash cleanup
- (gnome_calendar_edit_object): Set event editor calendar client.
-
- * gui/event-editor.h: Add new prototype
-
- * gui/event-editor.c: Trash signal stuff. We will manipulate
- the client directly. Make the toolbar save and menu save items
- work identically. Add icons to the toolbar.
- (save_event_object): Call cal_client_update_object
- (close_dialog): Unref the client and disconnect signals
- Actually destroy the event editor object.
- (obj_updated_cb): New function. Doesn't really do anything
- yet but it will inform the user the event has changed elsewhere
- in the future.
- (obj_removed_cb): ditto
- (event_editor_set_cal_client): New function to set the calendar
- client
-
- * gui/gnome-cal.c (gnome_calendar_new_appointment): Commit
- the sequence to the cal component and use non UTC times.
-
-2000-08-30 Lauris Kaplinski <lauris@helixcode.com>
-
- * gui/print.c: Countless small changes for gnome-print 0.21+
-
-2000-08-30 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-day-view.[hc]:
- * gui/e-day-view-main-item.c:
- * gui/e-week-view.[hc]:
- * gui/e-week-view-main-item.c:
- * gui/calendar-commands.c:
- * gui/gnome-cal.[hc]: switched to using new ECalendar widget,
- and a few other fixes.
-
-2000-08-30 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.h (GnomeCal): Removed unused field event_editor.
-
- * gui/e-day-view.c (e_day_view_key_press): Oops, set the
- dtstart/dtend on the component before adding it.
- (e_day_view_on_editing_stopped): No need to check for an UID.
- Update the summary properly.
-
-2000-08-30 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-week-view.c: Make sure the is_utc flag is always
- FALSE for icaltime_from_timet
- (e_week_view_on_unrecur_appointment): Use icaltimetype struct
- from the stack and make sure tzid is always NULL
- (e_week_view_key_press): ditto
-
-2000-08-30 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-day-view.c: Make sure the is_utc flag is always
- FALSE for icaltime_from_timet
- (e_day_view_on_unrecur_appointment): Use icaltimetype struct
- from the stack and make sure tzid is always NULL
- (e_day_view_finish_long_event_resize): ditto
- (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
-
-2000-08-30 JP Rosevear <jpr@helixcode.com>
-
- * cal-client/cal-client.c (add_instance): Actually add the
- comp_instance struct to the instances list. We now appear
- to able to keep events and todos between sessions. Yay!
-
-2000-08-29 Federico Mena Quintero <federico@helixcode.com>
-
- Now the views monitor the client by themselves; it does not make
- sense to proxy all notifications through the GnomeCal. The
- GnomeCal should just be a meta-widget that holds all the views.
-
- At some later point we'll want to decouple the views from the
- GnomeCal so that they can be embedded anywhere; they should emit
- signals to request appropriate actions from the toplevel GUI
- instead of calling the GnomeCal directly.
-
- * gui/e-day-view.c (e_day_view_set_cal_client): New function; now
- the day view monitors the client by itself.
- (cal_loaded_cb): New callback; moved over from
- e_day_view_update_all_events().
- (obj_updated_cb): New callback; moved over from
- e_day_view_update_event().
- (obj_removed_cb): New callback; moved over from
- e_day_view_remove_event().
- (e_day_view_update_all_events): Removed function.
- (e_day_view_update_event): Removed function.
- (e_day_view_remove_event): Removed function.
- (*): Use the day_view->client directly instead of fetching it from
- the GnomeCal.
- (e_day_view_destroy): Unref the client.
- (e_day_view_reload_events): Check if the client is loaded.
- (e_day_view_key_press): Set the vtype of the new component.
-
- * gui/e-week-view.c (e_week_view_set_cal_client): New function.
- (cal_loaded_cb): New callback.
- (obj_updated_cb): New callback.
- (obj_removed_cb): New callback.
- (e_week_view_update_all_events): Removed function.
- (e_week_view_update_event): Removed function.
- (e_week_view_remove_event): Removed function.
- (*): Use the week_view->client directly.
- (e_week_view_destroy): Unref the client.
- (e_week_view_reload_events): Check if the client is loaded.
-
- * gui/gnome-cal.c (setup_widgets): Set the cal_client on all the
- views.
- (gnome_calendar_update_all): Do not update the views, since now
- they do it themselves.
- (gnome_calendar_object_updated_cb): Likewise.
- (gnome_calendar_object_removed_cb): Likewise.
- (setup_widgets): Remove all to-do list cruft.
- (gnome_calendar_colors_changed): Likewise.
- (gnome_calendar_todo_properties_changed): Likewise.
-
- * gui/calendar-commands.h (todo_style_changed): Removed variable.
-
- * gui/gncal-todo.c: Removed old clist cruft; just left in the
- temporary dialog box for now.
-
-2000-08-29 Dan Winship <danw@helixcode.com>
-
- * cal-client/client-test.c:
- * cal-client/cal-client.c:
- * conduits/todo/todo-conduit.h:
- * conduits/calendar/calendar-conduit.h: remove USING_OAF checks.
-
-2000-08-29 JP Rosevear <jpr@helixcode.com>
-
- * gui/gnome-cal.c (gnome_calendar_edit_object): Use
- event_editor_set_event_object
-
- * gui/event-editor.c (event_editor_set_event_object): Rename
- from event_editor_set_ical_object
-
- * gui/event-editor.h: Update prototype
-
- * gui/e-week-view.c (e_week_view_on_new_appointment):
- Call cal_component_commit_sequence after event changes. Default
- to these being all day events.
-
-2000-08-29 JP Rosevear <jpr@helixcode.com>
-
- * gui/event-editor.c (dialog_to_comp_object): These are not UTC
- times
-
-2000-08-28 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-client/cal-client.c (cal_client_is_loaded): New function.
- We need this from code that dynamically updates from a client and
- could not have connected to the "cal_loaded" signal right after
- the client was created.
-
- * gui/calendar-model.c (load_objects): Do not try to load the
- objects if the client has not been loaded yet.
- (cal_loaded_cb): Check the status value.
-
- * gui/calendar-model.h (CalendarModel): Declare the private
- structure here so that gdb will give me love.
-
- * pcs/cal-factory.h (CalFactory): Likewise.
-
- * pcs/cal.h (Cal): Likewise.
-
- * cal-client/cal-listener.h (CalListener): Likewise.
-
- * cal-client/cal-client.h (CalClient): Likewise.
-
- * pcs/cal-backend.h (CalBackend): This no longer has a private
- structure, so remove it.
-
- * cal-util/Makefile.am (libcal_util_la_SOURCES): Removed the
- vCalendar and old iCalendar cruft.
- (libcal_utilinclude_HEADERS): Likewise.
- Removed the obsolete iCalendar test program.
-
-2000-08-28 JP Rosevear <jpr@helixcode.com>
-
- * cal-util/timeutil.h: We no longer need time_from_icaltimetype
- as libical has the API for this
-
- * cal-util/timeutil.c: ditto
-
- * cal-util/cal-recur.c: Replace time_from_icaltimetype with
- icaltime_as_timet
-
- * gui/calendar-model.c: ditto
-
- * gui/event-editor.c: ditto
-
- * gui/gnome-cal.c: ditto
-
-2000-08-28 Federico Mena Quintero <federico@helixcode.com>
-
- * pcs/cal-backend-file.c (remove_component): Remove the
- icalcomponent from the toplevel calendar here.
- (cal_backend_file_update_object): Do not remove it here.
- (cal_backend_file_remove_object): Do not remove it here.
- (add_component): Add the icalcomponent to the toplevel calendar if
- asked to.
- (cal_backend_file_update_object): Do not add it here.
-
-2000-08-28 JP Rosevear <jpr@helixcode.com>
-
- * gui/event-editor.c (dialog_to_comp_object): Initiliaze tzid to
- null, only set recurrence rules and exception dates if there
- are any
-
-2000-08-27 JP Rosevear <jpr@helixcode.com>
-
- * pcs/cal-backend-file.c (save): Write out the calendar object
- (cal_backend_file_update_object): Remove/add the icalcomponent
- from our master icalcomponent (the calendar)
- (cal_backend_file_remove_object): Remove the icalcomponent
- from our master icalcomponent
-
-2000-08-26 JP Rosevear <jpr@helixcode.com>
-
- * gui/Makefile.am: Remove gnorba stuff
-
- * gui/main.c: ditto
-
- * gui/component-factory.c: ditto
-
- * gui/control-factory.c: ditto
-
- * gui/*.gnorba: ditto
-
-2000-08-25 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-calendar-table.c (e_calendar_table_init): Uncomment
- debug code.
-
- * gui/calendar-model.c (set_complete): Set the completed
- date to the current date
- (calendar_model_set_value_at): Handle complete field
-
-2000-08-25 JP Rosevear <jpr@helixcode.com>
-
- * gui/calendar-model.c (get_is_complete): Don't attempt to
- free this if its null
- (calendar_model_duplicate_value): Implement for summary field
- value
- (calendar_model_initialize_value): Remove debug code
-
- * gui/e-calendar-table.c: Correct etable init xml
- (create_column): Pass the id to e_table_header_add_column
- rather than a hard coded one
- (e_calendar_table_init): Make sure summary column isn't
- added twice. Add an alarms column, else etable won't
- work with columns who have an ID higher than that
-
-2000-08-24 JP Rosevear <jpr@helixcode.com>
-
- * gui/gncal-todo.c (ok_button): Properly append to list
-
- * gui/event-editor.c (dialog_to_comp_object): ditto
-
- * gui/e-day-view.c (e_day_view_on_new_appointment): The base
- times are not UTC
-
- * gui/e-week-view.c (e_week_view_on_new_appointment): ditto
-
-2000-08-24 JP Rosevear <jpr@helixcode.com>
-
- * Update for libical 0.19
-
-2000-08-24 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/calendar-commands.c, gui/e-day-view.c, gui/e-week-view.c,
- gui/event-editor.c, gui/gncal-todo.c, gui/gnome-cal.c, gui/prop.c:
- Fixed some warnings.
-
-2000-08-24 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-week-view.c (e_week_view_on_new_appointment): Do not alloc
- the struct icaltimetype but point to one on the stack. More
- importantly, set the date.tzid to NULL.
-
-2000-08-24 JP Rosevear <jpr@helixcode.com>
-
- * gui/gnome-cal.c (save_event_object_cb): Make signal
- names saner
- (released_event_object_cb): ditto
- (gnome_calendar_edit_object): ditto
-
- * gui/event-editor.h: Make signal names saner
-
- * gui/event-editor.c (event_editor_class_init): Make signal
- names saner now that we don't use ical object
- (save_event_object): ditto with callback names
- (file_save_cb): ditto
- (tb_save_and_close_cb): ditto
- (event_editor_set_ical_object): ditto
-
- * gui/e-day-view.c (e_day_view_update_event): Umm,
- != CAL_COMPONENT_EVENT (I hope that wasn't me!)
-
-2000-08-24 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/e-day-view.c (e_day_view_on_new_appointment): Do not alloc
- the struct icaltimetype but point to one on the stack. More
- importantly, set the date.tzid to NULL.
-
-2000-08-24 JP Rosevear <jpr@helixcode.com>
-
- * gui/event-editor-dialog.glade: Remove owner field
-
- * gui/event-editor.c (clear_widgets): Forget about owner field
- (get_widgets): ditto
- (fill_widgets): ditto
-
-2000-08-24 JP Rosevear <jpr@helixcode.com>
-
- * gui/calendar-model.c (calendar_model_initialize_value): Handle
- summary field
- (calendar_model_value_is_empty): ditto
- (calendar_model_free_value): ditto
-
-2000-08-23 JP Rosevear <jpr@helixcode.com>
-
- * gui/event-editor-dialog.glade: Remove status bar
-
- * cal-util/cal-component.c (cal_component_set_rrule_list): Allow
- a null list
- (cal_component_set_rdate_list): Allow a null list
-
- * gui/e-day-view.c (e_day_view_on_new_appointment): Commit
- the CalComponent sequence
-
-2000-08-23 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/main.c: #include <e-util/e-cursors.h>
-
- * gui/e-day-view-time-item.c (e_day_view_time_item_draw):
- Initialize time_min_x1 and hour_r to keep gcc happy.
-
- * gui/e-day-view.c (e_day_view_update_event_label): Warning fix.
- (e_day_view_update_main_canvas_drag): Initialize start_row.
-
- * gui/e-week-view-event-item.c (e_week_view_event_item_draw):
- Initialize time_y_small_min, icon_x.
-
- * Makefile.am (SUBDIRS): Re-enable the gui directory.
-
- * gui/prop.c (prop_store_alarm_default_values): Temporarily #if 0
- out.
-
-2000-08-23 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-week-view.c (e_week_view_key_press): Set vtype of new
- CalComponent
- (e_week_view_on_new_appointment): ditto
-
- * gui/e-day-view.c (e_day_view_on_new_appointment): ditto
-
-2000-08-23 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-day-view-time-item.c: Include gnome.h for gettext purposes
-
- * gui/gnome-cal.c: ditto
-
- * gui/prop.c: #if out some alarm stuff
-
-2000-08-23 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/e-calendar-table.c (e_calendar_table_init): Updated
- function.
- (e_calendar_table_open_task): Updated function.
-
-2000-08-21 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-model.c (calendar_model_duplicate_value): Updated
- function.
- (calendar_model_free_value): Updated function.
- (calendar_model_initialize_value): Updated function.
- (calendar_model_value_is_empty): Updated function.
- (remove_object): Updated function.
- (obj_updated_cb): Updated function.
- (calendar_model_get_cal_client): Added inline docs.
- (calendar_model_delete_task): Updated.
- (calendar_model_mark_task_complete): Updated.
- (calendar_model_get_cal_object): Updated.
-
-2000-08-21 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-model.c (set_categories): New function.
- (parse_time): Moved over from the old set_time_t(). This just
- parses the time and leaves the warning dialog for the caller.
- (set_datetime): New function.
- (set_geo): Updated old function.
- (set_percent): Updated old function.
- (set_priority): Updated old function.
- (set_summary): New function.
- (set_url): New function.
- (calendar_model_set_value_at): Updated function.
- (calendar_model_is_cell_editable): Updated function.
- (calendar_model_append_row): Updated. Added an ugly hack to
- accomodate ETable's lack of a real API for adding new items.
- Also, don't try to set columns that are not editable.
-
-2000-08-21 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-week-view.c (e_week_view_reload_events):
- Use CalObjType
-
- * gui/e-day-view.c (e_day_view_reload_events): ditto
-
-2000-08-21 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-day-view-main-item.c (e_day_view_main_item_draw_day_event):
- Use CalComponent instead of iCalObject. #if some alarm stuff
-
-2000-08-21 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-day-view-top-item.c (e_day_view_top_draw_long_event):
- Use CalComponent instead of iCalObject. #if some alarm stuff
-
-2000-08-21 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-day-view.h: Update prototypes
-
- * gui/e-day-view.c (e_day_view_on_unrecur_appointment):
- Remove commented out portions.
-
- * gui/e-week-view.c (e_week_view_on_unrecur_appointment):
- Tidy.
-
-2000-08-21 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-day-view.c
- (e_day_view_update_event): Use CalComponent
- instead of iCalObject. Work around not having a compare
- dates routine for two CalComponents.
- (e_day_view_reshape_long_event): Use CalComponent instead
- of iCalObject, #if some alarm stuff
- (e_day_view_reshape_day_event): ditto
- (e_day_view_reload_events): Use revamped CalClient
- (e_day_view_update_event_cb): Use CalComponent
- instead of iCalObject
- (e_day_view_foreach_event_with_uid): ditto
- (e_day_view_remove_event_cb): ditto
- (e_day_view_update_event_label): ditto
- (e_day_view_find_event_from_uid): ditto
- (e_day_view_on_event_click): ditto
- (e_day_view_on_event_right_click): ditto
- (e_day_view_on_new_appointment): ditto
- (e_day_view_on_edit_appointment): ditto
- (e_day_view_on_delete_occurrence): ditto
- (e_day_view_on_delete_appointment): ditto
- (e_day_view_on_unrecur_appointment): ditto
- (e_day_view_on_top_canvas_motion): ditto
- (e_day_view_on_main_canvas_motion): ditto
- (e_day_view_finish_long_event_resize): ditto
- (e_day_view_finish_resize): ditto
- (e_day_view_free_event_array): ditto
- (e_day_view_add_event): ditto
- (e_day_view_key_press): ditto
- (e_day_view_on_editing_stopped): ditto
- (e_day_view_update_top_canvas_drag): ditto
- (e_day_view_update_main_canvas_drag): ditto
- (e_day_view_on_drag_data_get): ditto
- (e_day_view_on_top_canvas_drag_data_received): ditto
- (e_day_view_on_main_canvas_drag_data_received): ditto
-
-2000-08-20 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-week-view-event-item.c (e_week_view_event_item_draw_icons):
- Use CalComponent instead of iCalObject. #if some alarm stuff
-
-2000-08-20 JP Rosevear <jpr@helixcode.com>
-
- * gui/e-week-view.c (e_week_view_update_event): Use CalComponent
- instead of iCalObject. Work around not having a compare
- dates routine for two CalComponents.
- (e_week_view_reload_events): Use revamped CalClient
- (e_week_view_reshape_event_span): Use CalComponent instead
- of iCalObject, #if some alarm stuff
- (e_week_view_update_event_cb): Use CalComponent instead of
- iCalObject
- (e_week_view_foreach_event_with_uid): ditto
- (e_week_view_remove_event_cb): ditto
- (e_week_view_free_events): ditto
- (e_week_view_add_event): ditto
- (e_week_view_on_editing_stopped): ditto
- (e_week_view_find_event_from_uid): ditto
- (e_week_view_key_press): ditto
- (e_week_view_show_popup_menu): ditto
- (e_week_view_on_new_appointment): ditto
- (e_week_view_on_edit_appointment): ditto
- (e_week_view_on_delete_occurrence): ditto
- (e_week_view_on_delete_appointment): ditto
- (e_week_view_on_unrecur_appointment): ditto
-
- * gui/e-week-view.h: Update prototypes.
-
-2000-08-18 JP Rosevear <jpr@helixcode.com>
-
- * gui/event-editor.h: Update prototypes.
-
- * gui/event-editor.c: Need to come back here later to fix the
- alarm stuff. The gui also needs to be completely redone to
- support the fancier CalComponent settings (exrules, rdates, etc)
- There are some warnings that I put in to mark some of these
- spots
- (event_editor_destroy): Use Calcomponent instead
- of iCalObject
- (make_title_from_comp): ditto
- (clear_widgets): ditto
- (fill_widgets): ditto
- (classification_get): ditto
- (dialog_to_comp_object): ditto
- (save_ical_object): ditto
- (close_dialog): ditto
- (event_editor_set_ical_object): ditto
-
-2000-08-17 JP Rosevear <jpr@helixcode.com>
-
- * gui/gncal-todo.c (ok_button): Use CalComponent instead of
- iCalObject
- (cancel_button): ditto
- (gncal_todo_edit): ditto
- (add_todo): ditto
- (edit_todo): ditto
- (delete_todo): ditto
- (insert_in_clist): ditto
- (gncal_todo_update): ditto
-
- * gui/gncal-todo.h: Update prototypes
-
-2000-08-16 JP Rosevear <jpr@helixcode.com>
-
- Rework gnome-cal.c - alarms are a tad broken ATM so this
- will need more cleaning later.
-
- * gui/gnome-cal.c (snooze): Use CalComponent instead of
- iCalObject
- (edit): ditto
- (audio_notification): ditto
- (display_notification_cb): Use CalComponent member of
- alarm_notify_closure rather than iCalObject
- (display_notification): ditto
- (trigger_alarm_cb): ditto. Use CalComponent alarm types
- (gnome_calendar_tag_calendar_cb): New
- cal_client_generate_instances callback to
- mark_gtk_calendar_day's
- (gnome_calendar_tag_calendar): Use above callback
- (save_ical_object_cb): Use CalComponent instead of
- iCalObject
- (gnome_calendar_edit_object): ditto
- (gnome_calendar_new_appointment): ditto
-
-2000-08-15 JP Rosevear <jpr@helixcode.com>
-
- * gui/mark.c (mark_month_item_cb): Callback used to mark every
- event in a month.
- (mark_month_item): Use cal_client_generate_instances with
- above callback
-
-2000-08-15 JP Rosevear <jpr@helixcode.com>
-
- * gui/print.c (print_month_small): Use
- cal_client_get_objects_in_range
- (print_day_details_cb): Callback used to create columns and fill
- events into a day view. Code should be shared with e-day-view
- in reality. Maybe need to go back to layout.[hc] a bit later
- (print_day_details): Use cal_client_generate_instances with
- above callback. Iterate over results to expand events to fit.
- (print_day_summary_cb): Callback to build list of event info
- for a day
- (print_day_summary): Use cal_client_generate_instances with
- above callback to generate the required event info for printing
- (print_todo_details_cb): Callback used create list of todo info
- (print_todo_details): Use cal_client_generate_instances with
- above callback to generate required todo info for printing.
-
- * gui/layout.[hc]: No longer used.
-
-2000-08-12 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-model.c (get_is_overdue): Finished implementing.
- (calendar_model_value_at): Handle the color field.
-
-2000-08-11 Seth Alves <alves@hungry.com>
-
- * cal-util/cal-component.c (cal_component_get_pilot_id):
- (cal_component_set_pilot_id): stubs for pilot id accessors
- (cal_component_get_pilot_status):
- (cal_component_set_pilot_status): stubs for pilot status accessors
-
- * conduits/calendar/calendar-conduit.c (transmit): start to
- convert to cal-component interface
-
- * conduits/todo/todo-conduit.c (transmit): same
-
-2000-08-11 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-model.c (get_geo): Generate a prettier string for
- the geographical position.
- (get_classification): New function.
- (get_categories): New function.
- (get_completed): New function.
- (get_dtend): New function.
- (get_dtstart): New function.
- (get_due): New function.
- (get_percent): New function.
- (get_priority): New function.
- (get_summary): New function.
- (get_transparency): New function.
- (get_url): New function.
- (get_has_alarms): New function.
- (get_has_recurrences): New function.
- (get_is_complete): New function.
- (get_is_overdue): New function.
-
- * cal-util/cal-component.c (scan_property): Handle the GEO
- property.
- (free_icalcomponent): Likewise.
- (cal_component_get_geo): Likewise.
- (cal_component_set_geo): Likewise.
- (cal_component_free_geo): Likewise.
- (cal_component_set_exdate_list): Removed incorrect assertion.
- (cal_component_set_exrule_list): Removed incorrect assertion.
- (cal_component_get_next_alarm): Oops, this had not been
- implemented at all.
- (cal_component_has_rdates): New function.
- (cal_component_has_rrules): New function.
-
- * cal-util/cal-component.h (CalComponentField): Added the GEO
- property.
-
-2000-08-11 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (scan_property): Handle the
- PERCENT-COMPLETE property.
- (free_icalcomponent): Likewise.
- (cal_component_get_percent): Likewise.
- (cal_component_set_percent): Likewise.
- (cal_component_free_percent): Likewise.
- (scan_property): Handle the PRIORITY property.
- (free_icalcomponent): Likewise.
- (cal_component_get_priority): Likewise.
- (cal_component_set_priority): Likewise.
- (cal_component_free_priority): Likewise.
-
- * cal-util/cal-component.h (CalComponentField): New enumeration
- with the list of fields we support for ETable.
-
-2000-08-10 Dan Winship <danw@helixcode.com>
-
- * gui/component-factory.c (owner_set_cb): Update prototype.
-
-2000-08-10 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.c (gnome_calendar_new_appointment): New function.
- Mostly moved over from calendar-commands.c:display_objedit().
-
- * gui/calendar-commands.c (calendar_iterate): Removed. Wheee!
- (display_objedit): Removed.
- (new_appointment_cb): New function. Just call
- gnome_calendar_new_appointment().
- (display_objedit_today): Removed.
- (calendar_control_activate): Removed the "New appointment for
- today" option, since it is pretty useless.
-
-2000-08-10 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-client/cal-client.c (cal_client_generate_instances): There.
- A pretty function to generate recurrence instances atomically so
- that clients don't have to jump through hoops. Now we can get rid
- of the ugly calendar_iterate() function.
-
-2000-08-09 Cody Russell <bratsche@gnome.org>
-
- * gui/calendar-commands.c: Make the toolbar honor the user's
- gnomecc settings for detachable toolbars.
-
-2000-08-09 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/alarm.c (pop_alarm): Oops, subtract the new alarm's trigger
- time from the current time.
-
-2000-08-09 Christopher James Lahey <clahey@helixcode.com>
-
- * cal-client/cal-client.c: Fixed a warning.
-
-2000-08-09 Christopher James Lahey <clahey@helixcode.com>
-
- * cal-client/cal-client.c, gui/e-calendar-table.c, pcs/cal.c:
- Fixed some warnings.
-
-2000-08-08 Federico Mena Quintero <federico@helixcode.com>
-
- * idl/evolution-calendar.idl (Cal): Added a get_objects_in_range()
- method. Takes in a time range and the type of component we are
- interested in; returns a list of UIDs. The idea is that
- ocurrences get computed in the client; we can have multiple
- recurrences in iCalendar and we cannot identify them trivially
- across the wire.
- (Cal): Removed the get_events_in_range() method.
-
- * pcs/cal-backend.c (cal_backend_free_uid_list): New function.
- (cal_backend_get_objects_in_range): New function.
- (cal_backend_get_events_in_range): Removed.
-
- * pcs/cal-backend-file.c (cal_backend_file_get_objects_in_range):
- Implemented new method.
- (cal_backend_file_get_events_in_range): Removed.
-
- * pcs/cal.c (Cal_get_events_in_range): Removed.
- (uncorba_obj_type): New function.
- (Cal_get_uids): Use uncorba_obj_type().
- (Cal_get_n_objects): Likewise.
- (Cal_get_objects_in_range): Implemented new method.
-
- * cal-client/cal-client.c (cal_client_get_events_in_range): Removed.
- (cal_client_get_objects_in_range): Implemented.
- (corba_obj_type): New function.
- (cal_client_get_n_objects): Use corba_obj_type().
- (cal_client_get_uids): Likewise.
-
-2000-08-07 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (cal_component_clone): New function.
- (cal_component_get_icalcomponent): Ensure that the SEQUENCE
- property does not need incrementing.
-
- * gui/dialogs/alarm-notify-dialog.c (alarm_notify_dialog): Use
- CalComponent. Deal with an empty summary property.
-
-2000-08-07 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (cal_component_get_as_string): Doh,
- libical owns the string's memory, so do not free it.
-
- * cal-client/client-test.c (create_client): Connect to the destroy
- signal of the client here.
-
- * cal-client/test.ics: New test file, modified from Eric Busboom's
- test file from RFC 2445.
-
-2000-08-05 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-client/client-test.c (dump_component): This was gone for
- some reason.
- (main): Load a new test file.
-
-2000-08-04 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (cal_component_commit_sequence): New
- function to commit changes to the SEQUENCE property.
- (cal_component_get_as_string): Ensure that the sequence has been
- committed.
-
- * cal-client/cal-client.c (cal_client_get_object): Use
- CalComponent instead of the old iCalObject.
- (cal_client_update_object): Use iCalObject. Commit the SEQUENCE
- property before stringifying the object and piping it over to the
- Wombat.
-
-2000-08-04 Seth Alves <alves@hungry.com>
-
- * conduits/todo/todo-conduit.c (conduit_get_gpilot_conduit): if
- oaf isn't initialized by the time the conduit starts, start it
- up. we do this because we need to start wombat with oaf, and
- gpilotd doesn't currently start oaf.
-
-2000-08-04 Michael Meeks <michael@helixcode.com>
-
- * gui/calendar-commands.c (calendar_control_activate): unref.
-
-2000-08-02 Federico Mena Quintero <federico@helixcode.com>
-
- * pcs/cal-backend-file.c (cal_backend_file_get_uid_by_pilot_id):
- Added stub for now.
- (cal_backend_file_update_pilot_id): Likewise.
-
- * pcs/Makefile.am (libpcs_a_SOURCES): Removed cal-backend-imc.[ch]
- from the list of sources. The idea is to move vCalendar importing
- to the GUI as a convenience function.
-
-2000-08-02 Seth Alves <alves@hungry.com>
-
- * pcs/cal-backend-imc.c (cal_backend_imc_update_pilot_id): call
- save (cbimc) after setting the pilot id and status.
-
-2000-08-02 Joe Shaw <joe@helixcode.com>
-
- * pcs/cal-backend-file.c (cal_backend_file_update_pilot_id):
- Fixed a g_return_if_fail that had two parameters and thus
- wouldn't build.
-
-2000-08-03 Damon Chaplin <damon@helixcode.com>
-
- * gui/calendar-model.c (calendar_model_append_row): updated to match
- the new ETableModel append_row. This meant we could also get rid of
- the row_being_added and idle_id hack.
-
-2000-08-02 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/calendar-model.c: Emit "model_pre_change" signals as
- appropriate.
-
-2000-08-02 Federico Mena Quintero <federico@helixcode.com>
-
- * pcs/cal-backend-file.[ch]: New files for the iCalendar file
- backend.
-
- * pcs/Makefile.am (libpcs_a_SOURCES): Added cal-backend-file.[ch].
-
- * cal-util/cal-component.c (cal_component_set_icalcomponent):
- Return an operation success code for if we are passed a component
- of a type we don't support.
-
-2000-07-31 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-recur.c (*): Use CalComponent and the new property
- types instead of the old iCalObject stuff.
- (cal_recur_generate_instances): Renamed from
- cal_object_generate_events(). Ensure that the component has the
- DTSTART property.
- (generate_instances_for_year): Renamed from
- cal_object_generate_events_for_year().
- (cal_obj_expand_recurrence): Made static.
- (cal_recur_from_icalrecurrencetype): New function. We should
- really convert this whole file to use struct icalrecurrencetype
- instead.
- (cal_recur_free): New function.
-
- * cal-util/cal-recur.h (CalRecurType): Renamed from CalObjRecurType.
- (CalRecurrence): Renamed from CalObjRecurrence.
-
- * cal-util/timeutil.c (time_from_icaltimetype): New function.
-
- * cal-util/Makefile.am: Commented out the test-recur program.
-
-2000-08-01 Damon Chaplin <damon@helixcode.com>
-
- * Removed doc directory, since it is the old gnome-pim docs which
- aren't used any more.
-
- * Makefile.am (SUBDIRS): removed doc.
-
-2000-07-26 Peter Williams <peterw@helixcode.com>
-
- * gui/calendar-model.c: compile fix for Solaris
- (works under Linux, too; don't know about others)
-
- * this is a test of whether CVS merge does what I
- think it will do.
-
-2000-07-26 Federico Mena Quintero <federico@helixcode.com>
-
- OK, it seems that we have all the interesting properties for
- single-user calendars now. RFC 2445 can bite me.
-
- * cal-util/cal-component.c (scan_property): Handle the RRULE
- property. Yay!.
- (scan_recur): Likewise, yow!
- (get_recur_list): Likewise, yeehaw!
- (get_recur_list): Likewise, honk honk!
- (set_recur_list): Likewise, booooga booooga!
- (cal_component_get_rrule_list): Likewise, squeek squeek!
- (cal_component_set_rrule_list): That's it, I ran out of sounds.
- (cal_component_free_recur_list): Likewise.
- (scan_property): Handle the EXRULE property.
- (free_icalcomponent): Likewise.
- (cal_component_get_exrule_list): Likewise.
- (cal_component_set_exrule_list): Likewise.
- (set_period_list): Oops, free the old properties as well as
- removing them.
- (set_text_list): Ditto.
- (cal_component_set_exdate_list): Ditto.
-
- * cal-util/cal-component.c: Put all the functions used to free
- returned values all together.
- (cal_component_set_rdate_list): Oops, mark SEQUENCE property to be
- incremented since the RFC requires it.
- (scan_property): Handle the EXDATE property.
- (scan_exdate): Likewise.
- (free_icalcomponent): Likewise.
- (cal_component_get_exdate_list): Likewise.
- (cal_component_set_exdate_list): Likewise.
- (cal_component_free_exdate_list): Likewise.
-
-2000-07-26 Jeffrey Stedfast <fejj@helixcode.com>
-
- * gui/Makefile.am: Fixed a typo
-
-2000-07-26 Jeffrey Stedfast <fejj@helixcode.com>
-
- * gui/Makefile.am: Added a few xpm files to the EXTRA DIST section
-
-2000-07-25 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (cal_component_free_period_list): New function.
- (scan_property): Handle the RDATE property.
- (scan_period): Likewise.
- (free_icalcomponent): Likewise.
- (get_period_list): Likewise.
- (set_period_list): Likewise.
- (cal_component_get_rdate_list): Likewise.
- (cal_component_set_rdate_list): Likewise.
- (scan_text): Simplify a bit since we only handle the ALTREP
- parameter; there is no need to iterate over all parameters.
- (scan_datetime): Simplify; just handle the TZID parameter.
- (scan_summary): Simplify; just handle the ALTREP parameter.
- (cal_component_get_as_string): New function.
-
- * idl/evolution-calendar.idl (CalObjType): Removed the TYPE_OTHER;
- now we only expose the types of objects we know about.
-
- * cal-util/cal-util.h (CalObjType): Likewise.
-
- * cal-client/cal-client.c (cal_client_get_n_objects): Likewise.
- (cal_client_get_uids): Likewise.
-
- * conduits/calendar/calendar-conduit.c (get_calendar_objects): Likewise.
- (check_for_slow_setting): Likewise.
-
- * pcs/cal-backend-imc.c (count_objects): Likewise.
- (build_uids_list): Likewise.
-
- * pcs/cal.c (Cal_get_uids): Likewise.
- (Cal_get_n_objects): Likewise.
-
-2000-07-25 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-calendar-table.[hc]: new ECalendarTable to show an ETable view
- for Todo/Event items.
-
- * gui/task-assigned-to.xpm:
- * gui/task-recurring.xpm:
- * gui/task-assigned.xpm:
- * gui/task.xpm: new pixmaps (all the same at present) to go in the
- icon column of the ETable.
-
- * gui/event-editor.c: hid the silly 'Calendar' labels on the
- GnomeDateEdits and hid the times when you select 'All day event'.
- Also adjusted the time_t's so that when an all day event finishes on
- say midnight 13th May, we show 12th May in the dialog, since it
- implicitly includes all of that day up to midnight.
-
- * gui/dialogs/task-editor-dialog.glade:
- * gui/dialogs/task-editor.[hc]: unfinished dialog to edit tasks.
-
- * gui/gncal-todo.c: temporary hack so that we can use the simple dialog
- with our new ETable.
-
-2000-07-23 Damon Chaplin <damon@helixcode.com>
-
- * cal-util/calobj.h: added a few more fields.
-
- * cal-util/calobj.c (ical_object_create_from_vobject): check for a
- NULL return from vObjectUStringZValue for URL property to avoid SEGV.
- For some reason an empty 'URL:' property appears and causes trouble.
-
-2000-07-20 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component-factory.c (factory_fn): Update for the new
- `evolution_shell_component_new()' arg.
-
-2000-07-19 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (cal_component_alarm_set_trigger):
- Finish filling the trigger. What a pain, again.
- (cal_component_alarm_free_trigger): Implemented.
-
-2000-07-19 Fatih Demir <kabalak@gmx.net>
-
- * conduits/calendar/calendar-conduit-control-applet.desktop:
-
- * conduits/todo/todo-conduit-control-applet.desktop:
- Added the Turkish desktop entries.
-
-2000-07-18 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (cal_component_alarm_free): Free the
- icalcomponent if this is an unattached alarm.
- (scan_alarm_property): Handle the TRIGGER property.
- (cal_component_alarm_get_trigger): Ditto. Royal pain.
- (cal_component_alarm_set_trigger): Ditto. Less pain.
-
-2000-07-17 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-client/cal-client.c (cal_client_get_object): Fixed inline
- docs.
- (cal_client_new): Ditto.
- (cal_client_get_n_objects): Added inline docs.
-
-2000-07-14 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (CalComponentAlarm): New internal
- represntation for alarm components. We really don't map them to a
- CalComponent because it is more convenient to handle them as
- "child" structures.
- (make_alarm): New function to create a CalComponentAlarm from an
- icalcomponent representing a VALARM.
- (scan_alarm_property): New function to scan a property from an
- alarm component. We support ACTION.
- (cal_component_get_first_alarm): New function to start an iterator
- over the alarms in a calendar component.
- (cal_component_alarm_get_action): New function.
- (cal_component_alarm_set_action): New function.
-
-2000-07-13 Seth Alves <alves@hungry.com>
-
- * conduits/todo/todo-conduit.c: conduit based on the calendar conduit.
- this conduit syncs a pilot's ToDoDB database to wombat's list of "todo"
- events.
-
- * gui/gncal-todo.c (simple_todo_editor): set todo's priority control
- based on value from ical object during edit.
-
-2000-07-12 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/print.c: Revert Michael's GnomeFont patch until the
- gnome-print API stabilizes.
-
-2000-07-12 Michael Meeks <michael@helixcode.com>
-
- * gui/print.c (titled_box, print_text, print_month_small),
- (bound_text): GnomeFont update.
-
-2000-07-12 Seth Alves <alves@hungry.com>
-
- * conduits/calendar/calendar-conduit.c: fixed various problems
-
- * cal-client/Makefile.am: build a static version of the library
- to link with the conduits
-
- * cal-util/Makefile.am: same
-
-2000-07-11 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (scan_property): Handle the COMPLETED
- property.
- (free_icalcomponent): Ditto.
- (cal_component_get_completed): Ditto.
- (cal_component_set_completed): Ditto.
- (scan_property): Handle the TRANSPARENCY property.
- (free_icalcomponent): Ditto.
- (cal_component_get_transparency): Ditto.
- (cal_component_set_transparency): Ditto.
- (scan_property): Handle the URL property.
- (free_icalcomponent): Ditto.
- (cal_component_get_url): Ditto.
- (cal_component_set_url): Ditto.
-
- * pcs/cal-factory.c (queue_load_create_job): Removed unneeded
- check for the URI.
- (load_fn): Be more paranoid about the URI and notify the listener
- if we got passed a bad URI. Simplify the termination code a bit.
- (create_fn): Likewise.
- (queue_load_create_job): Be more paranoid about the URI.
-
-2000-07-10 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/Makefile.am: Remove pilot stuff for now.
-
- * Makefile.am (SUBDIRS): Remove `conduits'.
-
-2000-07-10 Dan Winship <danw@helixcode.com>
-
- * gui/Makefile.am (EXTRA_DIST): remove gnomecal.conduit
-
- * conduits/calendar/Makefile.am (EXTRA_DIST): We want
- calendar.conduit.in, not calendar.conduit.
-
-2000-07-10 Seth Alves <alves@hungry.com>
-
- * gui/Makefile.am (SUBDIRS):
- * conduits/calendar/Makefile.am: moved calendar-conduit stuff from
- the gui directory to here.
-
- * Makefile.am (SUBDIRS): added conduits to SIBDIRS
-
-2000-07-08 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/calendar-commands.c (calendar_control_activate): Remove
- "close calendar" command.
-
-2000-07-08 Anders Carlsson <andersca@gnu.org>
-
- * gui/e-week-view.c (e_week_view_on_button_press): Handle mouse wheel scrolling.
-
- * gui/e-day-view.c (e_day_view_on_time_canvas_button_press): New function to handle
- mouse wheel scrolling.
- (e_day_view_on_main_canvas_button_press): Handle mouse wheel scrolling.
-
-2000-07-07 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (scan_property): Handle the SEQUENCE
- property.
- (free_icalcomponent): Ditto.
- (cal_component_get_sequence): Ditto.
- (cal_component_set_sequence): Ditto.
- (cal_component_free_sequence): Ditto.
- (cal_component_set_last_modified): Removed incorrect assertion.
- (CalComponentPrivate): New need_sequence_inc flag. The sequence
- number must be incremented when certain properties change, so we
- store a flag that says if we need to bump it when piping the
- object over the wire.
- (free_icalcomponent): Reset need_sequence_inc.
- (cal_component_set_dtstart): Set need_sequence_inc.
- (cal_component_set_dtend): Ditto.
- (cal_component_set_due): Ditto.
-
-2000-07-06 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (scan_property): Handle the
- LAST-MODIFIED property.
- (free_icalcomponent): Ditto.
- (cal_component_get_last_modified): Ditto.
- (cal_component_set_last_modified): Ditto.
- (get_icaltimetype): New function to get struct icaltimetype
- values.
- (cal_component_get_created): Use get_icaltimetype().
- (set_icaltimetype): New function to set struct icaltimetype
- values.
- (cal_component_set_created): Use set_icaltimetype().
-
- * cal-util/cal-component.c (scan_property): Handle the CREATED
- property.
- (free_icalcomponent): Ditto.
- (cal_component_free_icaltimetype): Ditto.
- (cal_component_get_created): Ditto.
- (cal_component_set_created): Ditto.
- (cal_component_init): Do not create an UID here.
- (ensure_mandatory_properties): New function to ensure that the
- mandatory RFC properties are indeed in the component. If they are
- not, we create them on the fly.
- (cal_component_set_new_vtype): Use ensure_mandatory_properties().
- (cal_component_set_icalcomponent): Ditto.
- (cal_component_get_uid): Return the UID in a parameter, not as a
- function return value, for consistency's sake.
- (scan_property): Handle the DTSTAMP property.
- (free_icalcomponent): Ditto.
- (cal_component_get_dtstamp): Ditto.
- (cal_component_set_dtstamp): Ditto.
-
-2000-07-04 Damon Chaplin <damon@helixcode.com>
-
- * gui/gncal-todo.c (gncal_todo_update): Use &obj instead of &ico in
- the call to cal_client_get_object(). The ToDo list should work now.
-
- * gui/event-editor-dialog.glade: set the toplevel GnomeApp to invisible
- so it doesn't appear and then resize.
-
-2000-07-03 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (cal_component_get_summary): Use
- CalComponentText instead of CalComponentPropSummary. Removed the
- latter typedef.
- (cal_component_set_summary): Likewise.
- (scan_property): Handle the CLASSIFICATION property.
- (cal_component_get_classification): Ditto.
- (cal_component_set_classification): Ditto.
-
- * cal-util/cal-component.c (cal_component_free_text_list): Renamed
- from cal_component_free_description_list(). We can share this
- function since both comments and descriptions have the same form.
- (scan_text): Ditto.
- (get_text_list): New function.
- (set_text_list): New function.
- (cal_component_get_description_list): Use get_text_list().
- (cal_component_set_description_list): Use set_text_list().
- (cal_component_set_uid): Add sanity check.
- (cal_component_get_summary): Ditto.
- (cal_component_get_description_list): Ditto.
- (cal_component_get_dtstart): Ditto.
- (cal_component_get_dtend): Ditto.
- (cal_component_get_due): Ditto.
- (scan_property): Handle the COMMENT property.
- (cal_component_get_comment_list): Ditto.
- (cal_component_set_comment_list): Ditto.
-
-2000-07-02 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (scan_categories): Handle CATEGORIES.
- This can appear multiple times, so we maintain a list. We
- compress them later to a single property with multiple values.
- (cal_component_get_categories_list): Ditto.
- (cal_component_set_categories_list): Ditto.
- (cal_component_free_categories_list): Ditto.
- (free_icalcomponent): Properly free the mappings.
-
-2000-07-02 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (scan_datetime): Handle date/time and
- timezone pairs.
- (scan_property): Handle DTSTART and DTEND.
- (cal_component_free_datetime): Ditto.
- (get_datetime): Ditto.
- (cal_component_get_dtstart): Ditto.
- (set_datetime): Ditto.
- (cal_component_set_dtstart): Ditto.
- (cal_component_get_dtend): Ditto.
- (cal_component_set_dtend): Ditto.
- (scan_property): Handle DUE date.
- (cal_component_get_due): Ditto.
- (cal_component_set_due): Ditto.
-
-2000-07-01 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (cal_component_get_description_list):
- Handle the DESCRIPTION property. There can be multiple
- descriptions with parameters each, so we deal with a list instead
- of a single structure.
- (cal_component_set_description_list): Ditto.
- (cal_component_free_description_list): Ditto.
- (scan_property): Ditto.
- (scan_description): Ditto.
-
-2000-06-30 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c (cal_component_get_summary): To avoid
- passing a million parameters to setters/getters for properties
- that support parameters, we now pass client-side structures
- instead. Here we use CalComponentPropSummary.
- (cal_component_set_summary): Ditto.
-
-2000-06-29 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/component-factory.c: Make calendar die when evolution quits.
-
-2000-06-30 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.c: Change of plans. We use an
- icalcomponent from libical as our core representation so that we
- can preserve extension fields and fields that we don't (yet)
- support. CalComponent is just a wrapper with a nice API that
- provides non-iterative, random access to the ical's fields.
- (cal_component_destroy): Free the thing correctly.
- (cal_component_get_vtype): Re-implement in terms of icalcomponent.
- (cal_component_set_icalcomponent): New function to set the
- CalComponent's data from an existing icalcomponent.
- (cal_component_get_icalcomponent): New function.
- (cal_component_set_new_vtype): New convenience function to create
- an empty component.
- (scan_icalcomponent): Core scanning function.
- (scan_property): Another core scanning function.
- (cal_component_get_uid): Use the property directly.
- (cal_component_get_summary): Ditto. Handle the altrep parameter
- as well.
- (cal_component_set_summary): Ditto. Feel the pain, motherfucker.
- It is ridiculous how much code this involves.
- (scan_summary): Ditto.
-
-2000-06-29 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component-factory.c (owner_set_cb): Get an
- EvolutionShellClient instead of an Evolution_Shell to match the
- changes in libeshell.
-
-2000-06-29 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/Makefile.am: Do not link and include the pilot stuff for the
- calendar component, just for the Pilot conduit. Commented out the
- Pilot part so that Evolution can build. Sigh, we'll have to
- modify gnome-pilot to use OAF.
-
-2000-06-29 Peter Williams <peterw@helixcode.com>
-
- * gui/Makefile.am (LINK_FLAGS): Make the calendar-pilot-sync
- program conditional on HAVE_GNOME_PILOT, and add
- GNOME_PILOT_CFLAGS, GNOME_PILOT_LIBS, and PISOCK_LIBS in the
- appropriate places.
-
-2000-06-29 Seth Alves <alves@hungry.com>
-
- * pcs/cal.c (Cal_get_uid_by_pilot_id):
- (Cal_update_pilot_id):
- * pcs/cal-backend-imc.c (cal_backend_imc_update_pilot_id):
- (cal_backend_imc_get_uid_by_pilot_id):
- * pcs/cal-backend.c (cal_backend_get_uid_by_pilot_id):
- (cal_backend_update_pilot_id): server code to service these:
-
- * gui/calendar-pilot-sync.c: updated to make use of cal-client.
- also uses dirty bits on both sides to aid in syncing.
-
- * cal-client/cal-client.c (cal_client_get_uid_by_pilot_id): new
- function -- ask the cal server to return uid given an object's
- pilot id.
- (cal_client_update_pilot_id): new function -- inform the
- cal server of an objects pilot id and pilot dirty-flag.
-
-2000-06-28 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/cal-component.[ch]: New files for the new iCalendar
- component object. Today's properties: basic component type, UID,
- SUMMARY.
-
- * cal-util/Makefile.am: Added cal-component.[ch] to the list of
- sources.
-
-2000-06-27 Michael Meeks <michael@helixcode.com>
-
- * pcs/Makefile.am (INCLUDES): use BONOBO_VFS_GNOME_CFLAGS.
-
-2000-06-26 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/calendar-model.c: Added an #ifdefed value_to_string handler
- assignment.
-
-2000-06-26 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-model.c (calendar_model_duplicate_value):
- Implement.
- (calendar_model_initialize_value): Implement.
- (calendar_model_value_is_empty): Implement.
-
-2000-06-21 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-day-view.c (e_day_view_reshape_long_event): set event before
- using it!
- (e_day_view_init): used new colors from tigert.
-
-2000-06-21 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/e-day-view.c, gui/e-week-view.c: Remove the usage of the "x"
- and "y" arguments.
-
-2000-06-21 Damon Chaplin <damon@helixcode.com>
-
- * gui/gnome-cal.c (gnome_calendar_direction): changed so it keeps the
- selection range. It just moves it on one day/week etc. This makes
- it very handy for the keyboard shortcut code.
-
- * gui/calendar-commands.c (calendar_control_activate): fixed bug
- setting the radio button active.
-
- * gui/e-day-view.[hc]: added support for keyboard navigation and
- selection of the time range.
-
-2000-06-20 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-model.c (calendar_model_set_value_at): Implemented.
- (calendar_model_is_cell_editable): Implemented.
-
- * cal-client/cal-client.c (cal_client_update_object): Take in an
- iCalObject instead of a stringified version.
-
- * gui/gnome-cal.c (gnome_calendar_update_object): Removed.
- (gnome_calendar_remove_object): Removed.
- (save_ical_object_cb): Use the CalClient function.
-
- * gui/e-day-view.c (e_day_view_on_delete_occurrence): Likewise.
- (e_day_view_on_unrecur_appointment): Likewise.
- (e_day_view_finish_long_event_resize): Likewise.
- (e_day_view_finish_resize): Likewise.
- (e_day_view_key_press): Likewise.
- (e_day_view_on_editing_stopped): Likewise.
- (e_day_view_on_top_canvas_drag_data_received): Likewise.
- (e_day_view_on_main_canvas_drag_data_received): Likewise.
- (e_day_view_on_delete_appointment): Likewise.
-
- * gui/e-week-view.c (e_week_view_on_editing_stopped): Likewise.
- (e_week_view_key_press): Likewise.
- (e_week_view_on_delete_occurrence): Likewise.
- (e_week_view_on_unrecur_appointment): Likewise.
- (e_week_view_on_delete_appointment): Likewise.
-
- * gui/gncal-todo.c (ok_button): Likewise.
- (delete_todo): Likewise.
-
-2000-06-19 Damon Chaplin <damon@helixcode.com>
-
- * gui/event-editor-dialog.glade: tidied up dialog a bit, adding
- space etc.
-
- * gui/e-week-view.c (e_week_view_reshape_events): removed debug msg.
-
-2000-06-18 Ettore Perazzoli <ettore@helixcode.com>
-
- * cal-util/Makefile.am (INCLUDES): Include from
- `$(top_builddir)/libical/src/libical' too. [For the generated
- libical `icalversion.h' header.]
- * cal-client/Makefile.am (INCLUDES): Likewise.
-
-2000-06-18 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-day-view.c (e_day_view_on_top_canvas_drag_data_received):
- fixed a DnD bug.
-
-2000-06-17 Dan Winship <danw@helixcode.com>
-
- * cal-client/Makefile.am (INCLUDES): Fix to not depend on
- installed ical.h
-
-2000-06-17 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-week-view.c: added little buttons which are shown when there
- are more events than will fit in a day. Clicking on the button takes
- the user to the 1-Day view and shows the full day.
-
- * gui/e-day-view.c:
- * gui/e-week-view.c: set the "use_ellipsis" arg to TRUE for the EText
- items so we get tooltips automatically. Though we may want to use our
- own code to show tooltips so we can show the tips when the mouse is
- around the edges of the event box, and we may want to show the start
- and end times of the event in full.
-
- * gui/calendar-commands.c (calendar_control_activate):
- * gui/gnome-cal.h: added view_toolbar_buttons[] so we can access the
- radio buttons in the code easily. We need this if we want to jump to
- another view programmatically.
-
-2000-06-16 Damon Chaplin <damon@helixcode.com>
-
- * gui/jump.xpm: new icon for the EWeekView to jump to the day.
-
- * gui/Makefile.am (EXTRA_DIST): added jump.xpm
-
-2000-06-16 Damon Chaplin <damon@helixcode.com>
-
- * gui/calendar-model.c (calendar_model_class_init): #ifdef'ed out
- references to functions which don't exist yet, so evolution still
- compiles.
-
-2000-06-16 Damon Chaplin <damon@helixcode.com>
-
- * cal-util/test-recur.c: updated.
-
- * cal-util/cal-recur.[hc]: mostly finished, though it depends on the
- iCalObject struct being updated to support more of iCalendar.
-
-2000-06-16 Damon Chaplin <damon@helixcode.com>
-
- * pcs/.cvsignore: added icalendar-test.
-
-2000-06-15 Damon Chaplin <damon@helixcode.com>
-
- * cal-util/Makefile.am (test_recur_LDADD): use libical.a
-
-2000-06-15 Dan Winship <danw@helixcode.com>
-
- * cal-util/Makefile.am (noinst_PROGRAMS): merge the two separate
- noinst_PROGRAMS declarations into one so automake accepts it.
- (INCLUDES): include libical src dir so we don't depend on having
- ical.h already installed
-
-2000-06-14 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-model.c: GPtrArray cannot insert stuff in the
- middle of the array (!), so use plain GArray everywhere. Sigh.
-
-2000-06-13 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-client/cal-client.c (cal_client_get_object): Use vCalendar
- again.
-
- * cal-util/calobj.c (ical_object_find_in_string): From Seth, make
- it use vCalendar again.
-
-2000-06-13 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-model.c (obj_updated_cb): Juggle some eggs in
- asynchronous fashion. Finished implementing.
- (obj_removed_cb): Implemented. This one needs no juggling.
- (calendar_model_set_cal_client): Only load the objects if we have
- a client.
- (calendar_model_destroy): Disconnect from the client's signals.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Added
- calendar-model.[ch] to the list of sources.
-
- * pcs/cal-backend-imc.c (cal_backend_imc_get_n_objects): Doh,
- return the computed value.
-
-2000-06-13 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-model.c (CalendarModelPrivate): Added the array of
- objects and the hash table of UID->array index.
- (calendar_model_row_count): Return the length directly from the
- array instead of asking the Wombat.
- (calendar_model_value_at): Implemented.
- (calendar_model_new): Create an empty model. We provide a new
- setter function now.
- (calendar_model_construct): Removed function.
- (calendar_model_set_cal_client): New function to set the calendar
- client and object type at any time. This lets us reuse a calendar
- model object.
-
- * cal-util/calobj.h (iCalObjectField): Just report whether the
- object has alarms; not every single alarm.
-
-2000-06-13 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/Makefile.am (SHELL_OBJS): Removed.
- (evolution_calendar_LDADD): Link with
- `$(top_builddir)/shell/libeshell.a'.
-
-2000-06-09 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/component-factory.c (factory_fn): Pass NULL for the new args
- @create_folder_fn and @remove_folder_fn.
- (create_view): Updated to match the new
- `EvolutionShellComponentCreateViewFn'. Return
- `EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE' if type is not
- "calendar".
-
-2000-06-09 Federico Mena Quintero <federico@helixcode.com>
-
- * idl/evolution-calendar.idl (Cal): Added a get_n_objects()
- method.
-
- * pcs/cal-backend.c (cal_backend_get_n_objects): New function.
-
- * pcs/cal-backend-imc.c (cal_backend_imc_get_n_objects):
- Implemented.
-
- * pcs/cal.c (Cal_get_n_objects): Implemented.
-
- * cal-client/cal-client.c (cal_client_get_uids): Free the ev.
- (cal_client_get_n_objects): Implemented.
-
- * cal-util/calobj.h (iCalObjectField): New enumeration to identify
- the fields in an iCalObject.
-
-2000-06-08 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (event_editor_destroy): Free the private
- structure.
-
-2000-06-08 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/calobj.c (ical_object_to_vobject): Allow for NULL
- summaries.
-
-2000-06-07 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (toolbar): Added missing tooltips. We still
- need icons, though.
-
-2000-06-07 Seth Alves <alves@hungry.com>
-
- * cal-util/calobj.c (ical_object_find_in_string): put this back in,
- it's still used in cal-backend-imc.c:cal_backend_imc_update_object
-
- * cal-client/cal-client.c (cal_client_get_object): instead of
- returning a text representation, decode the text and return an
- iCalObject. Also added CalClientGetStatus which indicates
- success or type of failure.
-
- * cal-util/calobj.c (ical_object_find_in_string): #ifed out
- ical_object_find_in_string since it is unused now.
-
- * cal-client/client-test.c (list_uids): track get_object change
- * gui/calendar-commands.c (calendar_iterate): same
- * gui/e-day-view.c (e_day_view_update_event): same
- * gui/e-week-view.c (e_week_view_update_event): same
- * gui/print.c (print_day_details): same
- (print_day_summary): same
- (print_todo_details): same
- * gui/gnome-cal.c (trigger_alarm_cb): same
- * gui/gncal-todo.c (gncal_todo_update): same
-
-2000-06-06 Seth Alves <alves@hungry.com>
-
- * cal-util/icalendar.c, icalendar-save.c: fixed a bunch of problems
- * cal-util/calobj.c (ical_object_find_in_string): use libical
- instead of libversit
- (ical_object_to_string): same
- (dump_icalobject): prints the contents of an icalobject for debugging
-
- * gui/Makefile.am (LINK_FLAGS): link libical.a instead of libical.la
- so we don't have to modify the build system of the released libical
- * cal-client/Makefile.am (client_test_LDADD): same
- * cal-util/Makefile.am (icalendar_test_LDADD): same
-
-2000-06-06 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/calobj.c (ical_object_destroy): Removed from the public
- header; made static. Now everyone should use refcounting.
-
- * pcs/cal-backend-imc.c (free_ical_object): Use
- ical_object_unref().
- (remove_object): Likewise.
-
-2000-06-02 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-commands.c (print): New function to call the print
- engine.
- (calendar_toolbar): Added the Print button.
- (calendar_control_activate): Added the File/Print item.
-
- * gui/e-day-view.c (e_day_view_get_selected_time_range): Allow
- start_time and end_time to be NULL.
-
- * gui/e-week-view.c (e_week_view_get_selected_time_range):
- Likewise.
-
- * gui/print.c (range_selector_new): Show the range selector
- widgets. Use the correct radio group for all of them!
- (print_calendar): Do the dialog box here. We may want to split
- this function later into smaller chunks.
-
-2000-06-05 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-week-view-event-item.c (e_week_view_event_item_button_press):
- allow the right button to popup the menu, even when the event is
- being edited.
-
- * gui/e-week-view.c:
- * gui/e-day-view.c: Set the keyboard focus to the EDayView/EWeekView
- when the right button is clicked, so that any event being edited is
- saved before any action (e.g. opening the Event Editor dialog) is
- started. Note that this won't work if we switch to asynchronous
- notification.
-
-2000-06-02 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (tb_save_and_close_cb): Implemented.
- (toolbar): Added an icon for the Save and Close command.
- (save_ical_object): Recompute the title of the window here. Maybe
- it would be better to do it when we actually get the
- "object_changed" signal from the CalClient.
- (file_close_cb): Implemented.
-
-2000-06-02 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.c (save_ical_object_cb): Implemented.
- (gnome_calendar_add_object): Removed function, since it was
- identical to gnome_calendar_update_object(). Modified the rest
- of the code to use only the latter.
- (gnome_calendar_remove_object): Be more paranoid about the UID.
- (gnome_calendar_update_object): Ditto. Also, renamed this
- function from gnome_calendar_object_changed(), for consistency
- with the lower-level CalClient interface.
-
- * gui/event-editor.c (event_editor_class_init): New
- "save_ical_object" signal to ask that our parent store the
- calendar object to the backend.
- (save_ical_object): New function to save the calendar object,
- actually if just emits the signal.
- (file_save_cb): Implemented.
- (dialog_to_ical_object): We want priv->
- alarm_program_run_program_entry (i.e. the entry inside the
- GnomeFileEntry), not the file entry itself.
- (dialog_to_ical_object): Only insert the recurrence ending date if
- the event is recurrent!
-
-2000-06-02 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/Makefile.am: Fixed EXTRA_DIST.
-
-2000-06-01 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.c (editor_closed_cb): Handler for the
- "editor_closed" signal of the event editor; we just destroy it
- then.
-
- * gui/event-editor.c (app_delete_event_cb): Callback used when the
- dialog is closed. Release the iCalObject here instead of the
- event editor's destroy handler, and emit the new "editor_closed"
- signal.
-
-2000-06-01 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor-dialog.glade: Change of plans. The toplevel
- GnomeApp is now generated with Glade instead of being created in
- the program code. Otherwise we can't migrate the accelerators to
- the new toplevel and they won't work.
-
- * gui/event-editor.[ch]: EventEditor now derives from GtkObject.
- This lets us use the GnomeApp created by libglade and still have
- signals and stuff.
-
- * gui/event-editor.c (create_menu): Tell the UI handler that the
- menubar is the GnomeApp's existing one, not to create a new one.
- (create_toolbar): Tell the UI handler to use the GnomeApp's
- existing toolbar.
- (event_editor_focus): New function to raise/focus an event editor.
-
- * gui/gnome-cal.c (gnome_calendar_edit_object): Use
- event_editor_focus().
-
-2000-06-01 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/calendar-commands.c (calendar_control_activate): Put the
- toolbar into a frame to make it look like standard GNOME toolbars.
- Also, set `GNOME_DOCK_ITEM_BEH_NEVER_VERTICAL' so that it does not
- do evil things when its moved to the left or the right of the
- window.
-
-2000-05-31 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.h (GnomeCalendar): Added a hash table to map
- calendar objects to their respective event editors.
-
- * gui/gnome-cal.c (gnome_calendar_init): Create the
- object_editor_hash.
- (gnome_calendar_destroy): Free the object_editor_hash.
- (gnome_calendar_edit_object): New function to centralize the
- launching of event editors; if one already exists for a particular
- calendar object, we just raise its window.
- (edit): Use gnome_calendar_edit_object().
-
- * gui/calendar-commands.c (display_objedit): Use
- gnome_calendar_edit_object().
- (display_objedit_today): Likewise.
-
- * gui/e-day-view.c (e_day_view_on_new_appointment): Likewise.
- (e_day_view_on_edit_appointment): Likewise.
-
- * gui/e-week-view.c (e_week_view_on_new_appointment): Likewise.
- (e_week_view_on_edit_appointment): Likewise.
-
- * gui/event-editor.c (event_editor_new): Do not take in an
- iCalObject; rather provide an event_editor_set_ical_object()
- function. We need this because a single editor may be switched
- between different calendar objects. Also, do not show the event
- editor; leave it up to the client code.
- (event_editor_construct): Likewise.
- (clear_widgets): New function to clear the widgets to default
- values.
- (fill_widgets): New function to fill in the widgets from the
- iCalObject. We don't do this in init_widgets() anymore.
- (free_exception_clist_data): New function to free the exceptions
- clist data. We were leaking the row data.
- (init_widgets): Hook to the destroy signal of the exceptions
- clist.
- (event_editor_set_ical_object): New function. Now it also makes a
- copy of the calendar object for the event editor; clients do not
- need to copy it anymore.
- (event_editor_destroy): Unref the UI handler as well.
- (event_editor_class_init): New "ical_object_released" signal to
- notify the parent that we are no longer editing the calendar
- object.
- (make_title_from_ico): Handle NULL objects.
-
- * gui/event-editor.h (EventEditor): Removed fields that are no
- longer used.
-
-2000-05-31 Damon Chaplin <damon@helixcode.com>
-
- * cal-util/Makefile.am: added test-recur test program.
-
- * cal-util/test-recur.c: new file to test the recurrence code.
-
- * cal-util/.cvsignore: added test-recur.
-
- * cal-util/cal-recur.c: updated.
-
-2000-05-30 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor.c (event_editor_construct): Create the UI
- handler after we have constructed the parent GnomeApp.
- (main_menu): Menu template is now in place.
- (toolbar): Tollbar template is now in place.
- (create_toolbar): Turn off labels in the toolbar since it sucks;
- it should support non-homogeneous buttons with horizontal icons
- and text.
-
-2000-05-29 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.c (gnome_calendar_object_changed): Removed the
- flags argument, since now we just proxy the calendar object to the
- calendar client.
-
- * gui/event-editor.c (alarm_unit_get): Moved over from
- event-editor-utils.c.
-
- * gui/event-editor-utils.[ch]: Removed files, since the two
- functions that were left there (i.e. the ones not present in
- e-dialog-widgets) can simply be moved to event-editor.c.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Removed
- event-editor-utils.[ch] from the list of sources.
-
-2000-05-27 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor-utils.c: Moved many functions to
- e-util/e-dialog-widgets.c.
-
-2000-05-25 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/event-editor-dialog.glade: Put the main notebook directly
- under a simple GtkWindow. We are going to pull out the notebook
- and slap it into our custom-built GnomeApp, anwyays.
-
- * gui/event-editor.c: Made the EventEditor derive from GnomeApp.
- Added a BonoboUIHandler for its menu and toolbar.
- (make_title_from_ico): Create a nice title for the window.
- (get_widgets): Fetch the Glade widgets here instead of all over
- the place.
- (event_editor_new): Temporary hack to show the dialog here, just
- so that I can test it.
-
- * gui/Makefile.am (EXTRA_DIST): Added the Glade messages file.
-
-2000-05-25 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/main.c (init_bonobo): Do not initialize libglade twice.
-
- * gui/component-factory.c (create_view): Set the folder_uri
- property, otherwise the calendar will not get loaded into the
- view.
-
-2000-05-25 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/main.c: Make it so that warnings don't crash calendar.
-
-2000-05-25 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/evolution-calendar-control.c: Removed.
-
- * gui/main.c: New.
-
- * gui/control-factory.c: New.
- * gui/control-factory.h: New.
-
- * gui/calendar-component-factory.c: New.
- * gui/calendar-component-factory.c: New.
-
- * gui/evolution-calendar-control.c (calendar_control_factory):
- Renamed from `calendar_factory'.
- (calendar_control_factory_init): Renamed from
- `calendar_factory_init'.
-
- * gui/Makefile.am: Link with the files from `$(builddir)/shell'.
-
- * gui/evolution-calendar.gnorba: New.
- * gui/evolution-calendar.oafinfo: New.
-
-2000-05-24 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/print.c (range_selector_new): New function to create the
- custom range selector.
- (print_dialog): New function to show the print dialog.
- (print_calendar): Use the print dialog.
-
-2000-05-24 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/Makefile.am: Added libepaned.a.
-
- * gui/gnome-cal.c: Switched from GtkPaned to EPaned.
-
-2000-05-22 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/calendar-commands.c (calendar_get_events_in_range): Removed
- function.
-
- * gui/mark.c (mark_month_item): Use
- cal_client_get_events_in_range().
-
- * gui/calendar-commands.c (show_year_view_clicked): Comment out,
- since we don't have a year view.
-
- * gui/gnome-cal.c (setup_widgets): Removed the year view stuff.
- (gnome_calendar_get_current_view_name): Likewise.
- (gnome_calendar_update_view_times): Likewise.
- (gnome_calendar_direction): Likewise.
- (gnome_calendar_set_view): Likewise.
- (gnome_calendar_update_all): Likewise.
- (gnome_calendar_object_updated_cb): Likewise.
- (gnome_calendar_object_removed_cb): Likewise.
- (gnome_calendar_time_format_changed): Likewise.
- (gnome_calendar_get_current_time_range): Likewise.
-
- * gui/gnome-cal.h (GnomeCalendar): Removed the year view stuff.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Added layout.[ch],
- print.[ch]. Removed quick-view.[ch], year-view.[ch] since they
- are no longer used. Removed all the old Pilot crap.
-
-2000-05-20 Damon Chaplin <damon@helixcode.com>
-
- * cal-util/cal-recur.[hc]: new files to implement iCalendar recurrence
- rules. These are only part finished, but people may like to check that
- the architecture seems OK.
-
-2000-05-17 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-day-view.c (e_day_view_on_delete_occurrence):
- * gui/e-week-view.c (e_week_view_on_delete_occurrence): use a copy of
- the iCalObject so we detect the change in the "update_event" callback.
- Maybe we should just update the view ourselves and then we wouldn't
- need to detect any change in the callback.
-
- * cal-util/calobj.c (ical_object_reset_recurrence): new function to
- get rid of any recurrence rules. Used when we 'unrecur' an event.
-
- * gui/e-day-view.c (e_day_view_key_press): don't add a new event if it
- won't fit, or we end up adding a new event for each key press.
- (e_day_view_update_event_label): don't update it if it doesn't have
- an EText item (i.e. it isn't visible).
-
- * gui/e-day-view-time-item.c: allow selection of times using this
- column.
-
-2000-05-19 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/timeutil.c (time_add_minutes): Fixed warning message.
- (time_add_day): Likewise.
- (time_add_month): Likewise.
- (time_add_year): Likewise.
- (time_from_day): Of all functions, *this* one had to have a bug.
- Set the tm.tm_isdst to -1 to specify that we don't know whether
- the time is in DST or not. This fixes *many* bugs upstream.
- (time_week_begin): Likewise. We never noticed this since the week
- functions are never used.
- (time_week_end): Likewise.
-
-2000-05-17 Seth Alves <alves@hungry.com>
-
- * gui/event-editor.c: hooked up more widget signals to callbacks
- to the gladified dialog acts more like the original one.
-
-2000-05-16 Seth Alves <alves@hungry.com>
-
- * gui/event-editor.c (recurrence_toggled): hook the radio buttons
- to the pages of the notebook.
- (append_exception):
- (recurrence_exception_added):
- (recurrence_exception_deleted):
- (recurrence_exception_changed): code to deal with the recurrence
- exception list.
-
-2000-05-15 Seth Alves <alves@hungry.com>
-
- * gui/event-editor.[ch]: gladeified replacement for eventedit.c
-
- * gui/event-editor-utils.[ch]: utilities used by event-editor.c
-
- * gui/event-editor-dialog.glade: glade file used by event-editor.c
-
-2000-05-14 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.c (display_notification): Use the alarm
- notification dialog.
- (display_notification_cb): New callback for the result of the
- alarm notification dialog.
-
- * gui/dialogs/alarm-notify.glade: New file with the alarm
- notification dialog.
-
- * gui/dialogs/alarm-notify-dialog.[ch]: New file.
-
- * gui/dialogs/Makefile.am: New file.
-
- * gui/Makefile.am (SUBDIRS): Added the dialogs directory.
-
-2000-05-13 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.c (trigger_alarm_cb): Better error checking, and
- plug leaks of str_ico and ico.
-
- * gui/evolution-calendar-control.c (main): Initialize libglade.
-
-2000-05-13 Ettore Perazzoli <ettore@helixcode.com>
-
- * pcs/Makefile.am (INCLUDES): Add
- `-I$(top_builddir)/libical/src/libical'.
-
-2000-05-12 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/calobj.c (generate): Use a (dtend - dtstart) offset to
- compute the ending time of the occurrence. This takes care of
- recurring events that span multiple days. Also, removed the DST
- condition since it did not look right at all: if you have a daily
- appointment at 18:00, it still should happen at 18:00 even during
- daylight savings.
-
- * gui/gnome-cal.c (gnome_calendar_tag_calendar): Use the timeutil
- functions instead of calculating the month's times by hand. Use
- cal_obj_instance_list_free() instead of freeing the list by hand.
- Clip the range we pass to mark_gtk_calendar_day().
- (mark_gtk_calendar_day): Fixed off-by-one error at the end of the
- month by adding real day offsets.
-
-2000-05-11 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.c (add_alarms_for_object): New function to add
- today's alarms for a single object.
- (gnome_calendar_object_updated_cb): Update the object's alarms.
-
- * idl/evolution-calendar.idl (Cal): Added a
- get_alarms_for_object() method.
-
- * pcs/cal.c (Cal_get_alarms_for_object): Implemented method.
-
- * pcs/cal-backend.c (cal_backend_get_alarms_for_object): New
- function.
-
- * pcs/cal-backend-imc.c (cal_backend_imc_get_alarms_for_object):
- Implemented.
-
- * cal-client/cal-client.c (cal_client_get_alarms_for_object): New
- function.
-
-2000-05-11 Dan Winship <danw@helixcode.com>
-
- * gui/calendar-commands.c (calendar_control_activate): Now that we
- depend on current gnome-libs we can make the toolbar detachable
- again.
-
- * pcs/icalendar-save.c (timet_to_icaltime): remove unused timezone
- variable to make this compile on BSD systems (where timezone is
- the name of a function)
-
-2000-05-11 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/gnome-cal.c (gnome_calendar_update_all): Removed unused
- arguments. Load the initial alarms here.
- (load_alarms): New function to load a day's worth of alarms.
- (gnome_calendar_class_init): Eeeek! This was taking in an
- incorrect argument type.
- (gnome_calendar_init): Now the calendar keeps a hash table of
- UIDs->queued alarms. Create the hash table here.
- (gnome_calendar_destroy): Destroy the alarms hash table.
- (gnome_calendar_object_updated_cb): Remove the alarms for the
- object and regenerate them.
- (gnome_calendar_object_removed_cb): Remove the alarms for the
- object.
-
- * gui/alarm.c (alarm_add): Do not take in a CalendarAlarm, just
- the trigger time, the callback and the closure data. Return an
- opaque identifier for the alarm so that it can be removed by the
- client code if needed. Use the queue_alarm() helper function.
- (queue_alarm): Helper function to actually queue the alarm and set
- up the itimer. Deal with a nonzero return value from
- setitimer().
- (alarm_remove): New function to remove an alarm based on its ID.
- (pop_alarm): New helper function; pops the first alarm of the
- queue and resets the timer as appropriate.
- (alarm_ready): Simplified a lot by using pop_alarm().
-
- * idl/evolution-calendar.idl (Cal): Added get_alarms_in_range().
-
- * pcs/cal.c (build_instance_seq): New function to build a CORBA
- sequence from the internal list of instances.
- (Cal_get_events_in_range): Use build_instance_seq().
- (Cal_get_alarms_in_range): Implemented new method.
-
- * pcs/cal-backend.c (cal_backend_get_alarms_in_range): New
- function with the get_alarms_in_range() engine.
-
- * pcs/cal-backend-imc.c (cal_backend_imc_get_alarms_in_range):
- Implemented the get_alarms_in_range() method.
-
- * cal-client/cal-client.c (cal_client_get_alarms_in_range): New
- client-side function for getting the alarms.
- (build_instance_list): New helper function to build the
- CalObjInstance list from the CORBA sequence.
- (cal_client_get_events_in_range): Use build_instance_list().
-
- * gui/calendar-commands.h: #include <cal-util/calobj.h>. #include
- "gnome-cal.h".
-
- * gui/e-week-view.c: #include "calendar-commands.h" instead of
- main.h; the latter is an obsolete file and will be killed.
-
- * gui/evolution-calendar-control.c (main): Call init_bonobo()
- before anything else. We need the GTK+ object system initialized.
-
- * gui/Makefile.am (evolution_calendar_SOURCES): Do not use main.h.
-
- * cal-util/cal-util.c (cal_alarm_instance_list_free): New function.
-
-2000-05-10 Matt Loper <matt@helixcode.com>
-
- * gui/calendar-commands.c (calendar_control_activate): Move
- "about" menuitem to the help menu.
-
-2000-05-10 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/Makefile.am: Added main.h. Combined the two EXTRA_DIST
- sections.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * pcs/cal-backend-imc.c: Set the format when creating a new
- calendar.
-
-2000-05-09 Christopher James Lahey <clahey@helixcode.com>
-
- * pcs/cal-factory.c: Removed double free of method_string in
- uri->method_string.
-
-2000-05-08 Ettore Perazzoli <ettore@helixcode.com>
-
- * pcs/cal.h: Include "calendar/pcs/evolution-calendar.h" instead
- of "evolution-calendar.h".
-
- * pcs/cal-backend.h: Include "calendar/pcs/evolution-calendar.h"
- instead of "evolution-calendar.h".
-
-2000-05-08 Seth Alves <alves@hungry.com>
-
- * gui/e-day-view.c (e_day_view_on_delete_appointment): call
- e_day_view_stop_editing_event here to avoid a divide by zero
- a bit further on. i'm not sure if this is the best fix for this.
-
-2000-05-08 Federico Mena Quintero <federico@helixcode.com>
-
- * pcs/cal-backend.h (CalBackendClass): CalBackendClass now is just
- an interface for calendar backends; this is an abstract class.
- Put in the vtable for the backend methods.
-
- * pcs/cal-backend.c (cal_backend_new): Removed function, since
- CalBackend is not just an abstract class.
- Removed implementation-specific functions and made public
- functions call the virtual methods instead.
-
- * pcs/cal-backend-imc.[ch]: New files with the CalBackendIMC
- implementation; this implements a backend for iCalendar and
- vCalendar files. Moved the implementation-specific stuff from
- cal-backend.[ch] to here.
-
- * pcs/cal-backend-imc.c (CalendarFormat): Moved enumeration to
- here. Added a CAL_UNKNOWN value for when the backend is not
- loaded yet.
- (cal_backend_imc_init): Initialize priv->format as CAL_UNKNOWN.
- (save_to_vcal): Use the same VCProdIdProp value as in
- cal-util/calobj.c. Use "1.0" as the VCVersionProp as per the
- vCalendar spec.
- (ensure_uid): Return nothing, since the result value need not be
- used anymore.
- (add_object): Since we mark the calendar as dirty anyways, we do
- not need to check the result value of ensure_uid() anymore.
- (remove_object): Asssert that we know how to handle the object's
- type. We do this in add_object() anyways.
-
- * pcs/Makefile.am (libpcs_a_SOURCES): Added cal-backend-imc.[ch].
-
- * gui/gnome-cal.c: Replaced debugging printf()s with g_message()
- so that we can see the line number where they occur.
-
- * gui/gnome-cal.c (gnome_calendar_load_cb): Sort of handle the
- LOAD_METHOD_NOT_SUPPORTED result code, and added a default for the
- switch.
-
- * cal-client/cal-listener.h (CalListenerLoadStatus): Removed
- enumeration; it is stupid to translate all values for the
- CalClient when it is going to translate them again.
- (CalListenerClass::cal_loaded): This signal now passes the
- LoadStatus directly from the CORBA side.
-
- * cal-client/cal-listener.c (Listener_cal_loaded): Do not
- translate the status value.
-
- * cal-client/cal-client.h (CalClientLoadStatus): Added the
- CAL_CLIENT_LOAD_METHOD_NOT_SUPPORTED error code.
-
- * cal-client/cal-client.c (cal_loaded_cb): Translate the CORBA
- version of the LoadStatus result code.
-
- * pcs/cal-factory.c (CalFactoryPrivate): New methods field for the
- hash table from method strings to the GtkTypes for backend class
- types.
- (cal_factory_init): Create the priv->methods hash table.
- (cal_factory_destroy): Free the priv->methods hash table.
- (cal_factory_register_method): New function to register a backend
- class for a particular URI method.
- (launch_backend_for_uri): New function to launch a backend for a
- particular URI's method.
- (load_backend): Use launch_backend_for_uri(). Move the error
- notification code from load_fn() to here.
- (create_backend): Use launch_backend_for_uri(). Move the error
- notification code form create_fn() to here; it is #ifdefed out
- since currently cal_backend_create() does not have any error
- reporting capabilities.
-
- * idl/evolution-calendar.idl (Listener::LoadStatus): Added a
- PROTOCOL_NOT_SUPPORTED error code.
-
- * pcs/cal-factory.c (cal_factory_load cal_factory_create): Removed
- functions, since they were supposed to be internal only.
- (CalFactory_load): Call queue_load_create_job() directly.
- (CalFactory_create): Likewise.
-
-2000-05-08 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-week-view.c (e_week_view_remove_event_cb):
- * gui/e-day-view.c (e_day_view_remove_event_cb): don't set the ico->uid
- to NULL or we won't find any other occurrences of the event. Set the
- editing_event_day/num to -1 instead.
-
- * gui/e-week-view-event-item.c (e_week_view_event_item_draw): fixed the
- positioning of the icons for long events.
-
- * cal-util/calobj.c (ical_object_normalize_summary): forgot to
- terminate the string.
-
-2000-05-07 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-day-view.c (e_day_view_on_main_canvas_drag_data_received):
- (e_day_view_on_top_canvas_drag_data_received): show the EText item,
- just in case it hasn't moved, otherwise it won't appear.
-
- * gui/e-day-view.h (E_DAY_VIEW_BAR_WIDTH): increased from 6 to 8 to
- make it easier to drag an event. Also increased E_DAY_VIEW_GAP_WIDTH
- since it must be >= the BAR_WIDTH.
-
-2000-05-07 Matt Loper <matt@helixcode.com>
-
- * gui/evolution-calendar-control.c (PROPERTY_CALENDAR_URI):
- Changed to "folder_uri" from "calendar_uri".
- (set_prop): The uri given to us is a directory, so we append a
- filename onto the end before we use it.
-
-2000-05-06 Damon Chaplin <damon@helixcode.com>
-
- * cal-util/timeutil.c (time_day_begin):
- (time_day_end): changed these so they just do a simple localtime(),
- update the struct tm, then do a mktime(). I don't know why it used to
- look at the tm_isdst flags etc. From a little test program I wrote
- which steps through testing every hour for a year it wasn't working
- correctly, and the new code does.
- (time_add_day): also got rid of the stuff that looked at tm_isdst here.
- My test program now works better.
-
-2000-05-06 Chris Toshok <toshok@helixcode.com>
- * gui/.cvsignore: ignore evolution-calendar.pure
-
- * gui/Makefile.am: add support for building evolution-calendar.pure
-
-2000-05-06 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-day-view.c:
- * gui/e-week-view.c: finish editing event when user hits Return key.
- (e_week_view_on_text_item_event): stop event signals after doing any
- other calls, since otherwise it will also stop any other resulting
- event signals.
-
- * gui/e-week-view-event-item.c (e_week_view_event_item_draw): don't
- draw the start/end times while editing.
-
- * gui/eventedit.c: changed the Summary field to a GtkEntry, since we
- now only want a single line of text.
-
- * cal-util/calobj.c (ical_object_normalize_summary): new function to
- convert the summary field to a single line of text, by converting any
- sequence of CR & LF characters to a single space.
- (ical_object_create_from_vobject): call the above function. I think
- all functions that load iCalObjects go through this.
- (ical_new): called it here as well just in case.
-
-2000-05-06 Damon Chaplin <damon@helixcode.com>
-
- * gui/week-view.[hc]: removed.
-
-2000-05-06 Damon Chaplin <damon@helixcode.com>
-
- * gui/gncal-day-panel.[hc]:
- * gui/gncal-day-view.[hc]:
- * gui/gncal-full-day.[hc]:
- * gui/gncal-week-view.[hc]:
- * gui/layout.[hc]:
- * gui/view-utils.[hc]: removed old calendar view files.
-
-2000-05-06 Damon Chaplin <damon@helixcode.com>
-
- * cal-util/calobj.[hc]: added guint ref_count to iCalObject struct,
- and ical_object_ref/unref() functions. I've updated all the gui/
- stuff to use ref_counts but I haven't touched the pcs/ stuff. Maybe
- just using ical_object_destroy() is OK there.
-
- * gui/gncal-todo.c:
- * gui/calendar-commands.c:
- * gui/eventedit.c:
- * gui/e-week-view.c:
- * gui/e-day-view.c: use refcounting for iCalObjects.
-
- * gui/e-day-view-main-item.c:
- * gui/e-day-view-top-item.c:
- * gui/e-day-view.c: try not to ever draw outside the event, even when
- the event is very small.
-
-2000-05-05 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-day-view.c: don't allow recurring events to be resized or
- dragged, and don't show the resize/drag cursors. Actually it may be
- better to let the user do the resize/drag and then ask them what they
- want to do - change the single occurrence or the entire series.
-
- * gui/e-day-view-time-item.c (e_day_view_time_item_show_popup_menu):
- use e_auto_kill_popup_menu_on_hide() to destroy the popup menu.
-
- * gui/popup-menu.c: include e-gui-utils.h
-
-2000-05-04 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-day-view.c (e_day_view_foreach_event_with_uid): for the long
- events pass E_DAY_VIEW_LONG_EVENT as the day. Fixes SEGV.
-
- * gui/calendar-commands.c: when we switch views, grab the focus.
-
- * gui/gnome-cal.c (gnome_calendar_tag_calendar):
- (gnome_calendar_mark_gtk_calendar_day): changed this so it uses
- cal_client_get_events_in_range(), and doesn't load any objects.
- Also just return if it isn't visible.
-
- * gui/calendar-commands.c (calendar_get_events_in_range): call
- g_list_sort() to sort the list rather than g_list_insert_sorted() for
- each element. It is much more efficient.
- Also changed it so that the co->ev_start/end fields are copied from
- the CalObjInstance rather than the parameters to the function
- (that is right, isn't it?)
- Also freed the list elements, and finally the list.
- (calendar_iterate): changed this to use cal_client_get_events_in_range
- since that is more efficient than getting all the uids and then loading
- and parsing all the events.
-
- * pcs/cal-backend.c (save): output the '... saved' message before
- freeing the string!
-
- * gui/gncal-todo.c (gncal_todo_update):
- * gui/e-week-view.c (e_week_view_update_event):
- * gui/e-day-view.c (e_day_view_update_event):
- * gui/calendar-commands.c (calendar_get_events_in_range):
- (calendar_iterate): free obj_string after it is parsed.
-
-2000-05-02 Damon Chaplin <damon@helixcode.com>
-
- * gui/calendar-commands.c (calendar_control_activate): set the active
- radio button here. Oops - it wasn't a Bonobo problem after all.
-
- * gui/popup-menu.c (popup_menu): added call to
- e_auto_kill_popup_menu_on_hide() to destroy the menu.
-
- * gui/e-week-view.c (e_week_view_show_popup_menu):
- * gui/e-day-view.c (e_day_view_on_event_right_click): ico->user_data
- isn't useful any more, since the event editor keeps its own iCalObject.
- So for now we make the menu commands available even when the event is
- being edited in the event editor.
- Also corrected misspellings of 'occurance' -> 'occurrence'.
-
- * gui/eventedit.c (event_editor_destroy): destroy the iCalObject.
- The event editor now uses its own independent iCalObject.
-
- * gui/e-week-view.c (e_week_view_on_unrecur_appointment):
- * gui/e-day-view.c (e_day_view_on_unrecur_appointment): create a new
- uid for the new single instance. I'm not sure what we should do about
- the creation/last modification times of the objects.
-
- * gui/e-week-view.c (e_week_view_on_edit_appointment):
- * gui/e-day-view.c (e_day_view_on_edit_appointment): duplicate the
- iCalObject before passing it to the event editor, since it will change
- the fields. If we don't duplicate it we won't know what has changed
- when we get the "update_event" callback.
-
- * gui/e-week-view.c (e_week_view_key_press):
- * gui/e-day-view.c (e_day_view_key_press): set the created and last_mod
- times of the new iCalObject. We may want to set the default alarm as
- well.
-
- * cal-util/calobj.c (ical_gen_uid): made this function public so we
- can generate new uids if necessary.
-
-2000-05-01 Damon Chaplin <damon@helixcode.com>
-
- * gui/gnome-cal.[hc] (gnome_calendar_get_current_time_range): new
- function to get the currently seleted time range form the current view.
-
- * gui/calendar-commands.c (display_objedit): use the above function
- to get the time for the new appointment.
-
- * gui/e-week-view.c:
- * gui/e-day-view.c: use a shallow copy of the ico when we update the
- times (when resizing/dragging). Otherwise we won't detect that the
- time has changed in the "update_event" callback.
-
- Also added functions to get the currently selected time range.
-
-2000-04-30 Seth Alves <alves@hungry.com>
-
- * pcs/icalendar-save.c (icalcomponent_create_from_ical_object): set
- attendee and contact address correctly.
-
- * pcs/cal-backend.c (icalendar_calendar_load): init priv->object_hash
- when loading.
- (cal_get_type_from_filename): if file extension is .ical, consider
- the file an ical file.
-
-2000-05-01 Damon Chaplin <damon@helixcode.com>
-
- * cal-util/calobj.c (ical_object_compare_dates): new function to see
- if the event dates have changed (including any recurrence rules).
- It is used for optimization when we get the "object_changed" signal.
- We have to do far less work if the dates are unchanged.
-
- * gui/e-week-view.c:
- * gui/e-day-view.c: only draw the selection when we have the keyboard
- focus, since the user expects to be able to type in a new event when
- the selection is shown. Also keep the selection when we lose focus,
- but just don't show it.
-
- Also quite a few changes to cope with the new client/server
- architecture.
-
- * gui/e-day-view-top-item.c (e_day_view_top_item_draw):
- * gui/e-day-view-main-item.c (e_day_view_main_item_draw):
- * gui/e-week-view-main-item.c (e_week_view_main_item_draw_day):
- only draw the selection if the widget has the keyboard focus.
-
- * gui/gnome-cal.c (mark_gtk_calendar_day): fixed so it works with
- events longer than one day. And changed the code for updating events
- in the new views.
-
-2000-04-27 Ettore Perazzoli <ettore@helixcode.com>
-
- * gui/evolution-calendar-control.c
- (init_bonobo): OAFized.
-
- * gui/main.c (main): Initialize with OAF if `USING_OAF'.
-
- * gui/evolution-calendar-control.c: New #define
- `CONTROL_FACTORY_ID', varying according to whether we are
- `USING_OAF'.
- (calendar_factory_init): Use `CONTROL_FACTORY_ID'.
-
- * gui/Makefile.am: Updated for OAF.
-
- * pcs/cal-factory.h: Explicitly #include
- "calendar/pcs/evolution-calendar.h" instead of just
- "evolution-calendar.h".
-
- * cal-client/cal-client.c (cal_client_construct) [USING_OAF]: Use
- OAF.
-
- * cal-client/client-test.c (init_corba): New function, implemented
- differently depending on `USING_OAF'.
-
-2000-04-27 <alves@hungry.com>
-
- * pcs/cal-backend.c (cal_backend_load): fix memory leak
- (save_to_vcal): same
- (save): same
- (cal_backend_load): same
-
-2000-04-26 Christopher James Lahey <clahey@helixcode.com>
-
- * cal-util/.cvsignore: Replaced libcal-util.la with *.la
-
- * pcs/.cvsignore: Added *.la and *.lo.
-
-2000-04-25 Federico Mena Quintero <federico@helixcode.com>
-
- * pcs/cal-factory.c (backend_last_client_gone_cb): Renamed from
- backend_destroy_cb. Now we use it for the "last_client_gone"
- signal from the backend. Also, unref the backend to destroy it.
- (add_backend): Connect to the "last_client_gone" signal of the
- backend.
- (cal_factory_get_n_backends): New function to query the number of
- running backends.
-
- * pcs/cal-backend.c (cal_backend_class_init): Register the new
- "last_client_gone" signal. It is emitted when the last Cal client
- goes away. It is used to notify the factory when a backend may be
- safely destroyed.
- (cal_destroy_cb): Emit the "last_client_gone" signal when the last
- client disconnects from the backend.
-
-2000-04-25 Seth Alves <alves@hungry.com>
-
- * gui/e-day-view.c (e_day_view_find_event_from_ico): compare
- iCalObjects by their UIDs instead of by their pointers.
-
- * pcs/cal-backend.c (cal_backend_destroy): don't save on destroy.
-
-2000-04-25 Ettore Perazzoli <ettore@helixcode.com>
-
- * cal-client/Makefile.am: Add `$(datadir)/idl'.
-
- * pcs/Makefile.am (idl_flags): Add `$(datadir)/idl'.
- (INCLUDES): Use `$(BONOBO_GNOME_CFLAGS)'.
-
-2000-04-25 Seth Alves <alves@hungry.com>
-
- * gui/gnome-cal.c (gnome_calendar_destroy): hook for widget
- destroy -- used to unref the CalClient so wombat knows we are gone.
- (gnome_calendar_class_init): added a class init for this widget.
-
- * gui/e-day-view.c (e_day_view_update_event): allow for null ico
-
- * gui/e-week-view.c (e_week_view_update_event): allow for null ico
-
-2000-04-24 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-client/client-test.c (main): The path to the test calendar
- changed when we moved stuff around. Users will have to tweak this
- for their CVS setup, anyways.
- (create_client): Create or load the calendar as appropriate.
- (client_destroy_cb): Exit the main loop if both clients are gone.
- (main): Connect to the "destroy" signal of the clients so that we
- can terminate the test program.
-
-2000-04-24 Seth Alves <alves@hungry.com>
-
- * pcs/icalendar.c (parse_person): allow for null CN
- (parse_person): allow for null sent_by
-
- * pcs/Makefile.am: build icalendar-test
-
- * pcs/icalendar-test.c: a test which loads an ical file and
- converts it to our internal format, and then saves it back out.
-
-2000-04-24 Damon Chaplin <damon@helixcode.com>
-
- * gui/Makefile.am: added new source files and pixmaps, and removed
- old source files, which can be deleted.
-
- * gui/e-week-view-titles-item.[hc]:
- * gui/e-week-view-main-item.[hc]:
- * gui/e-week-view-event-item.[hc]:
- * gui/e-week-view.[hc]: new files implementing the week/month views.
-
- * gui/yearview.xpm:
- * gui/monthview.xpm:
- * gui/weekview.xpm:
- * gui/workweekview.xpm:
- * gui/dayview.xpm: new pixmaps for the toolbar buttons. These aren't
- intended to be the final pixmaps.
-
- * gui/calendar-commands.c: added radio buttons to the toolbar to
- switch between the calendar views, and moved the am_pm_flag here so we
- can get rid of view-utils.c.
-
- * gui/gnome-cal.[hc]: made it a subclass of GtkVBox, rearranged the
- widgets into 2 notebooks, and added the selection_start_time and
- selection_end_time fields.
-
- * gui/goto.c: updated to use new selection time range.
-
- * gui/quick-view.c: added '#include <gtk/gtkwindow.h>' so it compiles.
-
- * gui/e-day-view.[hc]: changed the interface to support the new
- selection time range, got rid of a few debugging messages and changed
- a few bits.
-
-2000-04-21 Seth Alves <alves@hungry.com>
-
- * pcs/icalendar-save.c: start on code to do the opposite of
- icalendar.c (convert from iCalObjects to libical's icalcomponents).
-
- * gui/calendar-commands.c (calendar_control_activate): moved
- "About Calendar" into the View menu so it shows up.
-
-2000-04-20 Seth Alves <alves@hungry.com>
-
- * gui/gnome-cal.c (gnome_calendar_changed_cb): new function: callback
- for listener's object updated signal.
- (gnome_calendar_object_removed_cb): new function: callback for
- listener's object removed signal.
- (gnome_calendar_new): hook up listener's "obj_updated" and
- "obj_removed" signals so if evolution is running twice,
- they will both see changes right away.
- (gnome_calendar_object_changed): don't call update_all, since
- it will be called by the listener.
- (gnome_calendar_remove_object): don't call update_all
- (gnome_calendar_add_object): don't call update_all
-
- * gui/gncal-full-day.c (child_realize): create fullday's gcs
- even if pixmap_bell has already been created. this was
- causing crashes if the calendar was run twice.
-
-2000-04-19 Seth Alves <alves@hungry.com>
-
- * gui/eventedit.c (ee_rp_init_rule): changed the order around
- a bit to avoid a Gtk-CRITICAL crash
-
- * gui/gncal-todo.c (gncal_todo_update): fixed code to populate
- the todo clist
-
- * cal-client/cal-client.c (cal_client_get_uids): don't check
- type against CALOBJ_TYPE_ANY since it will always match.
- (cal_client_get_uids): same (re: CALOBJ_TYPE_ANY)
-
- * pcs/cal-backend.c (build_uids_list): same (re: CALOBJ_TYPE_ANY)
-
- * pcs/cal.c (Cal_get_uids): same (re: CALOBJ_TYPE_ANY)
-
- * pcs/cal-backend.c (remove_object): don't call save from here
- because in all cases the caller of remove_object calls save
-
- * gui/calendar-commands.c (calendar_set_uri): calls gnome_calendar_open
- instead of checking on disk and calling load or create.
-
- * gui/gnome-cal.c (gnome_calendar_object_changed): fixed to use
- cal_client_update_object -- editing and dragging events works again
- (gnome_calendar_open): collapsed gnome_calendar_load and
- gnome_calendar_create into this function. added new type
- GnomeCalendarOpenMode which has the value CALENDAR_OPEN or
- CALENDAR_OPEN_OR_CREATE.
-
- * gui/evolution-calendar-control.c (calendar_properties_init): create
- a property bag for this control
- (set_prop): callback for property sets
- (get_prop): callback for proprety gets
-
- * gui/calendar-commands.c (calendar_set_uri): new function,
- called when the "calendar_uri" property is set on the calendar-
- control's property bag.
-
-2000-04-18 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/Makefile.am (INCLUDES): Fix include path.
-
-2000-04-16 Federico Mena Quintero <federico@helixcode.com>
-
- * pcs/cal-factory.h (CalFactoryClass): We have a new
- "last_calendar_gone" signal that Wombat can use to terminate
- itself properly.
-
- * pcs/cal-factory.c (cal_factory_class_init): Register the
- "last_calendar_gone" signal.
- (backend_destroy_cb): Emit the "last_calendar_gone" signal instead
- of killing the factory.
-
- * pcs/Makefile.am: Added $(CORBA_GENERATED) to BUILT_SOURCES.
- (INCLUDES): Make the log domain be "wombat-pcs".
-
-2000-04-17 Seth Alves <alves@hungry.com>
-
- * pcs/cal-backend.c (add_object): removed implicit save, since
- we don't want to save as we load from disk.
- (cal_backend_update_object): added a call to save, since it
- isn't done by add_object now.
-
-2000-04-16 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-util/Makefile.am: Renamed library from libcalutil to
- libcal-util, to be consistent with libcal-client. Install header
- files in $(includedir)/evolution/cal-util.
- (INCLUDES): Add "cal-util" log domain for glib.
- (libcal_clientincludedir): The header files are now installed in
- $(includedir)/evolution/cal-client.
-
- * cal-util/cal-util.h: Fix includes.
-
- * cal-client/client-test.c: Fix includes.
-
- * pcs/Makefile.am: Create libpcs.a, not a shared library, because
- it is for internal use by Wombat only. The header files should
- not be installed, either. Removed all the old Tlacuache stuff.
-
- * gui/Makefile.am (EXTRA_DIST): We no longer distribute
- gncal.desktop.
- (evolution_calendar_INCLUDES): Add "calendar-gui" for the glib log
- domain.
-
- * gui/*.[ch]: Fix cal-util and cal-client includes.
-
- * pcs/Makefile.am (INCLUDES): Added "pcs" log domain for glib.
-
- * pcs/*.[ch]: Fix cal-util includes.
-
-2000-04-11 Chris Toshok <toshok@helixcode.com>
-
- * pcs/icalendar.c (icaltime_to_timet): use HAVE_TIMEZONE to switch
- between linux's timezone variable and *bsd's method of getting the
- gmt offset.
-
-2000-04-10 Seth Alves <alves@hungry.com>
-
- * pcs/cal-backend.c (save_to_vcal): create and save an actual
- vcalendar instead of a list of vcal objects.
-
-2000-04-10 Damon Chaplin <damon@helixcode.com>
-
- * gui/Makefile.am (INCLUDES): moved srcdir directories to the top so
- we search headers in the evolution tree before installed headers.
- (Otherwise when you do 'make install' lots of files in gui/ get
- rebuilt, since they depend on the installed cal-client.h which has just
- been updated.)
-
-2000-04-09 Seth Alves <alves@hungry.com>
-
- * gui/gnome-cal.c (gnome_calendar_load): catch cal_loaded signal
- on the cal client.
- (gnome_calendar_load_cb): callback for cal_loaded signal. moved
- gnome_calendar_update_all from gnome_calendar_load to here.
-
- * gui/calendar-commands.c: minor cleanups
-
- * pcs/cal-backend.c (save_to_vcal): copied code from gnome-pim
- to write vcal to a file
- (save): filled it with more gnome-pim code
- (add_object): call save () after changing
- (remove_object): same
- (cal_backend_create): same
- (cal_backend_remove_object): same
-
-2000-04-08 Christopher James Lahey <clahey@helixcode.com>
-
- * gui/Makefile.am: Removed linking with libetable and libeminicard
- since they weren't being used.
-
-2000-04-08 Seth Alves <alves@hungry.com>
-
- * gui/gnome-cal.c (gnome_calendar_create): new function:
- friendly wrapper for cal_client_create_calendar
-
- * gui/calendar-commands.c (new_calendar): call gnome_calendar_create
- if no filename is provided
-
- * gui/prop.c (properties): calendar is a frame
-
- * gui/calendar-commands.c (calendar_control_activate): sort out the
- menus a bit, more of them show up now.
-
- * gui/Makefile.am: don't build library or test, just the bonobo control
-
- * gui/gncal-todo.c (simple_todo_editor): calendar is a frame instead
- of a window, now.
-
- * gui/gnome-cal.c (gnome_calendar_new): same
-
- * gui/goto.c (goto_dialog): same
-
-2000-04-06 Seth Alves <alves@hungry.com>
-
- * gui/calendar-commands.c (calendar_control_activate): removed
- uih from the argument list, added cal. use cal as user_data
- in callbacks rather than the control.
- (calendar_control_deactivate): removed uih from argument list
-
-2000-04-05 Seth Alves <alves@hungry.com>
-
- * gui/calendar-commands.c (setup_menu): removed
- (setup_appbar): removed
- (calendar_control_activate): new function -- does the work
- that setup_appbar and setup_menu used to do.
- (calendar_control_deactivate): undoes what calendar_control_activate
- does by removing the toolbar items and menu items.
-
- * gui/Makefile.am: build test-calendar-widget and evolution-calendar,
- common stuff is in a library
-
- * gui/gnome-cal.c (gnome_calendar_get_type): made the calendar widget
- based on a gtk_frame rather than a gnome_app
-
- * gui/calendar-commands.c: split out some of main.c
-
- * gui/evolution-calendar-control.c: bonobo bung so evolution
- can use the calendar widget
-
-2000-04-01 Matt Loper <matt@helixcode.com>
-
- * pcs/.cvsignore: Added *.lo.
-
-2000-03-30 Seth Alves <alves@hungry.com>
-
- * gui/main.c (calendar_get_events_in_range):
- cal_client_get_events_in_range returns a list of CalObjInstance *, not
- a list of (char *) uid.
-
- * Makefile.am (SUBDIRS): readded the gui directory
-
- * gui/main.c: temporarily added alarm_defaults back in,
- since the calendar doesn't link without it
-
-2000-03-29 Matt Loper <matt@helixcode.com>
-
- * Makefile.am: remove the gui directory, which doesn't compile.
-
-2000-03-28 Matt Loper <matt@helixcode.com>
-
- * pcs/Makefile.am: create a libpcs.la library, for use in the
- wombat.
-
-2000-03-28 Seth Alves <alves@hungry.com>
-
- * gui/Makefile.am (LINK_FLAGS): added libeutil.la and libetext.a
-
- * gui/main.c (calendar_iterate): switch from string_to_ical_object to
- ical_object_find_in_string
- (calendar_get_events_in_range): same
- (session_save_state): commented out references
- to gcal->client->filename
-
-2000-03-27 Federico Mena Quintero <federico@helixcode.com>
-
- * pcs/cal-backend.c (cal_backend_get_object): Use
- ical_object_to_string().
-
- * cal-util/calobj.c (ical_object_to_string): Moved over from
- pcs/cal-backend.c (was string_from_ical_object).
- (get_calendar_base_vobject): Likewise, moved over from
- pcs/cal-backend.c.
-
- * cal-util/cal-util.c: Removed string_to_ical_object(); the
- correct function is in calobj.[ch], called
- ical_object_find_in_string(). Removed ical_object_to_string,
- since we now implement it in calobj.c.
-
- * cal-util/calobj.c: Removed ical_object_new_from_string(); see
- above.
-
- * idl/evolution-calendar.idl (CalObjInstance): Calendar object
- instances now contain only the UID for the object, not the whole
- string representation of the object. This allows clients to
- implement caching of objects if they wish.
-
- * pcs/cal.c (Cal_get_events_in_range): Likewise.
-
- * pcs/cal-backend.c (build_event_list): Likewise.
-
- * cal-client/cal-client.c (cal_client_get_events_in_range):
- Likewise.
-
- * cal-util/cal-util.h (CalObjInstance): Likewise.
-
- * cal-util/cal-util.c (cal_obj_instance_list_free): Likewise.
- (cal_obj_uid_list_free): Assert that the UIDs in the list are not
- NULL.
-
- * pcs/tlacuache.gnorba (repo_id): The calendar factory also
- supports the Unknown interface.
-
-2000-03-17 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/e-day-view.c: Fix includes.
- (e_day_view_on_delete_occurance): Do not call save_default_calendar().
- (e_day_view_on_delete_appointment): Likewise.
- (e_day_view_on_unrecur_appointment): Likewise.
- (e_day_view_finish_long_event_resize): Likewise.
- (e_day_view_finish_resize): Likewise.
- (e_day_view_key_press): Likewise.
- (e_day_view_on_editing_stopped): Likewise.
- (e_day_view_on_top_canvas_drag_data_received): Likewise.
- (e_day_view_on_main_canvas_drag_data_received): Likewise.
-
-2000-03-13 Damon Chaplin <damon@helixcode.com>
-
- * gui/e-day-view*.[hc]: new files for the Day/Work-Week views.
-
-2000-03-12 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/main.c (gnome_calendar_locate): Removed function now that it
- is no CORBA server in the GUI.
- (save_default_calendar): Removed function. Now the personal
- calendar server will take care of saving modified calendars when
- appropriate.
- (close_cmd): Do not call unregister_calendar_services().
-
- * gui/eventedit.c (ee_ok): Do not save the calendar.
-
- * gui/gncal-day-panel.c (day_view_range_activated): Likewise.
-
- * gui/gncal-todo.c (ok_button): Likewise.
- (delete_todo): Likewise.
-
- * gui/gncal-full-day.c (delete_occurance): Likewise.
- (delete_appointment): Likewise.
- (unrecur_appointment): Likewise.
- (child_focus_out): Likewise.
- (update_from_drag_info): Likewise.
-
- * gui/gnome-cal.c (gnome_calendar_new): Removed obsolete call to
- create the CORBA server.
-
- * gui/gnome-cal.h (GnomeCalendar): Renamed `calc' field to
- `client'.
-
- * cal-client/cal-client.h (CalClient): Removed filename and
- corba_server fields.
-
-2000-03-10 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/main.c (main): Do not pass the INIT_SERVER flag to
- gnome_CORBA_init_with_popt_table(). Check for exceptions
- properly.
- (main): Initialize Bonobo.
- (main): Call process_dates() to parse the dates from the command
- line before we dump the events or the TODOs.
- (main): Use bonobo_main() instead of gtk_main().
-
- * cal-util/calobj.c (ical_new): Initialize the alarm types here.
- Do not call default_alarm() anymore, since that is a GUI issue.
- (default_alarm): Removed function.
- (alarm_defaults): Removed defaults data.
-
- * pcs/tlacuache.c (calendar_notify): Removed stubs for
- alarm_defaults, calendar_notify(), debug_alarms.
-
-2000-03-09 Federico Mena Quintero <federico@helixcode.com>
-
- * gui/Makefile.am: Removed the corba-cal stuff. Commented out the
- Pilot conduit stuff for now.
-
- * gui/calendar.c: Random #ifdefs to make it build, although this
- file is going away.
-
- * gui/Makefile.am: Removed referenes to calobj.[ch] and timeutil.[ch].
-
- * gui/calendar-conduit.c: Fixup includes.
-
- * gui/calendar-conduit.h: Fixup includes.
-
-2000-03-09 Seth Alves <alves@hungry.com>
-
- * gui/gnome-cal.h: replaced "Calendar *cal" with "CalClient *calc"
- in the GnomeCalendar struct.
-
- * gui/*.c: tracked change from Calendar * to CalClient
-
- * gui/main.c: moved alarm_defaults from here to cal-util/calobj.c
- (calendar_get_events_in_range): pulled this out of calendar.c and
- fixed it up to use cal-client stuff. i'm not sure where to put it yet.
-
- * gui/main.c (calendar_iterate): pulled this one out of calendar.c also
-
-2000-03-07 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-client/Makefile.am: Removed cal-client-alarm.[ch] from the
- list of sources. This was a miscommunication on our part.
-
-2000-03-05 Seth Alves <alves@hungry.com>
-
- * cal-client/cal-client-alarm.c: stubs for client side
- access to alarm structures. this will probably change,
- since i don't know what i'm doing.
-
- * cal-util/alarm-enums.h: enums for alarms needed by
- both the client and the server
-
- * remaining source files in calendar/... have been moved
- to calendar/gui.
-
- * gui/alarm.c: start to decouple the view from the model
- in the alarm editing code
-
-2000-03-03 Seth Alves <alves@hungry.com>
-
- * cal-util/Makefile.am: new file -- things shared between
- the client and server go in this directory
-
- * calobj.c calobj.h icalendar.c icalendar.h
- timeutil.c timeutil.h cal-util.c cal-util.h where moved
- backend stuff went into pcs. shared stuff went into
- cal-util.
-
-2000-03-02 Federico Mena Quintero <federico@helixcode.com>
-
- At this point the calendar client and personal calendar server
- files were moved to the idl/, cal-client/, and pcs/ directories.
-
- * idl/Makefile.am: New file.
-
- * cal-client/Makefile.am: New file. Moved the libcal-client stuff
- from calendar/Makefile.am to here.
-
- * pcs/Makefile.am: New file. Moved the tlacuache stuff from
- calendar/Makefile.am to here.
-
- * Makefile.am (SUBDIRS): Added the idl and cal-client directories.
-
- * calendar.h: Removed the references to cal-backend.h and its
- stuff. This file is going away soon!
-
- * icalendar.c: #include <config.h>. Also, we don't need to
- include cal-backend.h or gnome.h.
-
- * icalendar.h: Protect from multiple inclusions.
-
-2000-03-01 Federico Mena Quintero <federico@helixcode.com>
-
- * Makefile.am: Use the gnome-config flags for orbit-idl.
- Create a libcal-client library with the calendar client object.
-
-2000-02-29 Federico Mena Quintero <federico@helixcode.com>
-
- * Makefile.am: Removed stale rule for the conduit.
-
-2000-02-21 Matt Loper <matt@helixcode.com>
-
- * .cvsignore: Added *.lo.
-
-2000-02-19 Matt Loper <matt@helixcode.com>
-
- * .cvsignore: Added tlacuache and tl-test.
-
-2000-02-18 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * Makefile.am (INCLUDES): Use BONOBO_VFS_GNOME_CFLAGS instead of
- GNOMEUI_INCLUDES, as we use Bonobo and VFS.
-
-2000-02-17 Seth Alves <alves@hungry.com>
-
- * cal-backend.h: moved CalendarFormat type def here
-
- * cal-backend.c (cal_backend_load): if extension suggests
- an ical file, attempt to load an iCal file.
- (cal_get_type_from_filename): returns CAL_ICAL if file
- extension is 'ics' or 'ifb', else returns CAL_VCAL
- (icalendar_calendar_load): moved this here from
- icalendar.c because it needs to call the static function
- add_object.
-
-2000-02-17 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-client.c (cal_client_remove_object): Implemented.
-
- * cal.c (cal_notify_remove): Implemented.
- (Cal_remove_object): Implemented.
- (cal_get_epv): Fill in the remove_object field in the epv.
-
- * cal-backend.c (cal_backend_remove_object): Implemented.
- (notify_remove): New function to notify clients that an object was
- removed.
-
-2000-02-16 Russell Steinthal <rms39@columbia.edu>
-
- * calobj.[ch], eventedit.c, main.c: Change iCalObject.organizer
- from char* to iCalPerson*
-
- * calobj.[ch]: Change iCalObject.related from list of char* to
- list of iCalRelation*; assorted related fixes
-
- * icalendar.c: interface between libical and the gnomecal
- internal representation
-
-2000-02-11 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-client.c (cal_client_update_object): Implemented.
-
- * cal.c (cal_notify_update): New function to notify the listener
- about an updated object.
- (Cal_update_object): Implemented.
- (Cal_get_uids): set_release() the sequence to TRUE.
- (Cal_get_events_in_range): Likewise.
-
- * cal-backend.c (remove_object): New function to remove objects
- from a calendar backend.
- (cal_backend_update_object): New public function to update an
- object and notify clients about it.
-
- * evolution-calendar.idl (Cal): Added update_object() and
- delete_object() methods.
- (Listener): Removed the obj_changed method and renamed obj_added
- to obj_updated. We now only have updated and removed notifiers.
-
- * cal-listener.[ch]: Removed the "changed" notification code.
- Changed the "added" notification code to the "updated"
- notification.
-
- * cal-client.c: Likewise.
-
- * tlacuache.c (create_cal_factory): Connect to "destroy" on the
- factory and exit the main loop when the factory is destroyed.
-
- * cal-factory.c (backend_destroy_cb): New callback used when a
- backend is destroyed. Removes the backend from the factory's hash
- table and unrefs the factory if all backends go away.
- (add_calendar_client): Free the environment.
-
- * cal.c (cal_new): Use bonobo_object_unref() if we fail to
- initialize.
-
- * cal-listener.c (cal_listener_new): Likewise.
-
- * layout.c (layout_events): Plug li.partition memory leak.
-
-2000-02-10 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-backend.c (cal_backend_add_cal): Connect to the Cal's
- destroy signal.
- (cal_backend_remove_cal): Killed function now that removal of Cal
- objects is done in their destroy callback.
- (cal_destroy_cb): New callback to remove a Cal from the backend's
- list of clients. Also, the backend destroys itself when there are
- no more clients connected to it.
- (save): New placeholder function to save a backend.
- (destroy): New function to destroy a backend's data.
- (cal_backend_destroy): Save the calendar and destroy it.
-
- * cal.c (cal_destroy): Reset the priv->backend to NULL.
-
- * cal-factory.c (add_calendar_client): There is no need to call
- cal_backend_remove_cal(); we can now just destroy the Cal object.
- (create_fn): Make sure we always unref the URI.
- (load_fn): Move the URI unref to the end of the function for
- safety.
-
- * cal-factory.c (add_calendar_client): Unref the Cal only if
- notification of the listener was unsuccessful. Otherwise, the
- calendar user agent (Listener side) keeps the reference.
-
- * tl-test.c (list_uids): Free the calobj.
-
- * cal-client.c (cal_loaded_cb): Use bonobo_object_unref() to get
- rid of the listener.
- (load_or_create): Likewise.
- (destroy_factory): New function to get rid of the factory.
- (destroy_listener): New function to get rid of the listener.
- (destroy_cal): New function to get rid of the calendar client
- interface object.
- (cal_client_destroy): Free all resources.
- (cal_client_get_object): CORBA_free() the calobj string. Boy, I
- love memprof.
-
- * cal-listener.c (cal_listener_destroy): Reset the priv->cal to
- CORBA_OBJECT_NIL.
-
- * cal-backend.c (cal_backend_remove_cal): Do not unref the Cal,
- since the calendar user agent owns it.
- (cal_backend_add_cal): Do not ref the Cal, since the calendar user
- agent owns it.
-
- * cal-factory.c (add_calendar_client): Use bonobo_object_unref()
- to get rid of the calendar client interface object.
-
- * calobj.c (ical_object_create_from_vobject): Duplicate the
- default "PUBLIC" string.
-
-2000-02-09 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-factory.c (cal_factory_load): Added documentation comment.
- (load_fn): Do not print a message if the backend could not be
- loaded due to a non-fatal error.
- (queue_load_create_job): Moved the stuff from cal_factory_load()
- to here. Now this function serves to queue load or create
- requests.
- (cal_factory_load): Use queue_load_create_job().
- (cal_factory_create): Implemented; use queue_load_create_job().
- (create_fn): New job handler for creating new calendars.
- (create_backend): New function to create a new backend with a new
- calendar.
- (add_backend): New helper function to add backends to the
- factory's hash table.
- (load_backend): Use add_backend() instead of adding the backend by
- ourselves.
-
- * cal-client.c (load_or_create): Moved the functionality from
- cal_client_load_calendar() to here, and added an option to create
- a new calendar instead of loading an existing one.
- (cal_client_load_calendar): Use load_or_create().
- (cal_client_create_calendar): Implemented.
-
- * cal-backend.c (cal_backend_create): Implemented.
-
- * evolution-calendar.idl (LoadStatus): Added an IN_USE error for
- create requests.
-
- * cal-listener.h (CalListenerLoadStatus): Added CAL_LISTENER_LOAD_IN_USE.
-
- * cal-listener.c (Listener_cal_loaded): Convert the IN_USE error.
-
- * cal-client.h (CalClientLoadStatus): Added CAL_CLIENT_LOAD_IN_USE.
-
- * cal-client.c (cal_loaded_cb): Handle CAL_LISTENER_LOAD_IN_USE.
-
- * tl-test.c: New test program for the calendar client side; it
- also exercises the server side by sending commands to it.
-
- * Makefile.am: Added the tl-test program.
-
- * tlacuache.gnorba: Updated.
-
- * tlacuache.c (create_cal_factory): Use the right GOAD id.
-
- * cal-client.c (cal_client_construct): Use the right GOAD id.
-
-2000-02-08 Federico Mena Quintero <federico@helixcode.com>
-
- * evolution-calendar.idl (Cal): Added get_uids() method to get a
- list of UIDs based on object types.
-
- * cal-backend.c (cal_backend_get_uids): Implemented get_uids() in
- the backend.
-
- * cal.c (Cal_get_uids): Implemented get_uids() method.
-
- * cal-client.c (cal_client_get_uids): Implemented client-side
- function.
-
- * cal-util.c (cal_obj_instance_list_free): Doh. Free the list,
- not the last link.
- (cal_obj_uid_list_free): New function to free a list of UIDs.
-
- * GnomeCal.idl (Repository): Removed unused method
- get_object_by_id_list(). This is just for cleanup purposes and to
- remind me exactly of what needs to be moved over to
- evolution-calendar.idl.
- (Repository): Removed unused get_objects() method.
-
- * corba-cal.c (init_calendar_repo_class): Removed the unused
- get_objects method.
-
- * calobj.h (CalObjFindStatus): New status value enumeration for
- the find function.
-
- * calobj.c (ical_object_find_in_string): New function to parse a
- complete calendar and find a calendar object in it. This should
- be used instead ical_object_new_from_string() in the future.
-
- * evolution-calendar.idl (CalObjInstance): Added an uid field.
- Now the idea is that whenever calendar object strings are passed
- around, their UIDs are passed along with them so that the actual
- object can be pulled from the whole VCAL object using its UID to
- identify it.
-
- * cal-util.h (CalObjInstance): Added uid field.
-
- * cal-util.c (cal_obj_instance_list_free): Free the UIDs.
-
- * cal-backend.c (build_event_list): Store the object's UID in the
- instance structure.
-
- * cal.c (Cal_get_events_in_range): Copy the UID field to the CORBA
- structure.
-
- * cal-client.c (cal_client_get_events_in_range): Copy the UID
- field from the CORBA structure.
-
- * main.c (gnome_cal_file_menu): Removed unfinished html-month stuff.
-
- * Makefile.am (gnomecal_SOURCES): Removed html-month.c.
-
- * gnome-cal.c: #include "alarm.h"
- (mail_notify): Made static.
-
- * alarm.h: #include "calobj.h"
-
- * corba-cal-factory.h (init_corba_server): Fixed prototype.
-
- * quick-view.c (create_items_for_event): Made static.
-
- * gncal-todo.c (column_resized): Made static.
-
- * layout.c (find_index): Made static.
-
-2000-02-08 Federico Mena Quintero <federico@helixcode.com>
-
- * evolution-calendar.idl (CalObjInstance): New struct to wrap
- instances of calendar objects for recurrencies and alarms.
- (Cal::get_events_in_range): New method to get ocurring and
- recurring events by time range.
-
- * cal-backend.c (cal_backend_get_events_in_range): New function to
- get a list of event instances in a time range.
- (string_from_ical_object): New internal function.
- (cal_backend_get_object): Use string_from_ical_object() instead of
- doing everything ourselves.
- (cal_backend_get_events_in_range): New function to get a list of
- the events that occur or recur in a specified time range.
-
- * cal-client.c (cal_client_get_events_in_range): Implemented
- client-side function.
-
- * cal-util.h:
- * cal-util.c: New files with utilities and types common to the
- client and server parts.
- (CalObjInstance): New structure to hold an instance of an actual
- occurrence, recurrence, or alarm trigger of a calendar object.
- (cal_obj_instance_list_free): New function to free a list of
- calendar object instances.
-
- * cal.c (Cal_get_events_in_range): Implemented new method.
-
- * corba-cal.c (cal_repo_get_updated_objects): Free `str' with
- free(), not g_free(), since calendar_get_as_vcal_string() uses
- writeMemVObject(), which uses realloc(). Fixed in gnome-pim as
- well.
-
-2000-02-04 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-backend.c (get_calendar_base_vobject): New function to
- create the base VObject for a calendar.
- (cal_backend_get_object): Create the base calendar and add the
- sought object to it, then stringify it.
-
- * evolution-calendar.idl (Listener::obj_added
- Listener::obj_changed): Now these pass in just the UIDs, not the
- complete objects.
-
- * cal-listener.c (Listener_obj_added): Changed to pass in the uid,
- not the object.
- (Listener_obj_changed): Likewise.
-
- * cal-client.h (CalClientClass): Made the obj_added and
- obj_changed signals take in the UIDs, not the full objects.
-
- * cal-client.c (obj_added_cb): Likewise.
- (obj_changed_cb): Likewise.
-
-2000-02-04 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-backend.c (CalBackendPrivate): Renamed the event_hash field
- to object_hash. Now we hash all the calendar's objects here based
- on their UIDs.
- (ensure_uid): New function to create UIDs for calendar objects
- that don't have them.
- (add_object): Ensure the object has an UID before inserting it in
- the calendar.
- (cal_backend_get_object): New function.
-
-2000-02-03 Federico Mena Quintero <federico@helixcode.com>
-
- * evolution-calendar.idl (Cal): Added the get_object() method.
-
- * cal-client.c (cal_client_get_object): New function to get a
- calendar object by its UID.
-
- * cal.c (Cal_get_object): Implemented.
-
- * cal-backend.c (cal_backend_get_object): New unfinished backend
- function. We need some reorganizing of how the calendar objects
- are stored.
-
-2000-02-02 Federico Mena Quintero <federico@helixcode.com>
-
- * Makefile.am (gnomecal_SOURCES): Added the CORBA generated
- sources.
-
-2000-02-01 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-client.c (cal_loaded): Handle the cal_loaded signal from the
- listener. Store the calendar client interface object, and emit
- our own cal_loaded signal.
- (cal_client_load_calendar): Connect to the listener's signals.
- (cal_client_class_init): Added the "obj_added", "obj_removed",
- öbj_changed" signals.
- (obj_added_cb): Handle the signal from the listener.
- (obj_removed_cb): Likewise.
- (obj_changed_cb): Likewise.
-
-2000-01-30 Federico Mena Quintero <federico@helixcode.com>
-
- * Makefile.am (gnomecal_SOURCES): Added cal-client.[ch] and
- cal-listener.[ch].
-
-2000-01-30 Federico Mena Quintero <federico@helixcode.com>
-
- * evolution-calendar.idl: Changed the namespace from
- GNOME::Calendar to Evolution::Calendar.
- (Listener::LoadStatus): Fixed SUCESSS -> SUCCESS typo. And I
- never noticed it in the implementation. Ain't M-/ grand?
-
- * Makefile.am: Changed ocurrences of gnome-calendar.idl to
- evolution-calendar.idl.
-
- * *.[ch]: Changed GNOME_Calendar_foo identifiers to
- Evolution_Calendar_foo.
-
-2000-01-25 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-client.c cal-client.h: New files with the calendar client
- object.
-
-2000-01-25 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-factory.c (CalFactory_load): Check that the listener is not
- nil and emit and exception if it is.
-
- * gnome-calendar.idl (CalFactory::load CalFactory::create): Now
- these raise the NilListener exception.
-
- * tlacuache.c (calendar_notify): Error stub for alarms.
- (alarm_defaults): Stub array.
- (debug_alarms): Stub variable.
- (main): Initialize gnome-vfs.
-
-2000-01-24 Federico Mena Quintero <federico@helixcode.com>
-
- * tlacuache.c: New main module for the Tlacuache personal calendar
- server.
-
- * tlacuache.gnorba: New gnorba file for Tlacuache, the GNOME
- personal calendar server.
-
- * Makefile.am: Added the stuff necessary to build Tlacuache.
-
- * cal.c (Cal_get_uri): Convert the URI to a string before
- returning it.
-
- * cal-factory.c (CalFactory_create): Doh, this function is void.
-
- * job.c (job_add): Use g_idle_add(), not gtk_idle_add().
-
-2000-01-24 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-backend.c (cal_backend_remove_cal): New function to remove a
- calendar client interface object from a backend.
- (cal_backend_load): Convert the URI to string and use
- Parse_MIME_FromFileName(). The conversion is not very smart,
- though.
-
- * cal-factory.c (load_backend): Moved most of the error handling
- upstream to load_fn().
- (load_fn): Handle failure in case the backend could not be loaded.
- (cal_factory_destroy): Free the backends and the backend hash
- table.
- (add_calendar_client): Implemented. We create a Cal client
- interface object and attach it to the backend, and we notify the
- listener.
-
-2000-01-22 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-factory.c (lookup_backend): Renamed from lookup_calendar().
- Also, return a backend instead of a Cal client object.
-
- * cal-backend.c (cal_backend_load): Take in a GnomeVFSURI, not a
- string.
-
- * cal-listener.c (Listener_cal_loaded): Pass the load status to
- the signal.
- (cal_listener_destroy): Better error checking.
- (cal_listener_new): Better error checking.
-
- * cal-listener.h (CalListenerLoadStatus): New enum for the load
- status of a calendar.
- (CalListenerClass): Added the status argument to the cal_loaded
- signal.
-
- * gnome-calendar.idl (cal_loaded): Added a load status code.
-
- * cal-backend.h (CalBackendLoadStatus): Renamed from
- CalBackendLoadResult.
-
-2000-01-18 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-backend.c cal-backend.h: Moved the calendar backend here.
- This is the actual calendar-handling object.
- (load_from_vobject): Moved over from calendar.c. Modified to use
- a CalBackend instead of the old Calendar structure.
- (add_object): Likewise.
-
- * cal.c: Now the Cal object is just a calendar client interface
- object; we use it as a "viewport" onto a CalBackend. This also
- lets us do correct resource management.
-
- * cal-common.h: New file with common forward declarations; we
- can't have circular dependencies between headers.
-
-2000-01-18 Federico Mena Quintero <federico@helixcode.com>
-
- * cal-factory.c (cal_factory_load): Queue a load job.
- (load_fn): Load job handler. Lookup the calendar by URI, load it
- if it is not loaded, or just report it to the new listener if it is.
-
- * job.c job.h: New files with a simple job queue manager.
-
- * gnome-calendar.idl (Listener::cal_loaded): Do not return the
- whole calendar object string. The client will be able to query
- the calendar for the events it needs.
-
- * cal-listener.c (Listener_cal_loaded): Ref the calendar GNOME
- object. We unref it when the listener is destroyed.
-
-2000-01-17 Federico Mena Quintero <federico@helixcode.com>
-
- The files from the gncal directory of the gnome-pim module on CVS
- were moved here, to evolution/calendar, in preparation for the
- Evolution work. The calendar is being split into a model/view
- architecture. The model is a personal calendar server (PAS): it
- provides storage, notification, and event generation; the
- views/controllers are the calendar user agents and things like
- Pilot synchronizers.
-
-2000-01-11 Federico Mena Quintero <federico@helixcode.com>
-
- * cal.c: Removed the CORBA listener methods, adjusted for the new
- IDL.
-
- * cal-listener.c (cal_listener_init): Create the private
- structure. In it we hold a reference to the calendar the listener
- is watching.
- (cal_listener_destroy): Destroy the private structure and unref
- the calendar.
- (Listener_cal_loaded): Stuff the calendar into our private data.
- (Listener_obj_added): Adjusted for new IDL.
- (Listener_obj_removed): Likewise.
-
- * gnome-calendar.idl: New IDL for the personal calendar server.
-
- * cal.h cal.c: New files with the calendar object.
-
- * cal-listener.h cal-listener.c: New files with the calendar
- listener object.
-
- * cal-factory.h cal-factory.c: New files with the calendar factory
- object.
-
-2000-01-09 Eskil Heyn Olsen <deity@eskil.dk>
-
- * Makefile.am: Changes to remove todo capplet stuff from distro.
-
-2000-01-08 Vadim Strizhevsky <vadim@optonline.net>
-
- * calendar-conduit-control-applet.c: Added pilotID argument to
- gpilotd_conduit_mgmt_new.
-
-
-2000-01-05 Eskil Heyn Olsen <deity@eskil.dk>
-
- * GnomeCal.idl: Added an argument to get_number_of_objects, so you
- can choose which state the object should have
- (any/new/modified/...). Will also add one to choose type
- (event/journal etc).
-
- * corba-cal.c (cal_repo_get_number_of_objects): Implemented the
- new version of get_number_of_objects.
-
- * calendar-conduit.c (pre_sync): Calls various
- gnome_pilot_conduit_standard_abs_set_num_yadayda to get progress bars.
-
-2000-01-04 Eskil Heyn Olsen <deity@eskil.dk>
-
- * calendar-conduit.c (start_calendar_server): Let's not call
- g_error, but g_warning instead.
- (pre_sync): Get record numbers info, total, new, deleted etc, and
- tell gpilotd.
-
-1999-12-31 Eskil Heyn Olsen <deity@eskil.dk>
-
- * eventedit.c (ee_store_recur_end_to_ical): Adds 86400 secs (1
- day) to the date chooses by the user. This ensures the recurrence
- also occurs on that date.
- (ee_rp_init_ending_date): And subtracts 86400 secs when about to
- redisplay the box.
-
- * calendar.h: Added an argument to calendar_new, to enable certain
- features, such as initing alarms or nor.
-
- * calendar.c (calendar_new): Implemented support for the
- CALENDAR_INIT_ALARMS option to calendar_new.
-
- * corba-cal.c (cal_repo_get_updated_objects): Added
- CALENDAR_INIT_ALARMS to calendar_new calls.
-
- * main.c: Added CALENDAR_INIT_ALARMS to calendar_new calls. This
- should probably be CALENDAR_INIT_NIL, but I'm not sure, guess
- steintr should check it.
-
- * gnome-cal.c: Added CALENDAR_INIT_ALARMS to calendar_new calls.
-
- * calendar-pilot-sync.c: Added CALENDAR_INIT_NIL to calendar_new calls.
-
-1999-12-10 Russell Steinthal <rms39@columbia.edu>
-
- * eventedit.c (ee_create_ae): Fix sensitivity bug when used to
- create default alarm box (widgets in that box should always be
- sensitive, even if the enabled checkbutton is not set)
-
-1999-12-08 Eskil Heyn Olsen <deity@eskil.dk>
-
- * calendar-conduit-control-applet.c (setSettings): Capplets now
- sets first_sync on enable, this should make the conduit copy old
- entries from the pilot to gnomecal.
-
-1999-12-07 Eskil Heyn Olsen <deity@eskil.dk>
-
- * calendar-conduit.c (pre_sync): Check if local store is
- empty. If, force slow sync.
-
- * GnomeCal.idl (GNOME): Added get_number_of_objects.
-
- * corba-cal.c (cal_repo_get_number_of_objects): implemented the
- get_number_of_objects.
-
- * calendar-conduit-control-applet.c (setStateCfg): Fixed bug that
- caused the capplet to always set the sync action to Disable upon start.
-
-1999-12-05 Eskil Heyn Olsen <deity@eskil.dk>
-
- * Makefile.am (Conduits_second_DATA): Also install .desktop files
- for conduit capplets in the gnome/apps menu dir.
-
-1999-12-04 Eskil Heyn Olsen <deity@eskil.dk>
-
- * Makefile.am (EXTRA_DIST): Added .desktop files to EXTRA_DIST.
-
-1999-10-12 Clifford R. Conover <rusty@zootweb.com>
-
- * gncal-todo.c Todo List improvements.
-
- Cleaned up todo item highlighting, added support for highlighting
- events due today, and events not due yet. Colors are configurable
- on the Colors Tab of the properties window.
-
- Renamed Frame in Properties window to Colors rather then Month
- Colors since we are now asking for Todo item colors.
-
- Added ability to display time until todo item is due in list, it
- automatically selects the best denomination of time (up to weeks)
- and down to seconds to display. This should be made configurable
- in a future version.
-
- Changed Todo dialog to ask for time that event is due. This
- allows more accurate tracking of then the item is due, before the
- dialog was only asking for the date of the todo item.
-
-1999-12-03 Eskil Heyn Olsen <deity@eskil.dk>
-
- * calendar-conduit.c: undef DEBUG_CALCONDUT, suppresses debug output.
-
-1999-12-02 Russell Steinthal <rms39@columbia.edu>
-
- * alarm.c: Enhanced debug support: can be toggled on and off by
- SIGUSR1, reports alarms which could not be added
-
- * gnome-cal.c, main.[ch], prop.c: Add snooze capability for audio
- and display alarms. Snooze interval can be configured in the
- Properties box.
-
-1999-11-30 Eskil Heyn Olsen <deity@eskil.dk>
-
- * calendar-conduit.c (compare): Fixed compare bug. Also neated up
- some of the if's in set_status.
-
-1999-11-22 Russell Steinthal <rms39@columbia.edu>
-
- * Merged todo list coloring patch from stable
- * Added myself to AUTHORS, about box (per Miguel)
-
-1999-11-22 Eskil Heyn Olsen <deity@eskil.dk>
-
- * calendar-conduit.c (pre_sync): Writes some warning
- messages when pre_sync fails.
-
-1999-11-14 Eskil Heyn Olsen <deity@eskil.dk>
-
- * Makefile.am: Stupid misplaced endif cause gncal to depend on an
- install gnome-pilot... fixed... sorry.
-
-1999-11-12 Eskil Heyn Olsen <deity@eskil.dk>
-
- * Makefile.am (extra_pilot_bins): Fixed the if then else problem,
- using solution suggested by James Henstridge, appears to be caused
- by a (by now fixed) bug in my automake.
-
-1999-11-12 Russell Steinthal <rms39@columbia.edu>
-
- * prop.c: Config code for timeout, make Alarms property page use a
- vbox instead of an hbox so that the propbox stays a reasonable width.
-
- * gnome-cal.c, main.[ch]: Add timeout for audio alarms, code to load
- from config file
-
- * eventedit.c: Give some static functions external linkage so they
- can be used elsewhere (make_spin_button); add some prototypes to
- appease gcc.
-
-1999-11-11 Russell Steinthal <rms39@columbia.edu>
-
- * calendar.c (calendar_day_change): Add call to
- calendar_init_alarms() to schedule another day change alarm.
-
-1999-11-09 Eskil Heyn Olsen <deity@eskil.dk>
-
- * calendar-conduit.c: Enabled debug output. Sets a g_log_domain,
- now version 0.8.5. Consistent use of GSList/GList. Implemented
- compare, default uses one that compares the contents of a struct
- Appointment, but also has #ifdeffed code that does a field level
- comparison, not complete, but perhaps educational.
-
- * Makefile.am (#todo_conduit_control_applet_SOURCES): Fixed an
- unwanted conditional on libcalendar_conduit_la_LDFLAGS
-
-1999-11-05 Eskil Heyn Olsen <deity@eskil.dk>
-
- * calendar-conduit-control-applet.c (readStateCfg): Commented the
- code out, thus the capplet works again.
-
-1999-11-04 Eskil Olsen <deity@eskil.dk>
-
- * Makefile.am: Uses the PISOCK_LIBDIR, for people with odd install
- dirs for their pilot-link. Also install a pretty icon for the
- calendar-conduit.
-
- * calendar-conduit-control-applet.c: Modfied the
- try/revert/ok/cancel scheme to be more intuitive, also uses a
- GtkOptionMenu for the possible sync methods.
-
- * calendar-conduit-control-applet.desktop: use the nice icon...
-
- * calendar-conduit.c: Ack, had to define debug_alarms and
- alarm_default, otherwise they are undefined. Is gncal code messy
- or is this considered a way of configuring the cal engine ?
- Implemented delete_all syncabs methods.
-
- * calendar-pilot-sync.c: also had to declare debug_alarms and
- alarm_defaults, just as ugly.
-
-1999-11-02 Russell Steinthal <rms39@columbia.edu>
-
- * prop.c: Add new alarm page to properties box
-
- * prop.c, calobj.c, main.[ch] eventedit.c: New support for default
- alarms, configurable in the properties box.
-
- * gnome-cal.c, prop.c, main.[ch]: add option to beep on Display
- alarms
-
-1999-10-23 Russell Steinthal <rms39@columbia.edu>
-
- * calendar.c (calendar_new): Correctly initialize calendar_day_end
- and calendar_day_begin *before* installing day-change alarm.
-
-1999-10-21 Russell Steinthal <rms39@columbia.edu>
-
- * alarm.c, main.c: Added alarm debugging code
-
- * main.c (open_ok): Show an error box if the user tries to open a
- non-existent file; fixes bug #1818
-
-1999-10-19 Russell Steinthal <rms39@columbia.edu>
-
- * gnome-cal.c (calendar_notify): Fix typos which were causing
- invalid times in audio notification dialogs; fixes Bug #2561
-
-1999-10-18 Russell Steinthal <rms39@columbia.edu>
-
- * gncal-day-panel.c (gncal_day_panel_new): Placed the various
- elements of the day view in paned windows so that the user can
- adjust the relative sizes of the daily schedule, monthly calendar,
- and to-do list.
-
-1999-10-18 Martin Norbäck <norpan@bigfoot.com>
-
- * gncal.desktop: Added swedish translation
-
-1999-10-13 Eskil Olsen <deity@eskil.dk>
-
- * Makefile.am: Hopefully the fixes the much-hated
- gnome-pilot dependency.
-
-1999-10-07 Eskil Olsen <deity@eskil.dk>
-
- * calendar.c (calendar_object_changed): moved the pilot_status =
- MOD up, so even a CHANGE_SUMMARY will set the modified flag.
-
- * calendar-conduit.c: more _free calls, vamped the noise on output.
-
-1999-10-06 Eskil Olsen <deity@eskil.dk>
-
- * *conduit*[ch]: checks return values from gpilotd_init/connect.
-
- * calender.c (vcalendar_create_from_calendar): removed a set
- of cleanVObject cleanStrTbl, since the freed memory that the
- function returned.
-
-1999-09-27 Timur Bakeyev <mc@bat.ru>
-
- * timeutil.c (time_from_isodate): Use tm.gmtoff or timezone to get
- correct offset from UTC, according to HAVE_TM_GMTOFF or HAVE_TIMEZONE.
- See also 1999-07-19 Matt Martin <matt@abacusnet.net>
-
-1999-09-27 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * month-view.c (add_event): ditto
- (mark_current_day): ditto
- (month_view_set): ditto
-
- * goto.c (goto_dialog): ditto.
-
- * gnome-month-item.c (gnome_month_item_init): ditto.
-
- * gncal-day-panel.c (gncal_day_panel_new): ditto.
-
- * getdate.c (RelativeDate): ditto.
-
- * eventedit.c (set_all_day): ditto.
- (ee_rp_init_rule): ditto.
-
- * calendar.c (vcalendar_create_from_calendar): ditto.
-
- * calendar-conduit.c (update_record): ditto.
-
- * calobj.c (ical_object_generate_events): Get rid of pointers to
- values returned from localtime, as it uses a static buffer.
-
-1999-09-26 Eskil Olsen <deity@eskil.dk>
-
- * corba-cal.c: the g_free that was commented out since glib said
- was a duplicate free, was supposed to be a free.
-
- * GnomeCal.idl/corba-cal.c: added a get_object_id_list and a
- get_objects_by_id_list. Latter is not done.
-
- * calendar-conduit.c: rewrote the way the conduit iterates over
- records. It no longers fetches all entries (since that didn't work
- with more then 285 entries. It now fetches the id list, and gets
- each record. (will be using get_objects_by_id_list to get records
- in amounts of 10 or so later, to reduce amount of corba calls).
-
- * calendar-conduit.c: now sets alarm parameters when transferring
- from gnomecal to pilot.
-
-1999-09-23 Eskil Olsen <deity@eskil.dk>
-
- * calendar-conduit.c: better merge of summary/description
- when doing ical_from_remote (update_record), also handles
- import from gnomecal to pilot better, and on both ways, repeat
- events are much better now.
-
-1999-09-22 Eskil Olsen <deity@eskil.dk>
-
- * corba-cal.c: commented out a g_free that glib reported
- as being a duplicate free.
- * calendar-conduit.c: got gnomecal->pilot up and runnning.
-
-1999-02-06 Lauris Kaplinski <lauris@ariman.ee>
-
- * gncal.desktop: Added Estonian translations.
-
-1999-09-14 Federico Mena Quintero <federico@redhat.com>
-
- * gncal-full-day.c (child_popup_menu): Set the data pointers for
- all the items.
-
-1999-09-14 Kjartan Maraas <kmaraas@online.no>
-
- * doc/C/gnomecal.sgml: Merge from gnome-pim-1-0. Synced with newest
- user-guide.
-
-1999-09-01 Miguel de Icaza <miguel@gnu.org>
-
- * eventedit.c (ee_create_buttons): Make the OK button the default
- button per Russell's suggestion.
-
-1999-08-30 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * calendar.c (calendar_object_changed): Modify the
- object->last_mod field.
- (calendar_add_object): Ditto.
-
- Closes bug #676
-
- * main.c (save_calendar_cmd): Fix problem in which we warned the
- user about the calendar being modified the first time the calendar
- was used.
-
-1999-08-22 Tomas Ogren <stric@ing.umu.se>
-
- * gnomecal.gnorba: "GenericFactoy" is wrong...
-
-1999-08-15 Miguel de Icaza <miguel@gnu.org>
-
- * calobj.c (ical_gen_uid): Fix the hostname part.
-
-1999-08-07 Peter Teichman <pat4@acpub.duke.edu>
-
- * calendar-pilot-sync.c (sync_pilot): sync correctly for objects
- created on the pilot, but not dirty (because they have been synced
- with some other program in the past)
-
-1999-07-30 Miguel de Icaza <miguel@gnu.org>
-
- * month-view.c (month_view_init): Release points here.
-
-1999-08-02 Peter Teichman <pat4@acpub.duke.edu>
-
- * Makefile.am (libcalendar_conduit_la_LDFLAGS):
- libcalendar_conduit now installs
-
- * calendar-pilot-sync.c (sync_pilot): do deletion of appointments
- correctly, when they are deleted on the pilot
- (conduit_free_Appointment): protect against double-freeing parts
- of the Appointment structure
- (update_record): all-day events from the pilot are handled a bit
- more reasonably
-
-1999-08-01 Peter Teichman <pat4@acpub.duke.edu>
-
- * calendar-pilot-sync.c (sync_object_to_pilot): The multi-day
- appointment corruption bug is dead. Whoo!
-
-1999-07-31 Peter Teichman <pat4@acpub.duke.edu>
-
- * Makefile.am: fixed this up slightly with respect to pilot conduits
-
-1999-07-30 Jonathan Blandford <jrb@redhat.com>
-
- * Makefile.am (libcalendar_conduit_la_LIBADD): More autoconf-stuff
-
-1999-07-29 Jonathan Blandford <jrb@redhat.com>
-
- * gnome-cal.c (setup_widgets): Add scrolling to the yearview.
-
-1999-07-28 Miguel de Icaza <miguel@gnu.org>
-
- * calendar-pilot-sync.c: (sync_object_to_pilot): If the enddate is
- not set, set the repeatForever to 1. This fixes all of the
- birthdays problems I had.
-
- Make the code not take arguments
- (sync_cal_to_pilot): Nice event update information
-
- * calendar.c (calendar_new): Add Event UID hash table.
- (calendar_add_object): Add events to the hash table here.
- (calendar_remove_object): Remove events here.
- (calendar_object_find_event): Use the hash table here.
-
- * main.c (save_calendar_cmd): The object is already destroyed by
- gnome_dialog_run.
-
- * calendar-pilot-sync.c (sync_object_to_pilot): Do not turn
- archived bit on.
-
- * calobj.c (ical_gen_uid): Use the hostname, not the domain name.
- (ical_gen_uid): Add a serial number. Isodates can be small.
-
- * corba-cal.c (cal_repo_update_pilot_id): New method to update the
- pilot status.
- (cal_repo_get_updated_objects): New method. Returns a list of
- modified and not-sycned objects
-
- * calendar-pilot-sync.c (sync_cal_to_pilot): New function to sync
- from the GnomeCalendar to the pilot.
- (sync_object_to_pilot): Sync a single event to the pilot.
- (try_alarm): Alarm syncing code.
-
-1999-07-27 Miguel de Icaza <miguel@gnu.org>
-
- * calendar-pilot-sync.c: New file. Implements PalmPilot
- syncronization with the Gnome Calendar.
-
- * calobj.c (ical_object_new_from_string): New function. Creates
- an iCalObject from a vCalendar string that is supposed to contain
- only one vEvent.
-
- * calendar.c:
- (calendar_save): Split this routine in two.
-
- * gnome-cal.c (gnome_calendar_new): Create the corba server here.
-
- * main.c: Include gnorba.h, and corba-cal-factory.h here
- (close_cmd): Kill the calendar server on shutdown.
-
- * calobj.c (load_recur_yearly_day): Added a fixme comment. WE
- need to handle intervals in the years.
-
- * calendar.c (calendar_object_find_in_list, calendar_object_find,
- calendar_object_find_todo, calendar_object_find_event): New
- functions for looking up information.
-
- * main.c (gnome_calendar_locate): New function.
-
- * corba-cal.c (calendar_create_object): New file. Implements the
- corba server.
-
- * calendar.c (calendar_object_changed): Flag pilot-status as changed.
-
- * calobj.c (ical_object_to_vobject): Save pilot information for syncing.
- (ical_object_create_from_vobject): Load syncing information for
- pilot. Do it in a way compatible with KOrganizer.
-
-1999-07-26 Miguel de Icaza <miguel@gnu.org>
-
- * calobj.c (ical_object_create_from_vobject): Generate unique IDs
- on Vevents we load that lack it. WE need this for the old
- gnome calendar generated files (ie, before now :-).
-
- Required to sync with the Palm
-
-1999-07-26 Miguel de Icaza <miguel@gnu.org>
-
- * calobj.c (ical_object_create_from_vobject): Generate unique IDs
- on Vevents we load that lack it. WE need this for the old
- gnome calendar generated files (ie, before now :-).
-
- Required to sync with the Palm
-
-1999-07-19 Matt Martin <matt@abacusnet.net>
-
- * timeutil.c (time_from_isodate): Handle the 'Z' parameter to the
- ISO date format to convert from GMT time.
-
-1999-07-17 Nat Friedman <nat@gnome-support.com>
-
- * calendar.c (calendar_add_object): Copy the new UID into the
- iCalObject structure.
-
-1999-07-16 Miguel de Icaza <miguel@gnu.org>
-
- * gnome-month-item.c (gnome_month_item_set_arg): Merge fix from
- gnome-pim-1-0: Fixed cut&paste bug for day fontsets.
-
-1999-07-14 Miguel de Icaza <miguel@gnu.org>
-
- * calobj.c (ical_gen_uid): Returns a UID.
- (ical_object_new): Use a UID when creating an event. Should get
- syncing done easier.
-
-1999-07-14 Nicholas J Kreucher <nick@poetic.com>
-
- * calobj.c (skip_numbers): Actually skip over the numbers.
- (ical_object_to_vobject): Test the proper variable for storing the
- proper information.
-
-1999-07-14 Jean-Noel Guiheneuf <jean-noel.guiheneuf@wanadoo.fr>
-
- * timeutil.c (time_add_month): Fixed the problem with next month
- going from a 31-day to a 30-day by adjusting the date to the
- closest day at the end of the month.
-
-1999-06-07 Mike McEwan <mike@lotusland.demon.co.uk>
-
- * timeutil.c (time_add_month): Tell ktime' that we don't know
- about daylight saving time so that it does *not* make adjustments
- when we traverse a DST boundary.
- (time_year_begin): ditto.
- (time_year_end): ditto.
- (time_month_begin): ditto.
- (time_month_end): ditto.
-
-1999-06-16 Anders Carlsson <anders.carlsson@tordata.se>
-
- * main.c (new_calendar): Realize the toplevel widget when
- --hidden is passed to gnomecal. This fixes a segfault.
-
-1999-06-04 Robert Brady <rwb197@ecs.soton.ac.uk>
-
- * gnome-cal.h, gnome-cal.c: Fix abort() problem with the year view.
- (Bug #1367). Thanks to Owen Cliffe <oc197@ecs.soton.ac.uk> for
- helping track it down.
-
-1999-06-03 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * calobj.c (daynumberlist): One line bug fix from Sergey I Panov.
-
-1999-06-02 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * view-utils.c (nicetime): Use %H instead of %k, as %k is a GNU
- extension, not available in other systems.
-
-1999-06-01 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * calobj.c (daynumberlist): Work around broken software that
- writes a broken month-of-day as "zero". Use the dtstart date for
- this on this event.
-
-1999-05-28 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * Makefile.am (install-data-local): help files be gone. They are
- now installed from the Docbook stuff.
-
-1999-05-26 Russell Steinthal <steintr@condor.penguinpowered.com>
-
- * gncal-todo.c main.c main.h prop.c: Added support for priorities
- for todo items. Doesn't do much, but you can set them and sort by
- them. (Use the properties box to enable them; should they be on
- by default?)
-
-1999-05-25 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * main.c (parse_an_arg): Added missing break here. It was causing
- core dumps when invoked with --userfile.
-
- * gnome-cal.c (gnome_calendar_set_view): Add some assertions here,
- to pin point the bug reported on gnome-list.
-
- * calobj.c (load_recurrence): Make intervals always exist. a 0
- interval is wrong.
-
-1999-05-25 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * year-view.c: Removed unused macro CALENDAR_HEIGHT.
-
-1999-05-25 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * year-view.c (idle_handler): Set the canvas scroll region here,
- not in size_allocate(). Also, use the correct width and height
- based on the allocation and the precomputed minimum width/height
- values.
-
- * gnome-cal.c (setup_widgets): Set the scrollbar policy of the
- scrolled window.
-
- * main.c (setup_appbar): Use the correct type for the appbar.
-
- * gncal-day-view.c: Removed unused function switch_to_day().
-
- * gncal-day-panel.c (calendar_day_selected): Removed unused variable.
-
-1999-05-25 Nat Friedman <nat@nat.org>
-
- * doc/C/gnomecal.sgml: Fixed a typo.
-
- * gnome-cal.c (setup_widgets): Added a scrolled window widget into
- which the year view is placed.
-
- * year-view.c (CALENDAR_HEIGHT): The height of the total year view
- inside the scrolled window.
- (idle_handler): Set the height of the year view to
- CALENDAR_HEIGHT.
- (year_view_size_allocate): Set the scroll region of the year view
- canvas to allocation->width, CALENDAR_HEIGHT.
-
-1999-04-25 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * main.c (dump_todo): Add --todo flag to dump the todo contents.
-
-1999-04-19 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gncal-todo.c (add_activated): Use same hack used in edit_activated
-
-1999-04-16 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gncal-todo.c (edit_activated): Kill all grabs from the CList
- before running the new dialog box.
-
- This fixes the problem of button-3/Edit on the todo item blocking
- the GUI (actually, the main window responds, but not the todo
- window).
-
-1999-04-08 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gncal-todo.c (gncal_todo_init): Make sure we can get events for
- button3. The code for the nice popup menu was there but was not
- getting invoked.
-
-1999-04-01 Steve Murphy <murf@e-tools.com>
-
- * calobj.c (weekdaynum): Added this routine so Monthly recurrences
- use the weekday field as a simple integer for a single weekday.
-
- * calobj.c (load_recur_monthly_pos): Call weekdaynum instead of
- weekdaylist. The interface only lets the user input a single value
- anyway.
-
- * calobj.c (ical_object_to_vobject): instead of code to output day
- names from a bit array, use instead the value as an int and output
- a single dayname.
-
- * calobj.c (ical_object_generate_events): first_week_day gets the
- day int instead of the first entry in the bit field. I inserted a
- fair chunk of code to avoid calling generate if the day is out of
- range for a month. It may be unneccessary, because mktime will
- turn the extra days into a valid date the next month. But not all
- mktimes are equal, I fear.
-
- * eventedit.c (ee_store_recur_rule_to_ical): For case 3,
- (Monthly), I added code to set the interval slot of the recur
- struct; without this value, selecting a monthly recursing, by
- date, would lead to an infinite loop broken only by a failure to
- alloc more memory. Also, in the "by position" case, both
- u.month_pos and u.month_day were being assigned values. This is a
- mistake, as they are both part of an union, and the same
- thing. The weekday field should get the recur_rr_month_weekday
- value.
-
- * eventedit.c (ee_rp_init_rule): set default day from the weekday
- field instead of the u.month_day field, which is really the
- month_pos value.
-
- * gnome-cal.c (gnome_calendar_tag_calendar): Month days start with
- 1, not 0; thus, setting tm.tm_mday = 0, and then calling mktime
- will generate a time corresponding to the end of the previous
- month, which may have a mday anywhere from 28 to 31. The end time
- just adds 1 to the month, so your end time may not cover the last
- few days of this month, depending on what the biggest mday of last
- month was. I changed it so tm_mday is set to 1 instead.
-
-1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-todo.c (convert_time_t_to_char): Made static. Make it use
- the full year format for strftime().
-
-1999-03-27 Nuno Ferreira <nmrf@rnl.ist.utl.pt>
-
- * calobj.c: Include <config.h> So that strings get translated.
-
-1999-03-26 Tomas Ogren <stric@ing.umu.se>
-
- * prop.c (build_hours_menu): Made it respect 12/24h settings..
- Doesn't show until next time you open the dialog.. yet..
-
-1999-03-24 Tomas Ogren <stric@ing.umu.se>
-
- * gncal-week-view.c (gncal_week_view_set): Did some i18n work
- * eventedit.c (get_exception_string): Did some i18n work
-
-1999-03-24 Tomas Ogren <stric@ing.umu.se>
-
- * gncal-todo.c (gncal_todo_init): Made clist titles i18n:able
- * main.c (poptOption): Added which views that are possible for
- --view in the --help text (closes #367)
- * main.c (dump_events): Added (short) month to the strftime and made
- the strings i18n:able
-
-1999-03-23 Tomas Ogren <stric@ing.umu.se>
-
- * gncal/calobj.c: Added 2 paranthesis..
- "foobar = d / 60*60" is _NOT_ the same as "foobar = d / (60*60)"
- which caused heavy alarm-corruption with alarms between 2 hrs and
- 2 days.
-
-1999-03-23 Nat Friedman <nat@nat.org>
-
- * eventedit.c (ee_store_recur_rule_to_ical): Set the
- recur->interval to the value of the recur_rr_month_period spin
- button if the event is being set "by day." This closes bug #675
- as reported by bagfors@hpc2n.umu.se. Thanks for the report!
-
-1999-03-10 Clifford R. Conover <rconover@montana.edu>
-
- * gncal-todo.c (simple_todo_editor): Add support for Due Date when
- adding a TODO item here.
- (column_resized): New function
- (init_column_sorting): New function.
- (todo_click_column): New function.
- (convert_time_t_to_char, make_overdue_todo_style): New functions.
-
- * gnome-cal.c (gnome_calendar_todo_properties_changed): New
- function used to update the TODO when the properties have been
- chagned for it.
-
- * prop.c (prop_apply_todo): Apply TODO properties.
-
- * gncal-day-panel.c (todo_list_properties_changed): Update the
- TODO display here.
-
- * eventedit.c (date_edit_new): Made public
-
-1999-03-10 Craig A Soules (soules+@andrew.cmu.edu)
-
- * timeutil.c, calendar.c, calobj.c, gncal-day-panel.c: Add support
- for daylight time savings.
-
-1999-02-28 Martin Baulig <martin@home-of-linux.org>
-
- * gncal-full-day.c (recompute_motion): For DRAG_MOVE, DRAG_SIZE_TOP
- and DRAG_SIZE_BOTTOM: call child_focus_out () if the child currently
- has the focus.
-
-1999-02-27 Changwoo Ryu <cwryu@adam.kaist.ac.kr>
-
- * quick-view.c (QUICK_VIEW_FONTSET): Added Korean font to the
- fontset string.
- * mark.h (*_FONTSET): Likewise.
-
-1999-02-23 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * calobj.c (ical_object_to_vobject): Save the owner/organizer of
- the event.
- (ical_object_create_from_vobject): Load the owner/organizer of the event.
-
- * gncal-full-day.c (delete_occurance): Assign child to data (fixes
- crash on "delete this occurrance").
-
-1999-02-22 Timur Bakeyev <mc@bat.ru>
-
- * calendar.c: According to configured values, use either tm.tm_zone
- or tzname. In last case, also declare it extern.
-
- * prop.c: langinfo.h not available everywhere. Wrapped. BTW, works
- fine without it.
-
-1999-02-20 Tomas Ogren <stric@ing.umu.se>
-
- * main.c (init_username): Made use of g_get_{user,real}_name() instead
- of our own home-brew...
-
-1999-02-17 Sergey Panov <sipan@mit.edu>
-
- * gnome-month-item.c,gnome-month-item.h,goto.c,mark.h,
- month-view.c,prop.c,quick-view.c,year-view.c: will define
- fonts via fontset. Friendlier to locales that use iso8859-[^1]
- and koi8-r encodings. Does not solve problem for Asian languiges
- --- better solution is needed (e.g. standart GNOME fontstyles
- defined in gtkrc).
-
-1999-02-16 Sergey Panov <sipan@mit.edu>
-
- * main.c: Use N_() macro for color settings labels in
- color_props structure.
-
-1999-02-15 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * goto.c (goto_dialog): Indentation fixes.
-
-1999-02-15 Tomas Ogren <stric@ing.umu.se>
-
- * goto.c: Made a private copy of what localtime() returns, to be able
- to keep the data after more calls to localtime().
-
-1999-02-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * main.c (save_default_calendar): New function. Saves the
- calendar if it is the user's default calendar
-
- * gncal-full-day.c (unrecur_appointment):
- * gncal-day-panel.c (day_view_range_activated):
- * eventedit.c (ee_ok):
- * gncal-todo.c (ok_button): Added autosave for the default
- calendar.
-
-1999-02-09 Tomas Ogren <stric@ing.umu.se>
-
- * main.c: Removed the gtk_widget_realize call.
-
-1999-02-06 Changwoo Ryu <cwryu@adam.kaist.ac.kr>
-
- * gncal.desktop: Added Korean translations.
-
-1999-02-04 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * eventedit.c (date_edit_new): New convenience function to create
- a properly-configured date editor widget.
-
-1999-02-03 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-week-view.c (gncal_week_view_new): Make the calendar start
- weeks on Monday if appropriate.
- (gncal_week_view_time_format_changed): New function to notify the
- week view that the time format has changed.
-
- * gncal-day-panel.c (gncal_day_panel_new): Make the calendar start
- weeks on Monday if appropriate.
- (gncal_day_panel_time_format_changed): New function to notify the
- day panel that the time format has changed.
-
- * gnome-cal.c (gnome_calendar_time_format_changed): Tell the day
- and week views that the time format has changed.
-
-1999-02-01 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * eventedit.c (event_editor_init): Set the title of the event
- editor window.
-
-1999-01-31 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-day-view.c (gncal_day_view_expose): Do not remove the
- clipping rectangle here.
-
- * view-utils.c (view_utils_draw_events): Remove the clipping
- rectangle here, since the user of this function should not know
- about it.
-
-1999-01-30 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * view-utils.c (view_utils_draw_events): Improve this draw
- routine. Now it can split the text in lines and fit as many
- events as possible.
- (nicetime): Return strings without spaces at the beginning.
-
- * gncal-day-view.c (gncal_day_view_expose): Move clip-clear
- operation here.
-
-1999-01-29 Jason Tackaberry <tack@dok.org>
-
- * gncal-full-day.c (child_popup_menu): if the user clicks on an
- event that is an occurance, the menu will allow the user to delete
- all occurances of this event, or just the selected occurance.
- (delete_occurance): added.
-
- * eventedit.c (append_exception): force the clist to select the
- new exception. (fixes segfault)
- (delete_exception): if the last exception in the clist is deleted,
- move the selection index up. (fixes segfault)
-
-1999-01-28 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * main.c (parse_an_arg): Add --hidden key to hide the calendar at
- startup. Only works with GNOME window managers though :-(
-
- * calendar.c (calendar_day_change): Reschedule alarms for the new day.
-
- (calendar_init_alarms): Schedule an alarm for midnight to change
- the calendar_day_begin/calendar_day_end.
-
- * alarm.c (alarm_ready): If we reschedule, there is no need to
- activate any pending alarms.
-
-1999-01-28 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-full-day.c (child_new): Insert the summary text here.
- (child_focus_in): No need to raise the window, since we have
- Spiffo(tm) layout code. Boy, this is old code.
- (gncal_full_day_focus_child): Now that GtkText works better, we
- can avoid synthesizing a click which was causing grief, anyway.
- (child_button_press): Grab the focus before popping up the menu.
-
- * layout.c (find_index): Added a sanity check.
-
- * gncal-full-day.c (child_destroy): Unmap and unrealize the child
- before unparenting/destroying it.
- (child_unrealize): Unrealize the widget. What was I thinking?
- (child_new): Save the focus_out_event signal connection id in
- Child structure (in a new field).
- (child_destroy): Disconnect from the focus_out_event signal, since
- we don't want to get such an event when the widget is destroyed.
- (gncal_full_day_destroy): Destroy the children properly; it was
- leaking memory.
-
-1999-01-27 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * main.c (save_calendar_cmd): Warn if the calendar file has
- changed.
-
- * calendar.c (calendar_load, calendar_save): Keep track of the
- modification time for the calendar file.
-
-1999-01-20 Nat Friedman <nat@nat.org>
-
- * gncal-full-day.c (gncal_full_day_key_press): Only trap printable
- characters such that hotkeys work.
- (UNSELECT_TIMEOUT): Changed to 0. Much saner behavior.
-
- * prop.c (properties): Connect gnome_help_pbox_display to the
- GnomePropertyBox help button.
-
-1999-01-19 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * quick-view.c (quick_view_do_popup): Do not grab the mouse here
- (it was being grabbed incorrectly, anyways).
- (quick_view_map_event): Grab the mouse when the window is mapped.
- This avoids the ugly "while (xGrabPointer () != Success)" hack.
- (quick_view_button_release): Handle button releases here.
-
-1999-01-19 Tomas Ogren <stric@ing.umu.se>
-
- * main.c: do gtk_widget_realize on the toplevel window..
-
-1999-01-13 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-day-panel.c (gncal_day_panel_new): Make the little
- calendar start up with the correct date.
-
- * gncal-week-view.c (gncal_week_view_set): Add the month to the
- date range display label.
-
-1999-01-08 Nat Friedman <nat@nat.org>
-
- * main.c: Converted some more stuff to use the standards.
-
-1999-01-08 Nat Friedman <nat@nat.org>
-
- * main.c (setup_appbar): New function to create the status bar.
- (setup_menu): Install menu hints.
-
- Menu items updated to match the standards. New Settings menu
- created.
-
-1998-12-30 Jeff Garzik <jgarzik@pobox.com>
-
- * gncal/calendar.c, gncal/gnome-cal.c, gncal/main.c,
- gncal/quick-view.c:
- s/g_copy_strings/g_strconcat/
-
-1998-12-16 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- Rewrote the old and broken alarm system. It never actually
- worked properly. Now it works properly, and I figured a nice way
- to get the Audio alarm do something nicer (it is now like an alarm
- clock :-).
-
- * gnome-cal.c (calendar_notify): Now we take a CalendarAlarm to
- actually distinguish which alarm was triggered.
-
- * alarm.c (alarm_ready): The code was only activating the first
- alarm. Reschedule the timer upon delivery of an alarm.
-
-1998-12-14 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * year-view.c (idle_handler): Use the allocation size instead of
- the old fields in the canvas structure.
-
- * goto.c (create_days): Use gtk_widget_set_usize() instead of
- gnome_canvas_set_size().
- * quick-view.c (setup_event_list): Likewise.
-
-1998-12-09 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gncal-todo.c (simple_todo_editor): Use gnome_dialog_set_parent.
- * goto.c (goto_dialog): ditto
- * prop.c (properties): ditto.
-
-1998-11-23 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * eventedit.c (ee_rp_init_exceptions): Update GtkClist usage.
-
-1998-11-23 Andrew T. Veliath <andrewtv@usa.net>
-
- * gncal-day-panel.c (gncal_day_panel_new): Use
- gtk_scrolled_window_add_with_viewport instead of
- gtk_container_add (gtk changes).
-
-1998-11-23 Herbert V. Riedel <hvr@hvrlab.ml.org>
-
- * eventedit.c: use GPOINTER_TO_INT
-
- * gncal-todo.c: same.
-
-1998-11-22 Matthew Wilson <msw@redhat.com>
-
- * main.c: Fixed the popt event parsing callback to have the
- correct number of arguments. This stops it from segfaulting.
-
-1998-11-16 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * eventedit.c (ee_classification_widgets): Doh. Fixed stupid bug
- where the classification buttons were not being set correctly.
- (ee_store_general_values_to_ical): Take into account the fact that
- radio group lists are stored in reverse order of insertion.
-
- * gncal-todo.c (gncal_todo_init): Use a scrolled window to put the
- clist into.
-
-1998-11-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * calendar.c (calendar_save): Backup the old file before saving
- the caledar.
-
-1998-11-06 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * calobj.c: Add ctype.h
-
-1998-10-31 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gnome-cal.c (gnome_calendar_direction): Add the offset from the
- beginning of the current time unit (day/month/etc), otherwise it
- does not work right, for example, you are on the 31st day of a
- month and the next month is a 30-day one and you jump to the next
- month.
-
-1998-10-16 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * month-view.c: Changed a lot of stuff not to use the layout code
- -- the month view's days are too small to display layout
- usefully. Now they display a little list of the events in each
- day. We also have a popup menu for the days in the month view.
-
- * calendar.c (calendar_get_objects_in_range): Reverse the list so
- that it is returned in increasing order.
-
- * eventedit.c (event_editor_new_whole_day): New public function to
- create an event for the complete span of day_begin to day_end.
-
- * year-view.c (new_appointment): Use event_editor_new_whole_day().
-
- * year-view.c (yv_popup_menu): Mark strings for i18n.
-
-1998-10-12 Ji Lee <g@ucsd.edu>
-
- * eventedit.c (ee_store_recur_rule_to_ical): The interval was
- never being loaded from the spin button.
-
-1998-10-09 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * month-view.c (month_view_update): Create a list of children and
- lay them out nicely. Lots of functions added for this purpose.
- (adjust_segment): Main event segment adjustment routine.
- (adjust_children): Adjusts all the children in the month view.
- (child_create_segments): Creates the segments for a particular event.
- (layout_children): Uses the generic layout engine to organize the children.
-
-1998-10-08 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-todo.c (clist_row_selected): Set the sensitivity of the
- edit/delete buttons.
- (gncal_todo_update): Likewise. Thanks to Dirk Luetjens for the
- bug report.
-
- * layout.c: Do some cleanup; now we pass a struct with the layout
- algorithm's state instead of passing a trillion parameters around.
-
- * gncal-full-day.c (layout_children): Use the new generic layout
- engine.
- (child_compare): Sort keys are start time then end time, not just
- start time. This produces somewhat nicer results for the layout
- algorithm.
-
- The new layout code uses a partition of the time range occupied by
- the events, rather than using a fixed time granularity. This is
- better since the different parts of the program that use the
- layout module will have different semantics regarding snapping the
- event bounds to a fixed "time grid".
-
-1998-10-07 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * layout.[ch]: New files that abstract the event layout code from
- gncal-full-day.c into something useful for other parts of the
- program. Now all event layout is done here.
-
- * Makefile.am (gnomecal_SOURCES): Added layout.[ch] to the list of
- sources.
-
-1998-10-07 Carsten Schaar <nhadcasc@fs-maphy.uni-hannover.de>
-
- * main.c (main): Replaced the 'gnome_client_new_default' call with
- 'gnome_master_client'.
-
-1998-10-02 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * timeutil.c (time_day_begin): Changed name from
- time_start_of_day() to be consistent with the other begin/end functions.
- (time_day_end): Likewise.
-
- * calobj.c (ical_object_get_first_weekday): New public function to
- get the first toggled day in a weekday mask. Since we do not
- support multiple weekdays in a monthly-by-pos rule, we just fetch
- the first toggled one.
- (ical_object_generate_events): Added a missing break statement.
-
- * timeutil.c (time_month_end): Made it consistent with the rest of
- the time begin/end functions -- now it returns the first second of
- the *next* month.
- (time_week_end): Actually implemented this function. It will be
- used when the week view is rewritten.
-
- * calobj.c (time_in_range): Fix off-by-one in the comparison of
- the time against the end time.
-
- * gncal-full-day.c (expand_space): Fixed bug where the columns not
- were being expanded due to a missing "slot + j".
-
-1998-10-01 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * month-view.c (month_view_init): Use the font #defines.
- (month_view_new): Set the colors of the month view upon creation.
- (mark_current_day): New function to mark the current day in the
- month view.
- (month_view_set): Mark the current day.
- (month_view_colors_changed): Mark the current day and colorify the
- month item appropriately.
-
- * month-view.h: Added year and month fields to the MonthView
- structure.
-
- * main.c: Renamed the Appointments color property, since it will
- be used by the month view as well.
-
- * goto.c (update): Set the current day's font and color.
-
- * year-view.c (year_view_init): Set the fonts of the month items
- when creating them.
-
- * mark.h: Added new #defines for HEADING_FONT and TITLE_FONT.
-
- * year-view.c (year_view_init): Use the new font #defines.
-
- * prop.c (prop_apply_colors): Fixed to work with the
- I-am-paranoid-and-I-need-to-size-my-ints changes to
- GnomeColorPicker.
- (color_spec_from_picker): Likewise.
-
-1998-09-30 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * goto.c (create_days): Colorify the month item and prepare it for
- prelighting here.
-
- * main.c (color_props): Changed the default colors to something
- not dull.
-
- * year-view.c (compute_min_size): New function to compute the
- minimum size of the year view properly.
- (year_view_size_request): Added two new fields to the year view
- structure that contain the minimum size. Return this in the
- size_request method.
- (year_view_new): Call compute_min_size to save the minimum size
- for later use.
- (idle_handler): Make it resize the items correctly.
-
- * gnome-month-item.c (gnome_month_item_set_arg): Reshape when
- necessary. This is needed becaues we now actually calculate a
- minimum size for the month item based on the font sizes and paddings.
- (check_heading_sizes): New function to calculate a minimum size
- based on the headings' dimensions.
- (check_day_sizes): New function to calculate a minimum size based
- on the day number labels' dimensions.
- (check_sizes): New function that computes a minimum size for the
- month item.
- (reshape): Now calls check_sizes() to ensure a minimum size for
- the month item.
-
- * year-view.c (mark_current_day): New function to mark the current
- day in the year view.
-
- * mark.c: Removed mark_current_day from here.
-
-1998-09-29 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * prop.c (fetch_color_spec): Changed name from fetch_prelight_spec
- and made it conform to the new prelighting mechanism.
- (fake_mark_days): Set the proper day attributes.
- (reconfigure_month): Use colorify_month_item().
- (fake_mark_days): Use mark_month_item_index().
-
- * mark.c (colorify_month_item): New public function to reset the
- colors in a month item.
- (get_attributes): New internal function that creates an array of
- attributes for the days in a month item. This is the basis of all
- the new optimizations to month item marking.
- (unmark_month_item): Now it uses the attributes array to unmark
- only the days that need unmarking.
- (mark_event_in_month): Update the day attributes array.
- (month_item_prepare_prelight): Changed the definition of the
- prelight color query function. Use the new function.
- (day_event): Do color changes based on the day attributes array.
- (mark_month_item_index): New public function to mark a single day
- by index.
- (mark_event_in_month): Use mark_month_item_index().
-
- * gnome-month-item.c (gnome_month_item_num2child): Now takes an
- int, not a GnomeMonthItemChild.
- (gnome_month_item_child2num): Now returns an int, not a
- GnomeMonthItemChild.
- (gnome_month_item_num2day): Now takes an int, not a
- GnomeMonthItemChild.
-
- * goto.c (goto_dialog): Create the days before the year spin
- button, because the year_changed callback expects the month item
- to be created. The new semantics of the spin button cause it to
- emit a value_changed signal on the adjustment upon creation -- is
- this the behavior we want from it?
- (goto_dialog): Use gtk_window_set_modal() instead of the
- deprectaed gnome_dialog_set_modal().
-
- * quick-view.c (quick_view_new): Make it look not as crappy by
- putting the title inside the frame.
- (quick_view_do_popup): Fixed the pointer grab and added a cursor.
- (create_items_for_event): Query the text width/height from the
- text item using the new object arguments, so that the size of the
- popup window can be set properly.
-
- * year-view.c (do_quick_view_popup): Calculate a nice date string
- for the popup window.
-
-1998-09-28 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * quick-view.[ch]: New file that presents a quick view of the
- events in a particular day when the mouse is clicked on the year
- view. Work in progress.
-
- * year-view.c (do_quick_view_popup): New function that creates a
- quick view for the events in a day.
-
- * Makefile.am (gnomecal_SOURCES): Added quick-view.[ch] to the
- list of sources.
-
-1998-09-27 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * main.c: Hotkey for File/Exit should be C-q, not C-x.
-
-1998-09-24 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * year-view.c (do_popup_menu): New function to execute the popup
- menu in the year view.
- (day_event): Invoke the popup menu with the context set to days.
- (new_appointment): New function to create a new appointment from
- the year view.
- (do_jump): New function to do the appropriate view/date jumping
- from the popup menu.
-
- * main.c: Fixed two icons in the File menu.
-
-1998-09-21 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * main.c: Added underlined shortcuts and accelerators to the main menu.
-
-1998-09-16 Raja R Harinath <harinath@cs.umn.edu>
-
- * gncal-week-view.c (<gtk/gtklabel.h>): Include.
- * gncal-week-view.h (<gtk/gtkvbox.h>): Include.
-
-1998-09-06 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gnome-cal.c (mail_notify): Fixed the bug reported about the mail
- notification not beint sent until the program was terminated.
-
-1998-09-03 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-full-day.c (gncal_full_day_forall): Updated foreach ->
- forall from Gtk changes, bleah.
-
- * year-view.c (day_event): New function to handle events from
- days. Jumps to the day that is clicked.
-
- * main.c: Use a watch cursor while the previous/today/next
- functions are doing their job.
-
- * mark.c (month_item_prepare_prelight): New public utility
- function to prepare a month item for prelighting. It will store
- the proper prelight information and attach the appropriate signals.
- (mark_current_day): Make the current day bold as well (useful for
- color-blind people, I guess).
-
- * prop.c (set_current_day): Reset the date in the sample calendar
- and mark the current day.
- (fake_mark_days): Mark fake events in the sample calendar.
-
- * year-view.c (year_view_set): Use the general prelighting engine.
-
- * goto.c (day_event): Just process button presses, as prelighting
- is done behind the scenes now.
- (update): Use the general prelighting engine.
-
- * prop.c (create_colors_page): We can now configure the colors of
- the monthly calendars! Wheeeeee! There are still some nits to be
- fixed, which are listed in the TODO file.
- (build_color_spec): New function to build color specifications.
- (parse_color_spec): New function to parse color specifications.
-
- * mark.c: Modified all functions to use the configured colors.
- * goto.c: Likewise.
-
- * main.c (colors_changed): New function that notifies all
- calendars that colors have changed.
-
- * gnome-cal.c (gnome_calendar_colors_changed): New function that
- notifies all the views that the colors have changed.
-
- * month-view.c (month_view_colors_changed): New function that
- notifies the month view that colors have changed.
-
- * year-view.c (year_view_colors_changed): New function that
- notifies the year view that colors have changed.
-
- * gnome-month-item.h (struct _GnomeMonthItem): Added fields for
- outline and day box colors.
-
- * gnome-month-item.c (gnome_month_item_set_arg): Added
- outline_color, outline_color_gdk, day_box_color, and
- day_box_color_gdk arguments to month items. These are convenient
- to quickly set the colors of the month item.
- (gnome_month_item_get_arg): Likewise.
-
- * main.[ch]: Added a global array of structures for color preferences.
-
-1998-08-31 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * goto.c: Small code cleanup.
- (day_event): Upon receiving a LeaveNotify event, Reset the day's
- background to the correct color.
-
-1998-08-29 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * mark.[ch]: New files with utility functions to mark calendars
- with their events.
-
- * mark.c (mark_month_item): New public function to mark a month
- item with events.
- (unmark_month_item): New public function to unmark all the days in
- a month item to their default appearance.
-
- * year-view.c (year_view_set): Use the new unmark_month_item() and
- mark_month_item() to mark the months with events.
-
- * goto.c (update): New function that updates the calendar in the
- Go-to dialog by marking the days.
-
- * timeutil.c (time_year_begin): Modified to take a time_t value.
- (time_year_end): Likewise.
- (time_month_begin): Actually implemented this function, which was
- in the header file but not here.
- (time_days_in_month): New public function that returns the number
- of days in a month.
-
- * Makefile.am (gnomecal_SOURCES): Added mark.[ch] to the sources.
-
- * year-view.c (unmark_days): Use unmark_month_item().
-
- * gncal-full-day.c (gncal_full_day_destroy): Fixed crash when
- destroying the full day view. The full day's destroy method is
- unusual in that it destroys the list of child widgets itself, as
- it does not have a remove method, so it needs to reset the list to
- NULL.
-
-1998-08-27 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gnome-month-item.c (build_month): Now does the correct thing
- when the user wants weeks to start on Monday. Now all the Monday
- special casing, as far as day numbering is concerned, is only in
- this function.
-
- * year-view.c (mark_days): This function marks the days that have
- events in them. It also fixes a memory leak in the old
- implementation (it was leaking the whole list).
- (unmark_days): New function used to unmark all the days in the
- year view.
- (mark_event): New function that marks all the days that are
- spanned by a time range. It also fixes the bug in the old
- implementation where it could possibly mark days past the ends of
- the year (if the event crosses year boundaries, for example).
-
- * timeutil.c (time_year_begin): Take the year parameter since year
- 1, not 1900.
- (time_year_end): Likewise.
-
- * year-view.c (year_view_size_allocate): Now changing the size of
- the calendars is done in the idle loop.
- (idle_handler): This function actually does the resizing of the items.
-
- * year-view.h (struct _YearView): Added idle_id and need_resize
- fields.
-
-1998-08-26 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * year-view.c: Beginning of the new year view. Sizing and event
- marking needs to be finished.
-
- * gnome-cal.c: Updated for year-view.
- (gnome_calendar_time_format_changed): Use year_view_time_format_changed().
-
- * year-view.[ch]: Renamed the gncal-year-view.[ch] files to
- year-view.[ch].
-
- * Makefile.am (gnomecal_SOURCES): Updated year-view.[ch] in the
- list of source files.
-
-1998-08-25 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * goto.c (create_days): Set the heading color of the month item.
-
- * main.c: Use GNOME_STOCK_PIXMAP_JUMP_TO, now that it exists,
- instead of goto.xpm. Also, removed goto.xpm from cvs.
-
- * gnome-month-item.h (struct _GnomeMonthItem): Added fields for
- the heading and day number fonts. Added fields for heading and
- day number label colors.
-
- * gnome-month-item.c (gnome_month_item_class_init): ARG_DAY_NAMES
- should be write-only. Also, added arguments for heading and day
- number fonts. Added arguments for heading and day number colors.
-
-1998-08-24 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * prop.c (build_two_radio_group): Doh. Set the state of the radio
- buttons properly.
-
- * month-view.c (month_view_time_format_changed): New public
- function that notifies the month view of a time format change.
-
- * gnome-cal.c (gnome_calendar_time_format_changed): New public
- function that notifies the calendar of a time format change.
-
- * main.c (time_format_changed): Use gnome_calendar_time_format_changed().
-
- * month-view.c (month_view_update): New public function to update
- the month view when an event changes. This is still unfinished.
- (month_view_set): New public function to set the month in the
- month view.
-
- * gnome-cal.c (gnome_calendar_direction): Add case for month view.
- (gnome_calendar_set_view): Likewise.
- (gnome_calendar_update_all): Likewise.
-
- * timeutil.c (time_add_week): Implemented the time_add_week()
- function, which was on the header file.
- (time_add_month): Added public month-adding routine.
-
- * gnome-cal.c (gnome_calendar_get_current_view_name): Add case for
- month view.
- (gnome_calendar_goto): Likewise, and set the time on the month view.
-
- * month-view.c (month_view_new): Now it takes the calendar plus
- the time_t representing the month.
-
- * gnome-month-item.h: Added documentation on the object arguments
- for the month item.
-
- * month-view.c (month_view_init): Added a month/year heading to
- the month view.
-
- * TODO: Updated the TODO list a bit.
-
- * main.c (gnome_cal_file_menu): The preferences menu option should
- go in the File menu.
- (gnome_cal_edit_menu): Added stock pixmaps to the menu items.
- (gnome_cal_menu): Renamed the Calendar menu to Edit.
- (gnome_cal_help_menu): Use "About Gnomecal", not just "About".
-
- * prop.c (hour_activated): Notify the property box that it has changed.
-
- * main.c: Changed the Properties menu item to Preferences. These
- are global application preferences, not a single calendar's
- properties.
-
- * prop.c (prop_apply): Save the week_starts_on_monday flag to the
- configuration file.
- (properties): Added a check button for weeks starting on Monday.
- (properties): Beautified the Preferences dialog.
-
- * month-view.c (month_view_init):
- * goto.c (create_days): Set the month item to start weeks on
- Monday if appropriate.
-
- * main.c (init_calendar): A boolean is not an hour, so don't
- range_check_hour() on it.
- (init_calendar): Added a global week_starts_on_monday flag.
-
- * main.h: Added global week_starts_on_monday flag.
-
-1998-08-21 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * calobj.c (ical_object_create_from_vobject): If mail alarm or
- program alarm are missing the action, then set an empty default.
-
-1998-08-18 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gnome-month-item.c (gnome_month_item_day2index): New public
- function to get the displayed day index of the specified date.
-
- * gnome-cal.c (gnome_calendar_goto_today): New public function to
- jump to the current day.
-
- * goto.c (day_event): Jump to the selected day when the user
- clicks the mouse, and prelight days as appropriate.
-
- * timeutil.c (time_from_day): New public function to build a
- time_t from a year/month/day triplet.
-
- * gnome-month-item.c (gnome_month_item_num2child):
- (gnome_month_item_child2num): New public functions to convert an
- index into a child and vice-versa, respectively.
- (gnome_month_item_num2day): New public function to convert a child
- number into a displayed day number.
-
- * goto.c (goto_dialog): Doh, use gnome-dialog properly :-)
-
- * gnome-month-item.c (create_items): Use g_strdup()ed day names
- from the start.
-
-1998-08-17 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * main.c (gnome_toolbar): Made it use goto.xpm.
-
- * Makefile.am (EXTRA_DIST): Added goto.xpm to the list of files.
-
-1998-08-13 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gnome-month-item.c (gnome_month_item_set_arg): Doh. Actually
- recalculate the days using the month and year.
-
- * main.c: Added "Go to" button to quickly jump to a specific date.
-
- * goto.c: New file that defines the quick go-to date dialog.
-
- * Makefile.am (gnomecal_SOURCES): Added goto.c to the sources.
-
-1998-08-11 Nuno Ferreira <nmrf@rnl.ist.utl.pt>
-
- * main.c (new_calendar): Made title i18n friendly. This was bug
- #215.
-
- * eventedit.c (ee_store_recur_end_to_ical): Set recur->enddate to
- recur->_enddate, not to itself, when adding recurring event and
- supplying an end date. This fixes (at least part of) bug #99.
-
-1998-08-10 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * month-view.[ch]: Start of the month view widget. This will use
- the generic month item and extend it to have the semantics desired
- for the gnomecal month view.
-
- * gnome-month-item.[ch]: New generic canvas item for the month
- view and the "small calendars". This is intended to be a
- high-level display engine for monthly calendars. This is a work
- in progress.
-
- * gnome-cal.h (GnomeCalendar): Added a month_view field.
-
- * gnome-cal.c (setup_widgets): Create the month view and insert it
- into the notebook.
-
- * Makefile.am: Added month-view.[ch] and gnome-month-item.[ch] to
- the sources.
-
-1998-08-03 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * main.c (about_calendar_cmd): Use an array of const strings to
- keep gcc happy.
-
- * alarm.c (alarm_compare_by_time): Use gconstpointer to keep gcc happy.
- * calendar.c (calendar_object_compare_by_start): Likewise.
- * gncal-full-day.c (child_compare_by_start): Likewise.
-
-1998-07-07 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * main.c: Add support for --view flag.
- (session_save_state): Save the view mode;
- (new_calendar): Now takes a view mode flag.
-
- * gnome-cal.c (gnome_calendar_get_current_view_name): New
- function for enhancing the session management support for
- gnomecal.
- (gnome_calendar_set_view): New function that makes a given page
- active.
-
-1998-07-01 Nuno Ferreira <nmrf@rnl.ist.utl.pt>
-
- * gncal.desktop: Added Portuguese translation.
-
-Mon Jun 22 13:01:16 1998 Havoc Pennington <hp@pobox.com>
-
- * main.c (session_save_state): Use gnome_geometry_string to get
- the geometry string.
-
-1998-06-04 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * eventedit.c (ee_rp_init_rule): Do not subtract 1 from
- tm->tm_mday for the default_day.
-
- * gnome-cal.c (gnome_calendar_new):
- (gnome_calendar_goto): Use the start of the day -- things expect
- it to be that way.
-
-1998-05-27 Nuno Ferreira <nmrf@rnl.ist.utl.pt>
-
- * eventedit.c (ee_store_recur_rule_to_ical): Fill in
- ical->recur->interval from value in spin_button. This ixed an
- infinnite loop.
-
-1998-05-30 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-full-day.c (child_draw): Paint the decorations correctly.
- (child_draw_decor): Paint the recurrence/bell icons correctly.
-
-1998-05-25 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * eventedit.c (ee_rp_init_rule): Use the contents of
- ee->ical->dtstart for computing the predefined values of the recurrence.
-
- * gncal-full-day.c (gncal_full_day_unrealize): Fix the gc
- destruction in the unrealization code and fix the pixmap unrefing.
-
- * main.c (close_cmd): Remove a bad hack that disabled calendar
- widget destruction.
-
- * calobj.c (ical_object_generate_events): Fix for the weekly event
- generation. Was reported on the bug tracking system.
-
-1998-05-18 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gncal-full-day.c (layout_children): Implemented ultra-cool
- layout for the events that share the same time range. Gals and
- guys you can now drop Outlook on the recycle bin.
-
- Which reminds me. We do not have a recycle bin. How could that
- happen in a project as cool as this one? Someone explain this to
- me.
-
-1998-05-18 Federico Mena <federico@nuclecu.unam.mx>
-
- * gncal-full-day.c (paint_back): Eliminated unnecessary border repainting.
-
-Sun May 17 17:55:03 1998 Havoc Pennington <hp@pobox.com>
-
- * gncal-todo.c (simple_todo_editor): Close dialog when return is pressed.
-
-1998-05-15 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gnome-cal.c (mark_gtk_calendar_day): Bug free version of the
- range computation in place.
-
- * gncal-year-view.c (year_view_mark_day): Use the same new version
- of the range computation here.
-
- * calobj.c (ical_object_generate_events): Fix the begin/end
- condition.
-
-1998-05-14 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * timeutil.c (isodate_from_time_t): Do not add the spurious
- padding.
-
- * calobj.c (store_date_list): Bug fix: I was using the wrong
- pointer when saving the exception date list.
- (set_date_list): Bug fix: load correctly the complete exception
- date list.
- (set_date_list): Use ',' for the exception date separator as the
- versit people can not get their standard right.
-
- * gncal-full-day.c (unrecur_appointment): Support for making an
- existing recurrent event `movable' for a day.
-
- * calobj.c (ical_object_add_exdate): New routine, used to add
- exception dates.
- (ical_object_duplicate): New routine: used to do the magic
- recur->no-recur event.
-
-1998-05-08 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gncal-full-day.c (new_appointment): Use gtk_calendar freeze/thaw
-
- * gncal-year-view.c (gncal_year_view_set_year): Use gtkcalendar freeze/thaw.
-
- * eventedit.c (event_editor_init): Use gnome_dialog_set_close to
- avoid the ugly warning.
-
- * main.c (display_objedit): Default to the day the user is looking
- at.
-
-1998-05-05 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gncal-day-panel.c (full_day_size_allocated): Do not emit a value
- changed signal if the value is the same.
-
-1998-05-04 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * prop.c (prop_apply): Only run the apply code once.
-
-1998-05-03 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gncal-day-panel.c (update): Draw the day at startup.
- (gncal_day_panel_set): Fix selected-day display.
- (gncal_day_panel_new): Switch day on double clicks, not on single
- clicks.
-
- * calobj.c (ical_object_compute_end): Removed debug messages.
-
-1998-04-30 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * prop.c (prop_apply): Do not call prop_cancel, ths is now using
- GnomePropertyDialog.
-
-1998-04-29 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gncal-week-view.c (sync_week): Use gnome_calendar_tag_calendar.
-
- * gnome-cal.c (gnome_calendar_tag_calendar): New routine used to
- fill a gtk_calendar with the events on a GnomeCalendar object.
-
- * gncal-week-view.c (gncal_week_view_new): Set the week to the day
- we double clicked.
-
-1998-04-28 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gnome-cal.c (calendar_notify): Apply black magic to get mail
- notifications to work.
-
- * gncal-full-day.c (child_focus_out): Temporary optimization, the
- child_focus_out is constantly calling the
- gnome_calendar_object_changed when the property editor has been
- invoked. This happens every time the mouse moves crosses the main
- window.
-
- * calendar.c (calendar_object_changed): Reschedule alarms when a
- calendar object has changed its times.
-
-Sat Apr 25 22:20:45 1998 Havoc Pennington <hp@pobox.com>
-
- * eventedit.c, eventedit.h: Descend from GnomeDialog. Took vbox
- out of class structure; use GnomeDialog vbox
- instead. gnome_dialog_set_destroy instead of destroying in button
- callbacks. Don't create buttons, separator, or vbox manually.
- #include <libgnomeui/gnome-dialog.h>.
-
-1998-04-24 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * calobj.c (ical_object_create_from_vobject): Fixed alarm loading;
- Load snooze time and snooze count
-
-1998-04-23 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * calendar.c (calendar_save): Actually save the to-do entries.
-
- * gncal-todo.c (simple_todo_editor): Now you can add and edit
- to-do entries.
-
-1998-04-22 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-full-day.c: Made it use popup_menu().
-
- * popup-menu.c: New file with utility functions for creating popup
- menus. Maybe such a thing would be useful in libgnomeui, a la
- gnome-app-helper?
-
- * Makefile.am (gnomecal_SOURCES): Added popup-menu.[ch] to the sources.
-
-1998-04-22 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * prop.c (properties): Added Calendar properties editor.
- (properties): Make the code use a propery box.
-
- * main.c: Save/load properties (fix to old commit).
-
-1998-04-21 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-todo.c: New widget for editing TODO lists. This will be
- worked on a lot.
-
- * Makefile.am (gnomecal_SOURCES): Added gncal-todo.[ch] to the sources.
-
- * gncal-day-panel.c: Make it use the new TODO widget.
-
-1998-04-21 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * timeutil.c (isodate_from_time_t): Do not save with the global
- time flag (Z at the end of the isodate). When we figure out a way
- to load times in GMT time, we will add this back
-
- * view-utils.c (popup_menu): Moved this routine here as there are
- more users of this code.
-
- * gncal-day-view.c (gncal_day_view_class_init): Add button press
- handler.
- (new_appointment): New routine for creating appointments on a day.
-
-
-
- * main.c (save_ok): Added call to gtk_window_set_wmclass.
-
- * gncal-day-panel.c (calendar_day_selected): Fix, years for mktime
- should substract 1900 and gtk_calendar stores years relative to
- year 0.
-
- * gncal-week-view.c (gncal_week_view_new): Make the week view
- descend from VBox so that we can add a label to it.
- (gncal_week_view_set): Display the ending day of the week
- correctly.
-
- Added a label that displays the week range.
-
-1998-04-21 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gnome-cal.c: Made it use GncalDayPanel.
-
- * gncal-day-panel.c: New widget for the day view in the main
- calendar toplevel. It basically takes care of everything
- gnome-cal did by hand with respect to the day view.
-
- * Makefile.am (gnomecal_SOURCES): Added gncal-day-panel.[ch] to
- the rules.
-
- * main.c: Added a separator between the About menu item and the
- help topics.
-
-1998-04-20 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * eventedit.c (ee_ok): Mark the event as non-new after accepting changes.
-
-1998-04-20 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-full-day.c (gncal_full_day_get_day_start_yoffset): New
- public function that returns the y offset for the row
- corresponding to the "day begin" time.
-
- * gncal-full-day.c (gncal_full_day_key_press): Now any printable
- keystroke (not just Return) will activate the selected range.
-
- * gncal-full-day.c (paint_back): Made it use the new paint_row
- function instead of painting everything directly. We calculate
- areas in a smarter way so there is even less flicker than before,
- especially when selecting regions.
-
- * eventedit.c: Sensitize recurrence widgets properly.
-
- * calobj.c (duration_callback): Pass the correct pointer type to
- is_date_in_list().
-
-1998-04-20 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * calobj.c (duration_callback): Take exception dates into
- account.
-
- * gncal-full-day.c (new_appointment): Setup the event editor dates
- to those of the currently displayed day.
- (gncal_full_day_selection_range): Use sensible values in the case
- no range is selected.
- (new_appointment): Events now use the current day for event creation.
-
- * view-utils.c: Pretty up the time display.
-
- * calobj.c (ical_object_compute_end): Initialize
- ico->recur->enddate, otherwise we loop forever during final date computation.
-
- * eventedit.c: Now recurrence is toggled by a radio button in the
- recurrence page, as the checkbox is confusing.
-
- * calobj.c (is_date_in_list): Add support for the exclussion
- dates.
-
-1998-04-18 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gncal-year-view.c (double_click): Fix this routine as well.
-
- * gncal-week-view.c (jump_to_day): Bind the gtkcalendar signals to
- the week.
-
- * gncal-year-view.c (gncal_year_view_set_year): Put things in the
- proper range. Now the year view actually matches this year.
-
- * gnome-cal.html: Added small documentation.
-
- * main.c: Add more icons to the menus; Rename some menubar
- entries; Add `new' icon to the toolbar.
- (dump_events): Added argument handling and dumping of events from
- the command line. Extremely cool.
-
- * getdate.y: Taken from the CVS source code. Used for date
- parsing in the command line.
-
- Internationalized getdate.y. Wee! It even works with spanish.
-
- * calobj.c (ical_object_to_vobject): Add Quoted printable property
- to items containing new lines.
- (duration): Use unsigned integers, to work around buggy calendar
- files generated by korganizer.
-
- * main.c (save_calendar_cmd): Do not ask for file name if we are
- saving.
- (save_as_calendar_cmd): New command.
-
-
-1998-04-17 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * alarm.c (alarm_kill, alarm_init, alarm_add): Implement the alarm
- management framework.
-
-1998-04-17 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * calobj.c (ical_new): Added mandatory status property.
- (ical_object_to_vobject): Only store "related" list if it exists.
- (store_list): Add terminating null char and free the correct data.
-
- * main.c (save_calendar_cmd): Implemented calendar saving.
- (open_calendar_cmd): Implemented calendar loading.
- (new_calendar_cmd): Implemented calendar creation.
- (new_calendar): Don't load our test calendar by default.
-
- * gncal-full-day.c (delete_appointment): Delete appointment implemented.
-
- * eventedit.c (ee_store_recur_values_to_ical): Free/create
- ical's recurrence appropriately.
- (ee_rp_init_rule): Initialize all missing parameters from ical.
- (ee_rp_init_ending_date): Initialize missing fields from ical.
-
-1998-04-17 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gnome-cal.c (gnome_calendar_remove_object): Add support for
- removing objects.
-
-1998-04-17 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * eventedit.c (ee_init_recurrence_page): New function that creates
- the recurrence page in the toplevel notebook.
- (ee_store_recur_values_to_ical): Now we can also store the recurrences.
-
-1998-04-17 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * calobj.c (ical_object_generate_events): Implement
- RECUR_MONTHLY_BY_POS implemented.
- (ical_object_create_from_vobject): Fix the alarm
- initialization code.
- (save_alarm): Save alarms.
- (ical_object_generate_events): Fixed the recurrent code to take
- into account the recur->endate field (if at all specified).
-
- (ical_object_to_vobject): Implement recurrence rule saving.
-
-1998-04-16 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * eventedit.c (ee_store_alarm): Use menu_shell->children, not
- menu->children. Why does GtkMenu have a children field in the
- object structure?
- (check_dates): New function that insures that start_date < end_date.
- (check_times): In addition to checking whether the event spans the
- whole day, now it insures that start_time < end_time.
-
- * gncal-full-day.c (child_set_size): Now children get bigger
- temporarily while they are focused. This allows the handles not
- to "overlap" the rows used by the child and thus allow editing of
- very thin events.
- (recompute_motion): Fix for new child coordinates.
- (gncal_full_day_expose): Make it use find_child_by_window()
- instead of looking for it by hand.
-
- * bell.xpm recur.xpm: XPM files for events with alarm and
- recurrence, respectively.
-
-1998-04-15 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-full-day.c (button_1): Preserve the up/down cursor while dragging.
-
- * gncal-full-day.c (child_draw): Now children have a vertical
- handle as well. This can be used to move the child anytime, not
- only when it is focused.
- (recompute_motion): Modified for new drag behavior.
-
- * eventedit.c (ee_init_general_page): The general_owner may be
- null. Do the proper thing when creating the label.
- (ee_ok): Update the gnome calendar appropriately.
-
- * timeutil.h:
- * gncal-year-view.h: Add some missing prototypes.
-
- * gncal-full-day.c (child_popup_menu): Set the sensitivity of menu
- items according to whether the ical object is being edited or not.
-
- * eventedit.c (event_editor_new): Set the "being edited" flag on
- the ical object (stored as the ical object's user data).
- (event_editor_destroy): Release the flag.
-
- * calobj.h: The iCalObject structure now has a generic user_data pointer.
- * calobj.c (ical_object_set_user_data ical_object_get_user_data):
- Functions to set this data.
-
- * gncal-full-day.c (child_button_press): Do child popup menu correctly.
-
- * main.c (about_calendar_cmd): Fixed my address and added Arturo
- to the authors in the about box.
-
- * gncal-full-day.c (find_child_by_window): Compare child's widget
- windows by user_data (which will be the parent widget, that is,
- the text widget). We cannot assume that child->widget->window
- will be *the* window we are interested on because there may be
- child widgets with multiple windows.
-
-1998-04-15 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * calobj.c (ical_foreach): Define iterator routine.
-
-1998-04-15 Arturo Espinosa Aldama <arturo@nuclecu.unam.mx>
-
- * gncal-year-view.[hc]: Now using time_t for new and set.
- Random fixes, as well.
-
-1998-04-15 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-full-day.c (button_3): New popup menus activated with
- mouse button 3.
- (create_appointment): Create a new appointment from the popup
- menus. See the FIXME.
-
-1998-04-15 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gncal-full-day.c (layout_kill_rows): Routine to destory rows
- array properly.
-
- * gncal-year-view.c (gncal_year_view_new): Add missing year in
- call to strftime.
-
- * calobj.c (ical_object_create_from_vobject): Fixed memory leaks
- from the return values of versit's fakeCString.
-
-1998-04-14 Arturo Espinosa Aldama <arturo@nuclecu.unam.mx>
-
- * gncal-year-view.[hc]: New widget for the year view.
- * Makefile.am: added required compilation of the new files.
-
-1998-04-14 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * eventedit.c (event_editor_setup_time_frame): Fixed some table
- expansions to make the dialog look nicer when resized.
-
- * calobj.c (ignore_space): Fixed compiler warning about unused
- computed value.
- (ocurrencelist): Replace str by p confusion. Removed unused
- variables value and q.
- (daynumber): Fixed a couple of warnings about unused values.
- (load_recurrence): Removed unused variable c. Added a default
- clause to the switch(type).
-
- * eventedit.c (ee_rp_init_frequency): Removed unused variable content.
- Fixed a compiler warning by adding a missing cast.
-
- * calobj.c (ical_object_create_from_vobject): Make the
- load_recurrence() part work correctly. Eliminated use of
- syntax_error variable.
-
-1998-04-13 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-full-day.c (child_key_press): Unfocus the child and focus
- the parent fullday widget when the user presses Esc.
-
- * gncal-week-view.c (gncal_week_view_update): Now takes object and
- flags parameters.
- * gncal-day-view.c (gncal_day_view_update): Likewise.
- * gncal-full-day.c (gncal_full_day_update): Likewise.
- (child_focus_in): New function. In conjunction with
- child_focus_out(), these only display the handles in the child
- when it is focused. The result is that the user can see more of
- the child's text when nothing is focused, and we can also display
- fatter and nicer drag handles.
-
- * gnome-cal.c (gnome_calendar_object_changed): Now takes an
- additional flags parameter
- (gnome_calendar_update_all): Made function static. Now takes
- changed object and flags parameters as well.
- (gnome_calendar_object_changed): Now takes additional flags
- parameter to indicate what changed in the specified object.
-
- * calobj.h (CalObjectChange): New enum with flags to describe what
- has been changed in an object.
-
- * gncal-full-day.h:
- * gncal-full-day.c (gncal_full_day_focus_child): New function to
- let the outside world decide which child to focus.
- (gncal_full_day_focus_child): Bleah. We have to synthesize a
- click because GtkText will not set the cursor when you focus it.
-
- * gnome-cal.c (day_view_range_activated): Focus the new child in
- the full day widget.
-
- * eventedit.c (event_editor_setup_time_frame): Re-aligned some
- widgets to make it look prettier.
- (ee_alarm_widgets): Likewise.
- (ee_init_general_page): Likewise.
- (ee_classification_widgets): Likewise.
- (event_editor_init_widgets): Likewise.
-
- * gnome-cal.c (day_view_range_activated): Create new object and
- add it to the calendar. You can now select a range in the
- full-day view, hit Return, and a new event will be added at the
- selected range. I still have to figure out how to focus this new child.
-
- * gncal-full-day.c (paint_back): Rewrote function to avoid
- painting an area more than once -- eliminate flicker.
- (paint_back_rows): New function that calls paint_back() only for
- the area of the specified rows.
- (gncal_full_day_button_press):
- (gncal_full_day_button_release):
- (gncal_full_day_motion): Made these functions use
- paint_back_rows() instead of paint_back(), to eliminate flicker. Wheee!
-
-1998-04-12 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gnome-cal.c (setup_day_view): We now connect to the
- range_activated signal of the fullday widget instead of catching
- key presses ourselves.
- (day_view_range_activated): New function that creates a new
- iCalObject and inserts it into the calendar, not finished yet.
-
-1998-04-11 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-full-day.c (get_time_from_rows): New function, calculates
- a pair of time_t values from the specified start and number of rows.
-
- * gncal-full-day.h (GncalFullDayClass): New signal
- "range_activated". It is emitted when a range is selected and the
- user hits Return.
- (gncal_full_day_selection_range): New function, returns the
- selected range.
-
- * gncal-full-day.c (struct drag_info): Moved selection information
- to their own fields instead of sharing the child's drag fields.
- This allows us to keep the selection when a child is moved.
- (recompute_motion): Made the case when (row < di->sel_click_row)
- work correctly.
-
-1998-04-11 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gnome-cal.c (gnome_calendar_goto): Add support for navigating
- on the day view.
-
- * timeutil.c (time_start_of_day, time_end_of_day, time_day_hour):
- New time manipulation functions.
-
- * eventedit.c (ee_rp_init_frequency): Add the different frequency
- editors to a notebook. Make the notebook startup on the entry
- selected recurrence type;
-
-1998-04-11 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-full-day.c (recompute_motion): Now we support selecting a
- range in the main window (by clicking+dragging). It flickers
- horribly and is not perfect, but it is a start.
-
-1998-04-09 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-full-day.c: #include <string.h>
-
- * gncal-full-day.c (child_map): Show instead of just map the child
- widget (otherwise the text widget gets confused and will not focus).
-
- * calobj.c (ical_object_to_vobject): Quote chars as 'x', not "x".
-
- * calobj.h: Added prototype for ical_object_to_vobject().
-
- * gnome-cal.c (gnome_calendar_object_changed): New function. This
- should be called when a calendar object is changed.
-
- * gncal-full-day.c (update_from_drag_info): Call
- gnome_calendar_object_changed() instead of updating manually.
-
- * calendar.c (calendar_add_object):
- (calendar_remove_object): Set the modified flag to true.
-
- * gncal-full-day.c (gncal_full_day_draw): Finished implementing
- this function.
-
-1998-04-08 Raja R Harinath <harinath@cs.umn.edu>
-
- * gncal.c (update_calendar): Say `#if 0', not `#ifdef 0'.
-
-1998-04-07 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * eventedit.c: Removed unused global variable parent_class.
-
- * eventedit.h: Renamed gtk_window field to window.
- Made the parent_class field in the EventEditorClass structure be a
- GtkWindowClass, not a gnome property box class.
- Added prototype for event_editor_get_type().
-
-1998-04-06 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-week-view.c (gncal_week_view_new): Use the new
- gtk_table_set_homogeneous() instead of setting the variable directly.
-
-1998-04-03 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * eventedit.c (ee_create_ae): Make it return void.
- (ee_alarm_widgets): Remove some unused variables.
- (ee_store_alarm): Make it return void.
- #include <string.h>
-
- * eventedit.h: #include "gnome-cal.h"
-
- * calobj.c (list_free): Don't use g_free in the g_list_foreach.
-
- * calendar.h: Add prototype for calendar_load().
-
- * timeutil.h: Add prototypes for time_add_*().
-
- * calendar.c:
- * calobj.c:
- * eventedit.c:
- * gnome-cal.c: #include "timeutil.h"
-
- * gncal-day-view.c (gncal_day_view_size_request): Make the minimum
- width equal or larger to the title width.
-
- * main.c: #include "eventedit.h"
- (main): Add a return statement.
- (new_calendar): Show stuff *after* the calendar has been loaded.
-
- * gnome-cal.c (gnome_calendar_load): Update the day view.
- (setup_widgets): Hackish setup of a day view widget - will fix later.
- (gnome_calendar_init): Initialize all fields.
-
- * gnome-cal.h: Added day_view field. Maybe this should be changed
- when the a complete day view panel is complete.
-
- * gncal-day-view.c (gncal_day_view_update): Draw after update, not
- before.
-
-1998-04-06 Carsten Schaar <nhadcasc@fs-maphy.uni-hannover.de>
-
- * versit/.cvsignore: New file.
-
-Fri Apr 3 22:31:54 1998 Tom Tromey <tromey@cygnus.com>
-
- * calendar.c: Include <config.h>.
-
-1998-04-03 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * timeutil.c (time_add_year, time_add_year, time_add_week):
- Routines for time manipulation.
-
- * calobj.c (ical_object_destroy): Full destruction of the object.
-
- * eventedit.c: Finished the main event editor form; It still
- lacks the details and the recurrence bits. It now adds events
- and cancels.
-
-1998-04-03 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * view-utils.c (view_utils_draw_events): The "better" format
- string for strftime() wasn't better, after all :-(
-
-1998-04-02 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-full-day.c: New full-day widget. It is still a work in
- progress. It will be similar to M$ Schedule's nifty full day view
- widget, but with Gtk's elegance :-)
-
- * Makefile.am (gnomecal_SOURCES): Added gncal-full-day.[ch] to the sources.
-
-1998-04-02 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * eventedit.c: Object editor widget. We dropped ObjEdit.
-
- * timeutil.c (time_from_isodate): Fix.
-
- * view-utils.c (view_utils_draw_events): Changed the display
- formats.
-
-1998-04-02 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * view-utils.c (view_utils_draw_events): Use better format
- specifier for strftime().
- (view_utils_draw_textured_frame): Ultra-nifty function to draw
- textured "metal" frames, like Netscape's handles.
-
-1998-04-02 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * gncal-day-view.c (gncal_day_view_update): Day events are now
- cached inside the widget. They get initialized at this time.
-
- * view-utils.c (view_utils_draw_events): Use the list of events.
-
-1998-04-02 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-day-view.c (gncal_day_view_set_shadow): New customization
- function. We can't decide on a stupid border type :-)
- (gncal_day_view_init): Made GTK_SHADOW_ETCHED_IN be the default
- shadow type. Looks good.
-
-1998-04-02 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * main.c: New main program that uses our new datatypes and
- objects.
-
- * calendar.c (calendar_load_from_vobject, calendar_load):
- Implement loading of vCalendar objects and vCalendar files.
-
- * calobj.c (ical_object_create_from_vobject): Implement loading of
- vCalendar event and todo objects.
-
- * timeutil.c (isodate_from_time_t): New function.
-
- * gnome-cal.c, gnome-cal.h: Implement a toplevel widget, derived
- from GnomeApp. It holds all of the day views and arbitrates the
- display.
-
-1998-04-02 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-week-view.[ch]: New week view composite widget. This
- provides a full week view (7 day views plus busy time display --
- the latter is currently unimplemented).
-
-1998-04-01 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal-day-view.c: New day view widget. It is intended to be a
- child widget of the week view composite widget.
-
- * calendar.c (calendar_get_objects_in_range):
- (calendar_get_events_in_range):
- (calendar_get_journal_in_range):
- (calendar_get_journal_in_range): These functions now take a
- sort_func parameter, which is of type GCompareFunc. If the
- specified value is non-NULL, it will return a sorted list.
- Otherwise, it will return an unordered list.
- (calendar_compare_by_dtstart): Provide a generic sorting routine
- for calendar objects.
-
-1998-04-01 Miguel de Icaza <miguel@kernel.org>
-
- * Start from scratch
-
-Tue Mar 31 23:46:50 1998 Tom Tromey <tromey@cygnus.com>
-
- * timeutil.c (format_simple_hour): `buf' now static.
-
-1998-03-31 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal.c: Removed #include "gtkcalendar.h", because it now comes
- from libgnomeui.
-
- * Makefile.am (gncal_SOURCES): Added new source files to the rules.
-
- * timeutil.c (format_simple_hour): New function, formats an
- hour/am_pm pair into a string of the form "3am", "12pm", "05h",
- "19h", etc. It is used by the day view widget for its labels.
-
-1998-03-31 Craig Small <csmall@small.dropbear.id.au>
-
- * Now has (non working) session maangement
- * Uses a clist for the dailylist like gtt
-
-Sat Mar 21 15:43:20 1998 Tom Tromey <tromey@cygnus.com>
-
- * gncal.c: Use gnome_message_box_*, not gnome_messagebox_*.
-
-1998-03-12 Craig Small <csmall@small.dropbear.id.au>
-
- * Now linked (in some horrible way) to the gtkcalendar widget.
-
-Sun Mar 8 16:38:10 1998 Tom Tromey <tromey@cygnus.com>
-
- * Makefile.am (INCLUDES): Added GNOME_INCLUDEDIR.
- (gncal_LDADD): Don't include libsupport.a.
-
- * gncal.c (main): Use new gnome_init.
-
-1998-02-19 Federico Mena Quintero <federico@nuclecu.unam.mx>
-
- * gncal.c (main): Added app_id "gncal".
-
-1998-02-19 Carsten Schaar <nhadcasc@fs-maphy.uni-hannover.de>
-
- * Makefile.am (gncal_LDADD): Added '$(INTLLIBS)'
-
-1998-02-18 Raja R Harinath <harinath@cs.umn.edu>
-
- * Makefile.am (gncal_LDADD): Include `libsupport.a'.
-
- * calcs.c (month_atoi): Replace buggy explicit loop string compare
- with strcasecmp.
- (day_atoi): Likewise.
-
-Sun Jan 25 23:38:30 1998 Miguel de Icaza <miguel@nuclecu.unam.mx>
-
- * menus.c: Replace "Quit" with "Exit".
diff --git a/calendar/Makefile.am b/calendar/Makefile.am
index 89cea775bd..4fe6165577 100644
--- a/calendar/Makefile.am
+++ b/calendar/Makefile.am
@@ -1,9 +1,19 @@
-if ENABLE_PILOT_CONDUITS
-CONDUIT_DIR = conduits
-else
-CONDUIT_DIR =
-endif
+SUBDIRS = importers gui alarm-notify
-SUBDIRS = idl cal-util pcs cal-client gui importers $(CONDUIT_DIR)
+error_DATA = calendar.error
+errordir = $(privdatadir)/errors
+@EVO_PLUGIN_RULE@
-EXTRA_DIST = zones.h
+EXTRA_DIST = \
+ calendar.error.xml \
+ $(error_DATA) \
+ zones.h
+
+dist-hook:
+ cd $(distdir); rm -f $(BUILT_SOURCES)
+
+BUILT_SOURCES = $(error_DATA)
+
+CLEANFILES = $(BUILT_SOURCES)
+
+-include $(top_srcdir)/git.mk
diff --git a/calendar/TODO b/calendar/TODO
deleted file mode 100644
index 4a5dd6c6ff..0000000000
--- a/calendar/TODO
+++ /dev/null
@@ -1,88 +0,0 @@
-Cal-util:
-
-- calobj.h depends on libversit/vcc.h, because it uses a VObject for
- ical_object_create_from_vobject(). This should be an internal
- function in the PCS and nothing else (we do not install libversit,
- so our public libraries should not depend on it).
-
-- Or maybe we *should* install libversit, since the addressbook code
- uses it as well.
-
-- timeutil has a lot of crap and some namespace pollution. Clean it
- up.
-
-PCS:
-
-- When loading a calendar, substitute duplicated UIDs by new ones, and
- possibly print out a warning message.
-
------ Old Gnomecal TODO starts here -----
-
-Pilot:
-
-* Better support for untimed events (we have none now).
-
-* Hash objects based on their UIDs.
-
-* Add placeholders for deleted events, so that we can kill those
- when syncing to the pilot.
-
-BUGS:
-
-- Recurrence end date is wrong. An event that repeats daily will not
- be included in the ending date of the recurrence (off-by-one
- error?).
-
-- X-fields (extensions) are stripped from a vCal file when it is
- saved. They should be preserved.
-
-Features:
-
-- Add a calendar-week so that people know which week of the year it is
-
-Year view:
-
-- See why it is so fucking slow when opening its notebook page for the
- first time.
-
-Month view:
-
-- Popup menu like in the year view.
-
-- Double click on a day takes you to the day view.
-
-- DnD of appointments to move them around.
-
-Week view:
-
-- Nice display as in the Palm Pilot.
-
-Day view:
-
-- Rewrite in terms of the canvas and make it pretty.
-
-Preferences:
-
-- BUG: 12/24 hours stuff is not consistent - I remember that on editing
- new appointment you get the time-selectors always on 12-hr format
-
-Event editor dialog:
-
-- Make it figure out whether the alarm is in
- minutes/hours/days/etc. (via a cascade of conditions) and set the
- widgets appropriately.
-
-Gnome date selection widget:
-
-- Make the displayed date be localized properly -- use strftime().
-
-General:
-
-- Write online help. Nice help. Lots of help.
-
-- If you leave the calendar running overnight, the "current day"
- marker in the GnomeMonthItems does not get updated.
-
-- Add categories support. Color-coded categories.
-
-- Untimed events
diff --git a/calendar/alarm-notify/Makefile.am b/calendar/alarm-notify/Makefile.am
new file mode 100644
index 0000000000..09a6743dcf
--- /dev/null
+++ b/calendar/alarm-notify/Makefile.am
@@ -0,0 +1,71 @@
+if OS_WIN32
+bin_PROGRAMS = evolution-alarm-notify
+else
+privlibexec_PROGRAMS = evolution-alarm-notify
+endif
+
+if HAVE_WINDRES
+EVOLUTIONALARMNOTIFYICON = evolution-alarm-notify-icon.o
+endif
+
+evolution_alarm_notify_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DG_LOG_DOMAIN=\"evolution-alarm-notify\" \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/calendar \
+ -DEVOLUTION_UIDIR=\""$(uidir)"\" \
+ -DEVOLUTION_ICONDIR=\""$(icondir)"\" \
+ -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
+ -DEVOLUTION_LIBEXECDIR=\""$(privlibexecdir)"\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(LIBNOTIFY_CFLAGS) \
+ $(CANBERRA_CFLAGS) \
+ $(GTKHTML_CFLAGS)
+
+ui_DATA = \
+ alarm-notify.ui
+
+evolution_alarm_notify_SOURCES = \
+ alarm.c \
+ alarm.h \
+ alarm-notify.c \
+ alarm-notify.h \
+ alarm-notify-dialog.c \
+ alarm-notify-dialog.h \
+ alarm-queue.c \
+ alarm-queue.h \
+ config-data.c \
+ config-data.h \
+ notify-main.c \
+ util.c \
+ util.h
+
+evolution_alarm_notify_LDADD = \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(top_builddir)/composer/libevolution-mail-composer.la \
+ $(top_builddir)/calendar/gui/libevolution-calendar.la \
+ $(top_builddir)/calendar/importers/libevolution-calendar-importers.la \
+ $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
+ $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
+ $(top_builddir)/addressbook/util/libeabutil.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(LIBNOTIFY_LIBS) \
+ $(CANBERRA_LIBS) \
+ $(GTKHTML_LIBS)
+ $(EVOLUTIONALARMNOTIFYICON)
+
+if OS_WIN32
+evolution_alarm_notify_LDFLAGS = -mwindows
+endif
+
+EXTRA_DIST = $(ui_DATA) \
+ evolution-alarm-notify-icon.rc \
+ evolution-alarm-notify.ico
+
+
+evolution-alarm-notify-icon.o: evolution-alarm-notify.ico evolution-alarm-notify-icon.rc
+ $(WINDRES) evolution-alarm-notify-icon.rc evolution-alarm-notify-icon.o
+
+-include $(top_srcdir)/git.mk
diff --git a/calendar/alarm-notify/alarm-notify-dialog.c b/calendar/alarm-notify/alarm-notify-dialog.c
new file mode 100644
index 0000000000..ac6ce49d93
--- /dev/null
+++ b/calendar/alarm-notify/alarm-notify-dialog.c
@@ -0,0 +1,538 @@
+/*
+ * Evolution calendar - alarm notification dialog
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include "e-util/e-util.h"
+
+#include "alarm-notify-dialog.h"
+#include "config-data.h"
+#include "util.h"
+
+enum {
+ ALARM_DISPLAY_COLUMN,
+ ALARM_SUMMARY_COLUMN,
+ ALARM_DESCRIPTION_COLUMN,
+ ALARM_LOCATION_COLUMN,
+
+ ALARM_START_COLUMN,
+ ALARM_END_COLUMN,
+
+ ALARM_FUNCINFO_COLUMN,
+
+ N_ALARM_COLUMNS
+};
+
+/* The useful contents of the alarm notify dialog */
+
+typedef struct {
+ AlarmNotifyFunc func;
+ gpointer func_data;
+} AlarmFuncInfo;
+
+typedef struct {
+ GtkBuilder *builder;
+
+ GtkWidget *dialog;
+ GtkWidget *snooze_time_min;
+ GtkWidget *snooze_time_hrs;
+ GtkWidget *snooze_time_days;
+ GtkWidget *snooze_btn;
+ GtkWidget *edit_btn;
+ GtkWidget *print_btn;
+ GtkWidget *dismiss_btn;
+ GtkWidget *minutes_label;
+ GtkWidget *hrs_label;
+ GtkWidget *days_label;
+ GtkWidget *description;
+ GtkWidget *location;
+ GtkWidget *treeview;
+
+ AlarmFuncInfo *cur_funcinfo;
+
+} AlarmNotify;
+
+static void tree_selection_changed_cb (GtkTreeSelection *selection,
+ gpointer data);
+static void fill_in_labels (AlarmNotify *an,
+ const gchar *summary,
+ const gchar *description,
+ const gchar *location,
+ time_t occur_start,
+ time_t occur_end);
+
+static void edit_pressed_cb (GtkButton *button,
+ gpointer user_data);
+static void snooze_pressed_cb (GtkButton *button,
+ gpointer user_data);
+
+static void
+an_update_minutes_label (GtkSpinButton *sb,
+ gpointer data)
+{
+ AlarmNotify *an;
+ gint snooze_timeout_min;
+
+ an = (AlarmNotify *) data;
+
+ snooze_timeout_min = gtk_spin_button_get_value_as_int (sb);
+ gtk_label_set_text (GTK_LABEL (an->minutes_label), ngettext ("minute", "minutes", snooze_timeout_min));
+}
+
+static void
+an_update_hrs_label (GtkSpinButton *sb,
+ gpointer data)
+{
+ AlarmNotify *an;
+ gint snooze_timeout_hrs;
+
+ an = (AlarmNotify *) data;
+
+ snooze_timeout_hrs = gtk_spin_button_get_value_as_int (sb);
+ gtk_label_set_text (GTK_LABEL (an->hrs_label), ngettext ("hour", "hours", snooze_timeout_hrs));
+}
+
+static void
+an_update_days_label (GtkSpinButton *sb,
+ gpointer data)
+{
+ AlarmNotify *an;
+ gint snooze_timeout_days;
+
+ an = (AlarmNotify *) data;
+
+ snooze_timeout_days = gtk_spin_button_get_value_as_int (sb);
+ gtk_label_set_text (GTK_LABEL (an->days_label), ngettext ("day", "days", snooze_timeout_days));
+}
+
+static void
+dialog_response_cb (GtkDialog *dialog,
+ guint response_id,
+ gpointer user_data)
+{
+ AlarmNotify *an = user_data;
+ GtkTreeIter iter;
+ GtkTreeModel *model = NULL;
+ AlarmFuncInfo *funcinfo = NULL;
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (an->treeview));
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ gtk_tree_model_get (model, &iter, ALARM_FUNCINFO_COLUMN, &funcinfo, -1);
+ }
+
+ if (!funcinfo) {
+ GtkTreeModel *treemodel = gtk_tree_view_get_model (GTK_TREE_VIEW (an->treeview));
+ if (!gtk_tree_model_get_iter_first (treemodel, &iter))
+ return;
+
+ gtk_tree_model_get (treemodel, &iter, ALARM_FUNCINFO_COLUMN, &funcinfo, -1);
+ }
+
+ g_return_if_fail (funcinfo);
+
+ switch (response_id) {
+ case GTK_RESPONSE_CLOSE:
+ case GTK_RESPONSE_DELETE_EVENT:
+ (* funcinfo->func) (ALARM_NOTIFY_CLOSE, -1, funcinfo->func_data);
+ break;
+ }
+}
+
+static void
+edit_pressed_cb (GtkButton *button,
+ gpointer user_data)
+{
+ AlarmNotify *an = user_data;
+ AlarmFuncInfo *funcinfo = NULL;
+ GtkTreeIter iter;
+ GtkTreeModel *model = NULL;
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (an->treeview));
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ gtk_tree_model_get (model, &iter, ALARM_FUNCINFO_COLUMN, &funcinfo, -1);
+
+ g_return_if_fail (funcinfo);
+
+ (* funcinfo->func) (ALARM_NOTIFY_EDIT, -1, funcinfo->func_data);
+}
+
+static void
+print_pressed_cb (GtkButton *button,
+ gpointer user_data)
+{
+ AlarmNotify *an = user_data;
+ AlarmFuncInfo *funcinfo = NULL;
+ GtkTreeIter iter;
+ GtkTreeModel *model = NULL;
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (an->treeview));
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ gtk_tree_model_get (model, &iter, ALARM_FUNCINFO_COLUMN, &funcinfo, -1);
+
+ g_return_if_fail (funcinfo);
+
+ (* funcinfo->func) (ALARM_NOTIFY_PRINT, -1, funcinfo->func_data);
+}
+
+#define DEFAULT_SNOOZE_MINS 5
+
+static void
+snooze_pressed_cb (GtkButton *button,
+ gpointer user_data)
+{
+ gint snooze_timeout;
+ AlarmNotify *an = user_data;
+ GtkTreeIter iter;
+ GtkTreeModel *model = NULL;
+ AlarmFuncInfo *funcinfo = NULL;
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (an->treeview));
+
+ gtk_widget_grab_focus ((GtkWidget *) button);
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ gtk_tree_model_get (model, &iter, ALARM_FUNCINFO_COLUMN, &funcinfo, -1);
+
+ g_return_if_fail (funcinfo);
+
+ snooze_timeout = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (an->snooze_time_min));
+ snooze_timeout += 60 * (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (an->snooze_time_hrs)));
+ snooze_timeout += 60 * 24 * (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (an->snooze_time_days)));
+ if (!snooze_timeout)
+ snooze_timeout = DEFAULT_SNOOZE_MINS;
+ (* funcinfo->func) (ALARM_NOTIFY_SNOOZE, snooze_timeout, funcinfo->func_data);
+}
+
+static void
+dismiss_pressed_cb (GtkButton *button,
+ gpointer user_data)
+{
+ AlarmNotify *an = user_data;
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (an->treeview));
+
+ g_return_if_fail (model != NULL);
+
+ if (gtk_tree_model_iter_n_children (model, NULL) <= 1) {
+ gtk_dialog_response (GTK_DIALOG (an->dialog), GTK_RESPONSE_CLOSE);
+ } else {
+ GtkTreeIter iter;
+ AlarmFuncInfo *funcinfo = NULL;
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (an->treeview));
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ gtk_tree_model_get (model, &iter, ALARM_FUNCINFO_COLUMN, &funcinfo, -1);
+
+ g_return_if_fail (funcinfo);
+
+ (* funcinfo->func) (ALARM_NOTIFY_DISMISS, -1, funcinfo->func_data);
+ }
+}
+
+static void
+dialog_destroyed_cb (GtkWidget *dialog,
+ gpointer user_data)
+{
+ AlarmNotify *an = user_data;
+
+ g_object_unref (an->builder);
+ g_free (an);
+}
+
+/**
+ * notified_alarms_dialog_new:
+ *
+ * Return value: a new dialog in which you can add alarm notifications
+ **/
+AlarmNotificationsDialog *
+notified_alarms_dialog_new (void)
+{
+ GtkWidget *container;
+ GtkWidget *image;
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
+ AlarmNotificationsDialog *na = NULL;
+ AlarmNotify *an = g_new0 (AlarmNotify, 1);
+ GtkTreeViewColumn *column = NULL;
+ GtkTreeSelection *selection = NULL;
+ GtkTreeModel *model = GTK_TREE_MODEL (gtk_list_store_new (
+ N_ALARM_COLUMNS,
+
+ G_TYPE_STRING, /* Display */
+ G_TYPE_STRING, /* Summary */
+ G_TYPE_STRING, /* Description */
+ G_TYPE_STRING, /* Location */
+
+ G_TYPE_POINTER, /* Start */
+ G_TYPE_POINTER, /* End */
+
+ G_TYPE_POINTER /* FuncInfo */));
+
+ an->builder = gtk_builder_new ();
+ e_load_ui_builder_definition (an->builder, "alarm-notify.ui");
+
+ an->dialog = e_builder_get_widget (an->builder, "alarm-notify");
+ an->snooze_time_min = e_builder_get_widget (an->builder, "snooze-time-min");
+ an->minutes_label = e_builder_get_widget (an->builder, "minutes-label");
+ an->snooze_time_hrs = e_builder_get_widget (an->builder, "snooze-time-hrs");
+ an->hrs_label = e_builder_get_widget (an->builder, "hrs-label");
+ an->snooze_time_days = e_builder_get_widget (an->builder, "snooze-time-days");
+ an->days_label = e_builder_get_widget (an->builder, "days-label");
+ an->description = e_builder_get_widget (an->builder, "description-label");
+ an->location = e_builder_get_widget (an->builder, "location-label");
+ an->treeview = e_builder_get_widget (an->builder, "appointments-treeview");
+ an->snooze_btn = e_builder_get_widget (an->builder, "snooze-button");
+ an->edit_btn = e_builder_get_widget (an->builder, "edit-button");
+ an->print_btn = e_builder_get_widget (an->builder, "print-button");
+ an->dismiss_btn = e_builder_get_widget (an->builder, "dismiss-button");
+
+ if (!(an->dialog && an->treeview
+ && an->snooze_time_min && an->snooze_time_hrs && an->snooze_time_days
+ && an->description && an->location && an->edit_btn && an->print_btn && an->snooze_btn && an->dismiss_btn)) {
+ g_warning ("alarm_notify_dialog(): Could not find all widgets in alarm-notify.ui file!");
+ g_object_unref (an->builder);
+ g_free (an);
+ return NULL;
+ }
+
+ e_buffer_tagger_connect (GTK_TEXT_VIEW (an->description));
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (an->treeview), model);
+
+ gtk_window_set_keep_above (GTK_WINDOW (an->dialog), TRUE);
+
+ column = gtk_tree_view_column_new_with_attributes (
+ _("Start time"),
+ renderer, "text", ALARM_DISPLAY_COLUMN, NULL);
+
+ gtk_tree_view_column_set_attributes (
+ column, renderer,
+ "markup", ALARM_DISPLAY_COLUMN, NULL);
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW (an->treeview), column);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (an->treeview));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+ g_signal_connect (
+ selection, "changed",
+ G_CALLBACK (tree_selection_changed_cb), an);
+ tree_selection_changed_cb (selection, an);
+
+ gtk_widget_realize (an->dialog);
+
+ container = gtk_dialog_get_action_area (GTK_DIALOG (an->dialog));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 12);
+
+ container = gtk_dialog_get_content_area (GTK_DIALOG (an->dialog));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 0);
+
+ image = e_builder_get_widget (an->builder, "alarm-image");
+ gtk_image_set_from_icon_name (
+ GTK_IMAGE (image), "stock_alarm", GTK_ICON_SIZE_DIALOG);
+
+ g_signal_connect (
+ an->edit_btn, "clicked",
+ G_CALLBACK (edit_pressed_cb), an);
+ g_signal_connect (
+ an->print_btn, "clicked",
+ G_CALLBACK (print_pressed_cb), an);
+ g_signal_connect (
+ an->snooze_btn, "clicked",
+ G_CALLBACK (snooze_pressed_cb), an);
+ g_signal_connect (
+ an->dismiss_btn, "clicked",
+ G_CALLBACK (dismiss_pressed_cb), an);
+ g_signal_connect (
+ an->dialog, "response",
+ G_CALLBACK (dialog_response_cb), an);
+ g_signal_connect (
+ an->dialog, "destroy",
+ G_CALLBACK (dialog_destroyed_cb), an);
+
+ if (!gtk_widget_get_realized (an->dialog))
+ gtk_widget_realize (an->dialog);
+
+ gtk_window_set_icon_name (GTK_WINDOW (an->dialog), "stock_alarm");
+
+ /* Set callback for updating the snooze "minutes" label */
+ g_signal_connect (
+ an->snooze_time_min, "value_changed",
+ G_CALLBACK (an_update_minutes_label), an);
+
+ /* Set callback for updating the snooze "hours" label */
+ g_signal_connect (
+ an->snooze_time_hrs, "value_changed",
+ G_CALLBACK (an_update_hrs_label), an);
+
+ /* Set callback for updating the snooze "days" label */
+ g_signal_connect (
+ an->snooze_time_days, "value_changed",
+ G_CALLBACK (an_update_days_label), an);
+
+ na = g_new0 (AlarmNotificationsDialog, 1);
+
+ na->treeview = an->treeview;
+ na->dialog = an->dialog;
+
+ return na;
+}
+
+/**
+ * add_alarm_to_notified_alarms_dialog:
+ * @na: Pointer to the dialog-info
+ * @trigger: Trigger time for the alarm.
+ * @occur_start: Start of occurrence time for the event.
+ * @occur_end: End of occurrence time for the event.
+ * @vtype: Type of the component which corresponds to the alarm.
+ * @summary: Short summary of the appointment
+ * @description: Long description of the appointment
+ * @location: Location of the appointment
+ * @func: Function to be called when a dialog action is invoked.
+ * @func_data: Closure data for @func.
+ *
+ * The specified @func will be used to notify the client about result of
+ * the actions in the dialog.
+ *
+ * Return value: the iter in the treeview of the dialog
+ **/
+
+GtkTreeIter
+add_alarm_to_notified_alarms_dialog (AlarmNotificationsDialog *na,
+ time_t trigger,
+ time_t occur_start,
+ time_t occur_end,
+ ECalComponentVType vtype,
+ const gchar *summary,
+ const gchar *description,
+ const gchar *location,
+ AlarmNotifyFunc func,
+ gpointer func_data)
+{
+ GtkTreeIter iter = { 0 };
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (na->treeview));
+ AlarmFuncInfo *funcinfo = NULL;
+ gchar *to_display = NULL, *start, *end, *str_time;
+ icaltimezone *current_zone;
+
+ /* Iter is not yet defined but still we return it in all the g_return_val_if_fail() calls? */
+ g_return_val_if_fail (trigger != -1, iter);
+
+ /* Only VEVENTs or VTODOs can have alarms */
+ g_return_val_if_fail (vtype == E_CAL_COMPONENT_EVENT || vtype == E_CAL_COMPONENT_TODO, iter);
+ g_return_val_if_fail (summary != NULL, iter);
+ g_return_val_if_fail (description != NULL, iter);
+ g_return_val_if_fail (location != NULL, iter);
+ g_return_val_if_fail (func != NULL, iter);
+
+ funcinfo = g_new0 (AlarmFuncInfo, 1);
+ funcinfo->func = func;
+ funcinfo->func_data = func_data;
+
+ gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+
+ current_zone = config_data_get_timezone ();
+ start = timet_to_str_with_zone (occur_start, current_zone);
+ end = timet_to_str_with_zone (occur_end, current_zone);
+ str_time = calculate_time (occur_start, occur_end);
+ to_display = g_markup_printf_escaped (
+ "<big><b>%s</b></big>\n%s %s",
+ summary, start, str_time);
+ g_free (start);
+ g_free (end);
+ gtk_list_store_set (
+ GTK_LIST_STORE (model), &iter,
+ ALARM_DISPLAY_COLUMN, to_display, -1);
+ g_free (to_display);
+ g_free (str_time);
+
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, ALARM_SUMMARY_COLUMN, summary, -1);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, ALARM_DESCRIPTION_COLUMN, description, -1);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, ALARM_LOCATION_COLUMN, location, -1);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, ALARM_START_COLUMN, occur_start, -1);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, ALARM_END_COLUMN, occur_end, -1);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, ALARM_FUNCINFO_COLUMN, funcinfo, -1);
+
+ return iter;
+}
+
+static void
+tree_selection_changed_cb (GtkTreeSelection *selection,
+ gpointer user_data)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ AlarmNotify *an = user_data;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ gchar *summary, *description, *location;
+ time_t occur_start, occur_end;
+
+ gtk_widget_set_sensitive (an->snooze_btn, TRUE);
+ gtk_widget_set_sensitive (an->edit_btn, TRUE);
+ gtk_widget_set_sensitive (an->print_btn, TRUE);
+ gtk_widget_set_sensitive (an->dismiss_btn, TRUE);
+ gtk_tree_model_get (model, &iter, ALARM_SUMMARY_COLUMN, &summary, -1);
+ gtk_tree_model_get (model, &iter, ALARM_DESCRIPTION_COLUMN, &description, -1);
+ gtk_tree_model_get (model, &iter, ALARM_LOCATION_COLUMN, &location, -1);
+ gtk_tree_model_get (model, &iter, ALARM_START_COLUMN, &occur_start, -1);
+ gtk_tree_model_get (model, &iter, ALARM_END_COLUMN, &occur_end, -1);\
+ gtk_tree_model_get (model, &iter, ALARM_FUNCINFO_COLUMN, &an->cur_funcinfo, -1);
+
+ fill_in_labels (an, summary, description, location, occur_start, occur_end);
+
+ g_free (summary);
+ g_free (description);
+ g_free (location);
+ } else {
+ gtk_widget_set_sensitive (an->snooze_btn, FALSE);
+ gtk_widget_set_sensitive (an->edit_btn, FALSE);
+ gtk_widget_set_sensitive (an->print_btn, FALSE);
+ gtk_widget_set_sensitive (an->dismiss_btn, FALSE);
+
+ fill_in_labels (an, "", "", "", -1, -1);
+ }
+}
+
+static void
+fill_in_labels (AlarmNotify *an,
+ const gchar *summary,
+ const gchar *description,
+ const gchar *location,
+ time_t occur_start,
+ time_t occur_end)
+{
+ GtkTextTagTable *table = gtk_text_tag_table_new ();
+ GtkTextBuffer *buffer = gtk_text_buffer_new (table);
+ gtk_text_buffer_set_text (buffer, description, -1);
+ e_buffer_tagger_disconnect (GTK_TEXT_VIEW (an->description));
+ gtk_text_view_set_buffer (GTK_TEXT_VIEW (an->description), buffer);
+ gtk_label_set_text (GTK_LABEL (an->location), location);
+ e_buffer_tagger_connect (GTK_TEXT_VIEW (an->description));
+ e_buffer_tagger_update_tags (GTK_TEXT_VIEW (an->description));
+ g_object_unref (table);
+ g_object_unref (buffer);
+}
diff --git a/calendar/alarm-notify/alarm-notify-dialog.h b/calendar/alarm-notify/alarm-notify-dialog.h
new file mode 100644
index 0000000000..68e322540a
--- /dev/null
+++ b/calendar/alarm-notify/alarm-notify-dialog.h
@@ -0,0 +1,63 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef ALARM_NOTIFY_DIALOG_H
+#define ALARM_NOTIFY_DIALOG_H
+
+#include <time.h>
+#include <gtk/gtk.h>
+#include <libecal/libecal.h>
+
+typedef enum {
+ ALARM_NOTIFY_CLOSE,
+ ALARM_NOTIFY_SNOOZE,
+ ALARM_NOTIFY_EDIT,
+ ALARM_NOTIFY_PRINT,
+ ALARM_NOTIFY_DISMISS
+} AlarmNotifyResult;
+
+typedef struct _AlarmNotificationsDialog AlarmNotificationsDialog;
+
+struct _AlarmNotificationsDialog {
+ GtkWidget *dialog;
+ GtkWidget *treeview;
+};
+
+typedef void (*AlarmNotifyFunc) (AlarmNotifyResult result,
+ gint snooze_mins,
+ gpointer data);
+
+AlarmNotificationsDialog *
+ notified_alarms_dialog_new (void);
+GtkTreeIter add_alarm_to_notified_alarms_dialog
+ (AlarmNotificationsDialog *na,
+ time_t trigger,
+ time_t occur_start,
+ time_t occur_end,
+ ECalComponentVType vtype,
+ const gchar *summary,
+ const gchar *description,
+ const gchar *location,
+ AlarmNotifyFunc func,
+ gpointer func_data);
+
+#endif /* ALARM_NOTIFY_DIALOG_H */
diff --git a/calendar/alarm-notify/alarm-notify.c b/calendar/alarm-notify/alarm-notify.c
new file mode 100644
index 0000000000..73fadc100c
--- /dev/null
+++ b/calendar/alarm-notify/alarm-notify.c
@@ -0,0 +1,334 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <camel/camel.h>
+
+#include "e-util/e-util.h"
+
+#include "alarm.h"
+#include "alarm-notify.h"
+#include "alarm-queue.h"
+#include "config-data.h"
+
+#define ALARM_NOTIFY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), TYPE_ALARM_NOTIFY, AlarmNotifyPrivate))
+
+#define APPLICATION_ID "org.gnome.EvolutionAlarmNotify"
+
+struct _AlarmNotifyPrivate {
+ ESourceRegistry *registry;
+ GHashTable *clients;
+ GMutex mutex;
+};
+
+/* Forward Declarations */
+static void alarm_notify_initable_init (GInitableIface *interface);
+
+G_DEFINE_TYPE_WITH_CODE (
+ AlarmNotify, alarm_notify, GTK_TYPE_APPLICATION,
+ G_IMPLEMENT_INTERFACE (
+ G_TYPE_INITABLE, alarm_notify_initable_init))
+
+static void
+alarm_notify_load_calendars (AlarmNotify *an)
+{
+ GList *list, *iter;
+
+ /* Add all available ESources. alarm_notify_add_calendar() will
+ * discard the ones we're not interested in (mail accounts, etc.). */
+
+ list = e_source_registry_list_sources (an->priv->registry, NULL);
+
+ for (iter = list; iter != NULL; iter = g_list_next (iter))
+ alarm_notify_add_calendar (an, E_SOURCE (iter->data));
+
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+}
+
+static void
+alarm_notify_dispose (GObject *object)
+{
+ AlarmNotifyPrivate *priv;
+ GHashTableIter iter;
+ gpointer client;
+
+ priv = ALARM_NOTIFY_GET_PRIVATE (object);
+
+ if (priv->registry != NULL) {
+ g_object_unref (priv->registry);
+ priv->registry = NULL;
+ }
+
+ g_hash_table_iter_init (&iter, priv->clients);
+ while (g_hash_table_iter_next (&iter, NULL, &client))
+ alarm_queue_remove_client (client, TRUE);
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (alarm_notify_parent_class)->dispose (object);
+}
+
+static void
+alarm_notify_finalize (GObject *object)
+{
+ AlarmNotifyPrivate *priv;
+
+ priv = ALARM_NOTIFY_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->clients);
+
+ alarm_queue_done ();
+ alarm_done ();
+
+ g_mutex_clear (&priv->mutex);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (alarm_notify_parent_class)->finalize (object);
+}
+
+static void
+alarm_notify_startup (GApplication *application)
+{
+ GtkIconTheme *icon_theme;
+
+ /* Chain up to parent's startup() method. */
+ G_APPLICATION_CLASS (alarm_notify_parent_class)->startup (application);
+
+ /* Keep the application running. */
+ g_application_hold (application);
+
+ config_data_init_debugging ();
+
+ /* FIXME Ideally we should not use Camel libraries in calendar,
+ * though it is the case currently for attachments. Remove
+ * this once that is fixed. */
+
+ /* Initialize Camel's type system. */
+ camel_object_get_type ();
+
+ icon_theme = gtk_icon_theme_get_default ();
+ gtk_icon_theme_append_search_path (icon_theme, EVOLUTION_ICONDIR);
+}
+
+static void
+alarm_notify_activate (GApplication *application)
+{
+ AlarmNotify *an = ALARM_NOTIFY (application);
+
+ if (g_application_get_is_remote (application)) {
+ g_application_quit (application);
+ return;
+ }
+
+ if (an->priv->registry != NULL) {
+ alarm_notify_load_calendars (an);
+
+ g_signal_connect_swapped (
+ an->priv->registry, "source-added",
+ G_CALLBACK (alarm_notify_add_calendar), an);
+
+ g_signal_connect_swapped (
+ an->priv->registry, "source-removed",
+ G_CALLBACK (alarm_notify_remove_calendar), an);
+ }
+}
+
+static gboolean
+alarm_notify_initable (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ AlarmNotify *an = ALARM_NOTIFY (initable);
+
+ an->priv->registry = e_source_registry_new_sync (cancellable, error);
+
+ return (an->priv->registry != NULL);
+}
+
+static void
+alarm_notify_class_init (AlarmNotifyClass *class)
+{
+ GObjectClass *object_class;
+ GApplicationClass *application_class;
+
+ g_type_class_add_private (class, sizeof (AlarmNotifyPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = alarm_notify_dispose;
+ object_class->finalize = alarm_notify_finalize;
+
+ application_class = G_APPLICATION_CLASS (class);
+ application_class->startup = alarm_notify_startup;
+ application_class->activate = alarm_notify_activate;
+}
+
+static void
+alarm_notify_initable_init (GInitableIface *interface)
+{
+ /* XXX Awkward name since we're missing an 'E' prefix. */
+ interface->init = alarm_notify_initable;
+}
+
+static void
+alarm_notify_init (AlarmNotify *an)
+{
+ an->priv = ALARM_NOTIFY_GET_PRIVATE (an);
+ g_mutex_init (&an->priv->mutex);
+
+ an->priv->clients = g_hash_table_new_full (
+ (GHashFunc) e_source_hash,
+ (GEqualFunc) e_source_equal,
+ (GDestroyNotify) g_object_unref,
+ (GDestroyNotify) g_object_unref);
+
+ alarm_queue_init (an);
+}
+
+/**
+ * alarm_notify_new:
+ *
+ * Creates a new #AlarmNotify object.
+ *
+ * Returns: a newly-created #AlarmNotify
+ **/
+AlarmNotify *
+alarm_notify_new (GCancellable *cancellable,
+ GError **error)
+{
+ return g_initable_new (
+ TYPE_ALARM_NOTIFY, cancellable, error,
+ "application-id", APPLICATION_ID, NULL);
+}
+
+static void
+client_connect_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ AlarmNotify *an = ALARM_NOTIFY (user_data);
+ EClient *client;
+ ESource *source;
+ ECalClient *cal_client;
+ GError *error = NULL;
+
+ client = e_cal_client_connect_finish (result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ if (error != NULL) {
+ debug (("%s", error->message));
+ g_error_free (error);
+ return;
+ }
+
+ source = e_client_get_source (client);
+
+ g_hash_table_insert (
+ an->priv->clients,
+ g_object_ref (source), client);
+
+ cal_client = E_CAL_CLIENT (client);
+
+ /* to resolve floating DATE-TIME properly */
+ e_cal_client_set_default_timezone (
+ cal_client, config_data_get_timezone ());
+
+ alarm_queue_add_client (cal_client);
+}
+
+/**
+ * alarm_notify_add_calendar:
+ * @an: an #AlarmNotify
+ * @source: the #ESource to create an #ECal from
+ *
+ * Tells the alarm notification service to load a calendar and start
+ * monitoring its alarms.
+ **/
+void
+alarm_notify_add_calendar (AlarmNotify *an,
+ ESource *source)
+{
+ ECalClientSourceType source_type;
+ const gchar *extension_name;
+
+ g_return_if_fail (IS_ALARM_NOTIFY (an));
+
+ g_mutex_lock (&an->priv->mutex);
+
+ /* Check if we already know about this ESource. */
+ if (g_hash_table_lookup (an->priv->clients, source) != NULL) {
+ g_mutex_unlock (&an->priv->mutex);
+ return;
+ }
+
+ /* Check if this is an ESource we're interested in. */
+ if (e_source_has_extension (source, E_SOURCE_EXTENSION_CALENDAR))
+ source_type = E_CAL_CLIENT_SOURCE_TYPE_EVENTS;
+ else if (e_source_has_extension (source, E_SOURCE_EXTENSION_MEMO_LIST))
+ source_type = E_CAL_CLIENT_SOURCE_TYPE_MEMOS;
+ else if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
+ source_type = E_CAL_CLIENT_SOURCE_TYPE_TASKS;
+ else {
+ g_mutex_unlock (&an->priv->mutex);
+ return;
+ }
+
+ /* Check if alarms are even wanted on this ESource. */
+ extension_name = E_SOURCE_EXTENSION_ALARMS;
+ if (e_source_has_extension (source, extension_name)) {
+ ESourceAlarms *extension;
+ extension = e_source_get_extension (source, extension_name);
+ if (!e_source_alarms_get_include_me (extension)) {
+ g_mutex_unlock (&an->priv->mutex);
+ return;
+ }
+ }
+
+ debug (("Opening '%s' (%s)", e_source_get_display_name (source), e_source_get_uid (source)));
+
+ e_cal_client_connect (
+ source, source_type, NULL,
+ client_connect_cb, an);
+
+ g_mutex_unlock (&an->priv->mutex);
+}
+
+void
+alarm_notify_remove_calendar (AlarmNotify *an,
+ ESource *source)
+{
+ ECalClient *cal_client;
+
+ cal_client = g_hash_table_lookup (an->priv->clients, source);
+ if (cal_client != NULL) {
+ alarm_queue_remove_client (cal_client, FALSE);
+ g_hash_table_remove (an->priv->clients, source);
+ }
+}
diff --git a/calendar/alarm-notify/alarm-notify.h b/calendar/alarm-notify/alarm-notify.h
new file mode 100644
index 0000000000..45de689a4e
--- /dev/null
+++ b/calendar/alarm-notify/alarm-notify.h
@@ -0,0 +1,76 @@
+/*
+ *
+ * Evolution calendar - Alarm notification service object
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef ALARM_NOTIFY_H
+#define ALARM_NOTIFY_H
+
+#include <gtk/gtk.h>
+#include <libecal/libecal.h>
+
+/* Standard GObject macros */
+#define TYPE_ALARM_NOTIFY \
+ (alarm_notify_get_type ())
+#define ALARM_NOTIFY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), TYPE_ALARM_NOTIFY, AlarmNotify))
+#define ALARM_NOTIFY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), TYPE_ALARM_NOTIFY, AlarmNotifyClass))
+#define IS_ALARM_NOTIFY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), TYPE_ALARM_NOTIFY))
+#define IS_ALARM_NOTIFY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), TYPE_ALARM_NOTIFY))
+#define ALARM_NOTIFY_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), TYPE_ALARM_NOTIFY, AlarmNotifyClass))
+
+G_BEGIN_DECLS
+
+typedef struct _AlarmNotify AlarmNotify;
+typedef struct _AlarmNotifyClass AlarmNotifyClass;
+typedef struct _AlarmNotifyPrivate AlarmNotifyPrivate;
+
+struct _AlarmNotify {
+ GtkApplication parent;
+ AlarmNotifyPrivate *priv;
+};
+
+struct _AlarmNotifyClass {
+ GtkApplicationClass parent_class;
+};
+
+GType alarm_notify_get_type (void);
+AlarmNotify * alarm_notify_new (GCancellable *cancellable,
+ GError **error);
+void alarm_notify_add_calendar (AlarmNotify *an,
+ ESource *source);
+void alarm_notify_remove_calendar (AlarmNotify *an,
+ ESource *source);
+
+G_END_DECLS
+
+#endif /* ALARM_NOTIFY_H */
diff --git a/calendar/alarm-notify/alarm-notify.ui b/calendar/alarm-notify/alarm-notify.ui
new file mode 100644
index 0000000000..db83a54192
--- /dev/null
+++ b/calendar/alarm-notify/alarm-notify.ui
@@ -0,0 +1,407 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <!-- interface-requires gtk+ 3.0 -->
+ <object class="GtkAdjustment" id="adjustment-days">
+ <property name="upper">65535</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">5</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment-hours">
+ <property name="upper">65535</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">5</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment-minutes">
+ <property name="upper">65535</property>
+ <property name="value">5</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">5</property>
+ </object>
+ <object class="GtkImage" id="apply-icon">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-apply</property>
+ </object>
+ <object class="GtkDialog" id="alarm-notify">
+ <property name="can_focus">False</property>
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Appointments</property>
+ <property name="type_hint">dialog</property>
+ <child internal-child="vbox">
+ <object class="GtkBox" id="dialog-vbox1">
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child internal-child="action_area">
+ <object class="GtkButtonBox" id="dialog-action_area1">
+ <property name="can_focus">False</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="dismiss-all-button">
+ <property name="label" translatable="yes">Dismiss _All</property>
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="image">close-icon</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="main-grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">6</property>
+ <property name="margin_right">6</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkImage" id="alarm-image">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="yalign">0</property>
+ <property name="stock">gtk-dialog-info</property>
+ <property name="icon-size">6</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="appointments-scrolled-window">
+ <property name="height_request">75</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="appointments-treeview">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection" id="treeview-selection2"/>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="description">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTextView" id="description-label">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">False</property>
+ <property name="wrap_mode">word</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVButtonBox" id="button-box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="valign">start</property>
+ <property name="spacing">6</property>
+ <property name="layout_style">start</property>
+ <child>
+ <object class="GtkButton" id="snooze-button">
+ <property name="label" translatable="yes">_Snooze</property>
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="image">refresh-icon</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="edit-button">
+ <property name="label">gtk-edit</property>
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="print-button">
+ <property name="label">gtk-print</property>
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="dismiss-button">
+ <property name="label" translatable="yes">_Dismiss</property>
+ <property name="use_action_appearance">False</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_action_appearance">False</property>
+ <property name="image">apply-icon</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkGrid" id="bottom-grid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="location-labe">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Location:</property>
+ <property name="selectable">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="location-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">location of appointment</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="width">6</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="snooze-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Snooze _time:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="snooze-time-days">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="invisible_char">â—</property>
+ <property name="invisible_char_set">True</property>
+ <property name="adjustment">adjustment-days</property>
+ <property name="climb_rate">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="days-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes">days</property>
+ </object>
+ <packing>
+ <property name="left_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="snooze-time-hrs">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="invisible_char">â—</property>
+ <property name="invisible_char_set">True</property>
+ <property name="adjustment">adjustment-hours</property>
+ <property name="climb_rate">1</property>
+ </object>
+ <packing>
+ <property name="left_attach">3</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="hrs-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes">hours</property>
+ </object>
+ <packing>
+ <property name="left_attach">4</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="snooze-time-min">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">start</property>
+ <property name="invisible_char">â—</property>
+ <property name="invisible_char_set">True</property>
+ <property name="adjustment">adjustment-minutes</property>
+ <property name="climb_rate">1</property>
+ <property name="snap_to_ticks">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">5</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="minutes-label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">minutes</property>
+ </object>
+ <packing>
+ <property name="left_attach">6</property>
+ <property name="top_attach">1</property>
+ <property name="width">1</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ <property name="width">2</property>
+ <property name="height">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-7">dismiss-all-button</action-widget>
+ </action-widgets>
+ </object>
+ <object class="GtkImage" id="close-icon">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-close</property>
+ </object>
+ <object class="GtkImage" id="refresh-icon">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="stock">gtk-refresh</property>
+ </object>
+</interface>
diff --git a/calendar/alarm-notify/alarm-queue.c b/calendar/alarm-notify/alarm-queue.c
new file mode 100644
index 0000000000..4cab17fc3c
--- /dev/null
+++ b/calendar/alarm-notify/alarm-queue.c
@@ -0,0 +1,2497 @@
+/*
+ * Alarm queueing engine
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#ifdef HAVE_CANBERRA
+#include <canberra-gtk.h>
+#endif
+
+#ifdef HAVE_LIBNOTIFY
+#include <libnotify/notify.h>
+#endif
+
+#include "alarm.h"
+#include "alarm-notify-dialog.h"
+#include "alarm-queue.h"
+#include "alarm-notify.h"
+#include "config-data.h"
+#include "util.h"
+
+#include "calendar/gui/print.h"
+
+/* The dialog with alarm nofications */
+static AlarmNotificationsDialog *alarm_notifications_dialog = NULL;
+
+/* Whether the queueing system has been initialized */
+static gboolean alarm_queue_inited = FALSE;
+
+/* Clients we are monitoring for alarms */
+static GHashTable *client_alarms_hash = NULL;
+
+/* List of tray icons being displayed */
+static GList *tray_icons_list = NULL;
+
+/* Top Tray Image */
+static GtkStatusIcon *tray_icon = NULL;
+static gint tray_blink_id = -1;
+static gint tray_blink_countdown = 0;
+static AlarmNotify *an;
+
+/* Structure that stores a client we are monitoring */
+typedef struct {
+ /* Monitored client */
+ ECalClient *cal_client;
+
+ /* The live view to the calendar */
+ ECalClientView *view;
+
+ /* Hash table of component UID -> CompQueuedAlarms. If an element is
+ * present here, then it means its cqa->queued_alarms contains at least
+ * one queued alarm. When all the alarms for a component have been
+ * dequeued, the CompQueuedAlarms structure is removed from the hash
+ * table. Thus a CQA exists <=> it has queued alarms.
+ */
+ GHashTable *uid_alarms_hash;
+} ClientAlarms;
+
+/* Pair of a ECalComponentAlarms and the mapping from queued alarm IDs to the
+ * actual alarm instance structures.
+ */
+typedef struct {
+ /* The parent client alarms structure */
+ ClientAlarms *parent_client;
+
+ /* The component's UID */
+ ECalComponentId *id;
+
+ /* The actual component and its alarm instances */
+ ECalComponentAlarms *alarms;
+
+ /* List of QueuedAlarm structures */
+ GSList *queued_alarms;
+
+ /* Flags */
+ gboolean expecting_update;
+} CompQueuedAlarms;
+
+/* Pair of a queued alarm ID and the alarm trigger instance it refers to */
+typedef struct {
+ /* Alarm ID from alarm.h */
+ gpointer alarm_id;
+
+ /* Instance from our parent CompQueuedAlarms->alarms->alarms list */
+ ECalComponentAlarmInstance *instance;
+
+ /* original trigger of the instance from component */
+ time_t orig_trigger;
+
+ /* Whether this is a snoozed queued alarm or a normal one */
+ guint snooze : 1;
+} QueuedAlarm;
+
+/* Alarm ID for the midnight refresh function */
+static gpointer midnight_refresh_id = NULL;
+static time_t midnight = 0;
+
+static void remove_client_alarms (ClientAlarms *ca);
+static void display_notification (time_t trigger,
+ CompQueuedAlarms *cqa,
+ gpointer alarm_id,
+ gboolean use_description);
+static void audio_notification (time_t trigger,
+ CompQueuedAlarms *cqa,
+ gpointer alarm_id);
+static void mail_notification (time_t trigger,
+ CompQueuedAlarms *cqa,
+ gpointer alarm_id);
+static void procedure_notification (time_t trigger,
+ CompQueuedAlarms *cqa,
+ gpointer alarm_id);
+#ifdef HAVE_LIBNOTIFY
+static void popup_notification (time_t trigger,
+ CompQueuedAlarms *cqa,
+ gpointer alarm_id,
+ gboolean use_description);
+#endif
+static void query_objects_modified_cb (ECalClientView *view,
+ const GSList *objects,
+ gpointer data);
+static void query_objects_removed_cb (ECalClientView *view,
+ const GSList *uids,
+ gpointer data);
+
+static void update_cqa (CompQueuedAlarms *cqa,
+ ECalComponent *comp);
+static void update_qa (ECalComponentAlarms *alarms,
+ QueuedAlarm *qa);
+static void tray_list_remove_cqa (CompQueuedAlarms *cqa);
+static void on_dialog_objs_removed_cb (ECalClientView *view,
+ const GSList *uids,
+ gpointer data);
+
+/* Alarm queue engine */
+
+static void load_alarms_for_today (ClientAlarms *ca);
+static void midnight_refresh_cb (gpointer alarm_id,
+ time_t trigger,
+ gpointer data);
+
+/* Simple asynchronous message dispatcher */
+
+typedef struct _Message Message;
+typedef void (*MessageFunc) (Message *msg);
+
+struct _Message {
+ MessageFunc func;
+};
+
+/*
+static void
+message_proxy (Message *msg)
+{
+ g_return_if_fail (msg->func != NULL);
+ *
+ msg->func (msg);
+}
+ *
+static gpointer
+create_thread_pool (void)
+{
+ return g_thread_pool_new ((GFunc) message_proxy, NULL, 1, FALSE, NULL);
+}*/
+
+static void
+message_push (Message *msg)
+{
+ /* This used be pushed through the thread pool. This fix is made to
+ * work-around the crashers in dbus due to threading. The threading
+ * is not completely removed as its better to have alarm daemon
+ * running in a thread rather than blocking main thread. This is
+ * the reason the creation of thread pool is commented out. */
+ msg->func (msg);
+}
+
+/*
+ * use a static ring-buffer so we can call this twice
+ * in a printf without getting nonsense results.
+ */
+static const gchar *
+e_ctime (const time_t *timep)
+{
+ static gchar *buffer[4] = { 0, };
+ static gint next = 0;
+ const gchar *ret;
+
+ g_free (buffer[next]);
+ ret = buffer[next++] = g_strdup (ctime (timep));
+ if (buffer[next - 1] && *buffer[next - 1]) {
+ gint len = strlen (buffer[next - 1]);
+ while (len > 0 && (buffer[next - 1][len - 1] == '\n' ||
+ buffer[next - 1][len - 1] == '\r' ||
+ g_ascii_isspace (buffer[next - 1][len - 1])))
+ len--;
+
+ buffer[next - 1][len - 1] = 0;
+ }
+
+ if (next >= G_N_ELEMENTS (buffer))
+ next = 0;
+
+ return ret;
+}
+
+/* Queues an alarm trigger for midnight so that we can load the next
+ * day's worth of alarms. */
+static void
+queue_midnight_refresh (void)
+{
+ icaltimezone *zone;
+
+ if (midnight_refresh_id != NULL) {
+ alarm_remove (midnight_refresh_id);
+ midnight_refresh_id = NULL;
+ }
+
+ zone = config_data_get_timezone ();
+ midnight = time_day_end_with_zone (time (NULL), zone);
+
+ debug (("Refresh at %s", e_ctime (&midnight)));
+
+ midnight_refresh_id = alarm_add (
+ midnight, midnight_refresh_cb, NULL, NULL);
+ if (!midnight_refresh_id) {
+ debug (("Could not setup the midnight refresh alarm"));
+ /* FIXME: what to do? */
+ }
+}
+
+/* Loads a client's alarms; called from g_hash_table_foreach() */
+static void
+add_client_alarms_cb (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ ClientAlarms *ca = (ClientAlarms *) value;
+
+ debug (("Adding %p", ca));
+
+ load_alarms_for_today (ca);
+}
+
+struct _midnight_refresh_msg {
+ Message header;
+ gboolean remove;
+};
+
+/* Loads the alarms for the new day every midnight */
+static void
+midnight_refresh_async (struct _midnight_refresh_msg *msg)
+{
+ debug (("..."));
+
+ /* Re-load the alarms for all clients */
+ g_hash_table_foreach (client_alarms_hash, add_client_alarms_cb, NULL);
+
+ /* Re-schedule the midnight update */
+ if (msg->remove && midnight_refresh_id != NULL) {
+ debug (("Reschedule the midnight update"));
+ alarm_remove (midnight_refresh_id);
+ midnight_refresh_id = NULL;
+ }
+
+ queue_midnight_refresh ();
+
+ g_slice_free (struct _midnight_refresh_msg, msg);
+}
+
+static void
+midnight_refresh_cb (gpointer alarm_id,
+ time_t trigger,
+ gpointer data)
+{
+ struct _midnight_refresh_msg *msg;
+
+ msg = g_slice_new0 (struct _midnight_refresh_msg);
+ msg->header.func = (MessageFunc) midnight_refresh_async;
+ msg->remove = TRUE;
+
+ message_push ((Message *) msg);
+}
+
+/* Looks up a client in the client alarms hash table */
+static ClientAlarms *
+lookup_client (ECalClient *cal_client)
+{
+ return g_hash_table_lookup (client_alarms_hash, cal_client);
+}
+
+/* Looks up a queued alarm based on its alarm ID */
+static QueuedAlarm *
+lookup_queued_alarm (CompQueuedAlarms *cqa,
+ gpointer alarm_id)
+{
+ GSList *l;
+ QueuedAlarm *qa;
+
+ qa = NULL;
+
+ for (l = cqa->queued_alarms; l; l = l->next) {
+ qa = l->data;
+ if (qa->alarm_id == alarm_id)
+ return qa;
+ }
+
+ /* not found, might have been updated/removed */
+ return NULL;
+}
+
+/* Removes an alarm from the list of alarms of a component. If the alarm was
+ * the last one listed for the component, it removes the component itself.
+ */
+static gboolean
+remove_queued_alarm (CompQueuedAlarms *cqa,
+ gpointer alarm_id,
+ gboolean free_object,
+ gboolean remove_alarm)
+{
+ QueuedAlarm *qa = NULL;
+ GSList *l;
+
+ debug (("..."));
+
+ for (l = cqa->queued_alarms; l; l = l->next) {
+ qa = l->data;
+ if (qa->alarm_id == alarm_id)
+ break;
+ }
+
+ if (!l)
+ return FALSE;
+
+ cqa->queued_alarms = g_slist_delete_link (cqa->queued_alarms, l);
+
+ if (remove_alarm) {
+ GError *error = NULL;
+ ECalComponentId *id;
+
+ id = e_cal_component_get_id (cqa->alarms->comp);
+ if (id) {
+ cqa->expecting_update = TRUE;
+ e_cal_client_discard_alarm_sync (
+ cqa->parent_client->cal_client, id->uid,
+ id->rid, qa->instance->auid, NULL, &error);
+ cqa->expecting_update = FALSE;
+
+ if (error) {
+ if (!g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_NOT_SUPPORTED))
+ g_warning (
+ "%s: Failed to discard alarm: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+ e_cal_component_free_id (id);
+ }
+ }
+
+ g_free (qa);
+
+ /* If this was the last queued alarm for this component, remove the
+ * component itself.
+ */
+
+ if (cqa->queued_alarms != NULL)
+ return FALSE;
+
+ debug (("Last Component. Removing CQA- Free=%d", free_object));
+ if (free_object) {
+ cqa->id = NULL;
+ cqa->parent_client = NULL;
+ e_cal_component_alarms_free (cqa->alarms);
+ g_free (cqa);
+ } else {
+ e_cal_component_alarms_free (cqa->alarms);
+ cqa->alarms = NULL;
+ }
+
+ return TRUE;
+}
+
+/**
+ * has_known_notification:
+ * Test for notification method and returns if it knows it or not.
+ * @comp: Component with an alarm.
+ * @alarm_uid: ID of the alarm in the comp to test.
+ *
+ * Returns: %TRUE when we know the notification type, %FALSE otherwise.
+ */
+static gboolean
+has_known_notification (ECalComponent *comp,
+ const gchar *alarm_uid)
+{
+ ECalComponentAlarm *alarm;
+ ECalComponentAlarmAction action;
+
+ g_return_val_if_fail (comp != NULL, FALSE);
+ g_return_val_if_fail (alarm_uid != NULL, FALSE);
+
+ alarm = e_cal_component_get_alarm (comp, alarm_uid);
+ if (!alarm)
+ return FALSE;
+
+ e_cal_component_alarm_get_action (alarm, &action);
+ e_cal_component_alarm_free (alarm);
+
+ switch (action) {
+ case E_CAL_COMPONENT_ALARM_AUDIO:
+ case E_CAL_COMPONENT_ALARM_DISPLAY:
+ case E_CAL_COMPONENT_ALARM_EMAIL:
+ case E_CAL_COMPONENT_ALARM_PROCEDURE:
+ return TRUE;
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+/* Callback used when an alarm triggers */
+static void
+alarm_trigger_cb (gpointer alarm_id,
+ time_t trigger,
+ gpointer data)
+{
+ CompQueuedAlarms *cqa;
+ ECalComponent *comp;
+ QueuedAlarm *qa;
+ ECalComponentAlarm *alarm;
+ ECalComponentAlarmAction action;
+
+ cqa = data;
+ comp = cqa->alarms->comp;
+
+ config_data_set_last_notification_time (
+ cqa->parent_client->cal_client, trigger);
+ debug (("Setting Last notification time to %s", e_ctime (&trigger)));
+
+ qa = lookup_queued_alarm (cqa, alarm_id);
+ if (!qa)
+ return;
+
+ /* Decide what to do based on the alarm action. We use the trigger that
+ * is passed to us instead of the one from the instance structure
+ * because this may be a snoozed alarm instead of an original
+ * occurrence.
+ */
+
+ alarm = e_cal_component_get_alarm (comp, qa->instance->auid);
+ if (!alarm)
+ return;
+
+ e_cal_component_alarm_get_action (alarm, &action);
+ e_cal_component_alarm_free (alarm);
+
+ switch (action) {
+ case E_CAL_COMPONENT_ALARM_AUDIO:
+ audio_notification (trigger, cqa, alarm_id);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_DISPLAY:
+#ifdef HAVE_LIBNOTIFY
+ popup_notification (trigger, cqa, alarm_id, TRUE);
+#endif
+ display_notification (trigger, cqa, alarm_id, TRUE);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_EMAIL:
+ mail_notification (trigger, cqa, alarm_id);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_PROCEDURE:
+ procedure_notification (trigger, cqa, alarm_id);
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+ debug (("Notification sent: %d", action));
+}
+
+/* Adds the alarms in a ECalComponentAlarms structure to the alarms queued for a
+ * particular client. Also puts the triggers in the alarm timer queue.
+ */
+static void
+add_component_alarms (ClientAlarms *ca,
+ ECalComponentAlarms *alarms)
+{
+ ECalComponentId *id;
+ CompQueuedAlarms *cqa;
+ GSList *l;
+
+ /* No alarms? */
+ if (alarms == NULL || alarms->alarms == NULL) {
+ debug (("No alarms to add"));
+ if (alarms)
+ e_cal_component_alarms_free (alarms);
+ return;
+ }
+
+ cqa = g_new (CompQueuedAlarms, 1);
+ cqa->parent_client = ca;
+ cqa->alarms = alarms;
+ cqa->expecting_update = FALSE;
+
+ cqa->queued_alarms = NULL;
+ debug (("Creating CQA %p", cqa));
+
+ for (l = alarms->alarms; l; l = l->next) {
+ ECalComponentAlarmInstance *instance;
+ gpointer alarm_id;
+ QueuedAlarm *qa;
+
+ instance = l->data;
+
+ if (!has_known_notification (cqa->alarms->comp, instance->auid))
+ continue;
+
+ alarm_id = alarm_add (
+ instance->trigger, alarm_trigger_cb, cqa, NULL);
+ if (!alarm_id)
+ continue;
+
+ qa = g_new (QueuedAlarm, 1);
+ qa->alarm_id = alarm_id;
+ qa->instance = instance;
+ qa->orig_trigger = instance->trigger;
+ qa->snooze = FALSE;
+
+ cqa->queued_alarms = g_slist_prepend (cqa->queued_alarms, qa);
+ }
+
+ id = e_cal_component_get_id (alarms->comp);
+
+ /* If we failed to add all the alarms, then we should get rid of the cqa */
+ if (cqa->queued_alarms == NULL) {
+ e_cal_component_alarms_free (cqa->alarms);
+ cqa->alarms = NULL;
+ debug (("Failed to add all : %p", cqa));
+ g_free (cqa);
+ return;
+ }
+
+ cqa->queued_alarms = g_slist_reverse (cqa->queued_alarms);
+ cqa->id = id;
+ debug (("Alarm added for %s", id->uid));
+ g_hash_table_insert (ca->uid_alarms_hash, cqa->id, cqa);
+}
+
+/* Loads the alarms of a client for a given range of time */
+static void
+load_alarms (ClientAlarms *ca,
+ time_t start,
+ time_t end)
+{
+ gchar *str_query, *iso_start, *iso_end;
+ GError *error = NULL;
+
+ debug (("..."));
+
+ iso_start = isodate_from_time_t (start);
+ if (!iso_start)
+ return;
+
+ iso_end = isodate_from_time_t (end);
+ if (!iso_end) {
+ g_free (iso_start);
+ return;
+ }
+
+ str_query = g_strdup_printf (
+ "(has-alarms-in-range? (make-time \"%s\") "
+ "(make-time \"%s\"))", iso_start, iso_end);
+ g_free (iso_start);
+ g_free (iso_end);
+
+ /* create the live query */
+ if (ca->view) {
+ debug (("Disconnecting old queries"));
+ g_signal_handlers_disconnect_matched (
+ ca->view, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, ca);
+ g_object_unref (ca->view);
+ ca->view = NULL;
+ }
+
+ e_cal_client_get_view_sync (
+ ca->cal_client, str_query, &ca->view, NULL, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Could not get query for client: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ } else {
+ debug (("Setting Call backs"));
+
+ g_signal_connect (
+ ca->view, "objects-added",
+ G_CALLBACK (query_objects_modified_cb), ca);
+ g_signal_connect (
+ ca->view, "objects-modified",
+ G_CALLBACK (query_objects_modified_cb), ca);
+ g_signal_connect (
+ ca->view, "objects-removed",
+ G_CALLBACK (query_objects_removed_cb), ca);
+
+ e_cal_client_view_start (ca->view, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to start view: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+ }
+
+ g_free (str_query);
+}
+
+/* Loads today's remaining alarms for a client */
+static void
+load_alarms_for_today (ClientAlarms *ca)
+{
+ time_t now, from, day_end, day_start;
+ icaltimezone *zone;
+
+ now = time (NULL);
+ zone = config_data_get_timezone ();
+ day_start = time_day_begin_with_zone (now, zone);
+
+ /* Make sure we don't miss some events from the last notification.
+ * We add 1 to the saved notification time to make the time ranges
+ * half-open; we do not want to display the "last" displayed alarm
+ * twice, once when it occurs and once when the alarm daemon restarts.
+ */
+ from = config_data_get_last_notification_time (ca->cal_client) + 1;
+ if (from <= 0)
+ from = MAX (from, day_start);
+
+ /* Add one hour after midnight, just to cover the delay in 30 minutes
+ * midnight checking. */
+ day_end = time_day_end_with_zone (now, zone) + (60 * 60);
+ debug (("From %s to %s", e_ctime (&from), e_ctime (&day_end)));
+ load_alarms (ca, from, day_end);
+}
+
+/* Looks up a component's queued alarm structure in a client alarms structure */
+static CompQueuedAlarms *
+lookup_comp_queued_alarms (ClientAlarms *ca,
+ const ECalComponentId *id)
+{
+ return g_hash_table_lookup (ca->uid_alarms_hash, id);
+}
+
+static void
+remove_alarms (CompQueuedAlarms *cqa,
+ gboolean free_object)
+{
+ GSList *l;
+
+ debug (("Removing for %p", cqa));
+
+ tray_list_remove_cqa (cqa);
+
+ for (l = cqa->queued_alarms; l;) {
+ QueuedAlarm *qa;
+
+ qa = l->data;
+
+ /* Get the next element here because the list element will go
+ * away in remove_queued_alarm(). The qa will be freed there as
+ * well.
+ */
+ l = l->next;
+
+ alarm_remove (qa->alarm_id);
+ remove_queued_alarm (cqa, qa->alarm_id, free_object, FALSE);
+ }
+}
+
+/* Removes a component an its alarms */
+static void
+remove_comp (ClientAlarms *ca,
+ ECalComponentId *id)
+{
+ CompQueuedAlarms *cqa;
+
+ debug (("Removing uid %s", id->uid));
+
+ if (id->rid && !(*(id->rid))) {
+ g_free (id->rid);
+ id->rid = NULL;
+ }
+
+ cqa = lookup_comp_queued_alarms (ca, id);
+ if (!cqa)
+ return;
+
+ /* If a component is present, then it means we must have alarms queued
+ * for it.
+ */
+ g_return_if_fail (cqa->queued_alarms != NULL);
+
+ debug (("Removing CQA %p", cqa));
+ remove_alarms (cqa, TRUE);
+}
+
+/* Called when a calendar component changes; we must reload its corresponding
+ * alarms.
+ */
+struct _query_msg {
+ Message header;
+ GSList *objects;
+ gpointer data;
+};
+
+static GSList *
+duplicate_ical (const GSList *in_list)
+{
+ const GSList *l;
+ GSList *out_list = NULL;
+ for (l = in_list; l; l = l->next) {
+ out_list = g_slist_prepend (
+ out_list, icalcomponent_new_clone (l->data));
+ }
+
+ return g_slist_reverse (out_list);
+}
+
+static GSList *
+duplicate_ecal (const GSList *in_list)
+{
+ const GSList *l;
+ GSList *out_list = NULL;
+ for (l = in_list; l; l = l->next) {
+ ECalComponentId *id, *old;
+ old = l->data;
+ id = g_new0 (ECalComponentId, 1);
+ id->uid = g_strdup (old->uid);
+ id->rid = g_strdup (old->rid);
+ out_list = g_slist_prepend (out_list, id);
+ }
+
+ return g_slist_reverse (out_list);
+}
+
+static gboolean
+get_alarms_for_object (ECalClient *cal_client,
+ const ECalComponentId *id,
+ time_t start,
+ time_t end,
+ ECalComponentAlarms **alarms)
+{
+ icalcomponent *icalcomp;
+ ECalComponent *comp;
+ ECalComponentAlarmAction omit[] = {-1};
+
+ g_return_val_if_fail (cal_client != NULL, FALSE);
+ g_return_val_if_fail (id != NULL, FALSE);
+ g_return_val_if_fail (alarms != NULL, FALSE);
+ g_return_val_if_fail (start >= 0 && end >= 0, FALSE);
+ g_return_val_if_fail (start <= end, FALSE);
+
+ if (!e_cal_client_get_object_sync (
+ cal_client, id->uid, id->rid, &icalcomp, NULL, NULL))
+ return FALSE;
+
+ if (!icalcomp)
+ return FALSE;
+
+ comp = e_cal_component_new ();
+ if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
+ g_object_unref (comp);
+ return FALSE;
+ }
+
+ *alarms = e_cal_util_generate_alarms_for_comp (
+ comp, start, end, omit, e_cal_client_resolve_tzid_cb,
+ cal_client, e_cal_client_get_default_timezone (cal_client));
+
+ g_object_unref (comp);
+
+ return TRUE;
+}
+
+static void
+query_objects_changed_async (struct _query_msg *msg)
+{
+ ClientAlarms *ca;
+ time_t from, day_end;
+ ECalComponentAlarms *alarms;
+ gboolean found;
+ icaltimezone *zone;
+ CompQueuedAlarms *cqa;
+ GSList *l;
+ GSList *objects;
+
+ ca = msg->data;
+ objects = msg->objects;
+
+ from = config_data_get_last_notification_time (ca->cal_client);
+ if (from == -1)
+ from = time (NULL);
+ else
+ from += 1; /* we add 1 to make sure the alarm is not displayed twice */
+
+ zone = config_data_get_timezone ();
+
+ day_end = time_day_end_with_zone (time (NULL), zone);
+
+ for (l = objects; l != NULL; l = l->next) {
+ ECalComponentId *id;
+ GSList *sl;
+ ECalComponent *comp = e_cal_component_new ();
+
+ e_cal_component_set_icalcomponent (comp, l->data);
+
+ id = e_cal_component_get_id (comp);
+ found = get_alarms_for_object (ca->cal_client, id, from, day_end, &alarms);
+
+ if (!found) {
+ debug (("No Alarm found for client %p", ca->cal_client));
+ tray_list_remove_cqa (lookup_comp_queued_alarms (ca, id));
+ remove_comp (ca, id);
+ g_hash_table_remove (ca->uid_alarms_hash, id);
+ e_cal_component_free_id (id);
+ g_object_unref (comp);
+ comp = NULL;
+ continue;
+ }
+
+ cqa = lookup_comp_queued_alarms (ca, id);
+ if (!cqa) {
+ debug (("No currently queued alarms for %s", id->uid));
+ add_component_alarms (ca, alarms);
+ g_object_unref (comp);
+ comp = NULL;
+ continue;
+ }
+
+ debug (("Alarm Already Exist for %s", id->uid));
+ /* If the alarms or the alarms list is empty,
+ * remove it after updating the cqa structure. */
+ if (alarms == NULL || alarms->alarms == NULL) {
+
+ /* Update the cqa and its queued alarms
+ * for changes in summary and alarm_uid. */
+ update_cqa (cqa, comp);
+
+ if (alarms)
+ e_cal_component_alarms_free (alarms);
+ continue;
+ }
+
+ /* if already in the list, just update it */
+ remove_alarms (cqa, FALSE);
+ cqa->alarms = alarms;
+ cqa->queued_alarms = NULL;
+
+ /* add the new alarms */
+ for (sl = cqa->alarms->alarms; sl; sl = sl->next) {
+ ECalComponentAlarmInstance *instance;
+ gpointer alarm_id;
+ QueuedAlarm *qa;
+
+ instance = sl->data;
+
+ if (!has_known_notification (cqa->alarms->comp, instance->auid))
+ continue;
+
+ alarm_id = alarm_add (instance->trigger, alarm_trigger_cb, cqa, NULL);
+ if (!alarm_id)
+ continue;
+
+ qa = g_new (QueuedAlarm, 1);
+ qa->alarm_id = alarm_id;
+ qa->instance = instance;
+ qa->snooze = FALSE;
+ qa->orig_trigger = instance->trigger;
+ cqa->queued_alarms = g_slist_prepend (cqa->queued_alarms, qa);
+ debug (("Adding %p to queue", qa));
+ }
+
+ cqa->queued_alarms = g_slist_reverse (cqa->queued_alarms);
+ g_object_unref (comp);
+ comp = NULL;
+ }
+ g_slist_free (objects);
+
+ g_slice_free (struct _query_msg, msg);
+}
+
+static void
+query_objects_modified_cb (ECalClientView *view,
+ const GSList *objects,
+ gpointer data)
+{
+ struct _query_msg *msg;
+
+ msg = g_slice_new0 (struct _query_msg);
+ msg->header.func = (MessageFunc) query_objects_changed_async;
+ msg->objects = duplicate_ical (objects);
+ msg->data = data;
+
+ message_push ((Message *) msg);
+}
+
+/* Called when a calendar component is removed; we must delete its corresponding
+ * alarms.
+ */
+static void
+query_objects_removed_async (struct _query_msg *msg)
+{
+ ClientAlarms *ca;
+ GSList *l;
+ GSList *objects;
+
+ ca = msg->data;
+ objects = msg->objects;
+
+ debug (("Removing %d objects", g_slist_length (objects)));
+
+ for (l = objects; l != NULL; l = l->next) {
+ /* If the alarm is already triggered remove it. */
+ tray_list_remove_cqa (lookup_comp_queued_alarms (ca, l->data));
+ remove_comp (ca, l->data);
+ g_hash_table_remove (ca->uid_alarms_hash, l->data);
+ e_cal_component_free_id (l->data);
+ }
+
+ g_slist_free (objects);
+
+ g_slice_free (struct _query_msg, msg);
+}
+
+static void
+query_objects_removed_cb (ECalClientView *view,
+ const GSList *uids,
+ gpointer data)
+{
+ struct _query_msg *msg;
+
+ msg = g_slice_new0 (struct _query_msg);
+ msg->header.func = (MessageFunc) query_objects_removed_async;
+ msg->objects = duplicate_ecal (uids);
+ msg->data = data;
+
+ message_push ((Message *) msg);
+}
+
+/* Notification functions */
+
+/* Creates a snooze alarm based on an existing one. The snooze offset is
+ * compued with respect to the current time.
+ */
+static void
+create_snooze (CompQueuedAlarms *cqa,
+ gpointer alarm_id,
+ gint snooze_mins)
+{
+ QueuedAlarm *orig_qa;
+ time_t t;
+ gpointer new_id;
+
+ orig_qa = lookup_queued_alarm (cqa, alarm_id);
+ if (!orig_qa)
+ return;
+
+ t = time (NULL);
+ t += snooze_mins * 60;
+
+ new_id = alarm_add (t, alarm_trigger_cb, cqa, NULL);
+ if (!new_id) {
+ debug (("Unable to schedule trigger for %s", e_ctime (&t)));
+ return;
+ }
+
+ orig_qa->instance->trigger = t;
+ orig_qa->alarm_id = new_id;
+ orig_qa->snooze = TRUE;
+ debug (("Adding a alarm at %s", e_ctime (&t)));
+}
+
+/* Launches a component editor for a component */
+static void
+edit_component (ECalClient *cal_client,
+ ECalComponent *comp)
+{
+ ESource *source;
+ gchar *command_line;
+ const gchar *scheme;
+ const gchar *comp_uid;
+ const gchar *source_uid;
+ GError *error = NULL;
+
+ /* XXX Don't we have a function to construct these URIs?
+ * How are other apps expected to know this stuff? */
+
+ source = e_client_get_source (E_CLIENT (cal_client));
+ source_uid = e_source_get_uid (source);
+
+ e_cal_component_get_uid (comp, &comp_uid);
+
+ switch (e_cal_client_get_source_type (cal_client)) {
+ case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
+ scheme = "calendar:";
+ break;
+ case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
+ scheme = "task:";
+ break;
+ case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
+ scheme = "memo:";
+ break;
+ default:
+ g_return_if_reached ();
+ }
+
+ command_line = g_strdup_printf (
+ "%s %s///?source-uid=%s&comp-uid=%s",
+ PACKAGE, scheme, source_uid, comp_uid);
+
+ if (!g_spawn_command_line_async (command_line, &error)) {
+ g_critical ("%s", error->message);
+ g_error_free (error);
+ }
+
+ g_free (command_line);
+}
+
+static void
+print_component (ECalClient *cal_client,
+ ECalComponent *comp)
+{
+ print_comp (
+ comp,
+ cal_client,
+ config_data_get_timezone (),
+ config_data_get_24_hour_format (),
+ GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
+}
+
+typedef struct {
+ gchar *summary;
+ gchar *description;
+ gchar *location;
+ gboolean blink_state;
+ gboolean snooze_set;
+ gint blink_id;
+ time_t trigger;
+ CompQueuedAlarms *cqa;
+ gpointer alarm_id;
+ ECalComponent *comp;
+ ECalClient *cal_client;
+ ECalClientView *view;
+ GdkPixbuf *image;
+ GtkTreeIter iter;
+ gboolean is_in_tree;
+} TrayIconData;
+
+static void
+free_tray_icon_data (TrayIconData *tray_data)
+{
+ g_return_if_fail (tray_data != NULL);
+
+ if (tray_data->summary) {
+ g_free (tray_data->summary);
+ tray_data->summary = NULL;
+ }
+
+ if (tray_data->description) {
+ g_free (tray_data->description);
+ tray_data->description = NULL;
+ }
+
+ if (tray_data->location) {
+ g_free (tray_data->location);
+ tray_data->location = NULL;
+ }
+
+ g_object_unref (tray_data->cal_client);
+ tray_data->cal_client = NULL;
+
+ g_signal_handlers_disconnect_matched (
+ tray_data->view, G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL, on_dialog_objs_removed_cb, NULL);
+ g_object_unref (tray_data->view);
+ tray_data->view = NULL;
+
+ g_object_unref (tray_data->comp);
+ tray_data->comp = NULL;
+
+ tray_data->cqa = NULL;
+ tray_data->alarm_id = NULL;
+ tray_data->image = NULL;
+
+ g_free (tray_data);
+}
+
+static void
+on_dialog_objs_removed_async (struct _query_msg *msg)
+{
+ TrayIconData *tray_data;
+ GSList *l, *objects;
+ ECalComponentId *our_id;
+
+ debug (("..."));
+
+ tray_data = msg->data;
+ objects = msg->objects;
+
+ our_id = e_cal_component_get_id (tray_data->comp);
+ g_return_if_fail (our_id);
+
+ for (l = objects; l != NULL; l = l->next) {
+ ECalComponentId *id = l->data;
+
+ if (!id)
+ continue;
+
+ if (tray_data &&
+ g_strcmp0 (id->uid, our_id->uid) == 0 &&
+ g_strcmp0 (id->rid, our_id->rid) == 0) {
+ tray_data->cqa = NULL;
+ tray_data->alarm_id = NULL;
+ tray_icons_list = g_list_remove (
+ tray_icons_list, tray_data);
+ tray_data = NULL;
+ }
+
+ e_cal_component_free_id (id);
+ }
+
+ e_cal_component_free_id (our_id);
+ g_slist_free (objects);
+ g_slice_free (struct _query_msg, msg);
+}
+
+static void
+on_dialog_objs_removed_cb (ECalClientView *view,
+ const GSList *uids,
+ gpointer data)
+{
+ struct _query_msg *msg;
+
+ msg = g_slice_new0 (struct _query_msg);
+ msg->header.func = (MessageFunc) on_dialog_objs_removed_async;
+ msg->objects = duplicate_ecal (uids);
+ msg->data = data;
+
+ message_push ((Message *) msg);
+}
+
+struct _tray_cqa_msg {
+ Message header;
+ CompQueuedAlarms *cqa;
+};
+
+static void
+tray_list_remove_cqa_async (struct _tray_cqa_msg *msg)
+{
+ CompQueuedAlarms *cqa = msg->cqa;
+ GList *list = tray_icons_list;
+
+ debug (("Removing CQA %p from tray list", cqa));
+
+ while (list) {
+ TrayIconData *tray_data = list->data;
+ GList *tmp = list;
+ GtkTreeModel *model;
+
+ list = list->next;
+ if (tray_data->cqa == cqa) {
+ debug (("Found"));
+ tray_icons_list = g_list_delete_link (tray_icons_list, tmp);
+ if (alarm_notifications_dialog && tray_data->is_in_tree) {
+ model = gtk_tree_view_get_model (
+ GTK_TREE_VIEW (alarm_notifications_dialog->treeview));
+ gtk_list_store_remove (GTK_LIST_STORE (model), &(tray_data->iter));
+ tray_data->is_in_tree = FALSE;
+ }
+ free_tray_icon_data (tray_data);
+ }
+ }
+
+ debug (("%d alarms left", g_list_length (tray_icons_list)));
+
+ if (alarm_notifications_dialog) {
+ if (!g_list_length (tray_icons_list)) {
+ gtk_widget_destroy (alarm_notifications_dialog->dialog);
+ g_free (alarm_notifications_dialog);
+ alarm_notifications_dialog = NULL;
+ } else {
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ GtkTreeSelection *sel;
+
+ model = gtk_tree_view_get_model (
+ GTK_TREE_VIEW (alarm_notifications_dialog->treeview));
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ sel = gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (alarm_notifications_dialog->treeview));
+ gtk_tree_selection_select_iter (sel, &iter);
+ }
+ }
+ }
+
+ g_slice_free (struct _tray_cqa_msg, msg);
+}
+
+static void
+tray_list_remove_cqa (CompQueuedAlarms *cqa)
+{
+ struct _tray_cqa_msg *msg;
+
+ msg = g_slice_new0 (struct _tray_cqa_msg);
+ msg->header.func = (MessageFunc) tray_list_remove_cqa_async;
+ msg->cqa = cqa;
+
+ message_push ((Message *) msg);
+}
+
+/* Callback used from the alarm notify dialog */
+static void
+tray_list_remove_async (Message *msg)
+{
+ GList *list = tray_icons_list;
+
+ debug (("Removing %d alarms", g_list_length (list)));
+ while (list != NULL) {
+
+ TrayIconData *tray_data = list->data;
+
+ if (!tray_data->snooze_set) {
+ GList *temp = list->next;
+ gboolean status;
+
+ tray_icons_list = g_list_remove_link (tray_icons_list, list);
+ if (alarm_notifications_dialog && tray_data->is_in_tree) {
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (alarm_notifications_dialog->treeview));
+ gtk_list_store_remove (GTK_LIST_STORE (model), &tray_data->iter);
+ tray_data->is_in_tree = FALSE;
+ }
+ status = remove_queued_alarm (
+ tray_data->cqa,
+ tray_data->alarm_id, FALSE, TRUE);
+ if (status) {
+ g_hash_table_remove (
+ tray_data->cqa->parent_client->uid_alarms_hash,
+ tray_data->cqa->id);
+ e_cal_component_free_id (tray_data->cqa->id);
+ g_free (tray_data->cqa);
+ }
+ free_tray_icon_data (tray_data);
+ tray_data = NULL;
+ g_list_free_1 (list);
+ if (tray_icons_list != list) /* List head is modified */
+ list = tray_icons_list;
+ else
+ list = temp;
+ } else
+ list = list->next;
+ }
+
+ g_slice_free (Message, msg);
+}
+
+static void
+tray_list_remove_icons (void)
+{
+ Message *msg;
+
+ msg = g_slice_new0 (Message);
+ msg->func = tray_list_remove_async;
+
+ message_push (msg);
+}
+
+struct _tray_msg {
+ Message header;
+ TrayIconData *data;
+};
+
+static void
+tray_list_remove_data_async (struct _tray_msg *msg)
+{
+ TrayIconData *tray_data = msg->data;
+
+ debug (("Removing %p from tray list", tray_data));
+
+ tray_icons_list = g_list_remove_all (tray_icons_list, tray_data);
+ free_tray_icon_data (tray_data);
+ tray_data = NULL;
+
+ g_slice_free (struct _tray_msg, msg);
+}
+
+static void
+tray_list_remove_data (TrayIconData *data)
+{
+ struct _tray_msg *msg;
+
+ msg = g_slice_new0 (struct _tray_msg);
+ msg->header.func = (MessageFunc) tray_list_remove_data_async;
+ msg->data = data;
+
+ message_push ((Message *) msg);
+}
+
+static void
+notify_dialog_cb (AlarmNotifyResult result,
+ gint snooze_mins,
+ gpointer data)
+{
+ TrayIconData *tray_data = data;
+
+ debug (("Received from dialog"));
+
+ g_signal_handlers_disconnect_matched (
+ tray_data->view, G_SIGNAL_MATCH_FUNC,
+ 0, 0, NULL, on_dialog_objs_removed_cb, NULL);
+
+ switch (result) {
+ case ALARM_NOTIFY_SNOOZE:
+ debug (("Creating a snooze"));
+ create_snooze (tray_data->cqa, tray_data->alarm_id, snooze_mins);
+ tray_data->snooze_set = TRUE;
+ tray_list_remove_data (tray_data);
+ if (alarm_notifications_dialog) {
+ GtkTreeSelection *selection =
+ gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (alarm_notifications_dialog->treeview));
+ GtkTreeIter iter;
+ GtkTreeModel *model = NULL;
+
+ /* We can also use tray_data->iter */
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ tray_data->is_in_tree = FALSE;
+ if (!gtk_tree_model_get_iter_first (model, &iter)) {
+ /* We removed the last one */
+ gtk_widget_destroy (alarm_notifications_dialog->dialog);
+ g_free (alarm_notifications_dialog);
+ alarm_notifications_dialog = NULL;
+ } else {
+ /* Select the first */
+ gtk_tree_selection_select_iter (selection, &iter);
+ }
+ }
+
+ }
+
+ break;
+
+ case ALARM_NOTIFY_EDIT:
+ edit_component (tray_data->cal_client, tray_data->comp);
+
+ break;
+
+ case ALARM_NOTIFY_PRINT:
+ print_component (tray_data->cal_client, tray_data->comp);
+
+ break;
+
+ case ALARM_NOTIFY_DISMISS:
+ if (alarm_notifications_dialog && tray_data->is_in_tree) {
+ GtkTreeModel *model;
+
+ model = gtk_tree_view_get_model (
+ GTK_TREE_VIEW (alarm_notifications_dialog->treeview));
+ gtk_list_store_remove (GTK_LIST_STORE (model), &tray_data->iter);
+ tray_data->is_in_tree = FALSE;
+ }
+ break;
+
+ case ALARM_NOTIFY_CLOSE:
+ debug (("Dialog close"));
+ if (alarm_notifications_dialog) {
+ GtkTreeIter iter;
+ GtkTreeModel *model =
+ gtk_tree_view_get_model (
+ GTK_TREE_VIEW (alarm_notifications_dialog->treeview));
+ gboolean valid = gtk_tree_model_get_iter_first (model, &iter);
+
+ /* Maybe we should warn about this first? */
+ while (valid) {
+ valid = gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+ }
+
+ gtk_widget_destroy (alarm_notifications_dialog->dialog);
+ g_free (alarm_notifications_dialog);
+ alarm_notifications_dialog = NULL;
+
+ /* Task to remove the tray icons */
+ tray_list_remove_icons ();
+ }
+
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+
+ return;
+}
+
+static void
+remove_tray_icon (void)
+{
+ if (tray_blink_id > -1)
+ g_source_remove (tray_blink_id);
+ tray_blink_id = -1;
+
+ if (tray_icon) {
+ gtk_status_icon_set_visible (tray_icon, FALSE);
+ g_object_unref (tray_icon);
+ tray_icon = NULL;
+ }
+}
+
+/* Callbacks. */
+static gboolean
+open_alarm_dialog (TrayIconData *tray_data)
+{
+ QueuedAlarm *qa;
+
+ debug (("..."));
+ qa = lookup_queued_alarm (tray_data->cqa, tray_data->alarm_id);
+ if (qa) {
+ remove_tray_icon ();
+
+ if (!alarm_notifications_dialog)
+ alarm_notifications_dialog = notified_alarms_dialog_new ();
+
+ if (alarm_notifications_dialog) {
+
+ GtkTreeSelection *selection = NULL;
+
+ selection = gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (alarm_notifications_dialog->treeview));
+
+ tray_data->iter = add_alarm_to_notified_alarms_dialog (
+ alarm_notifications_dialog,
+ tray_data->trigger,
+ qa->instance->occur_start,
+ qa->instance->occur_end,
+ e_cal_component_get_vtype (tray_data->comp),
+ tray_data->summary,
+ tray_data->description,
+ tray_data->location,
+ notify_dialog_cb, tray_data);
+
+ tray_data->is_in_tree = TRUE;
+
+ gtk_tree_selection_select_iter (
+ selection, &tray_data->iter);
+
+ gtk_window_present (GTK_WINDOW (alarm_notifications_dialog->dialog));
+ }
+
+ } else {
+ remove_tray_icon ();
+ }
+
+ return TRUE;
+}
+
+static gint
+tray_icon_clicked_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ if (event->type == GDK_BUTTON_PRESS) {
+ guint event_button = 0;
+
+ debug (("left click and %d alarms", g_list_length (tray_icons_list)));
+
+ gdk_event_get_button (event, &event_button);
+ if (event_button == 1 && g_list_length (tray_icons_list) > 0) {
+ GList *tmp;
+ for (tmp = tray_icons_list; tmp; tmp = tmp->next) {
+ open_alarm_dialog (tmp->data);
+ }
+
+ return TRUE;
+ } else if (event_button == 3) {
+ debug (("right click"));
+
+ remove_tray_icon ();
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+icon_activated (GtkStatusIcon *icon)
+{
+ GdkEvent event;
+
+ event.type = GDK_BUTTON_PRESS;
+ event.button.button = 1;
+ event.button.time = gtk_get_current_event_time ();
+
+ tray_icon_clicked_cb (NULL, &event, NULL);
+}
+
+static void
+popup_menu (GtkStatusIcon *icon,
+ guint button,
+ guint activate_time)
+{
+ if (button == 3) {
+ /* right click */
+ GdkEvent event;
+
+ event.type = GDK_BUTTON_PRESS;
+ event.button.button = 3;
+ event.button.time = gtk_get_current_event_time ();
+
+ tray_icon_clicked_cb (NULL, &event, NULL);
+ }
+}
+
+static gboolean
+tray_icon_blink_cb (gpointer data)
+{
+ static gboolean tray_blink_state = FALSE;
+ const gchar *icon_name;
+
+ tray_blink_countdown--;
+ tray_blink_state = !tray_blink_state;
+
+ if (tray_blink_state || tray_blink_countdown <= 0)
+ icon_name = "appointment-missed";
+ else
+ icon_name = "appointment-soon";
+
+ if (tray_icon)
+ gtk_status_icon_set_from_icon_name (tray_icon, icon_name);
+
+ if (tray_blink_countdown <= 0)
+ tray_blink_id = -1;
+
+ return tray_blink_countdown > 0;
+}
+
+/* Add a new data to tray list */
+
+static void
+tray_list_add_async (struct _tray_msg *msg)
+{
+ tray_icons_list = g_list_prepend (tray_icons_list, msg->data);
+
+ g_slice_free (struct _tray_msg, msg);
+}
+
+static void
+tray_list_add_new (TrayIconData *data)
+{
+ struct _tray_msg *msg;
+
+ msg = g_slice_new0 (struct _tray_msg);
+ msg->header.func = (MessageFunc) tray_list_add_async;
+ msg->data = data;
+
+ message_push ((Message *) msg);
+}
+
+static void
+alarm_queue_get_alarm_summary (ECalClient *cal_client,
+ ECalComponent *comp,
+ const ECalComponentAlarmInstance *instance,
+ ECalComponentText *text,
+ ECalComponentAlarm **palarm)
+{
+ g_return_if_fail (comp != NULL);
+ g_return_if_fail (instance != NULL);
+ g_return_if_fail (instance->auid != NULL);
+ g_return_if_fail (text != NULL);
+ g_return_if_fail (palarm != NULL);
+
+ text->value = NULL;
+
+ if (e_client_check_capability (E_CLIENT (cal_client), CAL_STATIC_CAPABILITY_ALARM_DESCRIPTION)) {
+ *palarm = e_cal_component_get_alarm (comp, instance->auid);
+ if (*palarm) {
+ e_cal_component_alarm_get_description (*palarm, text);
+ if (!text->value || !*text->value) {
+ text->value = NULL;
+ e_cal_component_alarm_free (*palarm);
+ *palarm = NULL;
+ }
+ } else {
+ *palarm = NULL;
+ }
+ }
+
+ if (!text->value)
+ e_cal_component_get_summary (comp, text);
+}
+
+/* Performs notification of a display alarm */
+static void
+display_notification (time_t trigger,
+ CompQueuedAlarms *cqa,
+ gpointer alarm_id,
+ gboolean use_description)
+{
+ QueuedAlarm *qa;
+ ECalComponent *comp;
+ ECalComponentAlarm *comp_alarm = NULL;
+ const gchar *summary, *description, *location;
+ TrayIconData *tray_data;
+ ECalComponentText text;
+ GSList *text_list;
+ gchar *str, *start_str, *end_str, *alarm_str, *time_str;
+ icaltimezone *current_zone;
+ ECalComponentOrganizer organiser;
+
+ debug (("..."));
+
+ comp = cqa->alarms->comp;
+ qa = lookup_queued_alarm (cqa, alarm_id);
+ if (!qa)
+ return;
+
+ /* get a sensible description for the event */
+ alarm_queue_get_alarm_summary (cqa->parent_client->cal_client, comp, qa->instance, &text, &comp_alarm);
+ e_cal_component_get_organizer (comp, &organiser);
+
+ if (text.value)
+ summary = text.value;
+ else
+ summary = _("No summary available.");
+
+ e_cal_component_get_description_list (comp, &text_list);
+
+ if (text_list) {
+ text = *((ECalComponentText *) text_list->data);
+ if (text.value)
+ description = text.value;
+ else
+ description = _("No description available.");
+ } else {
+ description = _("No description available.");
+ }
+
+ e_cal_component_free_text_list (text_list);
+
+ e_cal_component_get_location (comp, &location);
+
+ if (!location)
+ location = _("No location information available.");
+
+ /* create the tray icon */
+ if (tray_icon == NULL) {
+ tray_icon = gtk_status_icon_new ();
+ gtk_status_icon_set_title (tray_icon, _("Evolution Reminders"));
+ gtk_status_icon_set_from_icon_name (
+ tray_icon, "appointment-soon");
+ g_signal_connect (
+ tray_icon, "activate",
+ G_CALLBACK (icon_activated), NULL);
+ g_signal_connect (
+ tray_icon, "popup-menu",
+ G_CALLBACK (popup_menu), NULL);
+ }
+
+ current_zone = config_data_get_timezone ();
+ alarm_str = timet_to_str_with_zone (trigger, current_zone);
+ start_str = timet_to_str_with_zone (qa->instance->occur_start, current_zone);
+ end_str = timet_to_str_with_zone (qa->instance->occur_end, current_zone);
+ time_str = calculate_time (qa->instance->occur_start, qa->instance->occur_end);
+
+ str = g_strdup_printf (
+ "%s\n%s %s",
+ summary, start_str, time_str);
+
+ /* create the private structure */
+ tray_data = g_new0 (TrayIconData, 1);
+ tray_data->summary = g_strdup (summary);
+ tray_data->description = g_strdup (description);
+ tray_data->location = g_strdup (location);
+ tray_data->trigger = trigger;
+ tray_data->cqa = cqa;
+ tray_data->alarm_id = alarm_id;
+ tray_data->comp = e_cal_component_clone (comp);
+ tray_data->cal_client = cqa->parent_client->cal_client;
+ tray_data->view = g_object_ref (cqa->parent_client->view);
+ tray_data->blink_state = FALSE;
+ tray_data->snooze_set = FALSE;
+ tray_data->is_in_tree = FALSE;
+ g_object_ref (tray_data->cal_client);
+
+ /* Task to add tray_data to the global tray_icon_list */
+ tray_list_add_new (tray_data);
+
+ if (g_list_length (tray_icons_list) > 1) {
+ gchar *tip;
+
+ tip = g_strdup_printf (ngettext (
+ "You have %d reminder", "You have %d reminders",
+ g_list_length (tray_icons_list)),
+ g_list_length (tray_icons_list));
+ gtk_status_icon_set_tooltip_text (tray_icon, tip);
+ }
+ else {
+ gtk_status_icon_set_tooltip_text (tray_icon, str);
+ }
+
+ if (comp_alarm)
+ e_cal_component_alarm_free (comp_alarm);
+ g_free (start_str);
+ g_free (end_str);
+ g_free (alarm_str);
+ g_free (time_str);
+ g_free (str);
+
+ g_signal_connect (
+ tray_data->view, "objects_removed",
+ G_CALLBACK (on_dialog_objs_removed_cb), tray_data);
+
+ /* FIXME: We should remove this check */
+ if (!config_data_get_notify_with_tray ()) {
+ tray_blink_id = -1;
+ open_alarm_dialog (tray_data);
+ if (alarm_notifications_dialog)
+ gtk_window_stick (GTK_WINDOW (
+ alarm_notifications_dialog->dialog));
+ } else {
+ if (tray_blink_id == -1) {
+ tray_blink_countdown = 30;
+ tray_blink_id = g_timeout_add (500, tray_icon_blink_cb, tray_data);
+ }
+ }
+}
+
+#ifdef HAVE_LIBNOTIFY
+static void
+popup_notification (time_t trigger,
+ CompQueuedAlarms *cqa,
+ gpointer alarm_id,
+ gboolean use_description)
+{
+ QueuedAlarm *qa;
+ ECalComponent *comp;
+ ECalComponentAlarm *comp_alarm = NULL;
+ const gchar *summary, *location;
+ ECalComponentText text;
+ gchar *str, *start_str, *end_str, *alarm_str, *time_str;
+ icaltimezone *current_zone;
+ ECalComponentOrganizer organiser;
+ NotifyNotification *notify;
+ gchar *body;
+
+ debug (("..."));
+
+ comp = cqa->alarms->comp;
+ qa = lookup_queued_alarm (cqa, alarm_id);
+ if (!qa)
+ return;
+ if (!notify_is_initted ())
+ notify_init (_("Evolution Reminders"));
+
+ /* get a sensible description for the event */
+ alarm_queue_get_alarm_summary (cqa->parent_client->cal_client, comp, qa->instance, &text, &comp_alarm);
+ e_cal_component_get_organizer (comp, &organiser);
+
+ if (text.value)
+ summary = text.value;
+ else
+ summary = _("No summary available.");
+
+ e_cal_component_get_location (comp, &location);
+
+ /* create the tray icon */
+
+ current_zone = config_data_get_timezone ();
+ alarm_str = timet_to_str_with_zone (trigger, current_zone);
+ start_str = timet_to_str_with_zone (qa->instance->occur_start, current_zone);
+ end_str = timet_to_str_with_zone (qa->instance->occur_end, current_zone);
+ time_str = calculate_time (qa->instance->occur_start, qa->instance->occur_end);
+
+ str = g_strdup_printf (
+ "%s %s",
+ start_str, time_str);
+
+ if (organiser.cn) {
+ if (location)
+ body = g_strdup_printf (
+ "<b>%s</b>\n%s %s\n%s %s",
+ organiser.cn, _("Location:"),
+ location, start_str, time_str);
+ else
+ body = g_strdup_printf (
+ "<b>%s</b>\n%s %s",
+ organiser.cn, start_str, time_str);
+ }
+ else {
+ if (location)
+ body = g_strdup_printf (
+ "%s %s\n%s %s", _("Location:"),
+ location, start_str, time_str);
+ else
+ body = g_strdup_printf (
+ "%s %s", start_str, time_str);
+ }
+
+ notify = notify_notification_new (summary, body, "appointment-soon");
+
+ /* If the user wants Evolution notifications suppressed, honor
+ * it even though evolution-alarm-notify is a separate process
+ * with its own .desktop file. */
+ notify_notification_set_hint (
+ notify, "desktop-entry",
+ g_variant_new_string (PACKAGE));
+
+ if (!notify_notification_show (notify, NULL))
+ g_warning ("Could not send notification to daemon\n");
+
+ if (comp_alarm)
+ e_cal_component_alarm_free (comp_alarm);
+ /* create the private structure */
+ g_free (start_str);
+ g_free (end_str);
+ g_free (alarm_str);
+ g_free (time_str);
+ g_free (str);
+
+}
+#endif
+
+/* Performs notification of an audio alarm */
+static void
+audio_notification (time_t trigger,
+ CompQueuedAlarms *cqa,
+ gpointer alarm_id)
+{
+ QueuedAlarm *qa;
+ ECalComponent *comp;
+ ECalComponentAlarm *alarm;
+ icalattach *attach;
+ gint flag = 0;
+
+ debug (("..."));
+
+ comp = cqa->alarms->comp;
+ qa = lookup_queued_alarm (cqa, alarm_id);
+ if (!qa)
+ return;
+
+ alarm = e_cal_component_get_alarm (comp, qa->instance->auid);
+ g_return_if_fail (alarm != NULL);
+
+ e_cal_component_alarm_get_attach (alarm, &attach);
+ e_cal_component_alarm_free (alarm);
+
+ if (attach && icalattach_get_is_url (attach)) {
+ const gchar *url;
+
+ url = icalattach_get_url (attach);
+ if (url && *url) {
+ gchar *filename;
+ GError *error = NULL;
+
+ filename = g_filename_from_uri (url, NULL, &error);
+
+ if (error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ } else if (filename && g_file_test (filename, G_FILE_TEST_EXISTS)) {
+#ifdef HAVE_CANBERRA
+ flag = 1;
+ ca_context_play (
+ ca_gtk_context_get (), 0,
+ CA_PROP_MEDIA_FILENAME, filename, NULL);
+#endif
+ }
+
+ g_free (filename);
+ }
+ }
+
+ if (!flag)
+ gdk_beep ();
+
+ if (attach)
+ icalattach_unref (attach);
+
+}
+
+/* Performs notification of a mail alarm */
+static void
+mail_notification (time_t trigger,
+ CompQueuedAlarms *cqa,
+ gpointer alarm_id)
+{
+ if (!e_client_check_capability (
+ E_CLIENT (cqa->parent_client->cal_client),
+ CAL_STATIC_CAPABILITY_NO_EMAIL_ALARMS))
+ return;
+
+ /* FIXME Implement this. */
+}
+
+/* Performs notification of a procedure alarm */
+static gboolean
+procedure_notification_dialog (const gchar *cmd,
+ const gchar *url)
+{
+ GtkWidget *container;
+ GtkWidget *dialog;
+ GtkWidget *label;
+ GtkWidget *checkbox;
+ gchar *str;
+ gint btn;
+
+ debug (("..."));
+
+ if (config_data_is_blessed_program (url))
+ return TRUE;
+
+ dialog = gtk_dialog_new_with_buttons (
+ _("Warning"), NULL, 0,
+ GTK_STOCK_NO, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_YES, GTK_RESPONSE_OK,
+ NULL);
+
+ str = g_strdup_printf (
+ _("An Evolution Calendar reminder is about to trigger. "
+ "This reminder is configured to run the following program:\n\n"
+ " %s\n\n"
+ "Are you sure you want to run this program?"),
+ cmd);
+ label = gtk_label_new (str);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
+ gtk_widget_show (label);
+
+ container = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ gtk_box_pack_start (GTK_BOX (container), label, TRUE, TRUE, 4);
+ g_free (str);
+
+ checkbox = gtk_check_button_new_with_label
+ (_("Do not ask me about this program again."));
+ gtk_widget_show (checkbox);
+ gtk_box_pack_start (GTK_BOX (container), checkbox, TRUE, TRUE, 4);
+
+ /* Run the dialog */
+ btn = gtk_dialog_run (GTK_DIALOG (dialog));
+ if (btn == GTK_RESPONSE_OK &&
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox)))
+ config_data_save_blessed_program (url);
+ gtk_widget_destroy (dialog);
+
+ return (btn == GTK_RESPONSE_OK);
+}
+
+static void
+procedure_notification (time_t trigger,
+ CompQueuedAlarms *cqa,
+ gpointer alarm_id)
+{
+ QueuedAlarm *qa;
+ ECalComponent *comp;
+ ECalComponentAlarm *alarm;
+ ECalComponentText description;
+ icalattach *attach;
+ const gchar *url;
+ gchar *cmd;
+ gboolean result = TRUE;
+
+ debug (("..."));
+
+ comp = cqa->alarms->comp;
+ qa = lookup_queued_alarm (cqa, alarm_id);
+ if (!qa)
+ return;
+
+ alarm = e_cal_component_get_alarm (comp, qa->instance->auid);
+ g_return_if_fail (alarm != NULL);
+
+ e_cal_component_alarm_get_attach (alarm, &attach);
+ e_cal_component_alarm_get_description (alarm, &description);
+ e_cal_component_alarm_free (alarm);
+
+ /* If the alarm has no attachment, simply display a notification dialog. */
+ if (!attach)
+ goto fallback;
+
+ if (!icalattach_get_is_url (attach)) {
+ icalattach_unref (attach);
+ goto fallback;
+ }
+
+ url = icalattach_get_url (attach);
+ g_return_if_fail (url != NULL);
+
+ /* Ask for confirmation before executing the stuff */
+ if (description.value)
+ cmd = g_strconcat (url, " ", description.value, NULL);
+ else
+ cmd = (gchar *) url;
+
+ if (procedure_notification_dialog (cmd, url))
+ result = g_spawn_command_line_async (cmd, NULL);
+
+ if (cmd != (gchar *) url)
+ g_free (cmd);
+
+ icalattach_unref (attach);
+
+ /* Fall back to display notification if we got an error */
+ if (result == FALSE)
+ goto fallback;
+
+ return;
+
+ fallback:
+
+ display_notification (trigger, cqa, alarm_id, FALSE);
+}
+
+static gboolean
+check_midnight_refresh (gpointer user_data)
+{
+ time_t new_midnight;
+ icaltimezone *zone;
+
+ debug (("..."));
+
+ zone = config_data_get_timezone ();
+ new_midnight = time_day_end_with_zone (time (NULL), zone);
+
+ if (new_midnight > midnight) {
+ struct _midnight_refresh_msg *msg;
+
+ msg = g_slice_new0 (struct _midnight_refresh_msg);
+ msg->header.func = (MessageFunc) midnight_refresh_async;
+ msg->remove = FALSE;
+
+ message_push ((Message *) msg);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+check_wall_clock_time_changed (gpointer user_data)
+{
+ static gint64 expected_wall_clock_time = 0;
+ gint64 wall_clock_time;
+
+ #define ADD_SECONDS(to, secs) ((to) + ((secs) * 1000000))
+
+ wall_clock_time = g_get_real_time ();
+
+ /* use one second margin */
+ if (wall_clock_time > ADD_SECONDS (expected_wall_clock_time, 1) ||
+ wall_clock_time < ADD_SECONDS (expected_wall_clock_time, -1)) {
+ debug (("Current wall-clock time differs from expected, rescheduling alarms"));
+ check_midnight_refresh (NULL);
+ alarm_reschedule_timeout ();
+ }
+
+ expected_wall_clock_time = ADD_SECONDS (wall_clock_time, 60);
+
+ #undef ADD_SECONDS
+
+ return TRUE;
+}
+
+/**
+ * alarm_queue_init:
+ *
+ * Initializes the alarm queueing system. This should be called near the
+ * beginning of the program.
+ **/
+void
+alarm_queue_init (gpointer data)
+{
+ an = data;
+ g_return_if_fail (alarm_queue_inited == FALSE);
+
+ debug (("..."));
+
+ client_alarms_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
+ queue_midnight_refresh ();
+
+ if (config_data_get_last_notification_time (NULL) == -1) {
+ time_t tmval = time_day_begin (time (NULL));
+ debug (("Setting last notification time to %s", e_ctime (&tmval)));
+ config_data_set_last_notification_time (NULL, tmval);
+ }
+
+ /* install timeout handler (every 30 mins) for not missing the midnight refresh */
+ g_timeout_add_seconds (1800, check_midnight_refresh, NULL);
+
+ /* monotonic time doesn't change during hibernation, while the wall clock time does,
+ * thus check for wall clock time changes and reschedule alarms when it changes */
+ g_timeout_add_seconds (60, check_wall_clock_time_changed, NULL);
+
+#ifdef HAVE_LIBNOTIFY
+ notify_init (_("Evolution Reminders"));
+#endif
+
+ alarm_queue_inited = TRUE;
+}
+
+static gboolean
+free_client_alarms_cb (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ ClientAlarms *ca = value;
+
+ debug (("ca=%p", ca));
+
+ if (ca) {
+ remove_client_alarms (ca);
+ if (ca->cal_client) {
+ debug (("Disconnecting Client"));
+
+ g_signal_handlers_disconnect_matched (
+ ca->cal_client, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, ca);
+ g_object_unref (ca->cal_client);
+ }
+
+ if (ca->view) {
+ debug (("Disconnecting Query"));
+
+ g_signal_handlers_disconnect_matched (
+ ca->view, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, ca);
+ g_object_unref (ca->view);
+ }
+
+ g_hash_table_destroy (ca->uid_alarms_hash);
+
+ g_free (ca);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * alarm_queue_done:
+ *
+ * Shuts down the alarm queueing system. This should be called near the end
+ * of the program. All the monitored calendar clients should already have been
+ * unregistered with alarm_queue_remove_client().
+ **/
+void
+alarm_queue_done (void)
+{
+ g_return_if_fail (alarm_queue_inited);
+
+ /* All clients must be unregistered by now */
+ g_return_if_fail (g_hash_table_size (client_alarms_hash) == 0);
+
+ debug (("..."));
+
+ g_hash_table_foreach_remove (
+ client_alarms_hash, (GHRFunc) free_client_alarms_cb, NULL);
+ g_hash_table_destroy (client_alarms_hash);
+ client_alarms_hash = NULL;
+
+ if (midnight_refresh_id != NULL) {
+ alarm_remove (midnight_refresh_id);
+ midnight_refresh_id = NULL;
+ }
+
+ alarm_queue_inited = FALSE;
+}
+
+static gboolean
+compare_ids (gpointer a,
+ gpointer b)
+{
+ ECalComponentId *id, *id1;
+
+ id = a;
+ id1 = b;
+ if (id->uid != NULL && id1->uid != NULL) {
+ if (g_str_equal (id->uid, id1->uid)) {
+
+ if (id->rid && id1->rid)
+ return g_str_equal (id->rid, id1->rid);
+ else if (!(id->rid && id1->rid))
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static guint
+hash_ids (gpointer a)
+{
+ ECalComponentId *id =a;
+
+ return g_str_hash (id->uid);
+}
+
+struct _alarm_client_msg {
+ Message header;
+ ECalClient *cal_client;
+};
+
+static void
+alarm_queue_add_async (struct _alarm_client_msg *msg)
+{
+ ClientAlarms *ca;
+ ECalClient *cal_client = msg->cal_client;
+
+ g_return_if_fail (alarm_queue_inited);
+ g_return_if_fail (cal_client != NULL);
+ g_return_if_fail (E_IS_CAL_CLIENT (cal_client));
+
+ ca = lookup_client (cal_client);
+ if (ca) {
+ /* We already have it. Unref the passed one*/
+ g_object_unref (cal_client);
+ return;
+ }
+
+ debug (("client=%p", cal_client));
+
+ ca = g_new (ClientAlarms, 1);
+
+ ca->cal_client = cal_client;
+ ca->view = NULL;
+
+ g_hash_table_insert (client_alarms_hash, cal_client, ca);
+
+ ca->uid_alarms_hash = g_hash_table_new (
+ (GHashFunc) hash_ids, (GEqualFunc) compare_ids);
+
+ load_alarms_for_today (ca);
+
+ g_slice_free (struct _alarm_client_msg, msg);
+}
+
+/**
+ * alarm_queue_add_client:
+ * @cal_client: A calendar client.
+ *
+ * Adds a calendar client to the alarm queueing system. Alarm trigger
+ * notifications will be presented at the appropriate times. The client should
+ * be removed with alarm_queue_remove_client() when receiving notifications
+ * from it is no longer desired.
+ *
+ * A client can be added any number of times to the alarm queueing system,
+ * but any single alarm trigger will only be presented once for a particular
+ * client. The client must still be removed the same number of times from the
+ * queueing system when it is no longer wanted.
+ **/
+void
+alarm_queue_add_client (ECalClient *cal_client)
+{
+ struct _alarm_client_msg *msg;
+
+ msg = g_slice_new0 (struct _alarm_client_msg);
+ msg->header.func = (MessageFunc) alarm_queue_add_async;
+ msg->cal_client = g_object_ref (cal_client);
+
+ message_push ((Message *) msg);
+}
+
+/* Removes a component an its alarms */
+static void
+remove_cqa (ClientAlarms *ca,
+ ECalComponentId *id,
+ CompQueuedAlarms *cqa)
+{
+
+ /* If a component is present, then it means we must have alarms queued
+ * for it.
+ */
+ g_return_if_fail (cqa->queued_alarms != NULL);
+
+ debug (("removing %d alarms", g_slist_length (cqa->queued_alarms)));
+ remove_alarms (cqa, TRUE);
+}
+
+static gboolean
+remove_comp_by_id (gpointer key,
+ gpointer value,
+ gpointer userdata)
+{
+
+ ClientAlarms *ca = (ClientAlarms *) userdata;
+
+ debug (("..."));
+
+/* if (!g_hash_table_size (ca->uid_alarms_hash)) */
+/* return; */
+
+ remove_cqa (ca, (ECalComponentId *) key, (CompQueuedAlarms *) value);
+
+ return TRUE;
+}
+
+/* Removes all the alarms queued for a particular calendar client */
+static void
+remove_client_alarms (ClientAlarms *ca)
+{
+ debug (("size %d", g_hash_table_size (ca->uid_alarms_hash)));
+
+ g_hash_table_foreach_remove (
+ ca->uid_alarms_hash, (GHRFunc) remove_comp_by_id, ca);
+
+ /* The hash table should be empty now */
+ g_return_if_fail (g_hash_table_size (ca->uid_alarms_hash) == 0);
+}
+
+/**
+ * alarm_queue_remove_client:
+ * @client: A calendar client.
+ *
+ * Removes a calendar client from the alarm queueing system.
+ **/
+static void
+alarm_queue_remove_async (struct _alarm_client_msg *msg)
+{
+ ClientAlarms *ca;
+ ECalClient *cal_client = msg->cal_client;
+
+ g_return_if_fail (alarm_queue_inited);
+ g_return_if_fail (cal_client != NULL);
+ g_return_if_fail (E_IS_CAL_CLIENT (cal_client));
+
+ ca = lookup_client (cal_client);
+ g_return_if_fail (ca != NULL);
+
+ debug (("..."));
+ remove_client_alarms (ca);
+
+ /* Clean up */
+ if (ca->cal_client) {
+ debug (("Disconnecting Client"));
+
+ g_signal_handlers_disconnect_matched (
+ ca->cal_client, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, ca);
+ g_object_unref (ca->cal_client);
+ ca->cal_client = NULL;
+ }
+
+ if (ca->view) {
+ debug (("Disconnecting Query"));
+
+ g_signal_handlers_disconnect_matched (
+ ca->view, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, ca);
+ g_object_unref (ca->view);
+ ca->view = NULL;
+ }
+
+ g_hash_table_destroy (ca->uid_alarms_hash);
+ ca->uid_alarms_hash = NULL;
+
+ g_free (ca);
+
+ g_hash_table_remove (client_alarms_hash, cal_client);
+
+ g_slice_free (struct _alarm_client_msg, msg);
+}
+
+/** alarm_queue_remove_client
+ *
+ * asynchronously remove client from alarm queue.
+ * @cal_client: Client to remove.
+ * @immediately: Indicates whether use thread or do it right now.
+ */
+
+void
+alarm_queue_remove_client (ECalClient *cal_client,
+ gboolean immediately)
+{
+ struct _alarm_client_msg *msg;
+
+ msg = g_slice_new0 (struct _alarm_client_msg);
+ msg->header.func = (MessageFunc) alarm_queue_remove_async;
+ msg->cal_client = cal_client;
+
+ if (immediately) {
+ alarm_queue_remove_async (msg);
+ } else
+ message_push ((Message *) msg);
+}
+
+/* Update non-time related variables for various structures on modification
+ * of an existing component to be called only from query_objects_changed_cb */
+static void
+update_cqa (CompQueuedAlarms *cqa,
+ ECalComponent *newcomp)
+{
+ ECalComponent *oldcomp;
+ ECalComponentAlarms *alarms = NULL;
+ GSList *qa_list; /* List of current QueuedAlarms corresponding to cqa */
+ time_t from, to;
+ icaltimezone *zone;
+ ECalComponentAlarmAction omit[] = {-1};
+
+ oldcomp = cqa->alarms->comp;
+
+ zone = config_data_get_timezone ();
+ from = time_day_begin_with_zone (time (NULL), zone);
+ to = time_day_end_with_zone (time (NULL), zone);
+
+ debug (("Generating alarms between %s and %s", e_ctime (&from), e_ctime (&to)));
+ alarms = e_cal_util_generate_alarms_for_comp (
+ newcomp, from, to, omit, e_cal_client_resolve_tzid_cb,
+ cqa->parent_client->cal_client, zone);
+
+ /* Update auids in Queued Alarms*/
+ for (qa_list = cqa->queued_alarms; qa_list; qa_list = qa_list->next) {
+ QueuedAlarm *qa = qa_list->data;
+ gchar *check_auid = (gchar *) qa->instance->auid;
+ ECalComponentAlarm *alarm;
+
+ alarm = e_cal_component_get_alarm (newcomp, check_auid);
+ if (alarm) {
+ e_cal_component_alarm_free (alarm);
+ continue;
+ } else {
+ alarm = e_cal_component_get_alarm (oldcomp, check_auid);
+ if (alarm) { /* Need to update QueuedAlarms */
+ e_cal_component_alarm_free (alarm);
+ if (alarms == NULL) {
+ debug (("No alarms found in the modified component"));
+ break;
+ }
+ update_qa (alarms, qa);
+ }
+ else
+ g_warning ("Failed in auid lookup for old component also\n");
+ }
+ }
+
+ /* Update the actual component stored in CompQueuedAlarms structure */
+ g_object_unref (cqa->alarms->comp);
+ cqa->alarms->comp = newcomp;
+ if (alarms != NULL)
+ e_cal_component_alarms_free (alarms);
+}
+
+static void
+update_qa (ECalComponentAlarms *alarms,
+ QueuedAlarm *qa)
+{
+ ECalComponentAlarmInstance *al_inst;
+ GSList *instance_list;
+
+ debug (("..."));
+ for (instance_list = alarms->alarms;
+ instance_list;
+ instance_list = instance_list->next) {
+ al_inst = instance_list->data;
+ /* FIXME If two or more alarm instances (audio, note)
+ * for same component have same trigger... */
+ if (al_inst->trigger == qa->orig_trigger) {
+ g_free ((gchar *) qa->instance->auid);
+ qa->instance->auid = g_strdup (al_inst->auid);
+ break;
+ }
+ }
+}
diff --git a/calendar/alarm-notify/alarm-queue.h b/calendar/alarm-notify/alarm-queue.h
new file mode 100644
index 0000000000..c2e8990527
--- /dev/null
+++ b/calendar/alarm-notify/alarm-queue.h
@@ -0,0 +1,37 @@
+/*
+ *
+ * Evolution calendar - Alarm queueing engine
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef ALARM_QUEUE_H
+#define ALARM_QUEUE_H
+
+#include <libecal/libecal.h>
+
+void alarm_queue_init (gpointer);
+void alarm_queue_done (void);
+
+void alarm_queue_add_client (ECalClient *cal_client);
+void alarm_queue_remove_client (ECalClient *cal_client, gboolean immediately);
+
+#endif
diff --git a/calendar/alarm-notify/alarm.c b/calendar/alarm-notify/alarm.c
new file mode 100644
index 0000000000..99d3dd669b
--- /dev/null
+++ b/calendar/alarm-notify/alarm.c
@@ -0,0 +1,337 @@
+/*
+ * Evolution calendar - Low-level alarm timer mechanism
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Miguel de Icaza <miguel@ximian.com>
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <time.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <gdk/gdk.h>
+#include "alarm.h"
+#include "config-data.h"
+
+/* Our glib timeout */
+static guint timeout_id;
+
+/* The list of pending alarms */
+static GList *alarms = NULL;
+
+/* A queued alarm structure */
+typedef struct {
+ time_t trigger;
+ AlarmFunction alarm_fn;
+ gpointer data;
+ AlarmDestroyNotify destroy_notify_fn;
+} AlarmRecord;
+
+static void setup_timeout (void);
+
+/* Removes the head alarm from the queue. Does not touch the timeout_id. */
+static void
+pop_alarm (void)
+{
+ AlarmRecord *ar;
+ GList *l;
+
+ if (!alarms) {
+ g_warning ("Nothing to pop from the alarm queue");
+ return;
+ }
+
+ ar = alarms->data;
+
+ l = alarms;
+ alarms = g_list_delete_link (alarms, l);
+
+ g_free (ar);
+}
+
+/* Callback from the alarm timeout */
+static gboolean
+alarm_ready_cb (gpointer data)
+{
+ time_t now;
+
+ if (!alarms) {
+ g_warning ("Alarm triggered, but no alarm present\n");
+ return FALSE;
+ }
+
+ timeout_id = 0;
+
+ now = time (NULL);
+
+ debug (("Alarm callback!"));
+ while (alarms) {
+ AlarmRecord *notify_id, *ar;
+ AlarmRecord ar_copy;
+
+ ar = alarms->data;
+
+ if (ar->trigger > now)
+ break;
+
+ debug (("Process alarm with trigger %lu", ar->trigger));
+ notify_id = ar;
+
+ ar_copy = *ar;
+ ar = &ar_copy;
+
+ /* This will free the original AlarmRecord;
+ * that's why we copy it. */
+ pop_alarm ();
+
+ (* ar->alarm_fn) (notify_id, ar->trigger, ar->data);
+
+ if (ar->destroy_notify_fn)
+ (* ar->destroy_notify_fn) (notify_id, ar->data);
+ }
+
+ /* We need this check because one of the alarm_fn above may have
+ * re-entered and added an alarm of its own, so the timer will
+ * already be set up.
+ */
+ if (alarms)
+ setup_timeout ();
+
+ return FALSE;
+}
+
+/* Sets up a timeout for the next minute. We do not need to be concerned with
+ * timezones here, as this is just a periodic check on the alarm queue.
+ */
+static void
+setup_timeout (void)
+{
+ const AlarmRecord *ar;
+ guint diff;
+ time_t now;
+
+ if (!alarms) {
+ g_warning ("No alarm to setup\n");
+ return;
+ }
+
+ ar = alarms->data;
+
+ /* Remove the existing time out */
+ if (timeout_id != 0) {
+ g_source_remove (timeout_id);
+ timeout_id = 0;
+ }
+
+ /* Ensure that if the trigger managed to get behind the
+ * current time we timeout immediately */
+ diff = MAX (0, ar->trigger - time (NULL));
+ now = time (NULL);
+
+ /* Add the time out */
+ debug (
+ ("Setting timeout for %d.%2d (from now) %lu %lu",
+ diff / 60, diff % 60, ar->trigger, now));
+ debug ((" %s", ctime (&ar->trigger)));
+ debug ((" %s", ctime (&now)));
+ timeout_id = g_timeout_add_seconds (diff, alarm_ready_cb, NULL);
+
+}
+
+/* Used from g_list_insert_sorted(); compares the
+ * trigger times of two AlarmRecord structures. */
+static gint
+compare_alarm_by_time (gconstpointer a,
+ gconstpointer b)
+{
+ const AlarmRecord *ara = a;
+ const AlarmRecord *arb = b;
+ time_t diff;
+
+ diff = ara->trigger - arb->trigger;
+ return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
+}
+
+/* Adds an alarm to the queue and sets up the timer */
+static void
+queue_alarm (AlarmRecord *ar)
+{
+ GList *old_head;
+
+ /* Track the current head of the list in case there are changes */
+ old_head = alarms;
+
+ /* Insert the new alarm in order if the alarm's trigger time is
+ * after the current time */
+ alarms = g_list_insert_sorted (alarms, ar, compare_alarm_by_time);
+
+ /* If there first item on the list didn't change, the time out is fine */
+ if (old_head == alarms)
+ return;
+
+ /* Set the timer for removal upon activation */
+ setup_timeout ();
+}
+
+/**
+ * alarm_add:
+ * @trigger: Time at which alarm will trigger.
+ * @alarm_fn: Callback for trigger.
+ * @data: Closure data for callback.
+ * @destroy_notify_fn: destroy notification callback.
+ *
+ * Adds an alarm to trigger at the specified time. The @alarm_fn will be called
+ * with the provided data and the alarm will be removed from the trigger list.
+ *
+ * Return value: An identifier for this alarm; it can be used to remove the
+ * alarm later with alarm_remove(). If the trigger time occurs in the past, then
+ * the alarm will not be queued and the function will return NULL.
+ **/
+gpointer
+alarm_add (time_t trigger,
+ AlarmFunction alarm_fn,
+ gpointer data,
+ AlarmDestroyNotify destroy_notify_fn)
+{
+ AlarmRecord *ar;
+
+ g_return_val_if_fail (trigger != -1, NULL);
+ g_return_val_if_fail (alarm_fn != NULL, NULL);
+
+ ar = g_new (AlarmRecord, 1);
+ ar->trigger = trigger;
+ ar->alarm_fn = alarm_fn;
+ ar->data = data;
+ ar->destroy_notify_fn = destroy_notify_fn;
+
+ queue_alarm (ar);
+
+ return ar;
+}
+
+/**
+ * alarm_remove:
+ * @alarm: A queued alarm identifier.
+ *
+ * Removes an alarm from the alarm queue.
+ **/
+void
+alarm_remove (gpointer alarm)
+{
+ AlarmRecord *notify_id, *ar;
+ AlarmRecord ar_copy;
+ AlarmRecord *old_head;
+ GList *l;
+
+ g_return_if_fail (alarm != NULL);
+
+ ar = alarm;
+
+ l = g_list_find (alarms, ar);
+ if (!l) {
+ g_warning (G_STRLOC ": Requested removal of nonexistent alarm!");
+ return;
+ }
+
+ old_head = alarms->data;
+
+ notify_id = ar;
+
+ if (old_head == ar) {
+ ar_copy = *ar;
+ ar = &ar_copy;
+
+ /* This will free the original AlarmRecord;
+ * that's why we copy it. */
+ pop_alarm ();
+ } else {
+ alarms = g_list_delete_link (alarms, l);
+ }
+
+ /* Reset the timeout */
+ if (!alarms) {
+ g_source_remove (timeout_id);
+ timeout_id = 0;
+ }
+
+ /* Notify about destructiono of the alarm */
+
+ if (ar->destroy_notify_fn)
+ (* ar->destroy_notify_fn) (notify_id, ar->data);
+
+}
+
+/**
+ * alarm_done:
+ *
+ * Terminates the alarm timer mechanism. This should be called at the end of
+ * the program.
+ **/
+void
+alarm_done (void)
+{
+ GList *l;
+
+ if (timeout_id == 0) {
+ if (alarms)
+ g_warning ("No timeout, but queue is not NULL\n");
+ return;
+ }
+
+ g_source_remove (timeout_id);
+ timeout_id = 0;
+
+ if (!alarms) {
+ g_warning ("timeout present, freed, but no alarms active\n");
+ return;
+ }
+
+ for (l = alarms; l; l = l->next) {
+ AlarmRecord *ar;
+
+ ar = l->data;
+
+ if (ar->destroy_notify_fn)
+ (* ar->destroy_notify_fn) (ar, ar->data);
+
+ g_free (ar);
+ }
+
+ g_list_free (alarms);
+ alarms = NULL;
+}
+
+/**
+ * alarm_reschedule_timeout:
+ *
+ * Re-sets timeout for alarms, if any.
+ **/
+void
+alarm_reschedule_timeout (void)
+{
+ if (alarms)
+ setup_timeout ();
+}
diff --git a/calendar/alarm-notify/alarm.h b/calendar/alarm-notify/alarm.h
new file mode 100644
index 0000000000..ad2b7f8e4b
--- /dev/null
+++ b/calendar/alarm-notify/alarm.h
@@ -0,0 +1,43 @@
+/*
+ * Evolution calendar - Low-level alarm timer mechanism
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Miguel de Icaza <miguel@ximian.com>
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef ALARM_H
+#define ALARM_H
+
+#include <time.h>
+#include <glib.h>
+
+typedef void (* AlarmFunction) (gpointer alarm_id, time_t trigger, gpointer data);
+typedef void (* AlarmDestroyNotify) (gpointer alarm_id, gpointer data);
+
+void alarm_done (void);
+
+gpointer alarm_add (time_t trigger, AlarmFunction alarm_fn, gpointer data,
+ AlarmDestroyNotify destroy_notify_fn);
+void alarm_remove (gpointer alarm);
+
+void alarm_reschedule_timeout (void);
+
+#endif
diff --git a/calendar/alarm-notify/config-data.c b/calendar/alarm-notify/config-data.c
new file mode 100644
index 0000000000..84a2e38265
--- /dev/null
+++ b/calendar/alarm-notify/config-data.c
@@ -0,0 +1,316 @@
+/*
+ * Evolution calendar - Configuration values for the alarm notification daemon
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include "config-data.h"
+
+/* Whether we have initied ourselves by reading
+ * the data from the configuration engine. */
+static GSettings *calendar_settings = NULL;
+
+/* Copied from ../calendar-config.c; returns whether the locale has 'am' and
+ * 'pm' strings defined.
+ */
+static gboolean
+locale_supports_12_hour_format (void)
+{
+ gchar s[16];
+ time_t t = 0;
+
+ strftime (s, sizeof s, "%p", gmtime (&t));
+ return s[0] != '\0';
+}
+
+void
+config_data_cleanup (void)
+{
+ if (calendar_settings)
+ g_object_unref (calendar_settings);
+ calendar_settings = NULL;
+}
+
+/* Ensures that the configuration values have been read */
+static void
+ensure_inited (void)
+{
+ if (calendar_settings)
+ return;
+
+ calendar_settings = g_settings_new ("org.gnome.evolution.calendar");
+}
+
+icaltimezone *
+config_data_get_timezone (void)
+{
+ gchar *location;
+ icaltimezone *local_timezone;
+
+ ensure_inited ();
+
+ if (g_settings_get_boolean (calendar_settings, "use-system-timezone"))
+ location = e_cal_util_get_system_timezone_location ();
+ else {
+ location = g_settings_get_string (calendar_settings, "timezone");
+ }
+
+ if (location && location[0])
+ local_timezone = icaltimezone_get_builtin_timezone (location);
+ else
+ local_timezone = icaltimezone_get_utc_timezone ();
+
+ g_free (location);
+
+ return local_timezone;
+}
+
+gboolean
+config_data_get_24_hour_format (void)
+{
+ ensure_inited ();
+
+ if (locale_supports_12_hour_format ()) {
+ return g_settings_get_boolean (calendar_settings, "use-24hour-format");
+ }
+
+ return TRUE;
+}
+
+gboolean
+config_data_get_notify_with_tray (void)
+{
+ ensure_inited ();
+
+ return g_settings_get_boolean (calendar_settings, "notify-with-tray");
+}
+
+static void
+source_written_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GError *error = NULL;
+
+ e_source_write_finish (E_SOURCE (source_object), result, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "Failed to write source changes: %s",
+ error->message);
+ g_error_free (error);
+ }
+}
+
+/**
+ * config_data_set_last_notification_time:
+ * @t: A time value.
+ *
+ * Saves the last notification time so that it can be fetched the next time the
+ * alarm daemon is run. This way the daemon can show alarms that should have
+ * triggered while it was not running.
+ **/
+void
+config_data_set_last_notification_time (ECalClient *cal,
+ time_t t)
+{
+ time_t current_t, now = time (NULL);
+
+ g_return_if_fail (t != -1);
+
+ if (cal != NULL) {
+ ESource *source;
+ ESourceAlarms *extension;
+ GTimeVal tv = {0};
+ const gchar *extension_name;
+ gchar *iso8601;
+
+ source = e_client_get_source (E_CLIENT (cal));
+ extension_name = E_SOURCE_EXTENSION_ALARMS;
+ extension = e_source_get_extension (source, extension_name);
+
+ iso8601 = (gchar *) e_source_alarms_get_last_notified (extension);
+ if (iso8601 != NULL)
+ g_time_val_from_iso8601 (iso8601, &tv);
+
+ if (t > (time_t) tv.tv_sec || (time_t) tv.tv_sec > now) {
+ tv.tv_sec = (glong) t;
+ iso8601 = g_time_val_to_iso8601 (&tv);
+ e_source_alarms_set_last_notified (extension, iso8601);
+ g_free (iso8601);
+
+ e_source_write (source, NULL, source_written_cb, NULL);
+ }
+ }
+
+ /* we only store the new notification time if it is bigger
+ * than the already stored one */
+ current_t = g_settings_get_int (calendar_settings, "last-notification-time");
+ if (t > current_t || current_t > now)
+ g_settings_set_int (calendar_settings, "last-notification-time", t);
+}
+
+/**
+ * config_data_get_last_notification_time:
+ *
+ * Queries the last saved value for alarm notification times.
+ *
+ * Return value: The last saved value, or -1 if no value had been saved before.
+ **/
+time_t
+config_data_get_last_notification_time (ECalClient *cal)
+{
+ time_t value, now;
+
+ if (cal != NULL) {
+ ESource *source;
+ ESourceAlarms *extension;
+ GTimeVal tmval = {0};
+ const gchar *extension_name;
+ const gchar *last_notified;
+ time_t now, val;
+
+ source = e_client_get_source (E_CLIENT (cal));
+ extension_name = E_SOURCE_EXTENSION_ALARMS;
+
+ if (!e_source_has_extension (source, extension_name))
+ goto skip;
+
+ extension = e_source_get_extension (source, extension_name);
+ last_notified = e_source_alarms_get_last_notified (extension);
+
+ if (last_notified == NULL || *last_notified == '\0')
+ goto skip;
+
+ if (!g_time_val_from_iso8601 (last_notified, &tmval))
+ goto skip;
+
+ now = time (NULL);
+ val = (time_t) tmval.tv_sec;
+
+ if (val > now)
+ val = now;
+
+ return val;
+ }
+
+skip:
+ value = g_settings_get_int (calendar_settings, "last-notification-time");
+ now = time (NULL);
+ if (value > now)
+ value = now;
+
+ return value;
+}
+
+/**
+ * config_data_save_blessed_program:
+ * @program: a program name
+ *
+ * Saves a program name as "blessed"
+ **/
+void
+config_data_save_blessed_program (const gchar *program)
+{
+ gchar **list;
+ gint i;
+ GPtrArray *array = g_ptr_array_new ();
+
+ list = g_settings_get_strv (calendar_settings, "notify-programs");
+ for (i = 0; i < g_strv_length (list); i++)
+ g_ptr_array_add (array, list[i]);
+
+ g_ptr_array_add (array, (gpointer) program);
+ g_ptr_array_add (array, NULL);
+
+ g_settings_set_strv (
+ calendar_settings, "notify-programs",
+ (const gchar *const *) array->pdata);
+
+ g_strfreev (list);
+ g_ptr_array_free (array, TRUE);
+}
+
+/**
+ * config_data_is_blessed_program:
+ * @program: a program name
+ *
+ * Checks to see if a program is blessed
+ *
+ * Return value: TRUE if program is blessed, FALSE otherwise
+ **/
+gboolean
+config_data_is_blessed_program (const gchar *program)
+{
+ gchar **list;
+ gint i = 0;
+ gboolean found = FALSE;
+
+ list = g_settings_get_strv (calendar_settings, "notify-programs");
+ if (!list)
+ return FALSE;
+
+ while (list[i] != NULL) {
+ if (!found)
+ found = strcmp ((gchar *) list[i], program) == 0;
+ i++;
+ }
+
+ g_strfreev (list);
+
+ return found;
+}
+
+static gboolean can_debug = FALSE;
+static GRecMutex rec_mutex;
+
+void
+config_data_init_debugging (void)
+{
+ can_debug = g_getenv ("ALARMS_DEBUG") != NULL;
+}
+
+/* returns whether started debugging;
+ * call config_data_stop_debugging() when started and you are done with it
+ */
+gboolean
+config_data_start_debugging (void)
+{
+ g_rec_mutex_lock (&rec_mutex);
+
+ if (can_debug)
+ return TRUE;
+
+ g_rec_mutex_unlock (&rec_mutex);
+
+ return FALSE;
+}
+
+void
+config_data_stop_debugging (void)
+{
+ g_rec_mutex_unlock (&rec_mutex);
+}
diff --git a/calendar/alarm-notify/config-data.h b/calendar/alarm-notify/config-data.h
new file mode 100644
index 0000000000..d30781c693
--- /dev/null
+++ b/calendar/alarm-notify/config-data.h
@@ -0,0 +1,61 @@
+/*
+ *
+ * Evolution calendar - Configuration values for the alarm notification daemon
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef CONFIG_DATA_H
+#define CONFIG_DATA_H
+
+#include <libical/ical.h>
+#include <libecal/libecal.h>
+
+void config_data_cleanup (void);
+
+icaltimezone * config_data_get_timezone (void);
+gboolean config_data_get_24_hour_format (void);
+gboolean config_data_get_notify_with_tray
+ (void);
+void config_data_set_last_notification_time
+ (ECalClient *cal,
+ time_t t);
+time_t config_data_get_last_notification_time
+ (ECalClient *cal);
+void config_data_save_blessed_program
+ (const gchar *program);
+gboolean config_data_is_blessed_program (const gchar *program);
+
+void config_data_init_debugging (void);
+gboolean config_data_start_debugging (void);
+void config_data_stop_debugging (void);
+
+#define debug(x) G_STMT_START { \
+ if (config_data_start_debugging ()) { \
+ g_print ("%s (%s): ", G_STRFUNC, G_STRLOC); \
+ g_print x; \
+ g_print ("\n"); \
+ \
+ config_data_stop_debugging (); \
+ } \
+ } G_STMT_END
+
+#endif
diff --git a/calendar/alarm-notify/evolution-alarm-notify-icon.rc b/calendar/alarm-notify/evolution-alarm-notify-icon.rc
new file mode 100644
index 0000000000..1f9ef65874
--- /dev/null
+++ b/calendar/alarm-notify/evolution-alarm-notify-icon.rc
@@ -0,0 +1 @@
+1 ICON "evolution-alarm-notify.ico"
diff --git a/calendar/alarm-notify/evolution-alarm-notify.ico b/calendar/alarm-notify/evolution-alarm-notify.ico
new file mode 100644
index 0000000000..6585452256
--- /dev/null
+++ b/calendar/alarm-notify/evolution-alarm-notify.ico
Binary files differ
diff --git a/calendar/alarm-notify/notify-main.c b/calendar/alarm-notify/notify-main.c
new file mode 100644
index 0000000000..3643ae65e7
--- /dev/null
+++ b/calendar/alarm-notify/notify-main.c
@@ -0,0 +1,124 @@
+/*
+ * Evolution calendar - Alarm notification service main file
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ * Rodrigo Moya <rodrigo@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <glib/gi18n.h>
+
+#include "alarm-notify.h"
+#include "config-data.h"
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include <conio.h>
+#ifndef PROCESS_DEP_ENABLE
+#define PROCESS_DEP_ENABLE 0x00000001
+#endif
+#ifndef PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION
+#define PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION 0x00000002
+#endif
+#endif
+
+#include "e-util/e-util-private.h"
+
+gint
+main (gint argc,
+ gchar **argv)
+{
+ AlarmNotify *alarm_notify_service;
+ gint exit_status;
+ GError *error = NULL;
+#ifdef G_OS_WIN32
+ gchar *path;
+
+ /* Reduce risks */
+ {
+ typedef BOOL (WINAPI *t_SetDllDirectoryA) (LPCSTR lpPathName);
+ t_SetDllDirectoryA p_SetDllDirectoryA;
+
+ p_SetDllDirectoryA = GetProcAddress (GetModuleHandle ("kernel32.dll"), "SetDllDirectoryA");
+ if (p_SetDllDirectoryA)
+ (*p_SetDllDirectoryA) ("");
+ }
+#ifndef _WIN64
+ {
+ typedef BOOL (WINAPI *t_SetProcessDEPPolicy) (DWORD dwFlags);
+ t_SetProcessDEPPolicy p_SetProcessDEPPolicy;
+
+ p_SetProcessDEPPolicy = GetProcAddress (GetModuleHandle ("kernel32.dll"), "SetProcessDEPPolicy");
+ if (p_SetProcessDEPPolicy)
+ (*p_SetProcessDEPPolicy) (PROCESS_DEP_ENABLE | PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION);
+ }
+#endif
+#endif
+
+ bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ gtk_init (&argc, &argv);
+
+ e_gdbus_templates_init_main_thread ();
+
+#ifdef G_OS_WIN32
+ path = g_build_path (";", _e_get_bindir (), g_getenv ("PATH"), NULL);
+
+ if (!g_setenv ("PATH", path, TRUE))
+ g_warning ("Could not set PATH for Evolution Alarm Notifier");
+#endif
+
+ alarm_notify_service = alarm_notify_new (NULL, &error);
+
+ if (error != NULL) {
+ g_printerr ("%s\n", error->message);
+ g_error_free (error);
+ exit (EXIT_FAILURE);
+ }
+
+ g_application_register (G_APPLICATION (alarm_notify_service), NULL, &error);
+
+ if (error != NULL) {
+ g_printerr ("%s\n", error->message);
+ g_error_free (error);
+ g_object_unref (alarm_notify_service);
+ exit (EXIT_FAILURE);
+ }
+
+ if (g_application_get_is_remote (G_APPLICATION (alarm_notify_service))) {
+ g_object_unref (alarm_notify_service);
+ return 0;
+ }
+
+ exit_status = g_application_run (
+ G_APPLICATION (alarm_notify_service), argc, argv);
+
+ g_object_unref (alarm_notify_service);
+ config_data_cleanup ();
+
+ return exit_status;
+}
diff --git a/calendar/alarm-notify/util.c b/calendar/alarm-notify/util.c
new file mode 100644
index 0000000000..d06df4db05
--- /dev/null
+++ b/calendar/alarm-notify/util.c
@@ -0,0 +1,91 @@
+/*
+ * Evolution calendar - utility functions
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+
+#include "config-data.h"
+#include "util.h"
+
+/* Converts a time_t to a string, relative to the specified timezone */
+gchar *
+timet_to_str_with_zone (time_t t,
+ icaltimezone *zone)
+{
+ struct icaltimetype itt;
+ struct tm tm;
+ gchar buf[256];
+
+ if (t == -1)
+ return g_strdup (_("invalid time"));
+
+ itt = icaltime_from_timet_with_zone (t, FALSE, zone);
+ tm = icaltimetype_to_tm (&itt);
+
+ e_time_format_date_and_time (&tm, config_data_get_24_hour_format (),
+ FALSE, FALSE, buf, sizeof (buf));
+ return g_strdup (buf);
+}
+
+gchar *
+calculate_time (time_t start,
+ time_t end)
+{
+ time_t difference = end - start;
+ gchar *str;
+ gint hours, minutes;
+ gchar *times[4];
+ gchar *joined;
+ gint i;
+
+ i = 0;
+ if (difference >= 3600) {
+ hours = difference / 3600;
+ difference %= 3600;
+
+ times[i++] = g_strdup_printf (ngettext ("%d hour", "%d hours", hours), hours);
+ }
+ if (difference >= 60) {
+ minutes = difference / 60;
+ difference %= 60;
+
+ times[i++] = g_strdup_printf (ngettext ("%d minute", "%d minutes", minutes), minutes);
+ }
+ if (i == 0 || difference != 0) {
+ /* TRANSLATORS: here, "second" is the time division (like "minute"), not the ordinal number (like "third") */
+ times[i++] = g_strdup_printf (ngettext ("%d second", "%d seconds", difference), (gint) difference);
+ }
+
+ times[i] = NULL;
+ joined = g_strjoinv (" ", times);
+ str = g_strconcat ("(", joined, ")", NULL);
+ while (i > 0)
+ g_free (times[--i]);
+ g_free (joined);
+
+ return str;
+}
diff --git a/calendar/alarm-notify/util.h b/calendar/alarm-notify/util.h
new file mode 100644
index 0000000000..a95f6d8e11
--- /dev/null
+++ b/calendar/alarm-notify/util.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * Evolution calendar - utility functions
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef UTIL_H
+#define UTIL_H
+
+#include <libecal/libecal.h>
+
+gchar *timet_to_str_with_zone (time_t t, icaltimezone *zone);
+gchar *calculate_time (time_t start, time_t end);
+#endif
diff --git a/calendar/cal-client/.cvsignore b/calendar/cal-client/.cvsignore
deleted file mode 100644
index 1537e6e01d..0000000000
--- a/calendar/cal-client/.cvsignore
+++ /dev/null
@@ -1,15 +0,0 @@
-Makefile.in
-.deps
-.libs
-.pure
-Makefile
-evolution-calendar-stubs.c
-evolution-calendar-skels.c
-evolution-calendar-common.c
-evolution-calendar.h
-evolution-calendar-common.lo
-evolution-calendar-skels.lo
-evolution-calendar-stubs.lo
-*.lo
-*.la
-client-test
diff --git a/calendar/cal-client/Makefile.am b/calendar/cal-client/Makefile.am
deleted file mode 100644
index c1ede1e84f..0000000000
--- a/calendar/cal-client/Makefile.am
+++ /dev/null
@@ -1,91 +0,0 @@
-#
-# libcal-client
-#
-
-CORBA_GENERATED = \
- evolution-calendar-common.c \
- evolution-calendar-skels.c \
- evolution-calendar-stubs.c
-
-CORBA_HEADERS_GENERATED = \
- evolution-calendar.h
-
-idls = \
- $(srcdir)/../idl/evolution-calendar.idl
-
-idl_flags = `$(GNOME_CONFIG) --cflags idl` -I $(datadir)/idl
-
-$(CORBA_GENERATED): $(idls)
- $(ORBIT_IDL) $(idl_flags) $(srcdir)/../idl/evolution-calendar.idl
-
-INCLUDES = \
- -DGNOMELOCALEDIR=\""$(localedir)"\" \
- -DG_LOG_DOMAIN=\"cal-client\" \
- -I$(top_srcdir)/calendar \
- -I$(srcdir) -I$(top_srcdir) \
- -I. \
- -I.. \
- -I$(top_builddir) \
- -I$(top_builddir)/libical/src/libical \
- -I$(top_srcdir)/libical/src/libical \
- -I$(top_builddir)/libwombat \
- -I$(top_srcdir)/libwombat \
- $(EVOLUTION_CALENDAR_CFLAGS)
-
-lib_LTLIBRARIES = libcal-client.la
-
-libcal_clientincludedir = $(includedir)/evolution/cal-client
-
-libcal_client_la_SOURCES = \
- $(CORBA_GENERATED) \
- cal-client-multi.c \
- cal-client-types.c \
- cal-client.c \
- cal-listener.c \
- cal-listener.h \
- cal-query.c \
- query-listener.c \
- query-listener.h
-
-libcal_clientinclude_HEADERS = \
- $(CORBA_HEADERS_GENERATED) \
- cal-client-multi.h \
- cal-client-types.h \
- cal-client.h \
- cal-query.h
-
-#
-# make a static library for use by calendar conduit's shared library
-#
-noinst_LTLIBRARIES = libcal-client-static.la
-libcal_client_static_la_SOURCES = $(libcal_client_la_SOURCES)
-libcal_client_static_la_LDFLAGS = --all-static
-
-
-#
-# client-test program
-#
-
-noinst_PROGRAMS = client-test
-
-client_test_SOURCES = \
- client-test.c
-
-client_test_INCLUDES = \
- $(INCLUDES) \
- -DG_LOG_DOMAIN=\"client-test\"
-
-client_test_LDADD = \
- $(EVOLUTION_CALENDAR_LIBS) \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/calendar/cal-util/libcal-util.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/libical/src/libical/libical-evolution.la \
- $(top_builddir)/libwombat/libwombat.la \
- libcal-client.la
-
-BUILT_SOURCES = $(CORBA_GENERATED)
-CLEANFILES = $(BUILT_SOURCES)
-
-dist-hook:
- cd $(distdir); rm -f $(BUILT_SOURCES)
diff --git a/calendar/cal-client/cal-client-multi.c b/calendar/cal-client/cal-client-multi.c
deleted file mode 100644
index aeebc72fda..0000000000
--- a/calendar/cal-client/cal-client-multi.c
+++ /dev/null
@@ -1,706 +0,0 @@
-/* Evolution calendar client
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Rodrigo Moya <rodrigo@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <gtk/gtksignal.h>
-#include "cal-client-multi.h"
-
-/* Private part of the CalClientMulti structure */
-struct _CalClientMultiPrivate {
- GHashTable *calendars;
- GList *uris;
-};
-
-static void cal_client_multi_class_init (CalClientMultiClass *klass);
-static void cal_client_multi_init (CalClientMulti *multi);
-static void cal_client_multi_destroy (GtkObject *object);
-
-/* signal IDs */
-enum {
- CAL_OPENED,
- OBJ_UPDATED,
- OBJ_REMOVED,
- CATEGORIES_CHANGED,
- FORGET_PASSWORD,
- LAST_SIGNAL
-};
-
-static guint cal_multi_signals[LAST_SIGNAL];
-static GtkObjectClass *parent_class = NULL;
-
-/*
- * Private functions
- */
-
-/**
- * cal_client_multi_get_type
- *
- * Registers the #CalClientMulti class if necessary, and returns the type ID
- * assigned to it.
- *
- * Returns: The type ID of the #CalClientMulti class
- */
-GtkType
-cal_client_multi_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type) {
- static const GtkTypeInfo info = {
- "CalClientMulti",
- sizeof (CalClientMulti),
- sizeof (CalClientMultiClass),
- (GtkClassInitFunc) cal_client_multi_class_init,
- (GtkObjectInitFunc) cal_client_multi_init,
- NULL,
- NULL,
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (GTK_TYPE_OBJECT, &info);
- }
-
- return type;
-}
-
-/* class initialization function for the multi calendar client */
-static void
-cal_client_multi_class_init (CalClientMultiClass *klass)
-{
- GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
-
- parent_class = gtk_type_class (GTK_TYPE_OBJECT);
-
- cal_multi_signals[CAL_OPENED] =
- gtk_signal_new ("cal_opened",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalClientMultiClass, cal_opened),
- gtk_marshal_NONE__POINTER_INT,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_POINTER, GTK_TYPE_ENUM);
- cal_multi_signals[OBJ_UPDATED] =
- gtk_signal_new ("obj_updated",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalClientMultiClass, obj_updated),
- gtk_marshal_NONE__POINTER_POINTER,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_POINTER, GTK_TYPE_STRING);
- cal_multi_signals[OBJ_REMOVED] =
- gtk_signal_new ("obj_removed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalClientMultiClass, obj_removed),
- gtk_marshal_NONE__POINTER_POINTER,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_POINTER, GTK_TYPE_STRING);
- cal_multi_signals[CATEGORIES_CHANGED] =
- gtk_signal_new ("categories_changed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalClientMultiClass, categories_changed),
- gtk_marshal_NONE__POINTER_POINTER,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_POINTER, GTK_TYPE_POINTER);
- cal_multi_signals[FORGET_PASSWORD] =
- gtk_signal_new ("forget_password",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalClientMultiClass, forget_password),
- gtk_marshal_NONE__POINTER_POINTER,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_STRING, GTK_TYPE_STRING);
-
- object_class->destroy = cal_client_multi_destroy;
-}
-
-/* object initialization function for the multi calendar client */
-static void
-cal_client_multi_init (CalClientMulti *multi)
-{
- multi->priv = g_new0 (CalClientMultiPrivate, 1);
- multi->priv->calendars = g_hash_table_new (g_str_hash, g_str_equal);
- multi->priv->uris = NULL;
-}
-
-static void
-free_calendar (gpointer key, gpointer value, gpointer data)
-{
- CalClientMulti *multi = (CalClientMulti *) data;
-
- g_return_if_fail (IS_CAL_CLIENT_MULTI (multi));
-
- multi->priv->uris = g_list_remove (multi->priv->uris, key);
-
- g_free (key);
- gtk_object_unref (GTK_OBJECT (value));
-}
-
-/* destroy handler for the multi calendar client */
-static void
-cal_client_multi_destroy (GtkObject *object)
-{
- CalClientMulti *multi = (CalClientMulti *) object;
-
- g_return_if_fail (IS_CAL_CLIENT_MULTI (multi));
-
- /* free memory */
- g_hash_table_foreach (multi->priv->calendars, free_calendar, multi);
- g_hash_table_destroy (multi->priv->calendars);
- g_list_free (multi->priv->uris);
-
- g_free (multi->priv);
- multi->priv = NULL;
-
- /* chain to parent class' destroy handler */
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-/**
- * cal_client_multi_new
- *
- * Creates a new multi-calendar client. This allows you to merge several
- * #CalClient objects into one entity, making it easier to manage
- * multiple calendars.
- *
- * Returns: A newly-created multi-calendar client.
- */
-CalClientMulti *
-cal_client_multi_new (void)
-{
- CalClientMulti *multi;
-
- multi = gtk_type_new (CAL_CLIENT_MULTI_TYPE);
- return multi;
-}
-
-/* CalClient's signal handlers */
-static void
-client_cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer user_data)
-{
- CalClientMulti *multi = (CalClientMulti *) user_data;
-
- g_return_if_fail (IS_CAL_CLIENT (client));
- g_return_if_fail (IS_CAL_CLIENT_MULTI (multi));
-
- gtk_signal_emit (GTK_OBJECT (multi),
- cal_multi_signals[CAL_OPENED],
- client, status);
-}
-
-static void
-client_obj_updated_cb (CalClient *client, const char *uid, gpointer user_data)
-{
- CalClientMulti *multi = (CalClientMulti *) user_data;
-
- g_return_if_fail (IS_CAL_CLIENT (client));
- g_return_if_fail (IS_CAL_CLIENT_MULTI (multi));
-
- gtk_signal_emit (GTK_OBJECT (multi),
- cal_multi_signals[OBJ_UPDATED],
- client, uid);
-}
-
-static void
-client_obj_removed_cb (CalClient *client, const char *uid, gpointer user_data)
-{
- CalClientMulti *multi = (CalClientMulti *) user_data;
-
- g_return_if_fail (IS_CAL_CLIENT (client));
- g_return_if_fail (IS_CAL_CLIENT_MULTI (multi));
-
- gtk_signal_emit (GTK_OBJECT (multi),
- cal_multi_signals[OBJ_REMOVED],
- client, uid);
-}
-
-static void
-client_categories_changed_cb (CalClient *client, GPtrArray *categories, gpointer user_data)
-{
- CalClientMulti *multi = (CalClientMulti *) user_data;
-
- g_return_if_fail (IS_CAL_CLIENT (client));
- g_return_if_fail (IS_CAL_CLIENT_MULTI (multi));
-
- gtk_signal_emit (GTK_OBJECT (multi),
- cal_multi_signals[CATEGORIES_CHANGED],
- client, categories);
-}
-
-static void
-client_forget_password_cb (CalClient *client, const char *key, gpointer user_data)
-{
- CalClientMulti *multi = (CalClientMulti *) user_data;
-
- g_return_if_fail (IS_CAL_CLIENT (client));
- g_return_if_fail (IS_CAL_CLIENT_MULTI (multi));
-
- gtk_signal_emit (GTK_OBJECT (multi),
- cal_multi_signals[FORGET_PASSWORD],
- client, key);
-}
-/**
- * cal_client_multi_add_client
- * @multi: A #CalClientMulti object.
- * @client: The #CalClient object to be added.
- *
- * Aggregates the given #CalClient to a #CalClientMulti object,
- * thus adding it to the list of managed calendars.
- */
-void
-cal_client_multi_add_client (CalClientMulti *multi, CalClient *client)
-{
- char *uri;
- CalClient *old_client;
-
- g_return_if_fail (IS_CAL_CLIENT_MULTI (multi));
- g_return_if_fail (IS_CAL_CLIENT (client));
-
- uri = g_strdup (cal_client_get_uri (client));
- old_client = g_hash_table_lookup (multi->priv->calendars, uri);
- if (old_client) {
- g_free (uri);
- return;
- }
-
- gtk_object_ref (GTK_OBJECT (client));
- multi->priv->uris = g_list_append (multi->priv->uris, uri);
- g_hash_table_insert (multi->priv->calendars, uri, client);
-
- /* set up CalClient's signal handlers */
- gtk_signal_disconnect_by_data (GTK_OBJECT (client), multi);
- gtk_signal_connect (GTK_OBJECT (client),
- "cal_opened",
- GTK_SIGNAL_FUNC (client_cal_opened_cb),
- multi);
- gtk_signal_connect (GTK_OBJECT (client),
- "obj_updated",
- GTK_SIGNAL_FUNC (client_obj_updated_cb),
- multi);
- gtk_signal_connect (GTK_OBJECT (client),
- "obj_removed",
- GTK_SIGNAL_FUNC (client_obj_removed_cb),
- multi);
- gtk_signal_connect (GTK_OBJECT (client),
- "categories_changed",
- GTK_SIGNAL_FUNC (client_categories_changed_cb),
- multi);
- gtk_signal_connect (GTK_OBJECT (client),
- "forget_password",
- GTK_SIGNAL_FUNC (client_forget_password_cb),
- multi);
-}
-
-typedef struct {
- CalClientAuthFunc func;
- gpointer user_data;
-} AuthFuncData;
-
-static void
-set_auth_func (gpointer key, gpointer value, gpointer user_data)
-{
- AuthFuncData *cb_data = (AuthFuncData *) user_data;
- CalClient *client = (CalClient *) value;
-
- g_return_if_fail (IS_CAL_CLIENT (client));
- g_return_if_fail (cb_data != NULL);
-
- cal_client_set_auth_func (client, cb_data->func, cb_data->user_data);
-}
-
-/**
- * cal_client_multi_set_auth_func
- * @multi: A #CalClientMulti object.
- * @func: The authentication function.
- * @user_data: Data to be passed to the authentication function.
- *
- * Sets the authentication function for all the clients in the
- * given #CalClientMulti.
- */
-void
-cal_client_multi_set_auth_func (CalClientMulti *multi,
- CalClientAuthFunc func,
- gpointer user_data)
-{
- AuthFuncData *cb_data;
-
- g_return_if_fail (IS_CAL_CLIENT_MULTI (multi));
-
- cb_data = g_new0 (AuthFuncData, 1);
- cb_data->func = func;
- cb_data->user_data = user_data;
- g_hash_table_foreach (multi->priv->calendars, set_auth_func, cb_data);
-
- g_free (cb_data);
-}
-
-/**
- * cal_client_multi_open_calendar
- * @multi: A #CalClientMulti object.
- * @str_uri: The URI of the calendar to be open
- * @only_if_exists:
- *
- * Open a new calendar in the given #CalClientMulti object.
- *
- * Returns: a pointer to the new #CalClient
- */
-CalClient *
-cal_client_multi_open_calendar (CalClientMulti *multi,
- const char *str_uri,
- gboolean only_if_exists)
-{
- CalClient *client;
- gboolean result;
-
- g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), FALSE);
-
- client = cal_client_new ();
-
- result = cal_client_open_calendar (client, str_uri, only_if_exists);
- if (result) {
- cal_client_multi_add_client (multi, client);
- gtk_object_unref (GTK_OBJECT (client));
- return client;
- }
-
- gtk_object_unref (GTK_OBJECT (client));
-
- return NULL;
-}
-
-/**
- * cal_client_multi_get_client_for_uri
- * @multi: A #CalClientMulti object.
- * @uri: The URI for the client.
- *
- * Returns the #CalClient object associated with the given
- * @uri for the given #CalClientMulti object.
- *
- * Returns: a pointer to the client or NULL if no client is
- * associated with that URI.
- */
-CalClient *
-cal_client_multi_get_client_for_uri (CalClientMulti *multi, const char *uri)
-{
- g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), NULL);
- g_return_val_if_fail (uri != NULL, NULL);
-
- return g_hash_table_lookup (multi->priv->calendars, uri);
-}
-
-/**
- * cal_client_multi_get_n_objects
- * @multi: A #CalClientMulti object.
- * @type: Type for objects
- *
- * Get the count of objects of the given type(s) for a #CalClientMulti
- * object.
- *
- * Returns: The count of objects of the given type(s).
- */
-int
-cal_client_multi_get_n_objects (CalClientMulti *multi,
- CalObjType type)
-{
- CalClient *client;
- GList *l;
- int count = 0;
-
- g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), -1);
-
- for (l = multi->priv->uris; l; l = l->next) {
- client = cal_client_multi_get_client_for_uri (multi,
- (const char *) l->data);
- if (IS_CAL_CLIENT (client))
- count += cal_client_get_n_objects (client, type);
- }
-
- return count;
-}
-
-/**
- * cal_client_multi_get_object
- */
-CalClientGetStatus
-cal_client_multi_get_object (CalClientMulti *multi,
- const char *uid,
- CalComponent **comp)
-{
- CalClient *client;
- GList *l;
-
- g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (uid != NULL, CAL_CLIENT_GET_NOT_FOUND);
-
- for (l = multi->priv->uris; l; l = l->next) {
- client = cal_client_multi_get_client_for_uri (multi,
- (const char *) l->data);
- if (IS_CAL_CLIENT (client)) {
- CalClientGetStatus status;
-
- status = cal_client_get_object (client, uid, comp);
- if (status == CAL_CLIENT_GET_SUCCESS)
- return status;
- }
- }
-
- return CAL_CLIENT_GET_NOT_FOUND;
-}
-
-/**
- * cal_client_multi_get_timezone
- * @multi: A #CalClientMulti object.
- * @tzid: ID for the timezone to be retrieved.
- * @zone: A pointer to where the icaltimezone object will be copied.
- */
-CalClientGetStatus
-cal_client_multi_get_timezone (CalClientMulti *multi,
- const char *tzid,
- icaltimezone **zone)
-{
- CalClient *client;
- GList *l;
-
- g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (tzid != NULL, CAL_CLIENT_GET_NOT_FOUND);
-
- for (l = multi->priv->uris; l; l = l->next) {
- client = cal_client_multi_get_client_for_uri (multi,
- (const char *) l->data);
- if (IS_CAL_CLIENT (client)) {
- CalClientGetStatus status;
-
- status = cal_client_get_timezone (client, tzid, zone);
- if (status == CAL_CLIENT_GET_SUCCESS)
- return status;
- }
- }
-
- return CAL_CLIENT_GET_NOT_FOUND;
-}
-
-/**
- * cal_client_multi_get_uids
- * @multi: A #CalClientMulti object.
- * @type: Type of objects whose IDs will be returned.
- *
- * Returns a list of UIDs for all the objects of the given
- * type(s) that are in the calendars managed by a
- * #CalClientMulti object
- *
- * Returns: a GList of UIDs.
- */
-GList *
-cal_client_multi_get_uids (CalClientMulti *multi, CalObjType type)
-{
- CalClient *client;
- GList *l;
- GList *result = NULL;
-
- g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), NULL);
-
- for (l = multi->priv->uris; l; l = l->next) {
- client = cal_client_multi_get_client_for_uri (multi,
- (const char *) l->data);
- if (IS_CAL_CLIENT (client)) {
- GList *tmp;
-
- tmp = cal_client_get_uids (client, type);
- if (tmp)
- result = g_list_concat (result, tmp);
- }
- }
-
- return result;
-}
-
-/**
- * cal_client_multi_get_changes
- * @multi: A #CalClientMulti object.
- * @type: Object type.
- * @change_id: Change ID.
- *
- * Returns a list of changes for the given #CalClientMulti
- * object.
- */
-GList *
-cal_client_multi_get_changes (CalClientMulti *multi,
- CalObjType type,
- const char *change_id)
-{
- CalClient *client;
- GList *l;
- GList *result = NULL;
-
- g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), NULL);
-
- for (l = multi->priv->uris; l; l = l->next) {
- client = cal_client_multi_get_client_for_uri (multi,
- (const char *) l->data);
- if (IS_CAL_CLIENT (client)) {
- GList *tmp;
-
- tmp = cal_client_get_changes (client, type, change_id);
- if (tmp)
- result = g_list_concat (result, tmp);
- }
- }
-
- return result;
-}
-
-/**
- * cal_client_multi_get_objects_in_range
- * @multi: A #CalClientMulti object.
- * @type: Type for objects.
- * @start: Start time.
- * @end: End time.
- *
- * Retrieves a list of all calendar components that are
- * scheduled within the given time range. The information is
- * retrieved from all the calendars being managed by the
- * given #CalClientMulti object.
- *
- * Returns: A list of UID strings. This should be freed using the
- * #cal_obj_uid_list_free() function.
- **/
-GList *
-cal_client_multi_get_objects_in_range (CalClientMulti *multi,
- CalObjType type,
- time_t start,
- time_t end)
-{
- CalClient *client;
- GList *l;
- GList *result = NULL;
-
- g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), NULL);
-
- for (l = multi->priv->uris; l; l = l->next) {
- client = cal_client_multi_get_client_for_uri (multi,
- (const char *) l->data);
- if (IS_CAL_CLIENT (client)) {
- GList *tmp;
-
- tmp = cal_client_get_objects_in_range (client, type, start, end);
- if (tmp)
- result = g_list_concat (result, tmp);
- }
- }
-
- return result;
-}
-
-/**
- * cal_client_multi_get_free_busy
- * @multi: A #CalClientMulti object.
- * @users: List of users to retrieve F/B information for.
- * @start: Start time.
- * @end: End time.
- *
- * Retrieves Free/Busy information for the given users in all
- * the calendars being managed by the given #CalClient multi
- * object.
- *
- * Returns: A GList of VFREEBUSY CalComponents
- */
-GList *
-cal_client_multi_get_free_busy (CalClientMulti *multi,
- GList *users,
- time_t start,
- time_t end)
-{
- CalClient *client;
- GList *l;
- GList *result = NULL;
-
- g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), NULL);
-
- for (l = multi->priv->uris; l; l = l->next) {
- client = cal_client_multi_get_client_for_uri (multi,
- (const char *) l->data);
- if (IS_CAL_CLIENT (client)) {
- GList *tmp;
-
- tmp = cal_client_get_free_busy (client, users, start, end);
- if (tmp)
- result = g_list_concat (result, tmp);
- }
- }
-
- return result;
-}
-
-/**
- * cal_client_multi_generate_instances
- */
-void
-cal_client_multi_generate_instances (CalClientMulti *multi,
- CalObjType type,
- time_t start,
- time_t end,
- CalRecurInstanceFn cb,
- gpointer cb_data)
-{
- CalClient *client;
- GList *l;
-
- g_return_if_fail (IS_CAL_CLIENT_MULTI (multi));
-
- for (l = multi->priv->uris; l; l = l->next) {
- client = cal_client_multi_get_client_for_uri (multi,
- (const char *) l->data);
- if (IS_CAL_CLIENT (client)) {
- cal_client_generate_instances (
- client, type, start, end, cb, cb_data);
- }
- }
-}
-
-/**
- * cal_client_multi_get_alarms_in_range
- */
-GSList *
-cal_client_multi_get_alarms_in_range (CalClientMulti *multi, time_t start, time_t end)
-{
- CalClient *client;
- GList *l;
- GSList *result = NULL;
-
- g_return_val_if_fail (IS_CAL_CLIENT_MULTI (multi), NULL);
-
- for (l = multi->priv->uris; l; l = l->next) {
- client = cal_client_multi_get_client_for_uri (multi,
- (const char *) l->data);
- if (IS_CAL_CLIENT (client)) {
- GSList *tmp;
-
- tmp = cal_client_get_alarms_in_range (client, start, end);
- if (tmp)
- result = g_slist_concat (result, tmp);
- }
- }
-
- return result;
-}
diff --git a/calendar/cal-client/cal-client-multi.h b/calendar/cal-client/cal-client-multi.h
deleted file mode 100644
index cded02e194..0000000000
--- a/calendar/cal-client/cal-client-multi.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/* Evolution calendar client
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Rodrigo Moya <rodrigo@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 CAL_CLIENT_MULTI_H
-#define CAL_CLIENT_MULTI_H
-
-#include <cal-client/cal-client.h>
-
-BEGIN_GNOME_DECLS
-
-#define CAL_CLIENT_MULTI_TYPE (cal_client_multi_get_type ())
-#define CAL_CLIENT_MULTI(obj) (GTK_CHECK_CAST ((obj), CAL_CLIENT_MULTI_TYPE, CalClientMulti))
-#define CAL_CLIENT_MULTI_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_CLIENT_MULTI_TYPE, CalClientMultiClass))
-#define IS_CAL_CLIENT_MULTI(obj) (GTK_CHECK_TYPE ((obj), CAL_CLIENT_MULTI_TYPE))
-#define IS_CAL_CLIENT_MULTI_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_CLIENT_MULTI_TYPE))
-
-typedef struct _CalClientMulti CalClientMulti;
-typedef struct _CalClientMultiClass CalClientMultiClass;
-typedef struct _CalClientMultiPrivate CalClientMultiPrivate;
-
-struct _CalClientMulti {
- GtkObject object;
-
- /* Private data */
- CalClientMultiPrivate *priv;
-};
-
-struct _CalClientMultiClass {
- GtkObjectClass parent_class;
-
- /* notification signals */
- void (* cal_opened) (CalClientMulti *multi, CalClient *client, CalClientOpenStatus status);
-
- void (* obj_updated) (CalClientMulti *multi, CalClient *client, const char *uid);
- void (* obj_removed) (CalClientMulti *multi, CalClient *client, const char *uid);
-
- void (* categories_changed) (CalClientMulti *multi, CalClient *client, GPtrArray *categories);
-
- void (* forget_password) (CalClientMulti *multi, CalClient *client, const char *key);
-};
-
-GtkType cal_client_multi_get_type (void);
-
-CalClientMulti *cal_client_multi_new (void);
-
-void cal_client_multi_add_client (CalClientMulti *multi, CalClient *client);
-void cal_client_multi_set_auth_func (CalClientMulti *multi,
- CalClientAuthFunc func,
- gpointer user_data);
-
-CalClient *cal_client_multi_open_calendar (CalClientMulti *multi,
- const char *str_uri,
- gboolean only_if_exists);
-CalClient *cal_client_multi_get_client_for_uri (CalClientMulti *multi,
- const char *uri);
-
-int cal_client_multi_get_n_objects (CalClientMulti *multi, CalObjType type);
-CalClientGetStatus cal_client_multi_get_object (CalClientMulti *multi,
- const char *uid,
- CalComponent **comp);
-CalClientGetStatus cal_client_multi_get_timezone (CalClientMulti *multi,
- const char *tzid,
- icaltimezone **zone);
-GList *cal_client_multi_get_uids (CalClientMulti *multi, CalObjType type);
-GList *cal_client_multi_get_changes (CalClientMulti *multi,
- CalObjType type,
- const char *change_id);
-GList *cal_client_multi_get_objects_in_range (CalClientMulti *multi,
- CalObjType type,
- time_t start,
- time_t end);
-GList *cal_client_multi_get_free_busy (CalClientMulti *multi,
- GList *users,
- time_t start,
- time_t end);
-void cal_client_multi_generate_instances (CalClientMulti *multi,
- CalObjType type,
- time_t start,
- time_t end,
- CalRecurInstanceFn cb,
- gpointer cb_data);
-GSList *cal_client_multi_get_alarms_in_range (CalClientMulti *multi,
- time_t start, time_t end);
-
-END_GNOME_DECLS
-
-#endif
diff --git a/calendar/cal-client/cal-client-types.c b/calendar/cal-client/cal-client-types.c
deleted file mode 100644
index 6ce98c02c2..0000000000
--- a/calendar/cal-client/cal-client-types.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/* Evolution calendar utilities and types
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@ximian.com>
- * JP Rosevear <jpr@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 <stdlib.h>
-#include "cal-client-types.h"
-
-
-
-/**
- * cal_client_change_list_free:
- * @list: List of #CalClientChange structures.
- *
- * Frees a list of #CalClientChange structures.
- **/
-void
-cal_client_change_list_free (GList *list)
-{
- CalClientChange *c;
- GList *l;
-
- for (l = list; l; l = l->next) {
- c = l->data;
-
- g_assert (c != NULL);
- g_assert (c->comp != NULL);
-
- gtk_object_unref (GTK_OBJECT (c->comp));
- g_free (c);
- }
-
- g_list_free (list);
-}
diff --git a/calendar/cal-client/cal-client-types.h b/calendar/cal-client/cal-client-types.h
deleted file mode 100644
index 9727fc9b3d..0000000000
--- a/calendar/cal-client/cal-client-types.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Evolution calendar utilities and types
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@ximian.com>
- * JP Rosevear <jpr@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 CAL_CLIENT_TYPES_H
-#define CAL_CLIENT_TYPES_H
-
-#include <libgnome/gnome-defs.h>
-#include <cal-util/cal-component.h>
-
-BEGIN_GNOME_DECLS
-
-
-
-typedef enum {
- CAL_CLIENT_CHANGE_ADDED = 1 << 0,
- CAL_CLIENT_CHANGE_MODIFIED = 1 << 1,
- CAL_CLIENT_CHANGE_DELETED = 1 << 2
-} CalClientChangeType;
-
-typedef struct
-{
- CalComponent *comp;
- CalClientChangeType type;
-} CalClientChange;
-
-void cal_client_change_list_free (GList *list);
-
-END_GNOME_DECLS
-
-#endif
-
diff --git a/calendar/cal-client/cal-client.c b/calendar/cal-client/cal-client.c
deleted file mode 100644
index ec5401fb0f..0000000000
--- a/calendar/cal-client/cal-client.c
+++ /dev/null
@@ -1,2752 +0,0 @@
-/* Evolution calendar client
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtksignal.h>
-#include <liboaf/liboaf.h>
-#include <bonobo/bonobo-exception.h>
-#include <bonobo/bonobo-moniker-util.h>
-#include <bonobo-conf/bonobo-config-database.h>
-#include <libgnome/gnome-util.h>
-
-#include "e-util/e-component-listener.h"
-#include "cal-client-types.h"
-#include "cal-client.h"
-#include "cal-listener.h"
-#include "wombat-client.h"
-
-
-
-/* Private part of the CalClient structure */
-struct _CalClientPrivate {
- /* Load state to avoid multiple loads */
- CalClientLoadState load_state;
-
- /* URI of the calendar that is being loaded or is already loaded, or
- * NULL if we are not loaded.
- */
- char *uri;
-
- /* Email address associated with this calendar, or NULL */
- char *email_address;
-
- /* The calendar factories we are contacting */
- GList *factories;
-
- /* Our calendar listener implementation */
- CalListener *listener;
-
- /* The calendar client interface object we are contacting */
- GNOME_Evolution_Calendar_Cal cal;
-
- /* The authentication function */
- CalClientAuthFunc auth_func;
- gpointer auth_user_data;
-
- /* The WombatClient */
- WombatClient *w_client;
-
- /* A cache of timezones retrieved from the server, to avoid getting
- them repeatedly for each get_object() call. */
- GHashTable *timezones;
-
- /* The default timezone to use to resolve DATE and floating DATE-TIME
- values. */
- icaltimezone *default_zone;
-
- /* The component listener to keep track of the lifetime of backends */
- EComponentListener *comp_listener;
-};
-
-
-
-/* Signal IDs */
-enum {
- CAL_OPENED,
- CAL_SET_MODE,
- OBJ_UPDATED,
- OBJ_REMOVED,
- BACKEND_ERROR,
- CATEGORIES_CHANGED,
- FORGET_PASSWORD,
- BACKEND_DIED,
- LAST_SIGNAL
-};
-
-static void cal_client_class_init (CalClientClass *class);
-static void cal_client_init (CalClient *client);
-static void cal_client_destroy (GtkObject *object);
-
-static char *client_get_password_cb (WombatClient *w_client,
- const gchar *prompt,
- const gchar *key,
- gpointer user_data);
-static void client_forget_password_cb (WombatClient *w_client,
- const gchar *key,
- gpointer user_data);
-static void cal_client_get_object_timezones_cb (icalparameter *param,
- void *data);
-
-static guint cal_client_signals[LAST_SIGNAL];
-
-static GtkObjectClass *parent_class;
-
-
-
-/**
- * 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.
- **/
-GtkType
-cal_client_get_type (void)
-{
- static GtkType cal_client_type = 0;
-
- if (!cal_client_type) {
- static const GtkTypeInfo cal_client_info = {
- "CalClient",
- sizeof (CalClient),
- sizeof (CalClientClass),
- (GtkClassInitFunc) cal_client_class_init,
- (GtkObjectInitFunc) cal_client_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- cal_client_type = gtk_type_unique (GTK_TYPE_OBJECT, &cal_client_info);
- }
-
- return cal_client_type;
-}
-
-#define marshal_NONE__ENUM_ENUM gtk_marshal_NONE__INT_INT
-
-/* Class initialization function for the calendar client */
-static void
-cal_client_class_init (CalClientClass *class)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) class;
-
- parent_class = gtk_type_class (GTK_TYPE_OBJECT);
-
- cal_client_signals[CAL_OPENED] =
- gtk_signal_new ("cal_opened",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalClientClass, cal_opened),
- gtk_marshal_NONE__ENUM,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_ENUM);
- cal_client_signals[CAL_SET_MODE] =
- gtk_signal_new ("cal_set_mode",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalClientClass, cal_set_mode),
- marshal_NONE__ENUM_ENUM,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_ENUM,
- GTK_TYPE_ENUM);
- cal_client_signals[OBJ_UPDATED] =
- gtk_signal_new ("obj_updated",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalClientClass, obj_updated),
- gtk_marshal_NONE__STRING,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_STRING);
- cal_client_signals[OBJ_REMOVED] =
- gtk_signal_new ("obj_removed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalClientClass, obj_removed),
- gtk_marshal_NONE__STRING,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_STRING);
- cal_client_signals[BACKEND_ERROR] =
- gtk_signal_new ("backend_error",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalClientClass, backend_error),
- gtk_marshal_NONE__STRING,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_STRING);
- cal_client_signals[CATEGORIES_CHANGED] =
- gtk_signal_new ("categories_changed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalClientClass, categories_changed),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_POINTER);
- cal_client_signals[FORGET_PASSWORD] =
- gtk_signal_new ("forget_password",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalClientClass, forget_password),
- gtk_marshal_NONE__STRING,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_STRING);
- cal_client_signals[BACKEND_DIED] =
- gtk_signal_new ("backend_died",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalClientClass, backend_died),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, cal_client_signals, LAST_SIGNAL);
-
- class->cal_opened = NULL;
- class->obj_updated = NULL;
- class->obj_removed = NULL;
- class->categories_changed = NULL;
- class->forget_password = NULL;
- class->backend_died = NULL;
-
- object_class->destroy = cal_client_destroy;
-}
-
-/* Object initialization function for the calendar client */
-static void
-cal_client_init (CalClient *client)
-{
- CalClientPrivate *priv;
-
- priv = g_new0 (CalClientPrivate, 1);
- client->priv = priv;
-
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- priv->uri = NULL;
- priv->email_address = NULL;
- priv->factories = NULL;
- priv->timezones = g_hash_table_new (g_str_hash, g_str_equal);
- priv->w_client = NULL;
- priv->default_zone = icaltimezone_get_utc_timezone ();
- priv->comp_listener = NULL;
-}
-
-/* Gets rid of the factories that a client knows about */
-static void
-destroy_factories (CalClient *client)
-{
- CalClientPrivate *priv;
- CORBA_Object factory;
- CORBA_Environment ev;
- int result;
- GList *f;
-
- priv = client->priv;
-
- CORBA_exception_init (&ev);
-
- for (f = priv->factories; f; f = f->next) {
- factory = f->data;
-
- result = CORBA_Object_is_nil (factory, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("destroy_factories(): could not see if a factory was nil");
- CORBA_exception_free (&ev);
-
- continue;
- }
-
- if (result)
- continue;
-
- CORBA_Object_release (factory, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("destroy_factories(): could not release a factory");
- CORBA_exception_free (&ev);
- }
- }
-
- g_list_free (priv->factories);
- priv->factories = NULL;
-}
-
-/* Gets rid of the calendar client interface object that a client knows about */
-static void
-destroy_cal (CalClient *client)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- int result;
-
- priv = client->priv;
-
- 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 "
- "calendar client interface object was nil");
- priv->cal = CORBA_OBJECT_NIL;
- CORBA_exception_free (&ev);
- return;
- }
- CORBA_exception_free (&ev);
-
- 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);
- priv->cal = CORBA_OBJECT_NIL;
-
-}
-
-static void
-free_timezone (gpointer key, gpointer value, gpointer data)
-{
- /* Note that the key comes from within the icaltimezone value, so we
- don't free that. */
- icaltimezone_free (value, TRUE);
-}
-
-/* Destroy handler for the calendar client */
-static void
-cal_client_destroy (GtkObject *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;
-
- /* The server unrefs the query listener, so we just NULL it out here */
- if (priv->listener) {
- cal_listener_stop_notification (priv->listener);
- priv->listener = NULL;
- }
-
- if (priv->comp_listener) {
- gtk_signal_disconnect_by_data (GTK_OBJECT (priv->comp_listener), client);
- gtk_object_unref (GTK_OBJECT (priv->comp_listener));
- priv->comp_listener = NULL;
- }
-
- priv->w_client = 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->email_address) {
- g_free (priv->email_address);
- priv->email_address = 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 (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-
-
-static void
-backend_died_cb (EComponentListener *cl, gpointer user_data)
-{
- CalClientPrivate *priv;
- CalClient *client = (CalClient *) user_data;
-
- g_return_if_fail (IS_CAL_CLIENT (client));
-
- priv = client->priv;
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[BACKEND_DIED]);
-}
-
-/* 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)
-{
- CalClient *client;
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_Cal cal_copy;
- CalClientOpenStatus client_status;
-
- client = CAL_CLIENT (data);
- priv = client->priv;
-
- g_assert (priv->load_state == CAL_CLIENT_LOAD_LOADING);
- g_assert (priv->uri != NULL);
-
- client_status = CAL_CLIENT_OPEN_ERROR;
-
- 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);
-
- priv->cal = cal_copy;
- priv->load_state = CAL_CLIENT_LOAD_LOADED;
-
- client_status = CAL_CLIENT_OPEN_SUCCESS;
-
- /* setup component listener */
- priv->comp_listener = e_component_listener_new (priv->cal, 0);
- gtk_signal_connect (GTK_OBJECT (priv->comp_listener), "component_died",
- GTK_SIGNAL_FUNC (backend_died_cb), client);
- goto out;
-
- case GNOME_Evolution_Calendar_Listener_ERROR:
- client_status = CAL_CLIENT_OPEN_ERROR;
- goto error;
-
- case GNOME_Evolution_Calendar_Listener_NOT_FOUND:
- client_status = CAL_CLIENT_OPEN_NOT_FOUND;
- goto error;
-
- case GNOME_Evolution_Calendar_Listener_METHOD_NOT_SUPPORTED:
- client_status = CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED;
- goto error;
-
- case GNOME_Evolution_Calendar_Listener_PERMISSION_DENIED :
- client_status = CAL_CLIENT_OPEN_PERMISSION_DENIED;
- goto error;
-
- default:
- g_assert_not_reached ();
- }
-
- error:
-
- bonobo_object_unref (BONOBO_OBJECT (priv->listener));
- priv->listener = NULL;
-
- /* 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.
- */
-
- out:
-
- /* 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.
- */
-
- gtk_object_ref (GTK_OBJECT (client));
-
- gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[CAL_OPENED],
- client_status);
-
- if (client_status != CAL_CLIENT_OPEN_SUCCESS) {
- priv->load_state = CAL_CLIENT_LOAD_NOT_LOADED;
- g_free (priv->uri);
- priv->uri = NULL;
- }
-
- g_assert (priv->load_state != CAL_CLIENT_LOAD_LOADING);
-
- gtk_object_unref (GTK_OBJECT (client));
-}
-
-/* Handle the cal_set_mode notification from the listener */
-static void
-cal_set_mode_cb (CalListener *listener,
- GNOME_Evolution_Calendar_Listener_SetModeStatus status,
- GNOME_Evolution_Calendar_CalMode mode,
- gpointer data)
-{
- CalClient *client;
- CalClientPrivate *priv;
- CalClientSetModeStatus client_status;
-
- client = CAL_CLIENT (data);
- priv = client->priv;
-
- client_status = CAL_CLIENT_OPEN_ERROR;
-
- switch (status) {
- case GNOME_Evolution_Calendar_Listener_MODE_SET:
- client_status = CAL_CLIENT_SET_MODE_SUCCESS;
- break;
- case GNOME_Evolution_Calendar_Listener_MODE_NOT_SET:
- client_status = CAL_CLIENT_SET_MODE_ERROR;
- break;
- case GNOME_Evolution_Calendar_Listener_MODE_NOT_SUPPORTED:
- client_status = CAL_CLIENT_SET_MODE_NOT_SUPPORTED;
- break;
- default:
- g_assert_not_reached ();
- }
-
- /* 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.
- */
-
- gtk_object_ref (GTK_OBJECT (client));
-
- gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[CAL_SET_MODE],
- client_status, mode);
-
- gtk_object_unref (GTK_OBJECT (client));
-}
-
-/* Handle the obj_updated signal from the listener */
-static void
-obj_updated_cb (CalListener *listener, const GNOME_Evolution_Calendar_CalObjUID uid, gpointer data)
-{
- CalClient *client;
-
- client = CAL_CLIENT (data);
- gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[OBJ_UPDATED], uid);
-}
-
-/* Handle the obj_removed signal from the listener */
-static void
-obj_removed_cb (CalListener *listener, const GNOME_Evolution_Calendar_CalObjUID uid, gpointer data)
-{
- CalClient *client;
-
- client = CAL_CLIENT (data);
- gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[OBJ_REMOVED], uid);
-}
-
-/* Handle the error_occurred signal from the listener */
-static void
-backend_error_cb (CalListener *listener, const char *message, gpointer data)
-{
- CalClient *client;
-
- client = CAL_CLIENT (data);
- gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[BACKEND_ERROR], message);
-}
-
-/* Handle the categories_changed signal from the listener */
-static void
-categories_changed_cb (CalListener *listener, const GNOME_Evolution_Calendar_StringSeq *categories,
- gpointer data)
-{
- CalClient *client;
- GPtrArray *cats;
- int i;
-
- client = CAL_CLIENT (data);
-
- cats = g_ptr_array_new ();
- g_ptr_array_set_size (cats, categories->_length);
-
- for (i = 0; i < categories->_length; i++)
- cats->pdata[i] = categories->_buffer[i];
-
- gtk_signal_emit (GTK_OBJECT (client), cal_client_signals[CATEGORIES_CHANGED], cats);
-
- g_ptr_array_free (cats, TRUE);
-}
-
-
-/* Handle the get_password signal from the Wombatclient */
-static gchar *
-client_get_password_cb (WombatClient *w_client,
- const gchar *prompt,
- const gchar *key,
- gpointer user_data)
-{
- CalClient *client;
-
- client = CAL_CLIENT (user_data);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
-
- if (client->priv->auth_func)
- return client->priv->auth_func (client, prompt, key, client->priv->auth_user_data);
-
- return NULL;
-}
-
-/* Handle the forget_password signal from the WombatClient */
-static void
-client_forget_password_cb (WombatClient *w_client,
- const gchar *key,
- gpointer user_data)
-{
- CalClient *client;
-
- client = CAL_CLIENT (user_data);
- g_return_if_fail (IS_CAL_CLIENT (client));
-
- gtk_signal_emit (GTK_OBJECT (client),
- cal_client_signals [FORGET_PASSWORD],
- key);
-}
-
-
-
-/**
- * cal_client_construct:
- * @client: A calendar client.
- *
- * Constructs a calendar client object by contacting all available
- * calendar factories.
- *
- * Return value: The same object as the @client argument, or NULL if the
- * calendar factory could not be contacted.
- **/
-CalClient *
-cal_client_construct (CalClient *client)
-{
- CalClientPrivate *priv;
- GNOME_Evolution_Calendar_CalFactory factory;
- OAF_ServerInfoList *servers;
- CORBA_Environment ev;
- int i;
-
- CORBA_exception_init (&ev);
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
-
- priv = client->priv;
-
- CORBA_exception_init (&ev);
-
- servers = oaf_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;
- }
-
- if (servers->_length == 0)
- g_warning ("No Calendar servers installed.");
-
- for (i = 0; i < servers->_length; i++) {
- const OAF_ServerInfo *info;
-
- info = servers->_buffer + i;
-
- factory = (GNOME_Evolution_Calendar_CalFactory)
- oaf_activate_from_id (info->iid, 0, NULL, &ev);
- if (BONOBO_EX (&ev)) {
- g_warning ("cal_client_construct: Could not activate calendar server %s", info->iid);
- CORBA_free (servers);
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- priv->factories = g_list_prepend (priv->factories, factory);
- }
-
- CORBA_free (servers);
-
- CORBA_exception_free (&ev);
- return client;
-}
-
-/**
- * cal_client_new:
- *
- * Creates a new calendar client. It should be initialized by calling
- * cal_client_open_calendar().
- *
- * 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)
-{
- CalClient *client;
-
- client = gtk_type_new (CAL_CLIENT_TYPE);
-
- if (!cal_client_construct (client)) {
- g_message ("cal_client_new(): could not construct the calendar client");
- gtk_object_unref (GTK_OBJECT (client));
- return NULL;
- }
-
- return client;
-}
-
-/**
- * cal_client_set_auth_func
- * @client: A calendar client.
- * @func: The authentication function
- * @data: User data to be used when calling the authentication function
- *
- * Associates the given authentication function with a calendar client. This
- * function will be called any time the calendar server needs a password
- * from the client. So, calendar clients should provide such authentication
- * function, which, when called, should act accordingly (by showing a dialog
- * box, for example, to ask the user for the password).
- *
- * The authentication function must have the following form:
- * char * auth_func (CalClient *client,
- * const gchar *prompt,
- * const gchar *key,
- * gpointer user_data)
- */
-void
-cal_client_set_auth_func (CalClient *client, CalClientAuthFunc func, gpointer data)
-{
- g_return_if_fail (client != NULL);
- g_return_if_fail (IS_CAL_CLIENT (client));
-
- client->priv->auth_func = func;
- 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;
- }
-
- /* create the WombatClient */
- priv->w_client = wombat_client_new (
- (WombatClientGetPasswordFn) client_get_password_cb,
- (WombatClientForgetPasswordFn) client_forget_password_cb,
- (gpointer) client);
- bonobo_object_add_interface (BONOBO_OBJECT (priv->listener),
- BONOBO_OBJECT (priv->w_client));
-
- 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))
- break;
- else if (BONOBO_USER_EX (&ev, ex_GNOME_Evolution_Calendar_CalFactory_UnsupportedMethod))
- unsupported++;
- }
-
- if (supported != NULL) {
- if (unsupported == g_list_length (priv->factories))
- *supported = FALSE;
- else
- *supported = TRUE;
- }
-
- if (BONOBO_EX (&ev)) {
- 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;
- }
-
- return TRUE;
-}
-
-/**
- * cal_client_open_calendar:
- * @client: A calendar client.
- * @str_uri: URI of calendar to open.
- * @only_if_exists: FALSE if the calendar should be opened even if there
- * was no storage for it, i.e. to create a new calendar or load an existing
- * one if it already exists. TRUE if it should only try to load calendars
- * that already exist.
- *
- * Makes a calendar client initiate a request to open a calendar. The calendar
- * client will emit the "cal_opened" signal when the response from the server is
- * received.
- *
- * 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)
-{
- 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);
-}
-
-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");
-}
-
-static char *
-get_default_uri (gboolean tasks)
-{
- Bonobo_ConfigDatabase db;
- char *uri;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev);
-
- if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) {
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- if (tasks)
- uri = bonobo_config_get_string (db, "/DefaultFolders/tasks_uri", &ev);
- else
- uri = bonobo_config_get_string (db, "/DefaultFolders/calendar_uri", &ev);
- bonobo_object_release_unref (db, NULL);
-
- if (BONOBO_EX (&ev)) {
- CORBA_exception_free (&ev);
- uri = get_fall_back_uri (tasks);
- } else {
- uri = cal_util_expand_uri (uri, tasks);
- }
-
- return uri;
-}
-
-gboolean
-cal_client_open_default_calendar (CalClient *client, gboolean only_if_exists)
-{
- char *default_uri, *fall_back;
- gboolean result, supported;
-
- g_return_val_if_fail (client != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
-
- 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_free (default_uri);
- g_free (fall_back);
-
- return result;
-}
-
-gboolean
-cal_client_open_default_tasks (CalClient *client, gboolean only_if_exists)
-{
- char *default_uri, *fall_back;
- gboolean result, supported;
-
- 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);
-
- 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_free (default_uri);
- g_free (fall_back);
-
- return result;
-}
-
-/* Builds an URI list out of a CORBA string sequence */
-static GList *
-build_uri_list (GNOME_Evolution_Calendar_StringSeq *seq)
-{
- GList *uris = NULL;
- int i;
-
- for (i = 0; i < seq->_length; i++)
- uris = g_list_prepend (uris, g_strdup (seq->_buffer[i]));
-
- return uris;
-}
-
-/**
- * cal_client_uri_list:
- * @client: A calendar client
- * @type: type of uri's to get
- *
- *
- * Return value: A list of URI's open on the wombat
- **/
-GList *
-cal_client_uri_list (CalClient *client, CalMode mode)
-{
- CalClientPrivate *priv;
- GNOME_Evolution_Calendar_StringSeq *uri_seq;
- GList *uris = NULL;
- CORBA_Environment ev;
- GList *f;
-
- g_return_val_if_fail (client != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
-
- priv = client->priv;
-
- for (f = priv->factories; f; f = f->next) {
- CORBA_exception_init (&ev);
- uri_seq = GNOME_Evolution_Calendar_CalFactory_uriList (f->data, mode, &ev);
-
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_uri_list(): request failed");
-
- /* free memory and return */
- g_list_foreach (uris, (GFunc) g_free, NULL);
- g_list_free (uris);
- uris = NULL;
- break;
- }
- else
- uris = g_list_concat (uris, build_uri_list (uri_seq));
-
- CORBA_exception_free (&ev);
- }
-
- return uris;
-}
-
-/**
- * cal_client_get_load_state:
- * @client: A calendar client.
- *
- * Queries the state of loading of a calendar client.
- *
- * Return value: A #CalClientLoadState value indicating whether the client has
- * not been loaded with cal_client_open_calendar() yet, whether it is being
- * loaded, or whether it is already loaded.
- **/
-CalClientLoadState
-cal_client_get_load_state (CalClient *client)
-{
- CalClientPrivate *priv;
-
- g_return_val_if_fail (client != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
-
- priv = client->priv;
- return priv->load_state;
-}
-
-/**
- * cal_client_get_uri:
- * @client: A calendar client.
- *
- * Queries the URI that is open in a calendar client.
- *
- * Return value: The URI of the calendar that is already loaded or is being
- * loaded, or NULL if the client has not started a load request yet.
- **/
-const char *
-cal_client_get_uri (CalClient *client)
-{
- CalClientPrivate *priv;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
-
- priv = client->priv;
- return priv->uri;
-}
-
-/**
- * cal_client_is_read_only:
- * @client: A calendar client.
- *
- * Queries whether the calendar client can perform modifications
- * on the calendar or not.
- *
- * Return value: TRUE if the calendar is read-only, FALSE otherwise.
- */
-gboolean
-cal_client_is_read_only (CalClient *client)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- CORBA_boolean read_only;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
-
- priv = client->priv;
-
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, FALSE);
-
- CORBA_exception_init (&ev);
- read_only = GNOME_Evolution_Calendar_Cal_isReadOnly (priv->cal, &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("cal_client_is_read_only: could not call isReadOnly method");
- }
- CORBA_exception_free (&ev);
-
- return read_only;
-}
-
-/**
- * cal_client_get_email_address:
- * @client: A calendar client.
- *
- * Queries the email address associated with a calendar client.
- *
- * Return value: The email address associated with the calendar that
- * 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_email_address (CalClient *client)
-{
- CalClientPrivate *priv;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
-
- if (priv->email_address == NULL) {
- CORBA_Environment ev;
- CORBA_char *email_address;
-
- CORBA_exception_init (&ev);
- email_address = GNOME_Evolution_Calendar_Cal_getEmailAddress (priv->cal, &ev);
- if (!BONOBO_EX (&ev)) {
- priv->email_address = g_strdup (email_address);
- CORBA_free (email_address);
- }
- CORBA_exception_free (&ev);
- }
-
- return priv->email_address;
-}
-
-/* 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)
-{
- CalClientPrivate *priv;
- gboolean retval = TRUE;
- CORBA_Environment ev;
-
- 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);
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_setMode (priv->cal, mode, &ev);
-
- if (BONOBO_EX (&ev))
- retval = FALSE;
-
- CORBA_exception_free (&ev);
-
- 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. */
-typedef struct _CalClientGetTimezonesData CalClientGetTimezonesData;
-struct _CalClientGetTimezonesData {
- CalClient *client;
-
- /* This starts out at CAL_CLIENT_GET_SUCCESS. If an error occurs this
- contains the last error. */
- CalClientGetStatus status;
-};
-
-
-/**
- * cal_client_get_object:
- * @client: A calendar client.
- * @uid: Unique identifier for a calendar component.
- * @comp: Return value for the calendar component object.
- *
- * Queries a calendar for a calendar component object based on its unique
- * identifier.
- *
- * Return value: Result code based on the status of the operation.
- **/
-CalClientGetStatus
-cal_client_get_object (CalClient *client, const char *uid, CalComponent **comp)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObj comp_str;
- CalClientGetStatus retval;
- icalcomponent *icalcomp;
- CalClientGetTimezonesData cb_data;
-
- 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 (uid != NULL, CAL_CLIENT_GET_NOT_FOUND);
- g_return_val_if_fail (comp != NULL, CAL_CLIENT_GET_NOT_FOUND);
-
- retval = CAL_CLIENT_GET_NOT_FOUND;
- *comp = NULL;
-
- 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;
- }
-
- icalcomp = icalparser_parse_string (comp_str);
- CORBA_free (comp_str);
-
- if (!icalcomp) {
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
- }
-
- *comp = cal_component_new ();
- if (!cal_component_set_icalcomponent (*comp, icalcomp)) {
- icalcomponent_free (icalcomp);
- gtk_object_unref (GTK_OBJECT (*comp));
- *comp = NULL;
-
- retval = CAL_CLIENT_GET_SYNTAX_ERROR;
- goto out;
- }
-
- /* 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);
-
- retval = cb_data.status;
-
- out:
-
- CORBA_exception_free (&ev);
- return retval;
-}
-
-
-static void
-cal_client_get_object_timezones_cb (icalparameter *param,
- void *data)
-{
- CalClientGetTimezonesData *cb_data = data;
- const char *tzid;
- icaltimezone *zone;
- CalClientGetStatus status;
-
- tzid = icalparameter_get_tzid (param);
- if (!tzid) {
- cb_data->status = CAL_CLIENT_GET_SYNTAX_ERROR;
- 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 GTK+ 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;
-}
-
-/* Resolves TZIDs for the recurrence generator. */
-icaltimezone*
-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);
-
- client = CAL_CLIENT (data);
-
- /* FIXME: Handle errors. */
- status = cal_client_get_timezone (client, tzid, &zone);
-
- 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)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObjUIDSeq *seq;
- int t;
- GList *uids;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
-
- t = corba_obj_type (type);
-
- CORBA_exception_init (&ev);
-
- 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;
- }
-
- CORBA_exception_free (&ev);
-
- uids = build_uid_list (seq);
- CORBA_free (seq);
-
- return uids;
-}
-
-/* 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;
-
- /* 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);
- gtk_object_unref (GTK_OBJECT (ccc->comp));
- continue;
- }
- ccc->type = corba_coc->type;
-
- list = g_list_prepend (list, ccc);
- }
-
- list = g_list_reverse (list);
-
- return list;
-}
-
-GList *
-cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalObjChangeSeq *seq;
- int t;
- GList *changes;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
-
- t = corba_obj_type (type);
- CORBA_exception_init (&ev);
-
- 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;
- }
-
- CORBA_exception_free (&ev);
-
- changes = build_change_list (seq);
- CORBA_free (seq);
-
- return changes;
-}
-
-/* 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;
-
- /* Create the list in reverse order */
-
- list = NULL;
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalObjInstance *corba_icoi;
- CalObjInstance *icoi;
-
- corba_icoi = &seq->_buffer[i];
- icoi = g_new (CalObjInstance, 1);
-
- icoi->uid = g_strdup (corba_icoi->uid);
- icoi->start = corba_icoi->start;
- icoi->end = corba_icoi->end;
-
- list = g_list_prepend (list, icoi);
- }
-
- 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);
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
-
- g_return_val_if_fail (start != -1 && end != -1, NULL);
- g_return_val_if_fail (start <= end, NULL);
-
- CORBA_exception_init (&ev);
-
- t = corba_obj_type (type);
-
- 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;
- }
- CORBA_exception_free (&ev);
-
- uids = build_uid_list (seq);
- CORBA_free (seq);
-
- return uids;
-}
-
-/**
- * cal_client_get_free_busy
- * @client:: A calendar client.
- * @users: List of users to retrieve free/busy information for.
- * @start: Start time for query.
- * @end: End time for query.
- *
- * Gets free/busy information from the calendar server.
- *
- * Returns: a GList of VFREEBUSY CalComponents
- */
-GList *
-cal_client_get_free_busy (CalClient *client, GList *users,
- time_t start, time_t end)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_UserList *corba_list;
- GNOME_Evolution_Calendar_CalObjSeq *calobj_list;
- GList *l;
- GList *comp_list = NULL;
- int len, i;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
-
- g_return_val_if_fail (start != -1 && end != -1, NULL);
- g_return_val_if_fail (start <= end, NULL);
-
- /* 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);
-
- for (l = g_list_first (users), i = 0; l; l = l->next, i++)
- corba_list->_buffer[i] = CORBA_string_dup ((CORBA_char *) 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) {
- g_message ("cal_client_get_free_busy(): could not get the objects");
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- for (i = 0; i < calobj_list->_length; i++) {
- CalComponent *comp;
- icalcomponent *icalcomp;
- icalcomponent_kind kind;
-
- icalcomp = icalparser_parse_string (calobj_list->_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);
- gtk_object_unref (GTK_OBJECT (comp));
- continue;
- }
-
- comp_list = g_list_append (comp_list, 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;
- 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);
- gtk_object_unref (GTK_OBJECT (comp));
-
- status = cal_client_get_object (client, uid, &comp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- /* 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);
- 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);
- gtk_object_unref (GTK_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 = gtk_signal_connect (GTK_OBJECT (client), "obj_updated",
- GTK_SIGNAL_FUNC (generate_instances_obj_updated_cb),
- uid_comp_hash);
-
- obj_removed_id = gtk_signal_connect (GTK_OBJECT (client), "obj_removed",
- GTK_SIGNAL_FUNC (generate_instances_obj_removed_cb),
- uid_comp_hash);
-
- /* Get the objects */
-
- for (l = uids; l; l = l->next) {
- CalComponent *comp;
- CalClientGetStatus status;
- char *uid;
- const char *comp_uid;
-
- uid = l->data;
-
- status = cal_client_get_object (client, uid, &comp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- /* 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);
- 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.
- */
-
- gtk_signal_disconnect (GTK_OBJECT (client), obj_updated_id);
- gtk_signal_disconnect (GTK_OBJECT (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;
-}
-
-struct comp_instance {
- CalComponent *comp;
- time_t start;
- time_t end;
-};
-
-/* Called from cal_recur_generate_instances(); adds an instance to the list */
-static gboolean
-add_instance (CalComponent *comp, time_t start, time_t end, gpointer data)
-{
- GList **list;
- struct comp_instance *ci;
-
- list = data;
-
- ci = g_new (struct comp_instance, 1);
-
- ci->comp = comp;
- gtk_object_ref (GTK_OBJECT (ci->comp));
-
- ci->start = start;
- ci->end = end;
-
- *list = g_list_prepend (*list, ci);
-
- return TRUE;
-}
-
-/* Used from g_list_sort(); compares two struct comp_instance structures */
-static gint
-compare_comp_instance (gconstpointer a, gconstpointer b)
-{
- const struct comp_instance *cia, *cib;
- time_t diff;
-
- cia = a;
- cib = b;
-
- diff = cia->start - cib->start;
- return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
-}
-
-/**
- * cal_client_generate_instances:
- * @client: A calendar client.
- * @type: Bitmask with types of objects to return.
- * @start: Start time for query.
- * @end: End time for query.
- * @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.
- *
- * The callback function should do a gtk_object_ref() of the calendar component
- * it gets passed if it intends to keep it around.
- **/
-void
-cal_client_generate_instances (CalClient *client, CalObjType type,
- time_t start, time_t end,
- CalRecurInstanceFn cb, gpointer cb_data)
-{
- CalClientPrivate *priv;
- GList *objects;
- GList *instances;
- GList *l;
-
- g_return_if_fail (client != NULL);
- g_return_if_fail (IS_CAL_CLIENT (client));
-
- priv = client->priv;
- g_return_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED);
-
- g_return_if_fail (start != -1 && end != -1);
- g_return_if_fail (start <= end);
- g_return_if_fail (cb != NULL);
-
- /* Generate objects */
-
- objects = get_objects_atomically (client, type, start, end);
- instances = NULL;
-
- for (l = objects; l; l = l->next) {
- CalComponent *comp;
-
- comp = l->data;
- cal_recur_generate_instances (comp, start, end, add_instance, &instances,
- cal_client_resolve_tzid_cb, client,
- priv->default_zone);
- gtk_object_unref (GTK_OBJECT (comp));
- }
-
- g_list_free (objects);
-
- /* Generate instances and spew them out */
-
- instances = g_list_sort (instances, compare_comp_instance);
-
- for (l = instances; l; l = l->next) {
- struct comp_instance *ci;
- gboolean result;
-
- ci = l->data;
-
- result = (* cb) (ci->comp, ci->start, ci->end, cb_data);
-
- if (!result)
- break;
- }
-
- /* Clean up */
-
- for (l = instances; l; l = l->next) {
- struct comp_instance *ci;
-
- ci = l->data;
- gtk_object_unref (GTK_OBJECT (ci->comp));
- g_free (ci);
- }
-
- 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)
-{
- GSList *comp_alarms;
- int i;
-
- comp_alarms = NULL;
-
- for (i = 0; i < seq->_length; i++) {
- GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms;
- CalComponent *comp;
- CalComponentAlarms *alarms;
- icalcomponent *icalcomp;
-
- corba_alarms = seq->_buffer + i;
-
- icalcomp = icalparser_parse_string (corba_alarms->calobj);
- if (!icalcomp)
- continue;
-
- comp = cal_component_new ();
- if (!cal_component_set_icalcomponent (comp, icalcomp)) {
- icalcomponent_free (icalcomp);
- gtk_object_unref (GTK_OBJECT (comp));
- 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);
- }
-
- return comp_alarms;
-}
-
-/**
- * cal_client_get_alarms_in_range:
- * @client: A calendar client.
- * @start: Start time for query.
- * @end: End time for query.
- *
- * Queries a calendar for the alarms that trigger in the specified range of
- * time.
- *
- * Return value: A list of #CalComponentAlarms structures. This should be freed
- * using the cal_client_free_alarms() function, or by freeing each element
- * separately with cal_component_alarms_free() and then freeing the list with
- * g_slist_free().
- **/
-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;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, NULL);
-
- g_return_val_if_fail (start != -1 && end != -1, NULL);
- g_return_val_if_fail (start <= end, NULL);
-
- CORBA_exception_init (&ev);
-
- 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);
- return NULL;
- }
- CORBA_exception_free (&ev);
-
- alarms = build_component_alarms_list (seq);
- CORBA_free (seq);
-
- return alarms;
-}
-
-/**
- * cal_client_free_alarms:
- * @comp_alarms: A list of #CalComponentAlarms structures.
- *
- * Frees a list of #CalComponentAlarms structures as returned by
- * cal_client_get_alarms_in_range().
- **/
-void
-cal_client_free_alarms (GSList *comp_alarms)
-{
- GSList *l;
-
- for (l = comp_alarms; l; l = l->next) {
- CalComponentAlarms *alarms;
-
- alarms = l->data;
- g_assert (alarms != NULL);
-
- cal_component_alarms_free (alarms);
- }
-
- g_slist_free (comp_alarms);
-}
-
-/**
- * cal_client_get_alarms_for_object:
- * @client: A calendar client.
- * @uid: Unique identifier for a calendar component.
- * @start: Start time for query.
- * @end: End time for query.
- * @alarms: Return value for the component's alarm instances. Will return NULL
- * if no instances occur within the specified time range. This should be freed
- * using the cal_component_alarms_free() function.
- *
- * Queries a calendar for the alarms of a particular object that trigger in the
- * specified range of time.
- *
- * Return value: TRUE on success, FALSE if the object was not found.
- **/
-gboolean
-cal_client_get_alarms_for_object (CalClient *client, const char *uid,
- time_t start, time_t end,
- CalComponentAlarms **alarms)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms;
- gboolean retval;
- icalcomponent *icalcomp;
- CalComponent *comp;
-
- 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, FALSE);
-
- g_return_val_if_fail (uid != NULL, FALSE);
- g_return_val_if_fail (start != -1 && end != -1, FALSE);
- g_return_val_if_fail (start <= end, FALSE);
- 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 (!icalcomp)
- goto out;
-
- comp = cal_component_new ();
- if (!cal_component_set_icalcomponent (comp, icalcomp)) {
- icalcomponent_free (icalcomp);
- gtk_object_unref (GTK_OBJECT (comp));
- goto out;
- }
-
- retval = TRUE;
-
- *alarms = g_new (CalComponentAlarms, 1);
- (*alarms)->comp = comp;
- (*alarms)->alarms = build_alarm_instance_list (comp, &corba_alarms->alarms);
- CORBA_free (corba_alarms);
-
- out:
- CORBA_exception_free (&ev);
- return retval;
-}
-
-typedef struct _ForeachTZIDCallbackData ForeachTZIDCallbackData;
-struct _ForeachTZIDCallbackData {
- CalClient *client;
- GHashTable *timezone_hash;
- gboolean include_all_timezones;
- gboolean success;
-};
-
-/* This adds the VTIMEZONE given by the TZID parameter to the GHashTable in
- data. */
-static void
-foreach_tzid_callback (icalparameter *param, void *cbdata)
-{
- ForeachTZIDCallbackData *data = cbdata;
- CalClientPrivate *priv;
- const char *tzid;
- icaltimezone *zone;
- icalcomponent *vtimezone_comp;
- char *vtimezone_as_string;
-
- priv = data->client->priv;
-
- /* Get the TZID string from the parameter. */
- tzid = icalparameter_get_tzid (param);
- if (!tzid)
- return;
-
- /* Check if we've already added it to the GHashTable. */
- if (g_hash_table_lookup (data->timezone_hash, tzid))
- return;
-
- if (data->include_all_timezones) {
- CalClientGetStatus status;
-
- status = cal_client_get_timezone (data->client, tzid, &zone);
- if (status != CAL_CLIENT_GET_SUCCESS) {
- data->success = FALSE;
- return;
- }
- } else {
- /* Check if it is in our cache. If it is, it must already be
- on the server so return. */
- if (g_hash_table_lookup (priv->timezones, tzid))
- return;
-
- /* Check if it is a builtin timezone. If it isn't, return. */
- zone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
- if (!zone)
- return;
- }
-
- /* Convert it to a string and add it to the hash. */
- vtimezone_comp = icaltimezone_get_component (zone);
- if (!vtimezone_comp)
- return;
-
- vtimezone_as_string = icalcomponent_as_ical_string (vtimezone_comp);
-
- g_hash_table_insert (data->timezone_hash, (char*) tzid,
- g_strdup (vtimezone_as_string));
-}
-
-/* This appends the value string to the GString given in data. */
-static void
-append_timezone_string (gpointer key, gpointer value, gpointer data)
-{
- GString *vcal_string = data;
-
- g_string_append (vcal_string, value);
- g_free (value);
-}
-
-
-/* This simply frees the hash values. */
-static void
-free_timezone_string (gpointer key, gpointer value, gpointer data)
-{
- g_free (value);
-}
-
-
-/* This converts the VEVENT/VTODO to a string. If include_all_timezones is
- TRUE, it includes all the VTIMEZONE components needed for the VEVENT/VTODO.
- If not, it only includes builtin timezones that may not be on the server.
-
- To do that we check every TZID in the component to see if it is a builtin
- timezone. If it is, we see if it it in our cache. If it is in our cache,
- then we know the server already has it and we don't need to send it.
- If it isn't in our cache, then we need to send it to the server.
- If we need to send any timezones to the server, then we have to create a
- complete VCALENDAR object, otherwise we can just send a single VEVENT/VTODO
- as before. */
-static char*
-cal_client_get_component_as_string_internal (CalClient *client,
- CalComponent *comp,
- gboolean include_all_timezones)
-{
- GHashTable *timezone_hash;
- GString *vcal_string;
- int initial_vcal_string_len;
- ForeachTZIDCallbackData cbdata;
- char *obj_string;
-
- CalClientPrivate *priv;
-
- priv = client->priv;
-
- timezone_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* Add any timezones needed to the hash. We use a hash since we only
- want to add each timezone once at most. */
- cbdata.client = client;
- cbdata.timezone_hash = timezone_hash;
- cbdata.include_all_timezones = include_all_timezones;
- cbdata.success = TRUE;
- icalcomponent_foreach_tzid (cal_component_get_icalcomponent (comp),
- foreach_tzid_callback, &cbdata);
- if (!cbdata.success) {
- g_hash_table_foreach (timezone_hash, free_timezone_string,
- NULL);
- return NULL;
- }
-
- /* Create the start of a VCALENDAR, to add the VTIMEZONES to,
- and remember its length so we know if any VTIMEZONEs get added. */
- 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"
- "METHOD:PUBLISH\n");
- initial_vcal_string_len = vcal_string->len;
-
- /* Now concatenate all the timezone strings. This also frees the
- timezone strings as it goes. */
- g_hash_table_foreach (timezone_hash, append_timezone_string,
- vcal_string);
-
- /* Get the string for the VEVENT/VTODO. */
- obj_string = cal_component_get_as_string (comp);
-
- /* If there were any timezones to send, create a complete VCALENDAR,
- else just send the VEVENT/VTODO string. */
- if (!include_all_timezones
- && vcal_string->len == initial_vcal_string_len) {
- g_string_free (vcal_string, TRUE);
- } else {
- g_string_append (vcal_string, obj_string);
- g_string_append (vcal_string, "END:VCALENDAR\n");
- g_free (obj_string);
- obj_string = vcal_string->str;
- g_string_free (vcal_string, FALSE);
- }
-
- g_hash_table_destroy (timezone_hash);
-
- return obj_string;
-}
-
-/**
- * cal_client_get_component_as_string:
- * @client: A calendar client.
- * @comp: A calendar component object.
- *
- * Gets a calendar component as an iCalendar string, with a toplevel
- * VCALENDAR component and all VTIMEZONEs needed for the component.
- *
- * Return value: the component as a complete iCalendar string, or NULL on
- * failure. The string should be freed after use.
- **/
-char*
-cal_client_get_component_as_string (CalClient *client,
- CalComponent *comp)
-{
- return cal_client_get_component_as_string_internal (client, comp,
- TRUE);
-}
-
-/**
- * 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)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- CalClientResult retval;
- char *obj_string;
-
- 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);
-
- 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);
-
- cal_component_commit_sequence (comp);
-
- obj_string = cal_client_get_component_as_string_internal (client,
- comp, FALSE);
- if (obj_string == NULL)
- return CAL_CLIENT_RESULT_INVALID_OBJECT;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, &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;
- }
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
-
- CORBA_exception_free (&ev);
- return retval;
-}
-
-/**
- * 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)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- CalClientResult retval;
- char *obj_string;
-
- 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);
-
- 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);
-
- /* Libical owns this memory, using one of its temporary buffers. */
- obj_string = icalcomponent_as_ical_string (icalcomp);
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_updateObjects (priv->cal, obj_string, &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;
- }
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
-
- CORBA_exception_free (&ev);
- return retval;
-}
-
-
-/**
- * cal_client_remove_object:
- * @client: A calendar client.
- * @uid: Unique identifier of the calendar component to remove.
- *
- * Asks a calendar to remove a component. If the server is able to remove the
- * component, all clients will be notified and they will emit the "obj_removed"
- * signal.
- *
- * Return value: a #CalClientResult value indicating the result of the
- * operation.
- **/
-CalClientResult
-cal_client_remove_object (CalClient *client, const char *uid)
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- CalClientResult retval;
-
- 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);
-
- 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);
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_Cal_removeObject (priv->cal, (char *) uid, &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;
- }
- else
- retval = CAL_CLIENT_RESULT_SUCCESS;
-
- CORBA_exception_free (&ev);
- return retval;
-}
-
-CalClientResult
-cal_client_send_object (CalClient *client, icalcomponent *icalcomp,
- icalcomponent **new_icalcomp, GList **users,
- char error_msg[256])
-{
- CalClientPrivate *priv;
- CORBA_Environment ev;
- CalClientResult retval;
- GNOME_Evolution_Calendar_UserList *user_list;
- char *obj_string;
- int i;
-
- 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);
-
- 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);
-
- /* Libical owns this memory, using one of its temporary buffers. */
- obj_string = icalcomponent_as_ical_string (icalcomp);
-
- 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;
- strcpy (error_msg,
- ((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;
- } 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);
- }
- }
-
- CORBA_exception_free (&ev);
-
- return retval;
-}
-
-/**
- * cal_client_get_query:
- * @client: A calendar client.
- * @sexp: S-expression representing the query.
- *
- * Creates a live query object from a loaded calendar.
- *
- * 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)
-{
- CalClientPrivate *priv;
-
- g_return_val_if_fail (client != NULL, NULL);
- g_return_val_if_fail (IS_CAL_CLIENT (client), NULL);
-
- priv = client->priv;
- g_return_val_if_fail (priv->load_state == CAL_CLIENT_LOAD_LOADED, FALSE);
-
- g_return_val_if_fail (sexp != NULL, NULL);
-
- return cal_query_new (priv->cal, sexp);
-}
-
-
-/* This ensures that the given timezone is on the server. We use this to pass
- the default timezone to the server, so it can resolve DATE and floating
- 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)
-{
- CalClientPrivate *priv;
- char *tzid, *obj_string;
- icaltimezone *tmp_zone;
- GString *vcal_string;
- gboolean retval = FALSE;
- icalcomponent *vtimezone_comp;
- char *vtimezone_as_string;
- CORBA_Environment ev;
-
- priv = client->priv;
-
- /* If the zone is NULL or UTC we don't need to do anything. */
- if (!zone)
- return TRUE;
-
- tzid = icaltimezone_get_tzid (zone);
-
- if (!strcmp (tzid, "UTC"))
- return TRUE;
-
- /* See if we already have it in the cache. If we do, it must be on
- the server already. */
- tmp_zone = g_hash_table_lookup (priv->timezones, tzid);
- if (tmp_zone)
- return TRUE;
-
- /* 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, &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;
-}
-
-
-gboolean
-cal_client_set_default_timezone (CalClient *client, icaltimezone *zone)
-{
- CalClientPrivate *priv;
- gboolean retval = FALSE;
- CORBA_Environment ev;
- 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))
- 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);
-
- 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;
- }
-
- retval = TRUE;
-
- priv->default_zone = zone;
-
- out:
-
- CORBA_exception_free (&ev);
- return retval;
-}
-
diff --git a/calendar/cal-client/cal-client.h b/calendar/cal-client/cal-client.h
deleted file mode 100644
index bb1a02e8e6..0000000000
--- a/calendar/cal-client/cal-client.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/* Evolution calendar client
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 CAL_CLIENT_H
-#define CAL_CLIENT_H
-
-#include <libgnome/gnome-defs.h>
-#include <gtk/gtkobject.h>
-#include <cal-util/cal-recur.h>
-#include <cal-util/cal-util.h>
-#include <cal-client/cal-query.h>
-
-BEGIN_GNOME_DECLS
-
-
-
-#define CAL_CLIENT_TYPE (cal_client_get_type ())
-#define CAL_CLIENT(obj) (GTK_CHECK_CAST ((obj), CAL_CLIENT_TYPE, CalClient))
-#define CAL_CLIENT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_CLIENT_TYPE, CalClientClass))
-#define IS_CAL_CLIENT(obj) (GTK_CHECK_TYPE ((obj), CAL_CLIENT_TYPE))
-#define IS_CAL_CLIENT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_CLIENT_TYPE))
-
-typedef struct _CalClient CalClient;
-typedef struct _CalClientClass CalClientClass;
-
-typedef struct _CalClientPrivate CalClientPrivate;
-
-/* Open status for the cal_opened signal */
-typedef enum {
- CAL_CLIENT_OPEN_SUCCESS,
- CAL_CLIENT_OPEN_ERROR,
- CAL_CLIENT_OPEN_NOT_FOUND,
- CAL_CLIENT_OPEN_PERMISSION_DENIED,
- CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED
-} CalClientOpenStatus;
-
-/* Set mode status for the cal_client_set_mode function */
-typedef enum {
- CAL_CLIENT_SET_MODE_SUCCESS,
- CAL_CLIENT_SET_MODE_ERROR,
- CAL_CLIENT_SET_MODE_NOT_SUPPORTED
-} CalClientSetModeStatus;
-
-/* Get status for the cal_client_get_object() function */
-typedef enum {
- CAL_CLIENT_GET_SUCCESS,
- CAL_CLIENT_GET_NOT_FOUND,
- CAL_CLIENT_GET_SYNTAX_ERROR
-} CalClientGetStatus;
-
-/* Status for update_object(s) and remove_object */
-typedef enum {
- CAL_CLIENT_RESULT_SUCCESS,
- CAL_CLIENT_RESULT_CORBA_ERROR,
- CAL_CLIENT_RESULT_INVALID_OBJECT,
- CAL_CLIENT_RESULT_NOT_FOUND,
- 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,
- CAL_CLIENT_LOAD_LOADING,
- CAL_CLIENT_LOAD_LOADED
-} CalClientLoadState;
-
-struct _CalClient {
- GtkObject object;
-
- /* Private data */
- CalClientPrivate *priv;
-};
-
-struct _CalClientClass {
- GtkObjectClass parent_class;
-
- /* 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 (* backend_error) (CalClient *client, const char *message);
-
- void (* categories_changed) (CalClient *client, GPtrArray *categories);
-
- void (* forget_password) (CalClient *client, const char *key);
-
- void (* backend_died) (CalClient *client);
-};
-
-typedef gchar * (* CalClientAuthFunc) (CalClient *client,
- const gchar *prompt,
- const gchar *key,
- gpointer user_data);
-
-GtkType cal_client_get_type (void);
-
-CalClient *cal_client_construct (CalClient *client);
-
-CalClient *cal_client_new (void);
-
-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);
-
-GList *cal_client_uri_list (CalClient *client, CalMode mode);
-
-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_email_address (CalClient *client);
-
-gboolean cal_client_set_mode (CalClient *client, CalMode mode);
-
-int cal_client_get_n_objects (CalClient *client, CalObjType type);
-
-CalClientGetStatus cal_client_get_object (CalClient *client,
- const char *uid,
- CalComponent **comp);
-
-CalClientGetStatus cal_client_get_timezone (CalClient *client,
- const char *tzid,
- icaltimezone **zone);
-
-GList *cal_client_get_uids (CalClient *client, CalObjType type);
-GList *cal_client_get_changes (CalClient *client, CalObjType type, const char *change_id);
-
-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);
-
-void cal_client_generate_instances (CalClient *client, CalObjType type,
- time_t start, time_t end,
- CalRecurInstanceFn cb, gpointer cb_data);
-
-GSList *cal_client_get_alarms_in_range (CalClient *client, time_t start, time_t end);
-
-void cal_client_free_alarms (GSList *comp_alarms);
-
-gboolean cal_client_get_alarms_for_object (CalClient *client, const char *uid,
- time_t start, time_t end,
- CalComponentAlarms **alarms);
-
-/* 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);
-
-/* Add or update multiple objects, possibly including VTIMEZONE data. */
-CalClientResult cal_client_update_objects (CalClient *client, icalcomponent *icalcomp);
-
-CalClientResult cal_client_remove_object (CalClient *client, const char *uid);
-
-CalClientSendResult cal_client_send_object (CalClient *client, icalcomponent *icalcomp,
- icalcomponent **new_icalcomp, GList **users,
- char error_msg[256]);
-
-CalQuery *cal_client_get_query (CalClient *client, const char *sexp);
-
-/* Resolves TZIDs for the recurrence generator. */
-icaltimezone *cal_client_resolve_tzid_cb (const char *tzid, gpointer data);
-
-/* Returns a complete VCALENDAR for a VEVENT/VTODO including all VTIMEZONEs
- used by the component. It also includes a 'METHOD:PUBLISH' property. */
-char* cal_client_get_component_as_string (CalClient *client,
- CalComponent *comp);
-
-
-
-
-END_GNOME_DECLS
-
-#endif
diff --git a/calendar/cal-client/cal-listener.c b/calendar/cal-client/cal-listener.c
deleted file mode 100644
index b96f0848fe..0000000000
--- a/calendar/cal-client/cal-listener.c
+++ /dev/null
@@ -1,398 +0,0 @@
-/* Evolution calendar listener
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 "cal-listener.h"
-
-
-
-/* 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;
-
- /* Whether notification is desired */
- gboolean notify : 1;
-};
-
-
-
-static void cal_listener_class_init (CalListenerClass *class);
-static void cal_listener_init (CalListener *listener);
-static void cal_listener_destroy (GtkObject *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,
- GNOME_Evolution_Calendar_CalObjUID uid,
- CORBA_Environment *ev);
-static void impl_notifyObjRemoved (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_CalObjUID 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 BonoboXObjectClass *parent_class;
-
-
-
-BONOBO_X_TYPE_FUNC_FULL (CalListener,
- GNOME_Evolution_Calendar_Listener,
- BONOBO_X_OBJECT_TYPE,
- cal_listener);
-
-/* Class initialization function for the calendar listener */
-static void
-cal_listener_class_init (CalListenerClass *class)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) class;
-
- parent_class = gtk_type_class (BONOBO_X_OBJECT_TYPE);
-
- class->epv.notifyCalOpened = impl_notifyCalOpened;
- class->epv.notifyCalSetMode = impl_notifyCalSetMode;
- class->epv.notifyObjUpdated = impl_notifyObjUpdated;
- class->epv.notifyObjRemoved = impl_notifyObjRemoved;
- class->epv.notifyErrorOccurred = impl_notifyErrorOccurred;
- class->epv.notifyCategoriesChanged = impl_notifyCategoriesChanged;
-
- object_class->destroy = cal_listener_destroy;
-}
-
-/* Object initialization function for the calendar listener */
-static void
-cal_listener_init (CalListener *listener)
-{
- CalListenerPrivate *priv;
-
- priv = g_new0 (CalListenerPrivate, 1);
- listener->priv = 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->notify = TRUE;
-}
-
-/* Destroy handler for the calendar listener */
-static void
-cal_listener_destroy (GtkObject *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->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;
-
- priv->notify = FALSE;
-
- g_free (priv);
- listener->priv = NULL;
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-
-
-/* CORBA servant implementation */
-
-/* ::notifyCalOpened method */
-static void
-impl_notifyCalOpened (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_OpenStatus status,
- GNOME_Evolution_Calendar_Cal cal,
- 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;
-
- if (!priv->notify)
- return;
-
- CORBA_exception_init (&aev);
- cal_copy = CORBA_Object_duplicate (cal, &aev);
-
- if (aev._major != CORBA_NO_EXCEPTION) {
- g_message ("Listener_notifyCalOpened(): could not duplicate the calendar");
- CORBA_exception_free (&aev);
- return;
- }
- CORBA_exception_free (&aev);
-
- g_assert (priv->cal_opened_fn != NULL);
- (* priv->cal_opened_fn) (listener, status, cal, priv->fn_data);
-}
-
-/* ::notifyCalSetMode method */
-static void
-impl_notifyCalSetMode (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_Listener_SetModeStatus status,
- GNOME_Evolution_Calendar_CalMode mode,
- CORBA_Environment *ev)
-{
- CalListener *listener;
- CalListenerPrivate *priv;
-
- listener = CAL_LISTENER (bonobo_object_from_servant (servant));
- priv = listener->priv;
-
- if (!priv->notify)
- return;
-
- g_assert (priv->cal_set_mode_fn != NULL);
- (* priv->cal_set_mode_fn) (listener, status, mode, priv->fn_data);
-}
-
-/* ::notifyObjUpdated method */
-static void
-impl_notifyObjUpdated (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_CalObjUID uid,
- CORBA_Environment *ev)
-{
- CalListener *listener;
- CalListenerPrivate *priv;
-
- listener = CAL_LISTENER (bonobo_object_from_servant (servant));
- priv = listener->priv;
-
- if (!priv->notify)
- return;
-
- g_assert (priv->obj_updated_fn != NULL);
- (* priv->obj_updated_fn) (listener, uid, priv->fn_data);
-}
-
-/* ::notifyObjRemoved method */
-static void
-impl_notifyObjRemoved (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_CalObjUID uid,
- CORBA_Environment *ev)
-{
- CalListener *listener;
- CalListenerPrivate *priv;
-
- listener = CAL_LISTENER (bonobo_object_from_servant (servant));
- priv = listener->priv;
-
- if (!priv->notify)
- return;
-
- g_assert (priv->obj_removed_fn != NULL);
- (* priv->obj_removed_fn) (listener, uid, priv->fn_data);
-}
-
-/* ::notifyErrorOccurred method */
-static void
-impl_notifyErrorOccurred (PortableServer_Servant servant,
- const CORBA_char *message,
- CORBA_Environment *ev)
-{
- CalListener *listener;
- CalListenerPrivate *priv;
-
- listener = CAL_LISTENER (bonobo_object_from_servant (servant));
- priv = listener->priv;
-
- if (!priv->notify)
- return;
-
- g_assert (priv->error_occurred_fn != NULL);
- (* priv->error_occurred_fn) (listener, message, priv->fn_data);
-}
-
-/* ::notifyCategoriesChanged method */
-static void
-impl_notifyCategoriesChanged (PortableServer_Servant servant,
- const GNOME_Evolution_Calendar_StringSeq *categories,
- CORBA_Environment *ev)
-{
- CalListener *listener;
- CalListenerPrivate *priv;
-
- listener = CAL_LISTENER (bonobo_object_from_servant (servant));
- priv = listener->priv;
-
- if (!priv->notify)
- return;
-
- g_assert (priv->categories_changed_fn != NULL);
- (* priv->categories_changed_fn) (listener, categories, priv->fn_data);
-}
-
-
-
-/**
- * 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.
- * @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.
- * @fn_data: Closure data pointer that will be passed to the notification
- * functions.
- *
- * Constructs a calendar listener by setting the callbacks that it will use for
- * notification from the calendar server.
- *
- * Return value: the same object as the @listener argument.
- **/
-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)
-{
- CalListenerPrivate *priv;
-
- 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;
-
- return 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.
- * @fn_data: Closure data pointer that will be passed to the notification
- * functions.
- *
- * Creates a new #CalListener object.
- *
- * 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,
- 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 = gtk_type_new (CAL_LISTENER_TYPE);
- 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);
-}
-
-/**
- * cal_listener_stop_notification:
- * @listener: A calendar listener.
- *
- * Informs a calendar 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
-cal_listener_stop_notification (CalListener *listener)
-{
- CalListenerPrivate *priv;
-
- g_return_if_fail (listener != NULL);
- g_return_if_fail (IS_CAL_LISTENER (listener));
-
- priv = listener->priv;
- g_return_if_fail (priv->notify != FALSE);
-
- priv->notify = FALSE;
-}
diff --git a/calendar/cal-client/cal-listener.h b/calendar/cal-client/cal-listener.h
deleted file mode 100644
index 4d557a1fbc..0000000000
--- a/calendar/cal-client/cal-listener.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* Evolution calendar listener
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 CAL_LISTENER_H
-#define CAL_LISTENER_H
-
-#include <libgnome/gnome-defs.h>
-#include <bonobo/bonobo-xobject.h>
-#include "evolution-calendar.h"
-
-BEGIN_GNOME_DECLS
-
-
-
-#define CAL_LISTENER_TYPE (cal_listener_get_type ())
-#define CAL_LISTENER(obj) (GTK_CHECK_CAST ((obj), CAL_LISTENER_TYPE, CalListener))
-#define CAL_LISTENER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_LISTENER_TYPE, \
- CalListenerClass))
-#define IS_CAL_LISTENER(obj) (GTK_CHECK_TYPE ((obj), CAL_LISTENER_TYPE))
-#define IS_CAL_LISTENER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_LISTENER_TYPE))
-
-typedef struct CalListenerPrivate CalListenerPrivate;
-
-typedef struct {
- BonoboXObject xobject;
-
- /* Private data */
- CalListenerPrivate *priv;
-} CalListener;
-
-typedef struct {
- BonoboXObjectClass parent_class;
-
- POA_GNOME_Evolution_Calendar_Listener__epv epv;
-} 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 GNOME_Evolution_Calendar_CalObjUID uid,
- gpointer data);
-typedef void (* CalListenerObjRemovedFn) (CalListener *listener,
- const GNOME_Evolution_Calendar_CalObjUID uid,
- gpointer data);
-
-typedef void (* CalListenerErrorOccurredFn) (CalListener *listener,
- const char *message,
- gpointer data);
-
-typedef void (* CalListenerCategoriesChangedFn) (CalListener *listener,
- const GNOME_Evolution_Calendar_StringSeq *categories,
- gpointer data);
-
-
-GtkType 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,
- CalListenerErrorOccurredFn error_occurred_fn,
- CalListenerCategoriesChangedFn categories_changed_fn,
- gpointer fn_data);
-
-void cal_listener_stop_notification (CalListener *listener);
-
-
-
-END_GNOME_DECLS
-
-#endif
diff --git a/calendar/cal-client/cal-query.c b/calendar/cal-client/cal-query.c
deleted file mode 100644
index 80ffe5c845..0000000000
--- a/calendar/cal-client/cal-query.c
+++ /dev/null
@@ -1,411 +0,0 @@
-/* Evolution calendar - Live query client object
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtksignal.h>
-#include <bonobo/bonobo-exception.h>
-#include "cal-query.h"
-#include "query-listener.h"
-
-
-
-/* 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;
-};
-
-
-
-static void cal_query_class_init (CalQueryClass *class);
-static void cal_query_init (CalQuery *query);
-static void cal_query_destroy (GtkObject *object);
-
-/* Signal IDs */
-enum {
- OBJ_UPDATED,
- OBJ_REMOVED,
- QUERY_DONE,
- EVAL_ERROR,
- LAST_SIGNAL
-};
-
-static void marshal_obj_updated (GtkObject *object,
- GtkSignalFunc func, gpointer func_data,
- GtkArg *args);
-static void marshal_query_done (GtkObject *object,
- GtkSignalFunc func, gpointer func_data,
- GtkArg *args);
-
-static guint query_signals[LAST_SIGNAL];
-
-static GtkObjectClass *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.
- **/
-GtkType
-cal_query_get_type (void)
-{
- static GtkType cal_query_type = 0;
-
- if (!cal_query_type) {
- static const GtkTypeInfo cal_query_info = {
- "CalQuery",
- sizeof (CalQuery),
- sizeof (CalQueryClass),
- (GtkClassInitFunc) cal_query_class_init,
- (GtkObjectInitFunc) cal_query_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- cal_query_type = gtk_type_unique (GTK_TYPE_OBJECT, &cal_query_info);
- }
-
- return cal_query_type;
-}
-
-/* Class initialization function for the calendar query */
-static void
-cal_query_class_init (CalQueryClass *class)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) class;
-
- parent_class = gtk_type_class (GTK_TYPE_OBJECT);
-
- query_signals[OBJ_UPDATED] =
- gtk_signal_new ("obj_updated",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalQueryClass, obj_updated),
- marshal_obj_updated,
- GTK_TYPE_NONE, 4,
- GTK_TYPE_STRING,
- GTK_TYPE_BOOL,
- GTK_TYPE_INT,
- GTK_TYPE_INT);
- query_signals[OBJ_REMOVED] =
- gtk_signal_new ("obj_removed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalQueryClass, obj_removed),
- gtk_marshal_NONE__STRING,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_STRING);
- query_signals[QUERY_DONE] =
- gtk_signal_new ("query_done",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalQueryClass, query_done),
- marshal_query_done,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_ENUM,
- GTK_TYPE_STRING);
- query_signals[EVAL_ERROR] =
- gtk_signal_new ("eval_error",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalQueryClass, eval_error),
- gtk_marshal_NONE__STRING,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_STRING);
-
- gtk_object_class_add_signals (object_class, query_signals, LAST_SIGNAL);
-
- class->obj_updated = NULL;
- class->obj_removed = NULL;
- class->query_done = NULL;
- class->eval_error = NULL;
-
- object_class->destroy = cal_query_destroy;
-}
-
-/* Object initialization function for the calendar query */
-static void
-cal_query_init (CalQuery *query)
-{
- CalQueryPrivate *priv;
-
- priv = g_new0 (CalQueryPrivate, 1);
- query->priv = priv;
-
- priv->ql = NULL;
- priv->corba_query = CORBA_OBJECT_NIL;
-}
-
-/* Destroy handler for the calendar query */
-static void
-cal_query_destroy (GtkObject *object)
-{
- 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;
- }
-
- g_free (priv);
- query->priv = NULL;
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-
-
-/* Marshalers */
-
-typedef void (* ObjUpdatedFunc) (CalQuery *query, const char *uid,
- gboolean query_in_progress, int n_scanned, int total,
- gpointer data);
-
-static void
-marshal_obj_updated (GtkObject *object, GtkSignalFunc func, gpointer func_data, GtkArg *args)
-{
- ObjUpdatedFunc f;
-
- f = (ObjUpdatedFunc) func;
-
- (* f) (CAL_QUERY (object), GTK_VALUE_STRING (args[0]),
- GTK_VALUE_BOOL (args[1]), GTK_VALUE_INT (args[2]), GTK_VALUE_INT (args[3]),
- func_data);
-}
-
-typedef void (* QueryDoneFunc) (CalQuery *query, CalQueryDoneStatus status, const char *error_str,
- gpointer data);
-
-static void
-marshal_query_done (GtkObject *object, GtkSignalFunc func, gpointer func_data, GtkArg *args)
-{
- QueryDoneFunc f;
-
- f = (QueryDoneFunc) func;
-
- (* f) (CAL_QUERY (object), GTK_VALUE_ENUM (args[0]), GTK_VALUE_STRING (args[1]),
- func_data);
-}
-
-
-
-/* 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)
-{
- CalQuery *query;
- int n;
-
- query = CAL_QUERY (data);
-
- for (n = 0; n < uids->_length; n++) {
- gtk_signal_emit (GTK_OBJECT (query), query_signals[OBJ_UPDATED],
- uids->_buffer[n], query_in_progress,
- (int) n_scanned, (int) total);
- }
-}
-
-/* Callback used when an object is removed from the query */
-static void
-obj_removed_cb (QueryListener *ql,
- const GNOME_Evolution_Calendar_CalObjUID uid,
- gpointer data)
-{
- CalQuery *query;
-
- query = CAL_QUERY (data);
-
- gtk_signal_emit (GTK_OBJECT (query), query_signals[OBJ_REMOVED],
- uid);
-}
-
-/* Callback used when the query terminates */
-static void
-query_done_cb (QueryListener *ql,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status,
- const CORBA_char *error_str,
- gpointer data)
-{
- CalQuery *query;
- CalQueryDoneStatus status;
-
- query = CAL_QUERY (data);
-
- switch (corba_status) {
- case GNOME_Evolution_Calendar_QueryListener_SUCCESS:
- status = CAL_QUERY_DONE_SUCCESS;
- break;
-
- case GNOME_Evolution_Calendar_QueryListener_PARSE_ERROR:
- status = CAL_QUERY_DONE_PARSE_ERROR;
- break;
-
- default:
- g_assert_not_reached ();
- return;
- }
-
- gtk_signal_emit (GTK_OBJECT (query), query_signals[QUERY_DONE],
- status, error_str);
-}
-
-/* Callback used when an error occurs when evaluating the query */
-static void
-eval_error_cb (QueryListener *ql,
- const CORBA_char *error_str,
- gpointer data)
-{
- CalQuery *query;
-
- query = CAL_QUERY (data);
-
- gtk_signal_emit (GTK_OBJECT (query), query_signals[EVAL_ERROR],
- error_str);
-}
-
-/**
- * cal_query_construct:
- * @query: A calendar query.
- * @cal: Handle to an open calendar.
- * @sexp: S-expression that defines the query.
- *
- * Constructs a query object by issuing the query creation request to the
- * calendar server.
- *
- * Return value: The same value as @query on success, or NULL if the request
- * failed.
- **/
-CalQuery *
-cal_query_construct (CalQuery *query,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp)
-{
- 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;
- }
-
- 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;
- }
-
- 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;
-}
-
-/**
- * cal_query_new:
- * @cal: Handle to an open calendar.
- * @sexp: S-expression that defines the query.
- *
- * Creates a new query object by issuing the query creation request to the
- * calendar server.
- *
- * Return value: A newly-created query object, or NULL if the request failed.
- **/
-CalQuery *
-cal_query_new (GNOME_Evolution_Calendar_Cal cal,
- const char *sexp)
-{
- CalQuery *query;
-
- query = gtk_type_new (CAL_QUERY_TYPE);
-
- if (!cal_query_construct (query, cal, sexp)) {
- gtk_object_unref (GTK_OBJECT (query));
- return NULL;
- }
-
- return query;
-}
diff --git a/calendar/cal-client/cal-query.h b/calendar/cal-client/cal-query.h
deleted file mode 100644
index 5af5f3864d..0000000000
--- a/calendar/cal-client/cal-query.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Evolution calendar - Live query client object
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 CAL_QUERY_H
-#define CAL_QUERY_H
-
-#include <libgnome/gnome-defs.h>
-#include <gtk/gtkobject.h>
-
-#include "evolution-calendar.h"
-
-BEGIN_GNOME_DECLS
-
-
-
-#define CAL_QUERY_TYPE (cal_query_get_type ())
-#define CAL_QUERY(obj) (GTK_CHECK_CAST ((obj), CAL_QUERY_TYPE, CalQuery))
-#define CAL_QUERY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_QUERY_TYPE, CalQueryClass))
-#define IS_CAL_QUERY(obj) (GTK_CHECK_TYPE ((obj), CAL_QUERY_TYPE))
-#define IS_CAL_QUERY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_QUERY_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 {
- GtkObject object;
-
- /* Private data */
- CalQueryPrivate *priv;
-} CalQuery;
-
-typedef struct {
- GtkObjectClass 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);
-} CalQueryClass;
-
-GtkType cal_query_get_type (void);
-
-CalQuery *cal_query_construct (CalQuery *query,
- GNOME_Evolution_Calendar_Cal cal,
- const char *sexp);
-
-CalQuery *cal_query_new (GNOME_Evolution_Calendar_Cal cal,
- const char *sexp);
-
-
-
-END_GNOME_DECLS
-
-#endif
diff --git a/calendar/cal-client/client-test.c b/calendar/cal-client/client-test.c
deleted file mode 100644
index 56651566eb..0000000000
--- a/calendar/cal-client/client-test.c
+++ /dev/null
@@ -1,239 +0,0 @@
-/* Evolution calendar client - test program
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 <stdlib.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtksignal.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-init.h>
-#include <liboaf/liboaf.h>
-#include <bonobo/bonobo-main.h>
-#include "cal-client.h"
-#include "cal-util/cal-component.h"
-
-static CalClient *client1;
-static CalClient *client2;
-
-/* Prints a message with a client identifier */
-static void
-cl_printf (CalClient *client, const char *format, ...)
-{
- va_list args;
-
- va_start (args, format);
- printf ("Client %s: ",
- client == client1 ? "1" :
- client == client2 ? "2" :
- "UNKNOWN");
- vprintf (format, args);
- va_end (args);
-}
-
-/* Dumps some interesting data from a component */
-static void
-dump_component (CalComponent *comp)
-{
- const char *uid;
- CalComponentText summary;
-
- cal_component_get_uid (comp, &uid);
-
- printf ("UID %s\n", uid);
-
- 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");
-}
-
-/* Lists the UIDs of objects in a calendar, called as an idle handler */
-static gboolean
-list_uids (gpointer data)
-{
- CalClient *client;
- GList *uids;
- GList *l;
-
- client = CAL_CLIENT (data);
-
- uids = cal_client_get_uids (client, CALOBJ_TYPE_ANY);
-
- cl_printf (client, "UIDs: ");
-
- if (!uids)
- printf ("none\n");
- else {
- for (l = uids; l; l = l->next) {
- char *uid;
-
- 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");
- gtk_object_unref (GTK_OBJECT (comp));
- } else {
- printf ("FAILED: %d\n", status);
- }
- }
- }
-
- cal_obj_uid_list_free (uids);
-
- gtk_object_unref (GTK_OBJECT (client));
-
- return FALSE;
-}
-
-/* Callback used when a calendar is opened */
-static void
-cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
-{
- cl_printf (client, "Load/create %s\n",
- ((status == CAL_CLIENT_OPEN_SUCCESS) ? "success" :
- (status == CAL_CLIENT_OPEN_ERROR) ? "error" :
- (status == CAL_CLIENT_OPEN_NOT_FOUND) ? "not found" :
- (status == CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED) ? "method not supported" :
- "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));
- gtk_object_unref (GTK_OBJECT (l->data));
- cl_printf (client, "Free/Busy -> %s\n", comp_str);
- g_free (comp_str);
- }
- g_list_free (comp_list);
- }
-
- g_idle_add (list_uids, client);
- }
- else
- gtk_object_unref (GTK_OBJECT (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 (GtkObject *object, gpointer data)
-{
- if (CAL_CLIENT (object) == client1)
- client1 = NULL;
- else if (CAL_CLIENT (object) == client2)
- client2 = NULL;
- else
- g_assert_not_reached ();
-
- if (!client1 && !client2)
- gtk_main_quit ();
-}
-
-/* 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)
-{
- gboolean result;
-
- *client = cal_client_new ();
- if (!*client) {
- g_message ("create_client(): could not create the client");
- exit (1);
- }
-
- gtk_signal_connect (GTK_OBJECT (*client), "destroy",
- client_destroy_cb,
- NULL);
-
- gtk_signal_connect (GTK_OBJECT (*client), "cal_opened",
- GTK_SIGNAL_FUNC (cal_opened_cb),
- NULL);
- gtk_signal_connect (GTK_OBJECT (*client), "obj_updated",
- GTK_SIGNAL_FUNC (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'",
- uri);
- exit (1);
- }
-}
-
-int
-main (int argc, char **argv)
-{
- char *dir;
-
- bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);
-
- gnome_init ("tl-test", VERSION, argc, argv);
- oaf_init (argc, argv);
-
- if (!bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL)) {
- g_message ("main(): could not initialize Bonobo");
- 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);
-
- bonobo_main ();
- return 0;
-}
diff --git a/calendar/cal-client/query-listener.c b/calendar/cal-client/query-listener.c
deleted file mode 100644
index ab02f2faca..0000000000
--- a/calendar/cal-client/query-listener.c
+++ /dev/null
@@ -1,321 +0,0 @@
-/* Evolution calendar - Live search query listener convenience object
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "query-listener.h"
-
-
-
-/* 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;
-};
-
-
-
-static void query_listener_class_init (QueryListenerClass *class);
-static void query_listener_init (QueryListener *ql);
-static void query_listener_destroy (GtkObject *object);
-
-static void impl_notifyObjUpdated (PortableServer_Servant servant,
- 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,
- GNOME_Evolution_Calendar_CalObjUID 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);
-
-static void impl_notifyEvalError (PortableServer_Servant servant,
- const CORBA_char *error_str,
- CORBA_Environment *ev);
-
-static BonoboXObjectClass *parent_class;
-
-
-
-BONOBO_X_TYPE_FUNC_FULL (QueryListener,
- GNOME_Evolution_Calendar_QueryListener,
- BONOBO_X_OBJECT_TYPE,
- query_listener);
-
-/* Class initialization function for the live search query listener */
-static void
-query_listener_class_init (QueryListenerClass *class)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) class;
-
- parent_class = gtk_type_class (BONOBO_X_OBJECT_TYPE);
-
- object_class->destroy = query_listener_destroy;
-
- class->epv.notifyObjUpdated = impl_notifyObjUpdated;
- class->epv.notifyObjRemoved = impl_notifyObjRemoved;
- class->epv.notifyQueryDone = impl_notifyQueryDone;
- class->epv.notifyEvalError = impl_notifyEvalError;
-}
-
-/* Object initialization function for the live search query listener */
-static void
-query_listener_init (QueryListener *ql)
-{
- QueryListenerPrivate *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;
-
- priv->notify = TRUE;
-}
-
-/* Destroy handler for the live search query listener */
-static void
-query_listener_destroy (GtkObject *object)
-{
- QueryListener *ql;
- QueryListenerPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_QUERY_LISTENER (object));
-
- ql = QUERY_LISTENER (object);
- 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;
-
- g_free (priv);
- ql->priv = NULL;
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-
-
-/* CORBA method implementations */
-
-/* ::notifyObjUpdated() method */
-static void
-impl_notifyObjUpdated (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_CalObjUIDSeq *uids,
- CORBA_boolean query_in_progress,
- CORBA_long n_scanned,
- CORBA_long total,
- 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_updated_fn != NULL);
- (* priv->obj_updated_fn) (ql, uids, query_in_progress, n_scanned, total, priv->fn_data);
-}
-
-/* ::notifyObjRemoved() method */
-static void
-impl_notifyObjRemoved (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_CalObjUID uid,
- 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);
-}
-
-/* ::notifyQueryDone() method */
-static void
-impl_notifyQueryDone (PortableServer_Servant servant,
- GNOME_Evolution_Calendar_QueryListener_QueryDoneStatus corba_status,
- const CORBA_char *error_str,
- 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->query_done_fn != NULL);
- (* priv->query_done_fn) (ql, corba_status, error_str, priv->fn_data);
-}
-
-/* ::notifyEvalError() method */
-static void
-impl_notifyEvalError (PortableServer_Servant servant,
- const CORBA_char *error_str,
- 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->eval_error_fn != NULL);
- (* priv->eval_error_fn) (ql, error_str, priv->fn_data);
-}
-
-
-
-/**
- * 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)
-{
- QueryListenerPrivate *priv;
-
- 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);
-
- priv = ql->priv;
-
- 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;
-
- return ql;
-}
-
-/**
- * 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.
- **/
-QueryListener *
-query_listener_new (QueryListenerObjUpdatedFn obj_updated_fn,
- QueryListenerObjRemovedFn obj_removed_fn,
- QueryListenerQueryDoneFn query_done_fn,
- QueryListenerEvalErrorFn eval_error_fn,
- gpointer fn_data)
-{
- QueryListener *ql;
-
- ql = gtk_type_new (QUERY_LISTENER_TYPE);
-
- 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;
-}
diff --git a/calendar/cal-client/query-listener.h b/calendar/cal-client/query-listener.h
deleted file mode 100644
index 65cc9fbad4..0000000000
--- a/calendar/cal-client/query-listener.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Evolution calendar - Live search query listener implementation
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 QUERY_LISTENER_H
-#define QUERY_LISTENER_H
-
-#include <bonobo/bonobo-xobject.h>
-#include "evolution-calendar.h"
-
-BEGIN_GNOME_DECLS
-
-
-
-#define QUERY_LISTENER_TYPE (query_listener_get_type ())
-#define QUERY_LISTENER(obj) (GTK_CHECK_CAST ((obj), QUERY_LISTENER_TYPE, QueryListener))
-#define QUERY_LISTENER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), QUERY_LISTENER_TYPE, \
- QueryListenerClass))
-#define IS_QUERY_LISTENER(obj) (GTK_CHECK_TYPE ((obj), QUERY_LISTENER_TYPE))
-#define IS_QUERY_LISTENER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), QUERY_LISTENER_TYPE))
-
-typedef struct _QueryListenerPrivate QueryListenerPrivate;
-
-typedef struct {
- BonoboXObject xobject;
-
- /* Private data */
- QueryListenerPrivate *priv;
-} QueryListener;
-
-typedef struct {
- BonoboXObjectClass parent_class;
-
- POA_GNOME_Evolution_Calendar_QueryListener__epv epv;
-} 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 GNOME_Evolution_Calendar_CalObjUID 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);
-
-GtkType 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);
-
-
-
-END_GNOME_DECLS
-
-#endif
diff --git a/calendar/cal-client/test.ics b/calendar/cal-client/test.ics
deleted file mode 100644
index 128251ee11..0000000000
--- a/calendar/cal-client/test.ics
+++ /dev/null
@@ -1,318 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//hacksw/handcal//NONSGML v1.0//EN
-
-BEGIN:VEVENT
-DTSTART:19970714T170000Z
-DTEND:19970715T035959Z
-SUMMARY:Bastille Day Party
-END:VEVENT
-
-BEGIN:VEVENT
-UID:19970901T130000Z-123401@host.com
-DTSTAMP:19970901T1300Z
-DTSTART:19970903T163000Z
-DTEND:19970903T190000Z
-SUMMARY:Annual Employee Review
-CLASS:PRIVATE
-CATEGORIES:BUSINESS,HUMAN RESOURCES
-END:VEVENT
-
-BEGIN:VEVENT
-UID:19970901T130000Z-123402@host.com
-DTSTAMP:19970901T1300Z
-DTSTART:19970401T163000Z
-DTEND:19970402T010000Z
-SUMMARY:Laurel is in sensitivity awareness class.
-CLASS:PUBLIC
-CATEGORIES:BUSINESS,HUMAN RESOURCES
-TRANSP:TRANSPARENT
-END:VEVENT
-
-BEGIN:VEVENT
-UID:19970901T130000Z-123403@host.com
-DTSTAMP:19970901T1300Z
-DTSTART:19971102
-SUMMARY:Our Blissful Anniversary
-CLASS:CONFIDENTIAL
-CATEGORIES:ANNIVERSARY,PERSONAL,SPECIAL OCCASION
-RRULE:FREQ=YEARLY
-END:VEVENT
-
-BEGIN:VTODO
-UID:19970901T130000Z-123404@host.com
-DTSTAMP:19970901T1300Z
-DTSTART:19970415T133000Z
-DUE:19970416T045959Z
-SUMMARY:1996 Income Tax Preparation
-CLASS:CONFIDENTIAL
-CATEGORIES:FAMILY,FINANCE
-PRIORITY:1
-STATUS:NEEDS-ACTION
-END:VTODO
-
-BEGIN:VJOURNAL
-UID:19970901T130000Z-123405@host.com
-DTSTAMP:19970901T1300Z
-DTSTART;VALUE=DATE:19970317
-SUMMARY:Staff meeting minutes
-DESCRIPTION:1. Staff meeting: Participants include Joe\, Lisa
- and Bob. Aurora project plans were reviewed. There is currently
- no budget reserves for this project. Lisa will escalate to
- management. Next meeting on Tuesday.\n
- 2. Telephone Conference: ABC Corp. sales representative called
- to discuss new printer. Promised to get us a demo by Friday.\n
- 3. Henry Miller (Handsoff Insurance): Car was totaled by tree.
- Is looking into a loaner car. 654-2323 (tel).
-END:VJOURNAL
-
-BEGIN:VFREEBUSY
-ORGANIZER:MAILTO:jane_doe@host1.com
-ATTENDEE:MAILTO:john_public@host2.com
-DTSTART:19971015T050000Z
-DTEND:19971016T050000Z
-DTSTAMP:19970901T083000Z
-END:VFREEBUSY
-
-BEGIN:VFREEBUSY
-ORGANIZER:MAILTO:jane_doe@host1.com
-ATTENDEE:MAILTO:john_public@host2.com
-DTSTAMP:19970901T100000Z
-FREEBUSY;VALUE=PERIOD:19971015T050000Z/PT8H30M,
- 19971015T160000Z/PT5H30M,19971015T223000Z/PT6H30M
-URL:http://host2.com/pub/busy/jpublic-01.ifb
-COMMENT:This iCalendar file contains busy time information for
- the next three months.
-END:VFREEBUSY
-
-BEGIN:VFREEBUSY
-ORGANIZER:jsmith@host.com
-DTSTART:19980313T141711Z
-DTEND:19980410T141711Z
-FREEBUSY:19980314T233000Z/19980315T003000Z
-FREEBUSY:19980316T153000Z/19980316T163000Z
-FREEBUSY:19980318T030000Z/19980318T040000Z
-URL:http://www.host.com/calendar/busytime/jsmith.ifb
-END:VFREEBUSY
-
-BEGIN:VTIMEZONE
-TZID:US-Eastern
-LAST-MODIFIED:19870101T000000Z
-BEGIN:STANDARD
-DTSTART:19971026T020000
-RDATE:19971026T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-TZNAME:EST
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:19971026T020000
-RDATE:19970406T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-TZNAME:EDT
-END:DAYLIGHT
-END:VTIMEZONE
-
-BEGIN:VTIMEZONE
-TZID:US-Eastern
-LAST-MODIFIED:19870101T000000Z
-TZURL:http://zones.stds_r_us.net/tz/US-Eastern
-BEGIN:STANDARD
-DTSTART:19671029T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-TZNAME:EST
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:19870405T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-TZNAME:EDT
-END:DAYLIGHT
-END:VTIMEZONE
-
-BEGIN:VTIMEZONE
-TZID:US--Fictitious-Eastern
-LAST-MODIFIED:19870101T000000Z
-BEGIN:STANDARD
-DTSTART:19671029T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-TZNAME:EST
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:19870405T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-TZNAME:EDT
-END:DAYLIGHT
-END:VTIMEZONE
-
-BEGIN:VTIMEZONE
-TZID:US--Fictitious-Eastern
-LAST-MODIFIED:19870101T000000Z
-BEGIN:STANDARD
-DTSTART:19671029T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-TZNAME:EST
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:19870405T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-TZNAME:EDT
-END:DAYLIGHT
-BEGIN:DAYLIGHT
-DTSTART:19990424T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=4
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-TZNAME:EDT
-END:DAYLIGHT
-END:VTIMEZONE
-
-BEGIN:VALARM
-TRIGGER;VALUE=DATE-TIME:19970317T133000Z
-REPEAT:4
-DURATION:PT15M
-ACTION:AUDIO
-ATTACH;FMTTYPE=audio/basic:ftp://host.com/pub/sounds/bell-01.aud
-END:VALARM
-BEGIN:VALARM
-TRIGGER:-PT30M
-REPEAT:2
-DURATION:PT15M
-ACTION:DISPLAY
-DESCRIPTION:Breakfast meeting with executive\n
- team at 8:30 AM EST.
-END:VALARM
-
-BEGIN:VALARM
-TRIGGER:-P2D
-ACTION:EMAIL
-ATTENDEE:MAILTO:john_doe@host.com
-SUMMARY:*** REMINDER: SEND AGENDA FOR WEEKLY STAFF MEETING ***
-DESCRIPTION:A draft agenda needs to be sent out to the attendees
- to the weekly managers meeting (MGR-LIST). Attached is a
- pointer the document template for the agenda file.
-ATTACH;FMTTYPE=application/binary:http://host.com/templates/agen
- da.doc
-END:VALARM
-
-BEGIN:VALARM
-TRIGGER;VALUE=DATE-TIME:19980101T050000Z
-REPEAT:23
-DURATION:PT1H
-ACTION:PROCEDURE
-ATTACH;FMTTYPE=application/binary:ftp://host.com/novo-
- procs/felizano.exe
-END:VALARM
-
-BEGIN:VTIMEZONE
-TZID:US-Eastern
-BEGIN:STANDARD
-DTSTART:19981025T020000
-RDATE:19981025T020000
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-TZNAME:EST
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:19990404T020000
-RDATE:19990404T020000
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-TZNAME:EDT
-END:DAYLIGHT
-END:VTIMEZONE
-
-BEGIN:VEVENT
-DTSTAMP:19980309T231000Z
-UID:guid-1.host1.com
-ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com
-ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP:
- MAILTO:employee-A@host.com
-DESCRIPTION:Project XYZ Review Meeting
-CATEGORIES:MEETING
-CLASS:PUBLIC
-CREATED:19980309T130000Z
-SUMMARY:XYZ Project Review
-DTSTART;TZID=US-Eastern:19980312T083000
-DTEND;TZID=US-Eastern:19980312T093000
-LOCATION:1CP Conference Room 4350
-END:VEVENT
-
-BEGIN:VEVENT
-DTSTAMP:19970324T1200Z
-SEQUENCE:0
-UID:uid3@host1.com
-ORGANIZER:MAILTO:jdoe@host1.com
-DTSTART:19970324T123000Z
-DTEND:19970324T210000Z
-CATEGORIES:MEETING,PROJECT
-CLASS:PUBLIC
-SUMMARY:Calendaring Interoperability Planning Meeting
-DESCRIPTION:Discuss how we can test c&s interoperability\n
- using iCalendar and other IETF standards.
-LOCATION:LDB Lobby
-ATTACH;FMTTYPE=application/postscript:ftp://xyzCorp.com/pub/
- conf/bkgrnd.ps
-END:VEVENT
-
-BEGIN:VTODO
-DTSTAMP:19980130T134500Z
-SEQUENCE:2
-UID:uid4@host1.com
-ORGANIZER:MAILTO:unclesam@us.gov
-ATTENDEE;PARTSTAT=ACCEPTED:MAILTO:jqpublic@host.com
-DUE:19980415T235959
-STATUS:NEEDS-ACTION
-SUMMARY:Submit Income Taxes
-BEGIN:VALARM
-ACTION:AUDIO
-TRIGGER:19980403T120000
-ATTACH;FMTTYPE=audio/basic:http://host.com/pub/audio-
- files/ssbanner.aud
-REPEAT:4
-DURATION:PT1H
-END:VALARM
-END:VTODO
-
-BEGIN:VJOURNAL
-DTSTAMP:19970324T120000Z
-UID:uid5@host1.com
-ORGANIZER:MAILTO:jsmith@host.com
-STATUS:DRAFT
-CLASS:PUBLIC
-CATEGORIES:Project Report, XYZ, Weekly Meeting
-DESCRIPTION:Project xyz Review Meeting Minutes\n
- Agenda\n1. Review of project version 1.0 requirements.\n2.
- Definition
- of project processes.\n3. Review of project schedule.\n
- Participants: John Smith\, Jane Doe\, Jim Dandy\n-It was
- decided that the requirements need to be signed off by
- product marketing.\n-Project processes were accepted.\n
- -Project schedule needs to account for scheduled holidays
- and employee vacation time. Check with HR for specific
- dates.\n-New schedule will be distributed by Friday.\n-
- Next weeks meeting is cancelled. No meeting until 3/23.
-END:VJOURNAL
-
-BEGIN:VFREEBUSY
-ORGANIZER:MAILTO:jsmith@host.com
-DTSTART:19980313T141711Z
-DTEND:19980410T141711Z
-FREEBUSY:19980314T233000Z/19980315T003000Z
-FREEBUSY:19980316T153000Z/19980316T163000Z
-FREEBUSY:19980318T030000Z/19980318T040000Z
-URL:http://www.host.com/calendar/busytime/jsmith.ifb
-END:VFREEBUSY
-END:VCALENDAR
diff --git a/calendar/cal-util/.cvsignore b/calendar/cal-util/.cvsignore
deleted file mode 100644
index 9f93120f8a..0000000000
--- a/calendar/cal-util/.cvsignore
+++ /dev/null
@@ -1,7 +0,0 @@
-.libs
-Makefile.in
-Makefile
-.deps
-*.lo
-*.la
-test-recur
diff --git a/calendar/cal-util/Makefile.am b/calendar/cal-util/Makefile.am
deleted file mode 100644
index 40ad034cf8..0000000000
--- a/calendar/cal-util/Makefile.am
+++ /dev/null
@@ -1,50 +0,0 @@
-noinst_PROGRAMS = test-recur
-
-INCLUDES = \
- -DGNOMELOCALEDIR=\""$(localedir)"\" \
- -DG_LOG_DOMAIN=\"cal-util\" \
- -I$(top_srcdir) \
- -I$(top_srcdir)/calendar \
- -I. \
- -I.. \
- -I$(top_builddir) \
- -I$(top_srcdir)/libical/src/libical \
- -I$(top_builddir)/libical/src/libical \
- $(EVOLUTION_CALENDAR_CFLAGS)
-
-#
-# cal util library
-#
-
-lib_LTLIBRARIES = libcal-util.la
-privlib_LTLIBRARIES = libcal-util-static.la
-
-libcal_util_la_SOURCES = \
- cal-component.c \
- cal-recur.c \
- cal-util.c \
- timeutil.c
-
-libcal_utilincludedir = $(includedir)/evolution/cal-util
-
-libcal_utilinclude_HEADERS = \
- cal-component.h \
- cal-recur.h \
- cal-util.h \
- timeutil.h
-
-#
-# static library for use in conduits' shared libraries
-#
-#lib_LTLIBRARIES = libcal-util-static.la
-libcal_util_static_la_SOURCES = $(libcal_util_la_SOURCES)
-libcal_util_static_la_LDFLAGS = -all-static
-
-test_recur_SOURCES = \
- test-recur.c
-
-test_recur_LDADD = \
- libcal-util.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/libical/src/libical/libical-evolution.la \
- $(EVOLUTION_CALENDAR_LIBS)
diff --git a/calendar/cal-util/cal-component.c b/calendar/cal-util/cal-component.c
deleted file mode 100644
index b91d4b26ad..0000000000
--- a/calendar/cal-util/cal-component.c
+++ /dev/null
@@ -1,5254 +0,0 @@
-/* Evolution calendar - iCalendar component object
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include "cal-component.h"
-#include "timeutil.h"
-
-
-
-/* Extension property for alarm components so that we can reference them by UID */
-#define EVOLUTION_ALARM_UID_PROPERTY "X-EVOLUTION-ALARM-UID"
-
-/* Private part of the CalComponent structure */
-struct _CalComponentPrivate {
- /* The icalcomponent we wrap */
- icalcomponent *icalcomp;
-
- /* Properties */
-
- icalproperty *uid;
-
- icalproperty *status;
-
- struct attendee {
- icalproperty *prop;
- icalparameter *cutype_param;
- icalparameter *member_param;
- icalparameter *role_param;
- icalparameter *partstat_param;
- icalparameter *rsvp_param;
- icalparameter *delto_param;
- icalparameter *delfrom_param;
- icalparameter *sentby_param;
- icalparameter *cn_param;
- icalparameter *language_param;
- };
-
- GSList *attendee_list;
-
- icalproperty *categories;
-
- icalproperty *classification;
-
- struct text {
- icalproperty *prop;
- icalparameter *altrep_param;
- };
-
- GSList *comment_list; /* list of struct text */
-
- icalproperty *completed;
-
- GSList *contact_list; /* list of struct text */
-
- icalproperty *created;
-
- GSList *description_list; /* list of struct text */
-
- struct datetime {
- icalproperty *prop;
- icalparameter *tzid_param;
- };
-
- struct datetime dtstart;
- struct datetime dtend;
-
- icalproperty *dtstamp;
-
- /* The DURATION property can be used instead of the VEVENT DTEND or
- the VTODO DUE dates. We do not use it directly ourselves, but we
- must be able to handle it from incoming data. If a DTEND or DUE
- is requested, we convert the DURATION if necessary. If DTEND or
- DUE is set, we remove any DURATION. */
- icalproperty *duration;
-
- struct datetime due;
-
- GSList *exdate_list; /* list of struct datetime */
- GSList *exrule_list; /* list of icalproperty objects */
-
- struct organizer {
- icalproperty *prop;
- icalparameter *sentby_param;
- icalparameter *cn_param;
- icalparameter *language_param;
- };
-
- struct organizer organizer;
-
- icalproperty *geo;
- icalproperty *last_modified;
- icalproperty *percent;
- icalproperty *priority;
-
- struct period {
- icalproperty *prop;
- icalparameter *value_param;
- };
-
- struct recur_id {
- struct datetime recur_time;
-
- icalparameter *range_param;
- };
-
- struct recur_id recur_id;
-
- GSList *rdate_list; /* list of struct period */
-
- GSList *rrule_list; /* list of icalproperty objects */
-
- icalproperty *sequence;
-
- struct {
- icalproperty *prop;
- icalparameter *altrep_param;
- } summary;
-
- icalproperty *transparency;
- icalproperty *url;
- icalproperty *location;
-
- /* Subcomponents */
-
- GHashTable *alarm_uid_hash;
-
- /* Whether we should increment the sequence number when piping the
- * object over the wire.
- */
- guint need_sequence_inc : 1;
-};
-
-/* Private structure for alarms */
-struct _CalComponentAlarm {
- /* Alarm icalcomponent we wrap */
- icalcomponent *icalcomp;
-
- /* Our extension UID property */
- icalproperty *uid;
-
- /* Properties */
-
- icalproperty *action;
- icalproperty *attach; /* FIXME: see scan_alarm_property() below */
-
- struct {
- icalproperty *prop;
- icalparameter *altrep_param;
- } description;
-
- icalproperty *duration;
- icalproperty *repeat;
- icalproperty *trigger;
-};
-
-
-
-static void cal_component_class_init (CalComponentClass *class);
-static void cal_component_init (CalComponent *comp);
-static void cal_component_destroy (GtkObject *object);
-
-static GtkObjectClass *parent_class;
-
-
-
-/**
- * cal_component_get_type:
- *
- * Registers the #CalComponent class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the #CalComponent class.
- **/
-GtkType
-cal_component_get_type (void)
-{
- static GtkType cal_component_type = 0;
-
- if (!cal_component_type) {
- static const GtkTypeInfo cal_component_info = {
- "CalComponent",
- sizeof (CalComponent),
- sizeof (CalComponentClass),
- (GtkClassInitFunc) cal_component_class_init,
- (GtkObjectInitFunc) cal_component_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- cal_component_type = gtk_type_unique (GTK_TYPE_OBJECT, &cal_component_info);
- }
-
- return cal_component_type;
-}
-
-/* Class initialization function for the calendar component object */
-static void
-cal_component_class_init (CalComponentClass *class)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) class;
-
- parent_class = gtk_type_class (GTK_TYPE_OBJECT);
-
- object_class->destroy = cal_component_destroy;
-}
-
-/* Object initialization function for the calendar component object */
-static void
-cal_component_init (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- priv = g_new0 (CalComponentPrivate, 1);
- comp->priv = priv;
-
- priv->alarm_uid_hash = g_hash_table_new (g_str_hash, g_str_equal);
-}
-
-/* Does a simple g_free() of the elements of a GSList and then frees the list
- * itself. Returns NULL.
- */
-static GSList *
-free_slist (GSList *slist)
-{
- GSList *l;
-
- for (l = slist; l; l = l->next)
- g_free (l->data);
-
- g_slist_free (slist);
- return NULL;
-}
-
-/* Used from g_hash_table_foreach_remove() to free the alarm UIDs hash table.
- * We do not need to do anything to individual elements since we were storing
- * the UID pointers inside the icalproperties themselves.
- */
-static gboolean
-free_alarm_cb (gpointer key, gpointer value, gpointer data)
-{
- return TRUE;
-}
-
-/* Frees the internal icalcomponent only if it does not have a parent. If it
- * does, it means we don't own it and we shouldn't free it.
- */
-static void
-free_icalcomponent (CalComponent *comp, gboolean free)
-{
- CalComponentPrivate *priv;
- GSList *l;
-
- priv = comp->priv;
-
- if (!priv->icalcomp)
- return;
-
- /* Free the icalcomponent */
-
- if (free && icalcomponent_get_parent (priv->icalcomp) == NULL) {
- icalcomponent_free (priv->icalcomp);
- priv->icalcomp = NULL;
- }
-
- /* Free the mappings */
-
- priv->uid = NULL;
-
- priv->status = NULL;
-
- for (l = priv->attendee_list; l != NULL; l = l->next)
- g_free (l->data);
- g_slist_free (priv->attendee_list);
- priv->attendee_list = NULL;
-
- priv->categories = NULL;
-
- priv->classification = NULL;
- priv->comment_list = NULL;
- priv->completed = NULL;
- priv->contact_list = NULL;
- priv->created = NULL;
-
- priv->description_list = free_slist (priv->description_list);
-
- priv->dtend.prop = NULL;
- priv->dtend.tzid_param = NULL;
-
- priv->dtstamp = NULL;
-
- priv->dtstart.prop = NULL;
- priv->dtstart.tzid_param = NULL;
-
- priv->due.prop = NULL;
- priv->due.tzid_param = NULL;
-
- priv->duration = NULL;
-
- priv->exdate_list = free_slist (priv->exdate_list);
-
- g_slist_free (priv->exrule_list);
- priv->exrule_list = NULL;
-
- priv->geo = NULL;
- priv->last_modified = NULL;
- priv->percent = NULL;
- priv->priority = NULL;
-
- priv->rdate_list = free_slist (priv->rdate_list);
-
- g_slist_free (priv->rrule_list);
- priv->rrule_list = NULL;
-
- priv->sequence = NULL;
-
- priv->summary.prop = NULL;
- priv->summary.altrep_param = NULL;
-
- priv->transparency = NULL;
- priv->url = NULL;
- priv->location = NULL;
-
- /* Free the subcomponents */
-
- g_hash_table_foreach_remove (priv->alarm_uid_hash, free_alarm_cb, NULL);
-
- /* Clean up */
-
- priv->need_sequence_inc = FALSE;
-}
-
-/* Destroy handler for the calendar component object */
-static void
-cal_component_destroy (GtkObject *object)
-{
- CalComponent *comp;
- CalComponentPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (object));
-
- comp = CAL_COMPONENT (object);
- priv = comp->priv;
-
- free_icalcomponent (comp, TRUE);
- g_hash_table_destroy (priv->alarm_uid_hash);
- priv->alarm_uid_hash = NULL;
-
- g_free (priv);
- comp->priv = NULL;
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-
-
-/**
- * cal_component_gen_uid:
- *
- * Generates a unique identifier suitable for calendar components.
- *
- * Return value: A unique identifier string. Every time this function is called
- * a different string is returned.
- **/
-char *
-cal_component_gen_uid (void)
-{
- char *iso, *ret;
- static char *hostname;
- time_t t = time (NULL);
- static int serial;
-
- if (!hostname) {
- static char buffer [512];
-
- if ((gethostname (buffer, sizeof (buffer) - 1) == 0) &&
- (buffer [0] != 0))
- hostname = buffer;
- else
- hostname = "localhost";
- }
-
- iso = isodate_from_time_t (t);
- ret = g_strdup_printf ("%s-%d-%d-%d-%d@%s",
- iso,
- getpid (),
- getgid (),
- getppid (),
- serial++,
- hostname);
- g_free (iso);
-
- return ret;
-}
-
-/**
- * cal_component_new:
- *
- * Creates a new empty calendar component object. You should set it from an
- * #icalcomponent structure by using cal_component_set_icalcomponent() or with a
- * new empty component type by using cal_component_set_new_vtype().
- *
- * Return value: A newly-created calendar component object.
- **/
-CalComponent *
-cal_component_new (void)
-{
- return CAL_COMPONENT (gtk_type_new (CAL_COMPONENT_TYPE));
-}
-
-/**
- * cal_component_clone:
- * @comp: A calendar component object.
- *
- * Creates a new calendar component object by copying the information from
- * another one.
- *
- * Return value: A newly-created calendar component with the same values as the
- * original one.
- **/
-CalComponent *
-cal_component_clone (CalComponent *comp)
-{
- CalComponentPrivate *priv;
- CalComponent *new_comp;
- icalcomponent *new_icalcomp;
-
- g_return_val_if_fail (comp != NULL, NULL);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), NULL);
-
- priv = comp->priv;
- g_return_val_if_fail (priv->need_sequence_inc == FALSE, NULL);
-
- new_comp = cal_component_new ();
-
- if (priv->icalcomp) {
- new_icalcomp = icalcomponent_new_clone (priv->icalcomp);
- cal_component_set_icalcomponent (new_comp, new_icalcomp);
- }
-
- return new_comp;
-}
-
-/* Scans an attendee property */
-static void
-scan_attendee (CalComponent *comp, GSList **attendee_list, icalproperty *prop)
-{
- struct attendee *attendee;
-
- attendee = g_new (struct attendee, 1);
- attendee->prop = prop;
-
- attendee->cutype_param = icalproperty_get_first_parameter (prop, ICAL_CUTYPE_PARAMETER);
- attendee->member_param = icalproperty_get_first_parameter (prop, ICAL_MEMBER_PARAMETER);
- attendee->role_param = icalproperty_get_first_parameter (prop, ICAL_ROLE_PARAMETER);
- attendee->partstat_param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER);
- attendee->rsvp_param = icalproperty_get_first_parameter (prop, ICAL_RSVP_PARAMETER);
- attendee->delto_param = icalproperty_get_first_parameter (prop, ICAL_DELEGATEDTO_PARAMETER);
- attendee->delfrom_param = icalproperty_get_first_parameter (prop, ICAL_DELEGATEDFROM_PARAMETER);
- attendee->sentby_param = icalproperty_get_first_parameter (prop, ICAL_SENTBY_PARAMETER);
- attendee->cn_param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER);
- attendee->language_param = icalproperty_get_first_parameter (prop, ICAL_LANGUAGE_PARAMETER);
-
- *attendee_list = g_slist_append (*attendee_list, attendee);
-}
-
-/* Scans a date/time and timezone pair property */
-static void
-scan_datetime (CalComponent *comp, struct datetime *datetime, icalproperty *prop)
-{
- CalComponentPrivate *priv;
-
- priv = comp->priv;
-
- datetime->prop = prop;
- datetime->tzid_param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER);
-}
-
-/* Scans an exception date property */
-static void
-scan_exdate (CalComponent *comp, icalproperty *prop)
-{
- CalComponentPrivate *priv;
- struct datetime *dt;
-
- priv = comp->priv;
-
- dt = g_new (struct datetime, 1);
- dt->prop = prop;
- dt->tzid_param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER);
-
- priv->exdate_list = g_slist_append (priv->exdate_list, dt);
-}
-
-/* Scans and attendee property */
-static void
-scan_organizer (CalComponent *comp, struct organizer *organizer, icalproperty *prop)
-{
- organizer->prop = prop;
-
- organizer->sentby_param = icalproperty_get_first_parameter (prop, ICAL_SENTBY_PARAMETER);
- organizer->cn_param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER);
- organizer->language_param = icalproperty_get_first_parameter (prop, ICAL_LANGUAGE_PARAMETER);
-}
-
-/* Scans an icalperiodtype property */
-static void
-scan_period (CalComponent *comp, GSList **list, icalproperty *prop)
-{
- struct period *period;
-
- period = g_new (struct period, 1);
- period->prop = prop;
- period->value_param = icalproperty_get_first_parameter (prop, ICAL_VALUE_PARAMETER);
-
- *list = g_slist_append (*list, period);
-}
-
-
-/* Scans an icalrecurtype property */
-static void
-scan_recur_id (CalComponent *comp, struct recur_id *recur_id, icalproperty *prop)
-{
- scan_datetime (comp, &recur_id->recur_time, prop);
-
- recur_id->range_param = icalproperty_get_first_parameter (prop, ICAL_RANGE_PARAMETER);
-}
-
-/* Scans an icalrecurtype property */
-static void
-scan_recur (CalComponent *comp, GSList **list, icalproperty *prop)
-{
- *list = g_slist_append (*list, prop);
-}
-
-/* Scans the summary property */
-static void
-scan_summary (CalComponent *comp, icalproperty *prop)
-{
- CalComponentPrivate *priv;
-
- priv = comp->priv;
-
- priv->summary.prop = prop;
- priv->summary.altrep_param = icalproperty_get_first_parameter (prop, ICAL_ALTREP_PARAMETER);
-}
-
-/* Scans a text (i.e. text + altrep) property */
-static void
-scan_text (CalComponent *comp, GSList **text_list, icalproperty *prop)
-{
- struct text *text;
-
- text = g_new (struct text, 1);
- text->prop = prop;
- text->altrep_param = icalproperty_get_first_parameter (prop, ICAL_ALTREP_PARAMETER);
-
- *text_list = g_slist_append (*text_list, text);
-}
-
-/* Scans an icalproperty and adds its mapping to the component */
-static void
-scan_property (CalComponent *comp, icalproperty *prop)
-{
- CalComponentPrivate *priv;
- icalproperty_kind kind;
-
- priv = comp->priv;
-
- kind = icalproperty_isa (prop);
-
- switch (kind) {
- case ICAL_STATUS_PROPERTY:
- priv->status = prop;
- break;
-
- case ICAL_ATTENDEE_PROPERTY:
- scan_attendee (comp, &priv->attendee_list, prop);
- break;
-
- case ICAL_CATEGORIES_PROPERTY:
- priv->categories = prop;
- break;
-
- case ICAL_CLASS_PROPERTY:
- priv->classification = prop;
- break;
-
- case ICAL_COMMENT_PROPERTY:
- scan_text (comp, &priv->comment_list, prop);
- break;
-
- case ICAL_COMPLETED_PROPERTY:
- priv->completed = prop;
- break;
-
- case ICAL_CONTACT_PROPERTY:
- scan_text (comp, &priv->contact_list, prop);
- break;
-
- case ICAL_CREATED_PROPERTY:
- priv->created = prop;
- break;
-
- case ICAL_DESCRIPTION_PROPERTY:
- scan_text (comp, &priv->description_list, prop);
- break;
-
- case ICAL_DTEND_PROPERTY:
- scan_datetime (comp, &priv->dtend, prop);
- break;
-
- case ICAL_DTSTAMP_PROPERTY:
- priv->dtstamp = prop;
- break;
-
- case ICAL_DTSTART_PROPERTY:
- scan_datetime (comp, &priv->dtstart, prop);
- break;
-
- case ICAL_DUE_PROPERTY:
- scan_datetime (comp, &priv->due, prop);
- break;
-
- case ICAL_DURATION_PROPERTY:
- priv->duration = prop;
- break;
-
- case ICAL_EXDATE_PROPERTY:
- scan_exdate (comp, prop);
- break;
-
- case ICAL_EXRULE_PROPERTY:
- scan_recur (comp, &priv->exrule_list, prop);
- break;
-
- case ICAL_GEO_PROPERTY:
- priv->geo = prop;
- break;
-
- case ICAL_LASTMODIFIED_PROPERTY:
- priv->last_modified = prop;
- break;
-
- case ICAL_ORGANIZER_PROPERTY:
- scan_organizer (comp, &priv->organizer, prop);
- break;
-
- case ICAL_PERCENTCOMPLETE_PROPERTY:
- priv->percent = prop;
- break;
-
- case ICAL_PRIORITY_PROPERTY:
- priv->priority = prop;
- break;
-
- case ICAL_RECURRENCEID_PROPERTY:
- scan_recur_id (comp, &priv->recur_id, prop);
- break;
-
- case ICAL_RDATE_PROPERTY:
- scan_period (comp, &priv->rdate_list, prop);
- break;
-
- case ICAL_RRULE_PROPERTY:
- scan_recur (comp, &priv->rrule_list, prop);
- break;
-
- case ICAL_SEQUENCE_PROPERTY:
- priv->sequence = prop;
- break;
-
- case ICAL_SUMMARY_PROPERTY:
- scan_summary (comp, prop);
- break;
-
- case ICAL_TRANSP_PROPERTY:
- priv->transparency = prop;
- break;
-
- case ICAL_UID_PROPERTY:
- priv->uid = prop;
- break;
-
- case ICAL_URL_PROPERTY:
- priv->url = prop;
- break;
-
- case ICAL_LOCATION_PROPERTY :
- priv->location = prop;
- break;
-
- default:
- break;
- }
-}
-
-/* Gets our alarm UID string from a property that is known to contain it */
-static const char *
-alarm_uid_from_prop (icalproperty *prop)
-{
- const char *xstr;
-
- g_assert (icalproperty_isa (prop) == ICAL_X_PROPERTY);
-
- xstr = icalproperty_get_x (prop);
- g_assert (xstr != NULL);
-
- return xstr;
-}
-
-/* Sets our alarm UID extension property on an alarm component. Returns a
- * pointer to the UID string inside the property itself.
- */
-static const char *
-set_alarm_uid (icalcomponent *alarm, const char *auid)
-{
- icalproperty *prop;
- const char *inprop_auid;
-
- /* Create the new property */
-
- prop = icalproperty_new_x ((char *) auid);
- icalproperty_set_x_name (prop, EVOLUTION_ALARM_UID_PROPERTY);
-
- icalcomponent_add_property (alarm, prop);
-
- inprop_auid = alarm_uid_from_prop (prop);
- return inprop_auid;
-}
-
-/* Removes any alarm UID extension properties from an alarm subcomponent */
-static void
-remove_alarm_uid (icalcomponent *alarm)
-{
- icalproperty *prop;
- GSList *list, *l;
-
- list = NULL;
-
- for (prop = icalcomponent_get_first_property (alarm, ICAL_X_PROPERTY);
- prop;
- prop = icalcomponent_get_next_property (alarm, ICAL_X_PROPERTY)) {
- const char *xname;
-
- xname = icalproperty_get_x_name (prop);
- g_assert (xname != NULL);
-
- if (strcmp (xname, EVOLUTION_ALARM_UID_PROPERTY) == 0)
- list = g_slist_prepend (list, prop);
- }
-
- for (l = list; l; l = l->next) {
- prop = l->data;
- icalcomponent_remove_property (alarm, prop);
- icalproperty_free (prop);
- }
-
- g_slist_free (list);
-}
-
-/* Adds an alarm subcomponent to the calendar component's mapping table. The
- * actual UID with which it gets added may not be the same as the specified one;
- * this function will change it if the table already had an alarm subcomponent
- * with the specified UID. Returns the actual UID used.
- */
-static const char *
-add_alarm (CalComponent *comp, icalcomponent *alarm, const char *auid)
-{
- CalComponentPrivate *priv;
- icalcomponent *old_alarm;
-
- priv = comp->priv;
-
- /* First we see if we already have an alarm with the requested UID. In
- * that case, we need to change the new UID to something else. This
- * should never happen, but who knows.
- */
-
- old_alarm = g_hash_table_lookup (priv->alarm_uid_hash, auid);
- if (old_alarm != NULL) {
- char *new_auid;
-
- g_message ("add_alarm(): Got alarm with duplicated UID `%s', changing it...", auid);
-
- remove_alarm_uid (alarm);
-
- new_auid = cal_component_gen_uid ();
- auid = set_alarm_uid (alarm, new_auid);
- g_free (new_auid);
- }
-
- g_hash_table_insert (priv->alarm_uid_hash, (char *) auid, alarm);
- return auid;
-}
-
-/* Scans an alarm subcomponent, adds an UID extension property to it (so that we
- * can reference alarms by unique IDs), and adds its mapping to the component. */
-static void
-scan_alarm (CalComponent *comp, icalcomponent *alarm)
-{
- CalComponentPrivate *priv;
- icalproperty *prop;
- const char *auid;
- char *new_auid;
-
- priv = comp->priv;
-
- for (prop = icalcomponent_get_first_property (alarm, ICAL_X_PROPERTY);
- prop;
- prop = icalcomponent_get_next_property (alarm, ICAL_X_PROPERTY)) {
- const char *xname;
-
- xname = icalproperty_get_x_name (prop);
- g_assert (xname != NULL);
-
- if (strcmp (xname, EVOLUTION_ALARM_UID_PROPERTY) == 0) {
- auid = alarm_uid_from_prop (prop);
- add_alarm (comp, alarm, auid);
- return;
- }
- }
-
- /* The component has no alarm UID property, so we create one. */
-
- new_auid = cal_component_gen_uid ();
- auid = set_alarm_uid (alarm, new_auid);
- g_free (new_auid);
-
- add_alarm (comp, alarm, auid);
-}
-
-/* Scans an icalcomponent for its properties so that we can provide
- * random-access to them. It also builds a hash table of the component's alarm
- * subcomponents.
- */
-static void
-scan_icalcomponent (CalComponent *comp)
-{
- CalComponentPrivate *priv;
- icalproperty *prop;
- icalcompiter iter;
-
- priv = comp->priv;
-
- g_assert (priv->icalcomp != NULL);
-
- /* Scan properties */
-
- for (prop = icalcomponent_get_first_property (priv->icalcomp, ICAL_ANY_PROPERTY);
- prop;
- prop = icalcomponent_get_next_property (priv->icalcomp, ICAL_ANY_PROPERTY))
- scan_property (comp, prop);
-
- /* Scan subcomponents */
-
- for (iter = icalcomponent_begin_component (priv->icalcomp, ICAL_VALARM_COMPONENT);
- icalcompiter_deref (&iter) != NULL;
- icalcompiter_next (&iter)) {
- icalcomponent *subcomp;
-
- subcomp = icalcompiter_deref (&iter);
- scan_alarm (comp, subcomp);
- }
-}
-
-/* Ensures that the mandatory calendar component properties (uid, dtstamp) do
- * exist. If they don't exist, it creates them automatically.
- */
-static void
-ensure_mandatory_properties (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- priv = comp->priv;
- g_assert (priv->icalcomp != NULL);
-
- if (!priv->uid) {
- char *uid;
-
- uid = cal_component_gen_uid ();
- priv->uid = icalproperty_new_uid (uid);
- g_free (uid);
-
- icalcomponent_add_property (priv->icalcomp, priv->uid);
- }
-
- if (!priv->dtstamp) {
- struct icaltimetype t;
-
- t = icaltime_current_time_with_zone (icaltimezone_get_utc_timezone ());
-
- priv->dtstamp = icalproperty_new_dtstamp (t);
- icalcomponent_add_property (priv->icalcomp, priv->dtstamp);
- }
-}
-
-/**
- * cal_component_set_new_vtype:
- * @comp: A calendar component object.
- * @type: Type of calendar component to create.
- *
- * Clears any existing component data from a calendar component object and
- * creates a new #icalcomponent of the specified type for it. The only property
- * that will be set in the new component will be its unique identifier.
- **/
-void
-cal_component_set_new_vtype (CalComponent *comp, CalComponentVType type)
-{
- CalComponentPrivate *priv;
- icalcomponent *icalcomp;
- icalcomponent_kind kind;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
-
- free_icalcomponent (comp, TRUE);
-
- if (type == CAL_COMPONENT_NO_TYPE)
- return;
-
- /* Figure out the kind and create the icalcomponent */
-
- switch (type) {
- case CAL_COMPONENT_EVENT:
- kind = ICAL_VEVENT_COMPONENT;
- break;
-
- case CAL_COMPONENT_TODO:
- kind = ICAL_VTODO_COMPONENT;
- break;
-
- case CAL_COMPONENT_JOURNAL:
- kind = ICAL_VJOURNAL_COMPONENT;
- break;
-
- case CAL_COMPONENT_FREEBUSY:
- kind = ICAL_VFREEBUSY_COMPONENT;
- break;
-
- case CAL_COMPONENT_TIMEZONE:
- kind = ICAL_VTIMEZONE_COMPONENT;
- break;
-
- default:
- g_assert_not_reached ();
- kind = ICAL_NO_COMPONENT;
- }
-
- icalcomp = icalcomponent_new (kind);
- if (!icalcomp) {
- g_message ("cal_component_set_new_vtype(): Could not create the icalcomponent!");
- return;
- }
-
- /* Scan the component to build our mapping table */
-
- priv->icalcomp = icalcomp;
- scan_icalcomponent (comp);
-
- /* Add missing stuff */
-
- ensure_mandatory_properties (comp);
-}
-
-/**
- * cal_component_set_icalcomponent:
- * @comp: A calendar component object.
- * @icalcomp: An #icalcomponent.
- *
- * Sets the contents of a calendar component object from an #icalcomponent
- * structure. If the @comp already had an #icalcomponent set into it, it will
- * will be freed automatically if the #icalcomponent does not have a parent
- * component itself.
- *
- * Supported component types are VEVENT, VTODO, VJOURNAL, VFREEBUSY, and VTIMEZONE.
- *
- * Return value: TRUE on success, FALSE if @icalcomp is an unsupported component
- * type.
- **/
-gboolean
-cal_component_set_icalcomponent (CalComponent *comp, icalcomponent *icalcomp)
-{
- CalComponentPrivate *priv;
- icalcomponent_kind kind;
-
- g_return_val_if_fail (comp != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE);
-
- priv = comp->priv;
-
- if (priv->icalcomp == icalcomp)
- return TRUE;
-
- free_icalcomponent (comp, TRUE);
-
- if (!icalcomp) {
- priv->icalcomp = NULL;
- return TRUE;
- }
-
- kind = icalcomponent_isa (icalcomp);
-
- if (!(kind == ICAL_VEVENT_COMPONENT
- || kind == ICAL_VTODO_COMPONENT
- || kind == ICAL_VJOURNAL_COMPONENT
- || kind == ICAL_VFREEBUSY_COMPONENT
- || kind == ICAL_VTIMEZONE_COMPONENT))
- return FALSE;
-
- priv->icalcomp = icalcomp;
-
- scan_icalcomponent (comp);
- ensure_mandatory_properties (comp);
-
- return TRUE;
-}
-
-/**
- * cal_component_get_icalcomponent:
- * @comp: A calendar component object.
- *
- * Queries the #icalcomponent structure that a calendar component object is
- * wrapping.
- *
- * Return value: An #icalcomponent structure, or NULL if the @comp has no
- * #icalcomponent set to it.
- **/
-icalcomponent *
-cal_component_get_icalcomponent (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- g_return_val_if_fail (comp != NULL, NULL);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), NULL);
-
- priv = comp->priv;
- g_return_val_if_fail (priv->need_sequence_inc == FALSE, NULL);
-
- return priv->icalcomp;
-}
-
-void
-cal_component_rescan (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
-
- /* Clear everything out */
- free_icalcomponent (comp, FALSE);
-
- /* Rescan */
- scan_icalcomponent (comp);
- ensure_mandatory_properties (comp);
-}
-
-void
-cal_component_strip_errors (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
-
- icalcomponent_strip_errors (priv->icalcomp);
-}
-
-/**
- * cal_component_get_vtype:
- * @comp: A calendar component object.
- *
- * Queries the type of a calendar component object.
- *
- * Return value: The type of the component, as defined by RFC 2445.
- **/
-CalComponentVType
-cal_component_get_vtype (CalComponent *comp)
-{
- CalComponentPrivate *priv;
- icalcomponent_kind kind;
-
- g_return_val_if_fail (comp != NULL, CAL_COMPONENT_NO_TYPE);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), CAL_COMPONENT_NO_TYPE);
-
- priv = comp->priv;
- g_return_val_if_fail (priv->icalcomp != NULL, CAL_COMPONENT_NO_TYPE);
-
- kind = icalcomponent_isa (priv->icalcomp);
- switch (kind) {
- case ICAL_VEVENT_COMPONENT:
- return CAL_COMPONENT_EVENT;
-
- case ICAL_VTODO_COMPONENT:
- return CAL_COMPONENT_TODO;
-
- case ICAL_VJOURNAL_COMPONENT:
- return CAL_COMPONENT_JOURNAL;
-
- case ICAL_VFREEBUSY_COMPONENT:
- return CAL_COMPONENT_FREEBUSY;
-
- case ICAL_VTIMEZONE_COMPONENT:
- return CAL_COMPONENT_TIMEZONE;
-
- default:
- /* We should have been loaded with a supported type! */
- g_assert_not_reached ();
- return CAL_COMPONENT_NO_TYPE;
- }
-}
-
-/**
- * cal_component_get_as_string:
- * @comp: A calendar component.
- *
- * Gets the iCalendar string representation of a calendar component. You should
- * call cal_component_commit_sequence() before this function to ensure that the
- * component's sequence number is consistent with the state of the object.
- *
- * Return value: String representation of the calendar component according to
- * RFC 2445.
- **/
-char *
-cal_component_get_as_string (CalComponent *comp)
-{
- CalComponentPrivate *priv;
- char *str, *buf;
-
- g_return_val_if_fail (comp != NULL, NULL);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), NULL);
-
- priv = comp->priv;
- g_return_val_if_fail (priv->icalcomp != NULL, NULL);
-
- /* Ensure that the user has committed the new SEQUENCE */
- g_return_val_if_fail (priv->need_sequence_inc == FALSE, NULL);
-
- /* We dup the string; libical owns that memory */
-
- str = icalcomponent_as_ical_string (priv->icalcomp);
-
- if (str)
- buf = g_strdup (str);
- else
- buf = NULL;
-
- return buf;
-}
-
-/* Used from g_hash_table_foreach(); ensures that an alarm subcomponent
- * has the mandatory properties it needs.
- */
-static void
-ensure_alarm_properties_cb (gpointer key, gpointer value, gpointer data)
-{
- CalComponent *comp;
- CalComponentPrivate *priv;
- icalcomponent *alarm;
- icalproperty *prop;
- enum icalproperty_action action;
- const char *str;
-
- alarm = value;
-
- comp = CAL_COMPONENT (data);
- priv = comp->priv;
-
- prop = icalcomponent_get_first_property (alarm, ICAL_ACTION_PROPERTY);
- if (!prop)
- return;
-
- action = icalproperty_get_action (prop);
-
- switch (action) {
- case ICAL_ACTION_DISPLAY:
- /* Ensure we have a DESCRIPTION property */
- prop = icalcomponent_get_first_property (alarm, ICAL_DESCRIPTION_PROPERTY);
- if (prop)
- break;
-
- if (!priv->summary.prop)
- str = _("Untitled appointment");
- else
- str = icalproperty_get_summary (priv->summary.prop);
-
- prop = icalproperty_new_description (str);
- icalcomponent_add_property (alarm, prop);
-
- break;
-
- default:
- break;
- /* FIXME: add other action types here */
- }
-}
-
-/* Ensures that alarm subcomponents have the mandatory properties they need,
- * even when clients may not have set them properly.
- */
-static void
-ensure_alarm_properties (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- priv = comp->priv;
-
- g_hash_table_foreach (priv->alarm_uid_hash, ensure_alarm_properties_cb, comp);
-}
-
-/**
- * cal_component_commit_sequence:
- * @comp:
- *
- * Increments the sequence number property in a calendar component object if it
- * needs it. This needs to be done when any of a number of properties listed in
- * RFC 2445 change values, such as the start and end dates of a component.
- *
- * This function must be called before calling cal_component_get_as_string() to
- * ensure that the component is fully consistent.
- **/
-void
-cal_component_commit_sequence (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- ensure_alarm_properties (comp);
-
- if (!priv->need_sequence_inc)
- return;
-
- if (priv->sequence) {
- int seq;
-
- seq = icalproperty_get_sequence (priv->sequence);
- icalproperty_set_sequence (priv->sequence, seq + 1);
- } else {
- /* The component had no SEQUENCE property, so assume that the
- * default would have been zero. Since it needed incrementing
- * anyways, we use a value of 1 here.
- */
- priv->sequence = icalproperty_new_sequence (1);
- icalcomponent_add_property (priv->icalcomp, priv->sequence);
- }
-
- priv->need_sequence_inc = FALSE;
-}
-
-void
-cal_component_abort_sequence (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
-
- priv->need_sequence_inc = FALSE;
-}
-
-/**
- * cal_component_get_uid:
- * @comp: A calendar component object.
- * @uid: Return value for the UID string.
- *
- * Queries the unique identifier of a calendar component object.
- **/
-void
-cal_component_get_uid (CalComponent *comp, const char **uid)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (uid != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- /* This MUST exist, since we ensured that it did */
- g_assert (priv->uid != NULL);
-
- *uid = icalproperty_get_uid (priv->uid);
-}
-
-/**
- * cal_component_set_uid:
- * @comp: A calendar component object.
- * @uid: Unique identifier.
- *
- * Sets the unique identifier string of a calendar component object.
- **/
-void
-cal_component_set_uid (CalComponent *comp, const char *uid)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (uid != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- /* This MUST exist, since we ensured that it did */
- g_assert (priv->uid != NULL);
-
- icalproperty_set_uid (priv->uid, (char *) uid);
-}
-
-/**
- * cal_component_get_categories:
- * @comp: A calendar component object.
- * @categories:
- *
- *
- **/
-void
-cal_component_get_categories (CalComponent *comp, const char **categories)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (categories != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (priv->categories)
- *categories = icalproperty_get_categories (priv->categories);
- else
- *categories = NULL;
-}
-
-/**
- * cal_component_set_categories:
- * @comp: A calendar component object.
- * @categories:
- *
- *
- **/
-void
-cal_component_set_categories (CalComponent *comp, const char *categories)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!categories || !(*categories)) {
- if (priv->categories) {
- icalcomponent_remove_property (priv->icalcomp, priv->categories);
- icalproperty_free (priv->categories);
- priv->url = NULL;
- }
-
- return;
- }
-
- if (priv->categories)
- icalproperty_set_categories (priv->categories, (char *) categories);
- else {
- priv->categories = icalproperty_new_categories ((char *) categories);
- icalcomponent_add_property (priv->icalcomp, priv->categories);
- }
-}
-
-
-/**
- * cal_component_get_categories_list:
- * @comp: A calendar component object.
- * @categ_list: Return value for the list of strings, where each string is a
- * category. This should be freed using cal_component_free_categories_list().
- *
- * Queries the list of categories of a calendar component object. Each element
- * in the returned categ_list is a string with the corresponding category.
- **/
-void
-cal_component_get_categories_list (CalComponent *comp, GSList **categ_list)
-{
- CalComponentPrivate *priv;
- const char *categories;
- const char *p;
- const char *cat_start;
- char *str;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (categ_list != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!priv->categories) {
- *categ_list = NULL;
- return;
- }
-
- categories = icalproperty_get_categories (priv->categories);
- g_assert (categories != NULL);
-
- cat_start = categories;
- *categ_list = NULL;
-
- for (p = categories; *p; p++)
- if (*p == ',') {
- str = g_strndup (cat_start, p - cat_start);
- *categ_list = g_slist_prepend (*categ_list, str);
-
- cat_start = p + 1;
- }
-
- str = g_strndup (cat_start, p - cat_start);
- *categ_list = g_slist_prepend (*categ_list, str);
-
- *categ_list = g_slist_reverse (*categ_list);
-}
-
-/* Creates a comma-delimited string of categories */
-static char *
-stringify_categories (GSList *categ_list)
-{
- GString *s;
- GSList *l;
- char *str;
-
- s = g_string_new (NULL);
-
- for (l = categ_list; l; l = l->next) {
- g_string_append (s, l->data);
-
- if (l->next != NULL)
- g_string_append (s, ",");
- }
-
- str = s->str;
- g_string_free (s, FALSE);
-
- return str;
-}
-
-/**
- * cal_component_set_categories_list:
- * @comp: A calendar component object.
- * @categ_list: List of strings, one for each category.
- *
- * Sets the list of categories of a calendar component object.
- **/
-void
-cal_component_set_categories_list (CalComponent *comp, GSList *categ_list)
-{
- CalComponentPrivate *priv;
- char *categories_str;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!categ_list) {
- if (priv->categories) {
- icalcomponent_remove_property (priv->icalcomp, priv->categories);
- icalproperty_free (priv->categories);
- }
-
- return;
- }
-
- /* Create a single string of categories */
- categories_str = stringify_categories (categ_list);
-
- /* Set the categories */
- priv->categories = icalproperty_new_categories (categories_str);
- g_free (categories_str);
-
- icalcomponent_add_property (priv->icalcomp, priv->categories);
-}
-
-/**
- * cal_component_get_classification:
- * @comp: A calendar component object.
- * @classif: Return value for the classification.
- *
- * Queries the classification of a calendar component object. If the
- * classification property is not set on this component, this function returns
- * #CAL_COMPONENT_CLASS_NONE.
- **/
-void
-cal_component_get_classification (CalComponent *comp, CalComponentClassification *classif)
-{
- CalComponentPrivate *priv;
- const char *class;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (classif != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!priv->classification) {
- *classif = CAL_COMPONENT_CLASS_NONE;
- return;
- }
-
- class = icalproperty_get_class (priv->classification);
-
- if (strcasecmp (class, "PUBLIC") == 0)
- *classif = CAL_COMPONENT_CLASS_PUBLIC;
- else if (strcasecmp (class, "PRIVATE") == 0)
- *classif = CAL_COMPONENT_CLASS_PRIVATE;
- else if (strcasecmp (class, "CONFIDENTIAL") == 0)
- *classif = CAL_COMPONENT_CLASS_CONFIDENTIAL;
- else
- *classif = CAL_COMPONENT_CLASS_UNKNOWN;
-}
-
-/**
- * cal_component_set_classification:
- * @comp: A calendar component object.
- * @classif: Classification to use.
- *
- * Sets the classification property of a calendar component object. To unset
- * the property, specify CAL_COMPONENT_CLASS_NONE for @classif.
- **/
-void
-cal_component_set_classification (CalComponent *comp, CalComponentClassification classif)
-{
- CalComponentPrivate *priv;
- char *str;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (classif != CAL_COMPONENT_CLASS_UNKNOWN);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (classif == CAL_COMPONENT_CLASS_NONE) {
- if (priv->classification) {
- icalcomponent_remove_property (priv->icalcomp, priv->classification);
- icalproperty_free (priv->classification);
- priv->classification = NULL;
- }
-
- return;
- }
-
- switch (classif) {
- case CAL_COMPONENT_CLASS_PUBLIC:
- str = "PUBLIC";
- break;
-
- case CAL_COMPONENT_CLASS_PRIVATE:
- str = "PRIVATE";
- break;
-
- case CAL_COMPONENT_CLASS_CONFIDENTIAL:
- str = "CONFIDENTIAL";
- break;
-
- default:
- g_assert_not_reached ();
- str = NULL;
- }
-
- if (priv->classification)
- icalproperty_set_class (priv->classification, str);
- else {
- priv->classification = icalproperty_new_class (str);
- icalcomponent_add_property (priv->icalcomp, priv->classification);
- }
-}
-
-/* Gets a text list value */
-static void
-get_text_list (GSList *text_list,
- const char *(* get_prop_func) (icalproperty *prop),
- GSList **tl)
-{
- GSList *l;
-
- *tl = NULL;
-
- if (!text_list)
- return;
-
- for (l = text_list; l; l = l->next) {
- struct text *text;
- CalComponentText *t;
-
- text = l->data;
- g_assert (text->prop != NULL);
-
- t = g_new (CalComponentText, 1);
- t->value = (* get_prop_func) (text->prop);
-
- if (text->altrep_param)
- t->altrep = icalparameter_get_altrep (text->altrep_param);
- else
- t->altrep = NULL;
-
- *tl = g_slist_prepend (*tl, t);
- }
-
- *tl = g_slist_reverse (*tl);
-}
-
-/* Sets a text list value */
-static void
-set_text_list (CalComponent *comp,
- icalproperty *(* new_prop_func) (const char *value),
- GSList **text_list,
- GSList *tl)
-{
- CalComponentPrivate *priv;
- GSList *l;
-
- priv = comp->priv;
-
- /* Remove old texts */
-
- for (l = *text_list; l; l = l->next) {
- struct text *text;
-
- text = l->data;
- g_assert (text->prop != NULL);
-
- icalcomponent_remove_property (priv->icalcomp, text->prop);
- icalproperty_free (text->prop);
- g_free (text);
- }
-
- g_slist_free (*text_list);
- *text_list = NULL;
-
- /* Add in new texts */
-
- for (l = tl; l; l = l->next) {
- CalComponentText *t;
- struct text *text;
-
- t = l->data;
- g_return_if_fail (t->value != NULL);
-
- text = g_new (struct text, 1);
-
- text->prop = (* new_prop_func) ((char *) t->value);
- icalcomponent_add_property (priv->icalcomp, text->prop);
-
- if (t->altrep) {
- text->altrep_param = icalparameter_new_altrep ((char *) t->altrep);
- icalproperty_add_parameter (text->prop, text->altrep_param);
- } else
- text->altrep_param = NULL;
-
- *text_list = g_slist_prepend (*text_list, text);
- }
-
- *text_list = g_slist_reverse (*text_list);
-}
-
-/**
- * cal_component_get_comment_list:
- * @comp: A calendar component object.
- * @text_list: Return value for the comment properties and their parameters, as
- * a list of #CalComponentText structures. This should be freed using the
- * cal_component_free_text_list() function.
- *
- * Queries the comment of a calendar component object. The comment property can
- * appear several times inside a calendar component, and so a list of
- * #CalComponentText is returned.
- **/
-void
-cal_component_get_comment_list (CalComponent *comp, GSList **text_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (text_list != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_text_list (priv->comment_list, icalproperty_get_comment, text_list);
-}
-
-/**
- * cal_component_set_comment_list:
- * @comp: A calendar component object.
- * @text_list: List of #CalComponentText structures.
- *
- * Sets the comment of a calendar component object. The comment property can
- * appear several times inside a calendar component, and so a list of
- * #CalComponentText structures is used.
- **/
-void
-cal_component_set_comment_list (CalComponent *comp, GSList *text_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_text_list (comp, icalproperty_new_comment, &priv->comment_list, text_list);
-}
-
-/**
- * cal_component_get_contact_list:
- * @comp: A calendar component object.
- * @text_list: Return value for the contact properties and their parameters, as
- * a list of #CalComponentText structures. This should be freed using the
- * cal_component_free_text_list() function.
- *
- * Queries the contact of a calendar component object. The contact property can
- * appear several times inside a calendar component, and so a list of
- * #CalComponentText is returned.
- **/
-void
-cal_component_get_contact_list (CalComponent *comp, GSList **text_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (text_list != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_text_list (priv->contact_list, icalproperty_get_contact, text_list);
-}
-
-/**
- * cal_component_set_contact_list:
- * @comp: A calendar component object.
- * @text_list: List of #CalComponentText structures.
- *
- * Sets the contact of a calendar component object. The contact property can
- * appear several times inside a calendar component, and so a list of
- * #CalComponentText structures is used.
- **/
-void
-cal_component_set_contact_list (CalComponent *comp, GSList *text_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_text_list (comp, icalproperty_new_contact, &priv->contact_list, text_list);
-}
-
-/* Gets a struct icaltimetype value */
-static void
-get_icaltimetype (icalproperty *prop,
- struct icaltimetype (* get_prop_func) (icalproperty *prop),
- struct icaltimetype **t)
-{
- if (!prop) {
- *t = NULL;
- return;
- }
-
- *t = g_new (struct icaltimetype, 1);
- **t = (* get_prop_func) (prop);
-}
-
-/* Sets a struct icaltimetype value */
-static void
-set_icaltimetype (CalComponent *comp, icalproperty **prop,
- icalproperty *(* prop_new_func) (struct icaltimetype v),
- void (* prop_set_func) (icalproperty *prop, struct icaltimetype v),
- struct icaltimetype *t)
-{
- CalComponentPrivate *priv;
-
- priv = comp->priv;
-
- if (!t) {
- if (*prop) {
- icalcomponent_remove_property (priv->icalcomp, *prop);
- icalproperty_free (*prop);
- *prop = NULL;
- }
-
- return;
- }
-
- if (*prop)
- (* prop_set_func) (*prop, *t);
- else {
- *prop = (* prop_new_func) (*t);
- icalcomponent_add_property (priv->icalcomp, *prop);
- }
-}
-
-/**
- * cal_component_get_completed:
- * @comp: A calendar component object.
- * @t: Return value for the completion date. This should be freed using the
- * cal_component_free_icaltimetype() function.
- *
- * Queries the date at which a calendar compoment object was completed.
- **/
-void
-cal_component_get_completed (CalComponent *comp, struct icaltimetype **t)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (t != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_icaltimetype (priv->completed, icalproperty_get_completed, t);
-}
-
-/**
- * cal_component_set_completed:
- * @comp: A calendar component object.
- * @t: Value for the completion date.
- *
- * Sets the date at which a calendar component object was completed.
- **/
-void
-cal_component_set_completed (CalComponent *comp, struct icaltimetype *t)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_icaltimetype (comp, &priv->completed,
- icalproperty_new_completed,
- icalproperty_set_completed,
- t);
-}
-
-
-/**
- * cal_component_get_created:
- * @comp: A calendar component object.
- * @t: Return value for the creation date. This should be freed using the
- * cal_component_free_icaltimetype() function.
- *
- * Queries the date in which a calendar component object was created in the
- * calendar store.
- **/
-void
-cal_component_get_created (CalComponent *comp, struct icaltimetype **t)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (t != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_icaltimetype (priv->created, icalproperty_get_created, t);
-}
-
-/**
- * cal_component_set_created:
- * @comp: A calendar component object.
- * @t: Value for the creation date.
- *
- * Sets the date in which a calendar component object is created in the calendar
- * store. This should only be used inside a calendar store application, i.e.
- * not by calendar user agents.
- **/
-void
-cal_component_set_created (CalComponent *comp, struct icaltimetype *t)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_icaltimetype (comp, &priv->created,
- icalproperty_new_created,
- icalproperty_set_created,
- t);
-}
-
-/**
- * cal_component_get_description_list:
- * @comp: A calendar component object.
- * @text_list: Return value for the description properties and their parameters,
- * as a list of #CalComponentText structures. This should be freed using the
- * cal_component_free_text_list() function.
- *
- * Queries the description of a calendar component object. Journal components
- * may have more than one description, and as such this function returns a list
- * of #CalComponentText structures. All other types of components can have at
- * most one description.
- **/
-void
-cal_component_get_description_list (CalComponent *comp, GSList **text_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (text_list != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_text_list (priv->description_list, icalproperty_get_description, text_list);
-}
-
-/**
- * cal_component_set_description_list:
- * @comp: A calendar component object.
- * @text_list: List of #CalComponentSummary structures.
- *
- * Sets the description of a calendar component object. Journal components may
- * have more than one description, and as such this function takes in a list of
- * #CalComponentDescription structures. All other types of components can have
- * at most one description.
- **/
-void
-cal_component_set_description_list (CalComponent *comp, GSList *text_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_text_list (comp, icalproperty_new_description, &priv->description_list, text_list);
-}
-
-/* Gets a date/time and timezone pair */
-static void
-get_datetime (struct datetime *datetime,
- struct icaltimetype (* get_prop_func) (icalproperty *prop),
- CalComponentDateTime *dt)
-{
- if (datetime->prop) {
- dt->value = g_new (struct icaltimetype, 1);
- *dt->value = (* get_prop_func) (datetime->prop);
- } else
- dt->value = NULL;
-
- /* If the icaltimetype has is_utc set, we set "UTC" as the TZID.
- This makes the timezone code simpler. */
- if (datetime->tzid_param)
- dt->tzid = g_strdup (icalparameter_get_tzid (datetime->tzid_param));
- else if (dt->value && dt->value->is_utc)
- dt->tzid = g_strdup ("UTC");
- else
- dt->tzid = NULL;
-}
-
-/* Sets a date/time and timezone pair */
-static void
-set_datetime (CalComponent *comp, struct datetime *datetime,
- icalproperty *(* prop_new_func) (struct icaltimetype v),
- void (* prop_set_func) (icalproperty * prop, struct icaltimetype v),
- CalComponentDateTime *dt)
-{
- CalComponentPrivate *priv;
-
- priv = comp->priv;
-
- /* If we are setting the property to NULL (i.e. removing it), then
- we remove it if it exists. */
- if (!dt) {
- if (datetime->prop) {
- icalcomponent_remove_property (priv->icalcomp, datetime->prop);
- icalproperty_free (datetime->prop);
-
- datetime->prop = NULL;
- datetime->tzid_param = NULL;
- }
-
- return;
- }
-
- g_return_if_fail (dt->value != NULL);
-
- /* If the TZID is set to "UTC", we set the is_utc flag. */
- if (dt->tzid && !strcmp (dt->tzid, "UTC"))
- dt->value->is_utc = 1;
- else
- dt->value->is_utc = 0;
-
- if (datetime->prop) {
- (* prop_set_func) (datetime->prop, *dt->value);
- } else {
- datetime->prop = (* prop_new_func) (*dt->value);
- icalcomponent_add_property (priv->icalcomp, datetime->prop);
- }
-
- /* If the TZID is set to "UTC", we don't want to save the TZID. */
- if (dt->tzid && strcmp (dt->tzid, "UTC")) {
- g_assert (datetime->prop != NULL);
-
- if (datetime->tzid_param) {
- icalparameter_set_tzid (datetime->tzid_param, (char *) dt->tzid);
- } else {
- datetime->tzid_param = icalparameter_new_tzid ((char *) dt->tzid);
- icalproperty_add_parameter (datetime->prop, datetime->tzid_param);
- }
- } else if (datetime->tzid_param) {
- icalproperty_remove_parameter (datetime->prop, ICAL_TZID_PARAMETER);
- icalparameter_free (datetime->tzid_param);
- datetime->tzid_param = NULL;
- }
-}
-
-
-/* This tries to get the DTSTART + DURATION for a VEVENT or VTODO. In a
- VEVENT this is used for the DTEND if no DTEND exists, In a VTOTO it is
- used for the DUE date if DUE doesn't exist. */
-static void
-cal_component_get_start_plus_duration (CalComponent *comp,
- CalComponentDateTime *dt)
-{
- CalComponentPrivate *priv;
- struct icaldurationtype duration;
-
- priv = comp->priv;
-
- if (!priv->duration)
- return;
-
- /* Get the DTSTART time. */
- get_datetime (&priv->dtstart, icalproperty_get_dtstart, dt);
- if (!dt->value)
- return;
-
- duration = icalproperty_get_duration (priv->duration);
-
- /* The DURATION shouldn't be negative, but just return DTSTART if it
- is, i.e. assume it is 0. */
- if (duration.is_neg)
- return;
-
- /* If DTSTART is a DATE value, then we need to check if the DURATION
- includes any hours, minutes or seconds. If it does, we need to
- make the DTEND/DUE a DATE-TIME value. */
- duration.days += duration.weeks * 7;
- if (dt->value->is_date) {
- if (duration.hours != 0 || duration.minutes != 0
- || duration.seconds != 0) {
- dt->value->is_date = 0;
- }
- }
-
- /* Add on the DURATION. */
- icaltime_adjust (dt->value, duration.days, duration.hours,
- duration.minutes, duration.seconds);
-}
-
-
-/**
- * cal_component_get_dtend:
- * @comp: A calendar component object.
- * @dt: Return value for the date/time end. This should be freed with the
- * cal_component_free_datetime() function.
- *
- * Queries the date/time end of a calendar component object.
- **/
-void
-cal_component_get_dtend (CalComponent *comp, CalComponentDateTime *dt)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (dt != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_datetime (&priv->dtend, icalproperty_get_dtend, dt);
-
- /* If we don't have a DTEND property, then we try to get DTSTART
- + DURATION. */
- if (!dt->value)
- cal_component_get_start_plus_duration (comp, dt);
-}
-
-/**
- * cal_component_set_dtend:
- * @comp: A calendar component object.
- * @dt: End date/time.
- *
- * Sets the date/time end property of a calendar component object.
- **/
-void
-cal_component_set_dtend (CalComponent *comp, CalComponentDateTime *dt)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_datetime (comp, &priv->dtend,
- icalproperty_new_dtend,
- icalproperty_set_dtend,
- dt);
-
- /* Make sure we remove any existing DURATION property, as it can't be
- used with a DTEND. If DTEND is set to NULL, i.e. removed, we also
- want to remove any DURATION. */
- if (priv->duration) {
- icalcomponent_remove_property (priv->icalcomp, priv->duration);
- icalproperty_free (priv->duration);
- priv->duration = NULL;
- }
-
- priv->need_sequence_inc = TRUE;
-}
-
-/**
- * cal_component_get_dtstamp:
- * @comp: A calendar component object.
- * @t: A value for the date/timestamp.
- *
- * Queries the date/timestamp property of a calendar component object, which is
- * the last time at which the object was modified by a calendar user agent.
- **/
-void
-cal_component_get_dtstamp (CalComponent *comp, struct icaltimetype *t)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (t != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- /* This MUST exist, since we ensured that it did */
- g_assert (priv->dtstamp != NULL);
-
- *t = icalproperty_get_dtstamp (priv->dtstamp);
-}
-
-/**
- * cal_component_set_dtstamp:
- * @comp: A calendar component object.
- * @t: Date/timestamp value.
- *
- * Sets the date/timestamp of a calendar component object. This should be
- * called whenever a calendar user agent makes a change to a component's
- * properties.
- **/
-void
-cal_component_set_dtstamp (CalComponent *comp, struct icaltimetype *t)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (t != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- /* This MUST exist, since we ensured that it did */
- g_assert (priv->dtstamp != NULL);
-
- icalproperty_set_dtstamp (priv->dtstamp, *t);
-}
-
-/**
- * cal_component_get_dtstart:
- * @comp: A calendar component object.
- * @dt: Return value for the date/time start. This should be freed with the
- * cal_component_free_datetime() function.
- *
- * Queries the date/time start of a calendar component object.
- **/
-void
-cal_component_get_dtstart (CalComponent *comp, CalComponentDateTime *dt)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (dt != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_datetime (&priv->dtstart, icalproperty_get_dtstart, dt);
-}
-
-/**
- * cal_component_set_dtstart:
- * @comp: A calendar component object.
- * @dt: Start date/time.
- *
- * Sets the date/time start property of a calendar component object.
- **/
-void
-cal_component_set_dtstart (CalComponent *comp, CalComponentDateTime *dt)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_datetime (comp, &priv->dtstart,
- icalproperty_new_dtstart,
- icalproperty_set_dtstart,
- dt);
-
- priv->need_sequence_inc = TRUE;
-}
-
-/**
- * cal_component_get_due:
- * @comp: A calendar component object.
- * @dt: Return value for the due date/time. This should be freed with the
- * cal_component_free_datetime() function.
- *
- * Queries the due date/time of a calendar component object.
- **/
-void
-cal_component_get_due (CalComponent *comp, CalComponentDateTime *dt)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (dt != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_datetime (&priv->due, icalproperty_get_due, dt);
-
- /* If we don't have a DTEND property, then we try to get DTSTART
- + DURATION. */
- if (!dt->value)
- cal_component_get_start_plus_duration (comp, dt);
-}
-
-/**
- * cal_component_set_due:
- * @comp: A calendar component object.
- * @dt: End date/time.
- *
- * Sets the due date/time property of a calendar component object.
- **/
-void
-cal_component_set_due (CalComponent *comp, CalComponentDateTime *dt)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_datetime (comp, &priv->due,
- icalproperty_new_due,
- icalproperty_set_due,
- dt);
-
- /* Make sure we remove any existing DURATION property, as it can't be
- used with a DTEND. If DTEND is set to NULL, i.e. removed, we also
- want to remove any DURATION. */
- if (priv->duration) {
- icalcomponent_remove_property (priv->icalcomp, priv->duration);
- icalproperty_free (priv->duration);
- priv->duration = NULL;
- }
-
- priv->need_sequence_inc = TRUE;
-}
-
-/* Builds a list of CalComponentPeriod structures based on a list of icalproperties */
-static void
-get_period_list (GSList *period_list,
- struct icaldatetimeperiodtype (* get_prop_func) (icalproperty *prop),
- GSList **list)
-{
- GSList *l;
-
- *list = NULL;
-
- if (!period_list)
- return;
-
- for (l = period_list; l; l = l->next) {
- struct period *period;
- CalComponentPeriod *p;
- struct icaldatetimeperiodtype ip;
-
- period = l->data;
- g_assert (period->prop != NULL);
-
- p = g_new (CalComponentPeriod, 1);
-
- /* Get value parameter */
-
- if (period->value_param) {
- icalparameter_value value_type;
-
- value_type = icalparameter_get_value (period->value_param);
-
- if (value_type == ICAL_VALUE_DATE || value_type == ICAL_VALUE_DATETIME)
- p->type = CAL_COMPONENT_PERIOD_DATETIME;
- else if (value_type == ICAL_VALUE_DURATION)
- p->type = CAL_COMPONENT_PERIOD_DURATION;
- else {
- g_message ("get_period_list(): Unknown value for period %d; "
- "using DATETIME", value_type);
- p->type = CAL_COMPONENT_PERIOD_DATETIME;
- }
- } else
- p->type = CAL_COMPONENT_PERIOD_DATETIME;
-
- /* Get start and end/duration */
-
- ip = (* get_prop_func) (period->prop);
-
- p->start = ip.period.start;
-
- if (p->type == CAL_COMPONENT_PERIOD_DATETIME)
- p->u.end = ip.period.end;
- else if (p->type == CAL_COMPONENT_PERIOD_DURATION)
- p->u.duration = ip.period.duration;
- else
- g_assert_not_reached ();
-
- /* Put in list */
-
- *list = g_slist_prepend (*list, p);
- }
-
- *list = g_slist_reverse (*list);
-}
-
-/* Sets a period list value */
-static void
-set_period_list (CalComponent *comp,
- icalproperty *(* new_prop_func) (struct icaldatetimeperiodtype period),
- GSList **period_list,
- GSList *pl)
-{
- CalComponentPrivate *priv;
- GSList *l;
-
- priv = comp->priv;
-
- /* Remove old periods */
-
- for (l = *period_list; l; l = l->next) {
- struct period *period;
-
- period = l->data;
- g_assert (period->prop != NULL);
-
- icalcomponent_remove_property (priv->icalcomp, period->prop);
- icalproperty_free (period->prop);
- g_free (period);
- }
-
- g_slist_free (*period_list);
- *period_list = NULL;
-
- /* Add in new periods */
-
- for (l = pl; l; l = l->next) {
- CalComponentPeriod *p;
- struct period *period;
- struct icaldatetimeperiodtype ip;
- icalparameter_value value_type;
-
- g_assert (l->data != NULL);
- p = l->data;
-
- /* Create libical value */
-
- ip.period.start = p->start;
-
- if (p->type == CAL_COMPONENT_PERIOD_DATETIME) {
- value_type = ICAL_VALUE_DATETIME;
- ip.period.end = p->u.end;
- } else if (p->type == CAL_COMPONENT_PERIOD_DURATION) {
- value_type = ICAL_VALUE_DURATION;
- ip.period.duration = p->u.duration;
- } else {
- g_assert_not_reached ();
- return;
- }
-
- /* Create property */
-
- period = g_new (struct period, 1);
-
- period->prop = (* new_prop_func) (ip);
- period->value_param = icalparameter_new_value (value_type);
- icalproperty_add_parameter (period->prop, period->value_param);
-
- /* Add to list */
-
- *period_list = g_slist_prepend (*period_list, period);
- }
-
- *period_list = g_slist_reverse (*period_list);
-}
-
-/**
- * cal_component_get_exdate_list:
- * @comp: A calendar component object.
- * @exdate_list: Return value for the list of exception dates, as a list of
- * #CalComponentDateTime structures. This should be freed using the
- * cal_component_free_exdate_list() function.
- *
- * Queries the list of exception date properties in a calendar component object.
- **/
-void
-cal_component_get_exdate_list (CalComponent *comp, GSList **exdate_list)
-{
- CalComponentPrivate *priv;
- GSList *l;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (exdate_list != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- *exdate_list = NULL;
-
- for (l = priv->exdate_list; l; l = l->next) {
- struct datetime *dt;
- CalComponentDateTime *cdt;
-
- dt = l->data;
-
- cdt = g_new (CalComponentDateTime, 1);
- cdt->value = g_new (struct icaltimetype, 1);
-
- *cdt->value = icalproperty_get_exdate (dt->prop);
-
- if (dt->tzid_param)
- cdt->tzid = g_strdup (icalparameter_get_tzid (dt->tzid_param));
- else
- cdt->tzid = NULL;
-
- *exdate_list = g_slist_prepend (*exdate_list, cdt);
- }
-
- *exdate_list = g_slist_reverse (*exdate_list);
-}
-
-/**
- * cal_component_set_exdate_list:
- * @comp: A calendar component object.
- * @exdate_list: List of #CalComponentDateTime structures.
- *
- * Sets the list of exception dates in a calendar component object.
- **/
-void
-cal_component_set_exdate_list (CalComponent *comp, GSList *exdate_list)
-{
- CalComponentPrivate *priv;
- GSList *l;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- /* Remove old exception dates */
-
- for (l = priv->exdate_list; l; l = l->next) {
- struct datetime *dt;
-
- dt = l->data;
-
- /* Removing the DATE or DATE-TIME property will also remove
- any TZID parameter. */
- icalcomponent_remove_property (priv->icalcomp, dt->prop);
- icalproperty_free (dt->prop);
- g_free (dt);
- }
-
- g_slist_free (priv->exdate_list);
- priv->exdate_list = NULL;
-
- /* Add in new exception dates */
-
- for (l = exdate_list; l; l = l->next) {
- CalComponentDateTime *cdt;
- struct datetime *dt;
-
- g_assert (l->data != NULL);
- cdt = l->data;
-
- g_assert (cdt->value != NULL);
-
- dt = g_new (struct datetime, 1);
- dt->prop = icalproperty_new_exdate (*cdt->value);
-
- if (cdt->tzid) {
- dt->tzid_param = icalparameter_new_tzid ((char *) cdt->tzid);
- icalproperty_add_parameter (dt->prop, dt->tzid_param);
- } else
- dt->tzid_param = NULL;
-
- icalcomponent_add_property (priv->icalcomp, dt->prop);
- priv->exdate_list = g_slist_prepend (priv->exdate_list, dt);
- }
-
- priv->exdate_list = g_slist_reverse (priv->exdate_list);
-
- priv->need_sequence_inc = TRUE;
-}
-
-/**
- * cal_component_has_exdates:
- * @comp: A calendar component object.
- *
- * Queries whether a calendar component object has any exception dates defined
- * for it.
- *
- * Return value: TRUE if the component has exception dates, FALSE otherwise.
- **/
-gboolean
-cal_component_has_exdates (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- g_return_val_if_fail (comp != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE);
-
- priv = comp->priv;
- g_return_val_if_fail (priv->icalcomp != NULL, FALSE);
-
- return (priv->exdate_list != NULL);
-}
-
-/* Gets a list of recurrence rules */
-static void
-get_recur_list (GSList *recur_list,
- struct icalrecurrencetype (* get_prop_func) (icalproperty *prop),
- GSList **list)
-{
- GSList *l;
-
- *list = NULL;
-
- for (l = recur_list; l; l = l->next) {
- icalproperty *prop;
- struct icalrecurrencetype *r;
-
- prop = l->data;
-
- r = g_new (struct icalrecurrencetype, 1);
- *r = (* get_prop_func) (prop);
-
- *list = g_slist_prepend (*list, r);
- }
-
- *list = g_slist_reverse (*list);
-}
-
-/* Sets a list of recurrence rules */
-static void
-set_recur_list (CalComponent *comp,
- icalproperty *(* new_prop_func) (struct icalrecurrencetype recur),
- GSList **recur_list,
- GSList *rl)
-{
- CalComponentPrivate *priv;
- GSList *l;
-
- priv = comp->priv;
-
- /* Remove old recurrences */
-
- for (l = *recur_list; l; l = l->next) {
- icalproperty *prop;
-
- prop = l->data;
- icalcomponent_remove_property (priv->icalcomp, prop);
- icalproperty_free (prop);
- }
-
- g_slist_free (*recur_list);
- *recur_list = NULL;
-
- /* Add in new recurrences */
-
- for (l = rl; l; l = l->next) {
- icalproperty *prop;
- struct icalrecurrencetype *recur;
-
- g_assert (l->data != NULL);
- recur = l->data;
-
- prop = (* new_prop_func) (*recur);
- icalcomponent_add_property (priv->icalcomp, prop);
-
- *recur_list = g_slist_prepend (*recur_list, prop);
- }
-
- *recur_list = g_slist_reverse (*recur_list);
-}
-
-/**
- * cal_component_get_exrule_list:
- * @comp: A calendar component object.
- * @recur_list: List of exception rules as struct #icalrecurrencetype
- * structures. This should be freed using the cal_component_free_recur_list()
- * function.
- *
- * Queries the list of exception rule properties of a calendar component
- * object.
- **/
-void
-cal_component_get_exrule_list (CalComponent *comp, GSList **recur_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (recur_list != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_recur_list (priv->exrule_list, icalproperty_get_exrule, recur_list);
-}
-
-/**
- * cal_component_get_exrule_property_list:
- * @comp: A calendar component object.
- * @recur_list: Returns a list of exception rule properties.
- *
- * Queries the list of exception rule properties of a calendar component object.
- **/
-void
-cal_component_get_exrule_property_list (CalComponent *comp, GSList **recur_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (recur_list != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- *recur_list = priv->exrule_list;
-}
-
-/**
- * cal_component_set_exrule_list:
- * @comp: A calendar component object.
- * @recur_list: List of struct #icalrecurrencetype structures.
- *
- * Sets the list of exception rules in a calendar component object.
- **/
-void
-cal_component_set_exrule_list (CalComponent *comp, GSList *recur_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_recur_list (comp, icalproperty_new_exrule, &priv->exrule_list, recur_list);
-
- priv->need_sequence_inc = TRUE;
-}
-
-/**
- * cal_component_has_exrules:
- * @comp: A calendar component object.
- *
- * Queries whether a calendar component object has any exception rules defined
- * for it.
- *
- * Return value: TRUE if the component has exception rules, FALSE otherwise.
- **/
-gboolean
-cal_component_has_exrules (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- g_return_val_if_fail (comp != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE);
-
- priv = comp->priv;
- g_return_val_if_fail (priv->icalcomp != NULL, FALSE);
-
- return (priv->exrule_list != NULL);
-}
-
-/**
- * cal_component_has_exceptions:
- * @comp: A calendar component object
- *
- * Queries whether a calendar component object has any exception dates
- * or exception rules.
- *
- * Return value: TRUE if the component has exceptions, FALSE otherwise.
- **/
-gboolean
-cal_component_has_exceptions (CalComponent *comp)
-{
- return cal_component_has_exdates (comp) || cal_component_has_exrules (comp);
-}
-
-/**
- * cal_component_get_geo:
- * @comp: A calendar component object.
- * @geo: Return value for the geographic position property. This should be
- * freed using the cal_component_free_geo() function.
- *
- * Sets the geographic position property of a calendar component object.
- **/
-void
-cal_component_get_geo (CalComponent *comp, struct icalgeotype **geo)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (geo != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (priv->geo) {
- *geo = g_new (struct icalgeotype, 1);
- **geo = icalproperty_get_geo (priv->geo);
- } else
- *geo = NULL;
-}
-
-/**
- * cal_component_set_geo:
- * @comp: A calendar component object.
- * @geo: Value for the geographic position property.
- *
- * Sets the geographic position property on a calendar component object.
- **/
-void
-cal_component_set_geo (CalComponent *comp, struct icalgeotype *geo)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!geo) {
- if (priv->geo) {
- icalcomponent_remove_property (priv->icalcomp, priv->geo);
- icalproperty_free (priv->geo);
- priv->geo = NULL;
- }
-
- return;
- }
-
- if (priv->geo)
- icalproperty_set_geo (priv->geo, *geo);
- else {
- priv->geo = icalproperty_new_geo (*geo);
- icalcomponent_add_property (priv->icalcomp, priv->geo);
- }
-}
-
-/**
- * cal_component_get_last_modified:
- * @comp: A calendar component object.
- * @t: Return value for the last modified time value.
- *
- * Queries the time at which a calendar component object was last modified in
- * the calendar store.
- **/
-void
-cal_component_get_last_modified (CalComponent *comp, struct icaltimetype **t)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (t != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_icaltimetype (priv->last_modified, icalproperty_get_lastmodified, t);
-}
-
-/**
- * cal_component_set_last_modified:
- * @comp: A calendar component object.
- * @t: Value for the last time modified.
- *
- * Sets the time at which a calendar component object was last stored in the
- * calendar store. This should not be called by plain calendar user agents.
- **/
-void
-cal_component_set_last_modified (CalComponent *comp, struct icaltimetype *t)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_icaltimetype (comp, &priv->last_modified,
- icalproperty_new_lastmodified,
- icalproperty_set_lastmodified,
- t);
-}
-
-/**
- * cal_component_get_organizer:
- * @comp: A calendar component object
- * @organizer: A value for the organizer
- *
- * Queries the organizer property of a calendar component object
- **/
-void
-cal_component_get_organizer (CalComponent *comp, CalComponentOrganizer *organizer)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (organizer != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (priv->organizer.prop)
- organizer->value = icalproperty_get_organizer (priv->organizer.prop);
- else
- organizer->value = NULL;
-
- if (priv->organizer.sentby_param)
- organizer->sentby = icalparameter_get_sentby (priv->organizer.sentby_param);
- else
- organizer->sentby = NULL;
-
- if (priv->organizer.cn_param)
- organizer->cn = icalparameter_get_sentby (priv->organizer.cn_param);
- else
- organizer->cn = NULL;
-
- if (priv->organizer.language_param)
- organizer->language = icalparameter_get_sentby (priv->organizer.language_param);
- else
- organizer->language = NULL;
-
-}
-
-/**
- * cal_component_set_organizer:
- * @comp: A calendar component object.
- * @organizer: Value for the organizer property
- *
- * Sets the organizer of a calendar component object
- **/
-void
-cal_component_set_organizer (CalComponent *comp, CalComponentOrganizer *organizer)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!organizer) {
- if (priv->organizer.prop) {
- icalcomponent_remove_property (priv->icalcomp, priv->organizer.prop);
- icalproperty_free (priv->organizer.prop);
-
- priv->organizer.prop = NULL;
- priv->organizer.sentby_param = NULL;
- priv->organizer.cn_param = NULL;
- priv->organizer.language_param = NULL;
- }
-
- return;
- }
-
- g_return_if_fail (organizer->value != NULL);
-
- if (priv->organizer.prop)
- icalproperty_set_organizer (priv->organizer.prop, (char *) organizer->value);
- else {
- priv->organizer.prop = icalproperty_new_organizer ((char *) organizer->value);
- icalcomponent_add_property (priv->icalcomp, priv->organizer.prop);
- }
-
- if (organizer->sentby) {
- g_assert (priv->organizer.prop != NULL);
-
- if (priv->organizer.sentby_param)
- icalparameter_set_sentby (priv->organizer.sentby_param,
- (char *) organizer->sentby);
- else {
- priv->organizer.sentby_param = icalparameter_new_sentby (
- (char *) organizer->sentby);
- icalproperty_add_parameter (priv->organizer.prop,
- priv->organizer.sentby_param);
- }
- } else if (priv->organizer.sentby_param) {
- icalproperty_remove_parameter (priv->organizer.prop, ICAL_SENTBY_PARAMETER);
- icalparameter_free (priv->organizer.sentby_param);
- priv->organizer.sentby_param = NULL;
- }
-
- if (organizer->cn) {
- g_assert (priv->organizer.prop != NULL);
-
- if (priv->organizer.cn_param)
- icalparameter_set_cn (priv->organizer.cn_param,
- (char *) organizer->cn);
- else {
- priv->organizer.cn_param = icalparameter_new_cn (
- (char *) organizer->cn);
- icalproperty_add_parameter (priv->organizer.prop,
- priv->organizer.cn_param);
- }
- } else if (priv->organizer.cn_param) {
- icalproperty_remove_parameter (priv->organizer.prop, ICAL_CN_PARAMETER);
- icalparameter_free (priv->organizer.cn_param);
- priv->organizer.cn_param = NULL;
- }
-
- if (organizer->language) {
- g_assert (priv->organizer.prop != NULL);
-
- if (priv->organizer.language_param)
- icalparameter_set_language (priv->organizer.language_param,
- (char *) organizer->language);
- else {
- priv->organizer.language_param = icalparameter_new_language (
- (char *) organizer->language);
- icalproperty_add_parameter (priv->organizer.prop,
- priv->organizer.language_param);
- }
- } else if (priv->organizer.language_param) {
- icalproperty_remove_parameter (priv->organizer.prop, ICAL_LANGUAGE_PARAMETER);
- icalparameter_free (priv->organizer.language_param);
- priv->organizer.language_param = NULL;
- }
-
-
-}
-
-
-/**
- * cal_component_has_organizer:
- * @comp:
- *
- *
- *
- * Return value:
- **/
-gboolean
-cal_component_has_organizer (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- g_return_val_if_fail (comp != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE);
-
- priv = comp->priv;
-
- return priv->organizer.prop != NULL;
-}
-
-/**
- * cal_component_get_percent:
- * @comp: A calendar component object.
- * @percent: Return value for the percent-complete property. This should be
- * freed using the cal_component_free_percent() function.
- *
- * Queries the percent-complete property of a calendar component object.
- **/
-void
-cal_component_get_percent (CalComponent *comp, int **percent)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (percent != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (priv->percent) {
- *percent = g_new (int, 1);
- **percent = icalproperty_get_percentcomplete (priv->percent);
- } else
- *percent = NULL;
-}
-
-/**
- * cal_component_set_percent:
- * @comp: A calendar component object.
- * @percent: Value for the percent-complete property.
- *
- * Sets the percent-complete property of a calendar component object.
- **/
-void
-cal_component_set_percent (CalComponent *comp, int *percent)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!percent) {
- if (priv->percent) {
- icalcomponent_remove_property (priv->icalcomp, priv->percent);
- icalproperty_free (priv->percent);
- priv->percent = NULL;
- }
-
- return;
- }
-
- g_return_if_fail (*percent >= 0 && *percent <= 100);
-
- if (priv->percent)
- icalproperty_set_percentcomplete (priv->percent, *percent);
- else {
- priv->percent = icalproperty_new_percentcomplete (*percent);
- icalcomponent_add_property (priv->icalcomp, priv->percent);
- }
-}
-
-/**
- * cal_component_get_priority:
- * @comp: A calendar component object.
- * @priority: Return value for the priority property. This should be freed using
- * the cal_component_free_priority() function.
- *
- * Queries the priority property of a calendar component object.
- **/
-void
-cal_component_get_priority (CalComponent *comp, int **priority)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (priority != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (priv->priority) {
- *priority = g_new (int, 1);
- **priority = icalproperty_get_priority (priv->priority);
- } else
- *priority = NULL;
-}
-
-/**
- * cal_component_set_priority:
- * @comp: A calendar component object.
- * @priority: Value for the priority property.
- *
- * Sets the priority property of a calendar component object.
- **/
-void
-cal_component_set_priority (CalComponent *comp, int *priority)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!priority) {
- if (priv->priority) {
- icalcomponent_remove_property (priv->icalcomp, priv->priority);
- icalproperty_free (priv->priority);
- priv->priority = NULL;
- }
-
- return;
- }
-
- g_return_if_fail (*priority >= 0 && *priority <= 9);
-
- if (priv->priority)
- icalproperty_set_priority (priv->priority, *priority);
- else {
- priv->priority = icalproperty_new_priority (*priority);
- icalcomponent_add_property (priv->icalcomp, priv->priority);
- }
-}
-
-/**
- * cal_component_get_recurid:
- * @comp: A calendar component object.
- * @recur_id: Return value for the recurrence id property
- *
- * Queries the recurrence id property of a calendar component object
- **/
-void
-cal_component_get_recurid (CalComponent *comp, CalComponentRange *recur_id)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (recur_id != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_datetime (&priv->recur_id.recur_time,
- icalproperty_get_recurrenceid,
- &recur_id->datetime);
-}
-
-/**
- * cal_component_set_recurid:
- * @comp: A calendar component object.
- * @recur_id: Value for the recurrence id property.
- *
- * Sets the recurrence id property of a calendar component object.
- **/
-void
-cal_component_set_recurid (CalComponent *comp, CalComponentRange *recur_id)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_datetime (comp, &priv->recur_id.recur_time,
- icalproperty_new_recurrenceid,
- icalproperty_set_recurrenceid,
- &recur_id->datetime);
-}
-
-/**
- * cal_component_get_rdate_list:
- * @comp: A calendar component object.
- * @period_list: Return value for the list of recurrence dates, as a list of
- * #CalComponentPeriod structures. This should be freed using the
- * cal_component_free_period_list() function.
- *
- * Queries the list of recurrence date properties in a calendar component
- * object.
- **/
-void
-cal_component_get_rdate_list (CalComponent *comp, GSList **period_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (period_list != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_period_list (priv->rdate_list, icalproperty_get_rdate, period_list);
-}
-
-/**
- * cal_component_set_rdate_list:
- * @comp: A calendar component object.
- * @period_list: List of #CalComponentPeriod structures.
- *
- * Sets the list of recurrence dates in a calendar component object.
- **/
-void
-cal_component_set_rdate_list (CalComponent *comp, GSList *period_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_period_list (comp, icalproperty_new_rdate, &priv->rdate_list, period_list);
-
- priv->need_sequence_inc = TRUE;
-}
-
-/**
- * cal_component_has_rdates:
- * @comp: A calendar component object.
- *
- * Queries whether a calendar component object has any recurrence dates defined
- * for it.
- *
- * Return value: TRUE if the component has recurrence dates, FALSE otherwise.
- **/
-gboolean
-cal_component_has_rdates (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- g_return_val_if_fail (comp != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE);
-
- priv = comp->priv;
- g_return_val_if_fail (priv->icalcomp != NULL, FALSE);
-
- return (priv->rdate_list != NULL);
-}
-
-/**
- * cal_component_get_rrule_list:
- * @comp: A calendar component object.
- * @recur_list: List of recurrence rules as struct #icalrecurrencetype
- * structures. This should be freed using the cal_component_free_recur_list()
- * function.
- *
- * Queries the list of recurrence rule properties of a calendar component
- * object.
- **/
-void
-cal_component_get_rrule_list (CalComponent *comp, GSList **recur_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (recur_list != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_recur_list (priv->rrule_list, icalproperty_get_rrule, recur_list);
-}
-
-/**
- * cal_component_get_rrule_property_list:
- * @comp: A calendar component object.
- * @recur_list: Returns a list of recurrence rule properties.
- *
- * Queries a list of recurrence rule properties of a calendar component object.
- **/
-void
-cal_component_get_rrule_property_list (CalComponent *comp, GSList **recur_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (recur_list != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- *recur_list = priv->rrule_list;
-}
-
-/**
- * cal_component_set_rrule_list:
- * @comp: A calendar component object.
- * @recur_list: List of struct #icalrecurrencetype structures.
- *
- * Sets the list of recurrence rules in a calendar component object.
- **/
-void
-cal_component_set_rrule_list (CalComponent *comp, GSList *recur_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_recur_list (comp, icalproperty_new_rrule, &priv->rrule_list, recur_list);
-
- priv->need_sequence_inc = TRUE;
-}
-
-/**
- * cal_component_has_rrules:
- * @comp: A calendar component object.
- *
- * Queries whether a calendar component object has any recurrence rules defined
- * for it.
- *
- * Return value: TRUE if the component has recurrence rules, FALSE otherwise.
- **/
-gboolean
-cal_component_has_rrules (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- g_return_val_if_fail (comp != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE);
-
- priv = comp->priv;
- g_return_val_if_fail (priv->icalcomp != NULL, FALSE);
-
- return (priv->rrule_list != NULL);
-}
-
-/**
- * cal_component_has_recurrences:
- * @comp: A calendar component object
- *
- * Queries whether a calendar component object has any recurrence dates or
- * recurrence rules.
- *
- * Return value: TRUE if the component has recurrences, FALSE otherwise.
- **/
-gboolean
-cal_component_has_recurrences (CalComponent *comp)
-{
- return cal_component_has_rdates (comp) || cal_component_has_rrules (comp);
-}
-
-/**
- * cal_component_get_sequence:
- * @comp: A calendar component object.
- * @sequence: Return value for the sequence number. This should be freed using
- * cal_component_free_sequence().
- *
- * Queries the sequence number of a calendar component object.
- **/
-void
-cal_component_get_sequence (CalComponent *comp, int **sequence)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (sequence != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!priv->sequence) {
- *sequence = NULL;
- return;
- }
-
- *sequence = g_new (int, 1);
- **sequence = icalproperty_get_sequence (priv->sequence);
-}
-
-/**
- * cal_component_set_sequence:
- * @comp: A calendar component object.
- * @sequence: Sequence number value.
- *
- * Sets the sequence number of a calendar component object. Normally this
- * function should not be called, since the sequence number is incremented
- * automatically at the proper times.
- **/
-void
-cal_component_set_sequence (CalComponent *comp, int *sequence)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- priv->need_sequence_inc = FALSE;
-
- if (!sequence) {
- if (priv->sequence) {
- icalcomponent_remove_property (priv->icalcomp, priv->sequence);
- icalproperty_free (priv->sequence);
- priv->sequence = NULL;
- }
-
- return;
- }
-
- if (priv->sequence)
- icalproperty_set_sequence (priv->sequence, *sequence);
- else {
- priv->sequence = icalproperty_new_sequence (*sequence);
- icalcomponent_add_property (priv->icalcomp, priv->sequence);
- }
-}
-
-/**
- * cal_component_get_status:
- * @comp: A calendar component object.
- * @status: Return value for the status value. It is set to #ICAL_STATUS_NONE
- * if the component has no status property.
- *
- * Queries the status property of a calendar component object.
- **/
-void
-cal_component_get_status (CalComponent *comp, icalproperty_status *status)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (status != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!priv->status) {
- *status = ICAL_STATUS_NONE;
- return;
- }
-
- *status = icalproperty_get_status (priv->status);
-}
-
-/**
- * cal_component_set_status:
- * @comp: A calendar component object.
- * @status: Status value. You should use #ICAL_STATUS_NONE if you want to unset
- * this property.
- *
- * Sets the status property of a calendar component object.
- **/
-void
-cal_component_set_status (CalComponent *comp, icalproperty_status status)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- priv->need_sequence_inc = TRUE;
-
- if (status == ICAL_STATUS_NONE) {
- if (priv->status) {
- icalcomponent_remove_property (priv->icalcomp, priv->status);
- icalproperty_free (priv->status);
- priv->status = NULL;
- }
-
- return;
- }
-
- if (priv->status) {
- icalproperty_set_status (priv->status, status);
- } else {
- priv->status = icalproperty_new_status (status);
- icalcomponent_add_property (priv->icalcomp, priv->status);
- }
-}
-
-/**
- * cal_component_get_summary:
- * @comp: A calendar component object.
- * @summary: Return value for the summary property and its parameters.
- *
- * Queries the summary of a calendar component object.
- **/
-void
-cal_component_get_summary (CalComponent *comp, CalComponentText *summary)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (summary != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (priv->summary.prop)
- summary->value = icalproperty_get_summary (priv->summary.prop);
- else
- summary->value = NULL;
-
- if (priv->summary.altrep_param)
- summary->altrep = icalparameter_get_altrep (priv->summary.altrep_param);
- else
- summary->altrep = NULL;
-}
-
-/**
- * cal_component_set_summary:
- * @comp: A calendar component object.
- * @summary: Summary property and its parameters.
- *
- * Sets the summary of a calendar component object.
- **/
-void
-cal_component_set_summary (CalComponent *comp, CalComponentText *summary)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!summary) {
- if (priv->summary.prop) {
- icalcomponent_remove_property (priv->icalcomp, priv->summary.prop);
- icalproperty_free (priv->summary.prop);
-
- priv->summary.prop = NULL;
- priv->summary.altrep_param = NULL;
- }
-
- return;
- }
-
- g_return_if_fail (summary->value != NULL);
-
- if (priv->summary.prop)
- icalproperty_set_summary (priv->summary.prop, (char *) summary->value);
- else {
- priv->summary.prop = icalproperty_new_summary ((char *) summary->value);
- icalcomponent_add_property (priv->icalcomp, priv->summary.prop);
- }
-
- if (summary->altrep) {
- g_assert (priv->summary.prop != NULL);
-
- if (priv->summary.altrep_param)
- icalparameter_set_altrep (priv->summary.altrep_param,
- (char *) summary->altrep);
- else {
- priv->summary.altrep_param = icalparameter_new_altrep (
- (char *) summary->altrep);
- icalproperty_add_parameter (priv->summary.prop,
- priv->summary.altrep_param);
- }
- } else if (priv->summary.altrep_param) {
- icalproperty_remove_parameter (priv->summary.prop, ICAL_ALTREP_PARAMETER);
- icalparameter_free (priv->summary.altrep_param);
- priv->summary.altrep_param = NULL;
- }
-}
-
-/**
- * cal_component_get_transparency:
- * @comp: A calendar component object.
- * @transp: Return value for the time transparency.
- *
- * Queries the time transparency of a calendar component object.
- **/
-void
-cal_component_get_transparency (CalComponent *comp, CalComponentTransparency *transp)
-{
- CalComponentPrivate *priv;
- const char *val;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (transp != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!priv->transparency) {
- *transp = CAL_COMPONENT_TRANSP_NONE;
- return;
- }
-
- val = icalproperty_get_transp (priv->transparency);
-
- if (strcasecmp (val, "TRANSPARENT") == 0)
- *transp = CAL_COMPONENT_TRANSP_TRANSPARENT;
- else if (strcasecmp (val, "OPAQUE") == 0)
- *transp = CAL_COMPONENT_TRANSP_OPAQUE;
- else
- *transp = CAL_COMPONENT_TRANSP_UNKNOWN;
-}
-
-/**
- * cal_component_set_transparency:
- * @comp: A calendar component object.
- * @transp: Time transparency value.
- *
- * Sets the time transparency of a calendar component object.
- **/
-void
-cal_component_set_transparency (CalComponent *comp, CalComponentTransparency transp)
-{
- CalComponentPrivate *priv;
- char *str;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (transp != CAL_COMPONENT_TRANSP_UNKNOWN);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
-
- if (transp == CAL_COMPONENT_TRANSP_NONE) {
- if (priv->transparency) {
- icalcomponent_remove_property (priv->icalcomp, priv->transparency);
- icalproperty_free (priv->transparency);
- priv->transparency = NULL;
- }
-
- return;
- }
-
- switch (transp) {
- case CAL_COMPONENT_TRANSP_TRANSPARENT:
- str = "TRANSPARENT";
- break;
-
- case CAL_COMPONENT_TRANSP_OPAQUE:
- str = "OPAQUE";
- break;
-
- default:
- g_assert_not_reached ();
- str = NULL;
- }
-
- if (priv->transparency)
- icalproperty_set_transp (priv->transparency, str);
- else {
- priv->transparency = icalproperty_new_transp (str);
- icalcomponent_add_property (priv->icalcomp, priv->transparency);
- }
-}
-
-/**
- * cal_component_get_url:
- * @comp: A calendar component object.
- * @url: Return value for the URL.
- *
- * Queries the uniform resource locator property of a calendar component object.
- **/
-void
-cal_component_get_url (CalComponent *comp, const char **url)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (url != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (priv->url)
- *url = icalproperty_get_url (priv->url);
- else
- *url = NULL;
-}
-
-/**
- * cal_component_set_url:
- * @comp: A calendar component object.
- * @url: URL value.
- *
- * Sets the uniform resource locator property of a calendar component object.
- **/
-void
-cal_component_set_url (CalComponent *comp, const char *url)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!url || !(*url)) {
- if (priv->url) {
- icalcomponent_remove_property (priv->icalcomp, priv->url);
- icalproperty_free (priv->url);
- priv->url = NULL;
- }
-
- return;
- }
-
- if (priv->url)
- icalproperty_set_url (priv->url, (char *) url);
- else {
- priv->url = icalproperty_new_url ((char *) url);
- icalcomponent_add_property (priv->icalcomp, priv->url);
- }
-}
-
-/* Gets a text list value */
-static void
-get_attendee_list (GSList *attendee_list, GSList **al)
-{
- GSList *l;
-
- *al = NULL;
-
- if (!attendee_list)
- return;
-
- for (l = attendee_list; l; l = l->next) {
- struct attendee *attendee;
- CalComponentAttendee *a;
-
- attendee = l->data;
- g_assert (attendee->prop != NULL);
-
- a = g_new0 (CalComponentAttendee, 1);
- a->value = icalproperty_get_attendee (attendee->prop);
-
- if (attendee->member_param)
- a->member = icalparameter_get_member (attendee->member_param);
- if (attendee->cutype_param)
- a->cutype = icalparameter_get_cutype (attendee->cutype_param);
- if (attendee->role_param)
- a->role = icalparameter_get_role (attendee->role_param);
- if (attendee->partstat_param)
- a->status = icalparameter_get_role (attendee->partstat_param);
- if (attendee->rsvp_param && icalparameter_get_rsvp (attendee->rsvp_param) == ICAL_RSVP_TRUE)
- a->rsvp = TRUE;
- else
- a->rsvp = FALSE;
- if (attendee->delfrom_param)
- a->delfrom = icalparameter_get_sentby (attendee->delfrom_param);
- if (attendee->delto_param)
- a->delto = icalparameter_get_sentby (attendee->delto_param);
- if (attendee->sentby_param)
- a->sentby = icalparameter_get_sentby (attendee->sentby_param);
- if (attendee->cn_param)
- a->cn = icalparameter_get_sentby (attendee->cn_param);
- if (attendee->language_param)
- a->language = icalparameter_get_sentby (attendee->language_param);
-
- *al = g_slist_prepend (*al, a);
- }
-
- *al = g_slist_reverse (*al);
-}
-
-
-/* Sets a text list value */
-static void
-set_attendee_list (CalComponent *comp,
- GSList **attendee_list,
- GSList *al)
-{
- CalComponentPrivate *priv;
- GSList *l;
-
- priv = comp->priv;
-
- /* Remove old attendees */
-
- for (l = *attendee_list; l; l = l->next) {
- struct attendee *attendee;
-
- attendee = l->data;
- g_assert (attendee->prop != NULL);
-
- icalcomponent_remove_property (priv->icalcomp, attendee->prop);
- icalproperty_free (attendee->prop);
- g_free (attendee);
- }
-
- g_slist_free (*attendee_list);
- *attendee_list = NULL;
-
- /* Add in new attendees */
-
- for (l = al; l; l = l->next) {
- CalComponentAttendee *a;
- struct attendee *attendee;
-
- a = l->data;
- g_return_if_fail (a->value != NULL);
-
- attendee = g_new0 (struct attendee, 1);
-
- attendee->prop = icalproperty_new_attendee (a->value);
- icalcomponent_add_property (priv->icalcomp, attendee->prop);
-
- if (a->member) {
- attendee->member_param = icalparameter_new_member (a->member);
- icalproperty_add_parameter (attendee->prop, attendee->member_param);
- }
-
- attendee->cutype_param = icalparameter_new_cutype (a->cutype);
- icalproperty_add_parameter (attendee->prop, attendee->cutype_param);
-
- attendee->role_param = icalparameter_new_role (a->role);
- icalproperty_add_parameter (attendee->prop, attendee->role_param);
-
- attendee->partstat_param = icalparameter_new_partstat (a->status);
- icalproperty_add_parameter (attendee->prop, attendee->partstat_param);
-
- if (a->rsvp)
- attendee->rsvp_param = icalparameter_new_rsvp (ICAL_RSVP_TRUE);
- else
- attendee->rsvp_param = icalparameter_new_rsvp (ICAL_RSVP_FALSE);
- icalproperty_add_parameter (attendee->prop, attendee->rsvp_param);
-
- if (a->delfrom) {
- attendee->delfrom_param = icalparameter_new_delegatedfrom (a->delfrom);
- icalproperty_add_parameter (attendee->prop, attendee->delfrom_param);
- }
- if (a->delto) {
- attendee->delto_param = icalparameter_new_delegatedto (a->delto);
- icalproperty_add_parameter (attendee->prop, attendee->delto_param);
- }
- if (a->sentby) {
- attendee->sentby_param = icalparameter_new_sentby (a->sentby);
- icalproperty_add_parameter (attendee->prop, attendee->sentby_param);
- }
- if (a->cn) {
- attendee->cn_param = icalparameter_new_cn (a->cn);
- icalproperty_add_parameter (attendee->prop, attendee->cn_param);
- }
- if (a->language) {
- attendee->language_param = icalparameter_new_language (a->language);
- icalproperty_add_parameter (attendee->prop, attendee->language_param);
- }
-
- *attendee_list = g_slist_prepend (*attendee_list, attendee);
- }
-
- *attendee_list = g_slist_reverse (*attendee_list);
-}
-
-/**
- * cal_component_get_attendee_list:
- * @comp: A calendar component object.
- * @attendee_list: Return value for the attendee property.
- * This should be freed using the cal_component_free_attendee_list ()
- * function.
- *
- * Queries the attendee properties of the calendar component object
- **/
-void
-cal_component_get_attendee_list (CalComponent *comp, GSList **attendee_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (attendee_list != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- get_attendee_list (priv->attendee_list, attendee_list);
-}
-
-/**
- * cal_component_set_attendee_list:
- * @comp: A calendar component object.
- * @attendee_list: Values for attendee properties
- *
- * Sets the attendees of a calendar component object
- **/
-void
-cal_component_set_attendee_list (CalComponent *comp, GSList *attendee_list)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- set_attendee_list (comp, &priv->attendee_list, attendee_list);
-}
-
-gboolean
-cal_component_has_attendees (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- g_return_val_if_fail (comp != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE);
-
- priv = comp->priv;
-
- if (g_slist_length (priv->attendee_list) > 0)
- return TRUE;
-
- return FALSE;
-}
-
-/**
- * cal_component_get_location:
- * @comp: A calendar component object.
- * @url: Return value for the location.
- *
- * Queries the location property of a calendar component object.
- **/
-void
-cal_component_get_location (CalComponent *comp, const char **location)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (location != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (priv->location)
- *location = icalproperty_get_location (priv->location);
- else
- *location = NULL;
-}
-
-/**
- * cal_component_set_location:
- * @comp: A calendar component object.
- * @url: Location value.
- *
- * Sets the location property of a calendar component object.
- **/
-void
-cal_component_set_location (CalComponent *comp, const char *location)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- if (!location || !(*location)) {
- if (priv->location) {
- icalcomponent_remove_property (priv->icalcomp, priv->location);
- icalproperty_free (priv->location);
- priv->location = NULL;
- }
-
- return;
- }
-
- if (priv->location)
- icalproperty_set_location (priv->location, (char *) location);
- else {
- priv->location = icalproperty_new_location ((char *) location);
- icalcomponent_add_property (priv->icalcomp, priv->location);
- }
-}
-
-
-
-/**
- * cal_component_free_categories_list:
- * @categ_list: List of category strings.
- *
- * Frees a list of category strings.
- **/
-void
-cal_component_free_categories_list (GSList *categ_list)
-{
- GSList *l;
-
- for (l = categ_list; l; l = l->next)
- g_free (l->data);
-
- g_slist_free (categ_list);
-}
-
-/**
- * cal_component_free_datetime:
- * @dt: A date/time structure.
- *
- * Frees a date/time structure.
- **/
-void
-cal_component_free_datetime (CalComponentDateTime *dt)
-{
- g_return_if_fail (dt != NULL);
-
- g_free (dt->value);
- g_free ((char*)dt->tzid);
-}
-
-/**
- * cal_component_free_exdate_list:
- * @exdate_list: List of #CalComponentDateTime structures.
- *
- * Frees a list of #CalComponentDateTime structures as returned by the
- * cal_component_get_exdate_list() function.
- **/
-void
-cal_component_free_exdate_list (GSList *exdate_list)
-{
- GSList *l;
-
- for (l = exdate_list; l; l = l->next) {
- CalComponentDateTime *cdt;
-
- g_assert (l->data != NULL);
- cdt = l->data;
-
- g_assert (cdt->value != NULL);
- g_free (cdt->value);
- g_free ((char*)cdt->tzid);
-
- g_free (cdt);
- }
-
- g_slist_free (exdate_list);
-}
-
-/**
- * cal_component_free_geo:
- * @geo: An #icalgeotype structure.
- *
- * Frees a struct #icalgeotype structure as returned by the calendar component
- * functions.
- **/
-void
-cal_component_free_geo (struct icalgeotype *geo)
-{
- g_return_if_fail (geo != NULL);
-
- g_free (geo);
-}
-
-/**
- * cal_component_free_icaltimetype:
- * @t: An #icaltimetype structure.
- *
- * Frees a struct #icaltimetype value as returned by the calendar component
- * functions.
- **/
-void
-cal_component_free_icaltimetype (struct icaltimetype *t)
-{
- g_return_if_fail (t != NULL);
-
- g_free (t);
-}
-
-/**
- * cal_component_free_percent:
- * @percent: Percent value.
- *
- * Frees a percent value as returned by the cal_component_get_percent()
- * function.
- **/
-void
-cal_component_free_percent (int *percent)
-{
- g_return_if_fail (percent != NULL);
-
- g_free (percent);
-}
-
-/**
- * cal_component_free_priority:
- * @priority: Priority value.
- *
- * Frees a priority value as returned by the cal_component_get_priority()
- * function.
- **/
-void
-cal_component_free_priority (int *priority)
-{
- g_return_if_fail (priority != NULL);
-
- g_free (priority);
-}
-
-/**
- * cal_component_free_period_list:
- * @period_list: List of #CalComponentPeriod structures.
- *
- * Frees a list of #CalComponentPeriod structures.
- **/
-void
-cal_component_free_period_list (GSList *period_list)
-{
- GSList *l;
-
- for (l = period_list; l; l = l->next) {
- CalComponentPeriod *period;
-
- g_assert (l->data != NULL);
-
- period = l->data;
- g_free (period);
- }
-
- g_slist_free (period_list);
-}
-
-/**
- * cal_component_free_recur_list:
- * @recur_list: List of struct #icalrecurrencetype structures.
- *
- * Frees a list of struct #icalrecurrencetype structures.
- **/
-void
-cal_component_free_recur_list (GSList *recur_list)
-{
- GSList *l;
-
- for (l = recur_list; l; l = l->next) {
- struct icalrecurrencetype *r;
-
- g_assert (l->data != NULL);
- r = l->data;
-
- g_free (r);
- }
-
- g_slist_free (recur_list);
-}
-
-/**
- * cal_component_free_sequence:
- * @sequence: Sequence number value.
- *
- * Frees a sequence number value.
- **/
-void
-cal_component_free_sequence (int *sequence)
-{
- g_return_if_fail (sequence != NULL);
-
- g_free (sequence);
-}
-
-/**
- * cal_component_free_text_list:
- * @text_list: List of #CalComponentText structures.
- *
- * Frees a list of #CalComponentText structures. This function should only be
- * used to free lists of text values as returned by the other getter functions
- * of #CalComponent.
- **/
-void
-cal_component_free_text_list (GSList *text_list)
-{
- GSList *l;
-
- for (l = text_list; l; l = l->next) {
- CalComponentText *text;
-
- g_assert (l->data != NULL);
-
- text = l->data;
- g_return_if_fail (text != NULL);
- g_free (text);
- }
-
- g_slist_free (text_list);
-}
-
-/**
- * cal_component_free_attendee_list:
- * @attendee_list:
- *
- *
- **/
-void
-cal_component_free_attendee_list (GSList *attendee_list)
-{
- GSList *l;
-
- for (l = attendee_list; l; l = l->next) {
- CalComponentAttendee *attendee;
-
- g_assert (l->data != NULL);
-
- attendee = l->data;
- g_return_if_fail (attendee != NULL);
- g_free (attendee);
- }
-
- g_slist_free (attendee_list);
-}
-
-
-
-/**
- * cal_component_has_alarms:
- * @comp: A calendar component object.
- *
- * Checks whether the component has any alarms.
- *
- * Return value: TRUE if the component has any alarms.
- **/
-gboolean
-cal_component_has_alarms (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- g_return_val_if_fail (comp != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE);
-
- priv = comp->priv;
- g_return_val_if_fail (priv->icalcomp != NULL, FALSE);
-
- return g_hash_table_size (priv->alarm_uid_hash) != 0;
-}
-
-/**
- * cal_component_add_alarm:
- * @comp: A calendar component.
- * @alarm: An alarm.
- *
- * Adds an alarm subcomponent to a calendar component. You should have created
- * the @alarm by using cal_component_alarm_new(); it is invalid to use a
- * #CalComponentAlarm structure that came from cal_component_get_alarm(). After
- * adding the alarm, the @alarm structure is no longer valid because the
- * internal structures may change and you should get rid of it by using
- * cal_component_alarm_free().
- **/
-void
-cal_component_add_alarm (CalComponent *comp, CalComponentAlarm *alarm)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (alarm != NULL);
-
- priv = comp->priv;
-
- add_alarm (comp, alarm->icalcomp, icalproperty_get_x (alarm->uid));
- icalcomponent_add_component (priv->icalcomp, alarm->icalcomp);
-}
-
-/**
- * cal_component_remove_alarm:
- * @comp: A calendar component.
- * @auid: UID of the alarm to remove.
- *
- * Removes an alarm subcomponent from a calendar component. If the alarm that
- * corresponds to the specified @auid had been fetched with
- * cal_component_get_alarm(), then those alarm structures will be invalid; you
- * should get rid of them with cal_component_alarm_free() before using this
- * function.
- **/
-void
-cal_component_remove_alarm (CalComponent *comp, const char *auid)
-{
- CalComponentPrivate *priv;
- icalcomponent *alarm;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
- g_return_if_fail (auid != NULL);
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- alarm = g_hash_table_lookup (priv->alarm_uid_hash, auid);
- if (!alarm)
- return;
-
- g_hash_table_remove (priv->alarm_uid_hash, auid);
- icalcomponent_remove_component (priv->icalcomp, alarm);
- icalcomponent_free (alarm);
-}
-
-static gboolean
-for_each_remove_all_alarms (gpointer key, gpointer value, gpointer data)
-{
- CalComponent *comp = CAL_COMPONENT (data);
- CalComponentPrivate *priv;
- icalcomponent *alarm = value;
-
- priv = comp->priv;
-
- icalcomponent_remove_component (priv->icalcomp, alarm);
- icalcomponent_free (alarm);
-
- return TRUE;
-}
-
-/**
- * cal_component_remove_all_alarms:
- * @comp: A calendar component
- *
- * Remove all alarms from the calendar component
- **/
-void
-cal_component_remove_all_alarms (CalComponent *comp)
-{
- CalComponentPrivate *priv;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- priv = comp->priv;
- g_return_if_fail (priv->icalcomp != NULL);
-
- g_hash_table_foreach_remove (priv->alarm_uid_hash, for_each_remove_all_alarms, comp);
-}
-
-
-/* Scans an icalproperty from a calendar component and adds its mapping to our
- * own alarm structure.
- */
-static void
-scan_alarm_property (CalComponentAlarm *alarm, icalproperty *prop)
-{
- icalproperty_kind kind;
- const char *xname;
-
- kind = icalproperty_isa (prop);
-
- switch (kind) {
- case ICAL_ACTION_PROPERTY:
- alarm->action = prop;
- break;
-
- case ICAL_ATTACH_PROPERTY:
- /* FIXME: mail alarms may have any number of these, not just one */
- alarm->attach = prop;
- break;
-
- case ICAL_DESCRIPTION_PROPERTY:
- alarm->description.prop = prop;
- alarm->description.altrep_param = icalproperty_get_first_parameter (
- prop, ICAL_ALTREP_PARAMETER);
- break;
-
- case ICAL_DURATION_PROPERTY:
- alarm->duration = prop;
- break;
-
- case ICAL_REPEAT_PROPERTY:
- alarm->repeat = prop;
- break;
-
- case ICAL_TRIGGER_PROPERTY:
- alarm->trigger = prop;
- break;
-
- case ICAL_X_PROPERTY:
- xname = icalproperty_get_x_name (prop);
- g_assert (xname != NULL);
-
- if (strcmp (xname, EVOLUTION_ALARM_UID_PROPERTY) == 0)
- alarm->uid = prop;
-
- break;
-
- default:
- break;
- }
-}
-
-/* Creates a CalComponentAlarm from a libical alarm subcomponent */
-static CalComponentAlarm *
-make_alarm (icalcomponent *subcomp)
-{
- CalComponentAlarm *alarm;
- icalproperty *prop;
-
- alarm = g_new (CalComponentAlarm, 1);
-
- alarm->icalcomp = subcomp;
- alarm->uid = NULL;
-
- alarm->action = NULL;
- alarm->attach = NULL;
- alarm->description.prop = NULL;
- alarm->description.altrep_param = NULL;
- alarm->duration = NULL;
- alarm->repeat = NULL;
- alarm->trigger = NULL;
-
- for (prop = icalcomponent_get_first_property (subcomp, ICAL_ANY_PROPERTY);
- prop;
- prop = icalcomponent_get_next_property (subcomp, ICAL_ANY_PROPERTY))
- scan_alarm_property (alarm, prop);
-
- g_assert (alarm->uid != NULL);
-
- return alarm;
-}
-
-/**
- * cal_component_get_alarm_uids:
- * @comp: A calendar component.
- *
- * Builds a list of the unique identifiers of the alarm subcomponents inside a
- * calendar component.
- *
- * Return value: List of unique identifiers for alarms. This should be freed
- * using cal_obj_uid_list_free().
- **/
-GList *
-cal_component_get_alarm_uids (CalComponent *comp)
-{
- CalComponentPrivate *priv;
- icalcompiter iter;
- GList *l;
-
- g_return_val_if_fail (comp != NULL, NULL);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), NULL);
-
- priv = comp->priv;
- g_return_val_if_fail (priv->icalcomp != NULL, NULL);
-
- l = NULL;
- for (iter = icalcomponent_begin_component (priv->icalcomp, ICAL_VALARM_COMPONENT);
- icalcompiter_deref (&iter) != NULL;
- icalcompiter_next (&iter)) {
- icalcomponent *subcomp;
- icalproperty *prop;
-
- subcomp = icalcompiter_deref (&iter);
- for (prop = icalcomponent_get_first_property (subcomp, ICAL_X_PROPERTY);
- prop;
- prop = icalcomponent_get_next_property (subcomp, ICAL_X_PROPERTY)) {
- const char *xname;
-
- xname = icalproperty_get_x_name (prop);
- g_assert (xname != NULL);
-
- if (strcmp (xname, EVOLUTION_ALARM_UID_PROPERTY) == 0) {
- const char *auid;
-
- auid = alarm_uid_from_prop (prop);
- l = g_list_append (l, g_strdup (auid));
- }
- }
- }
-
- return l;
-}
-
-/**
- * cal_component_get_alarm:
- * @comp: A calendar component.
- * @auid: Unique identifier for the sought alarm subcomponent.
- *
- * Queries a particular alarm subcomponent of a calendar component.
- *
- * Return value: The alarm subcomponent that corresponds to the specified @auid,
- * or #NULL if no alarm exists with that UID. This should be freed using
- * cal_component_alarm_free().
- **/
-CalComponentAlarm *
-cal_component_get_alarm (CalComponent *comp, const char *auid)
-{
- CalComponentPrivate *priv;
- icalcomponent *alarm;
-
- g_return_val_if_fail (comp != NULL, NULL);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), NULL);
-
- priv = comp->priv;
- g_return_val_if_fail (priv->icalcomp != NULL, NULL);
-
- g_return_val_if_fail (auid != NULL, NULL);
-
- alarm = g_hash_table_lookup (priv->alarm_uid_hash, auid);
-
- if (alarm)
- return make_alarm (alarm);
- else
- return NULL;
-}
-
-/**
- * cal_component_alarms_free:
- * @alarms: Component alarms structure.
- *
- * Frees a #CalComponentAlarms structure.
- **/
-void
-cal_component_alarms_free (CalComponentAlarms *alarms)
-{
- GSList *l;
-
- g_return_if_fail (alarms != NULL);
-
- g_assert (alarms->comp != NULL);
- gtk_object_unref (GTK_OBJECT (alarms->comp));
-
- for (l = alarms->alarms; l; l = l->next) {
- CalAlarmInstance *instance;
-
- instance = l->data;
- g_assert (instance != NULL);
- g_free (instance);
- }
-
- g_slist_free (alarms->alarms);
- g_free (alarms);
-}
-
-/**
- * cal_component_alarm_new:
- *
- *
- *
- * Return value: a new alarm component
- **/
-CalComponentAlarm *
-cal_component_alarm_new (void)
-{
- CalComponentAlarm *alarm;
- char *new_auid ;
-
- alarm = g_new (CalComponentAlarm, 1);
-
- alarm->icalcomp = icalcomponent_new (ICAL_VALARM_COMPONENT);
-
- new_auid = cal_component_gen_uid ();
- alarm->uid = icalproperty_new_x (new_auid);
- icalproperty_set_x_name (alarm->uid, EVOLUTION_ALARM_UID_PROPERTY);
- icalcomponent_add_property (alarm->icalcomp, alarm->uid);
- g_free (new_auid);
-
- alarm->action = NULL;
- alarm->attach = NULL;
- alarm->description.prop = NULL;
- alarm->description.altrep_param = NULL;
- alarm->duration = NULL;
- alarm->repeat = NULL;
- alarm->trigger = NULL;
-
- return alarm;
-}
-
-/**
- * cal_component_alarm_clone:
- * @alarm: An alarm subcomponent.
- *
- * Creates a new alarm subcomponent by copying the information from another one.
- *
- * Return value: A newly-created alarm subcomponent with the same values as the
- * original one. Should be freed with cal_component_alarm_free().
- **/
-CalComponentAlarm *
-cal_component_alarm_clone (CalComponentAlarm *alarm)
-{
- icalcomponent *icalcomp;
-
- g_return_val_if_fail (alarm != NULL, NULL);
-
- icalcomp = icalcomponent_new_clone (alarm->icalcomp);
- return make_alarm (icalcomp);
-}
-
-/**
- * cal_component_alarm_free:
- * @alarm: A calendar alarm.
- *
- * Frees an alarm structure.
- **/
-void
-cal_component_alarm_free (CalComponentAlarm *alarm)
-{
- g_return_if_fail (alarm != NULL);
-
- g_assert (alarm->icalcomp != NULL);
-
- if (icalcomponent_get_parent (alarm->icalcomp) == NULL)
- icalcomponent_free (alarm->icalcomp);
-
- alarm->icalcomp = NULL;
- alarm->uid = NULL;
- alarm->action = NULL;
- alarm->attach = NULL;
- alarm->description.prop = NULL;
- alarm->description.altrep_param = NULL;
- alarm->duration = NULL;
- alarm->repeat = NULL;
- alarm->trigger = NULL;
-
- g_free (alarm);
-}
-
-/**
- * cal_component_alarm_get_uid:
- * @alarm: An alarm subcomponent.
- *
- * Queries the unique identifier of an alarm subcomponent.
- *
- * Return value: UID of the alarm.
- **/
-const char *
-cal_component_alarm_get_uid (CalComponentAlarm *alarm)
-{
- g_return_val_if_fail (alarm != NULL, NULL);
-
- return alarm_uid_from_prop (alarm->uid);
-}
-
-/**
- * cal_component_alarm_get_action:
- * @alarm: An alarm.
- * @action: Return value for the alarm's action type.
- *
- * Queries the action type of an alarm.
- **/
-void
-cal_component_alarm_get_action (CalComponentAlarm *alarm, CalAlarmAction *action)
-{
- enum icalproperty_action ipa;
-
- g_return_if_fail (alarm != NULL);
- g_return_if_fail (action != NULL);
-
- g_assert (alarm->icalcomp != NULL);
-
- if (!alarm->action) {
- *action = CAL_ALARM_NONE;
- return;
- }
-
- ipa = icalproperty_get_action (alarm->action);
-
- switch (ipa) {
- case ICAL_ACTION_AUDIO:
- *action = CAL_ALARM_AUDIO;
- break;
-
- case ICAL_ACTION_DISPLAY:
- *action = CAL_ALARM_DISPLAY;
- break;
-
- case ICAL_ACTION_EMAIL:
- *action = CAL_ALARM_EMAIL;
- break;
-
- case ICAL_ACTION_PROCEDURE:
- *action = CAL_ALARM_PROCEDURE;
- break;
-
- case ICAL_ACTION_NONE:
- *action = CAL_ALARM_NONE;
- break;
-
- default:
- *action = CAL_ALARM_UNKNOWN;
- }
-}
-
-/**
- * cal_component_alarm_set_action:
- * @alarm: An alarm.
- * @action: Action type.
- *
- * Sets the action type for an alarm.
- **/
-void
-cal_component_alarm_set_action (CalComponentAlarm *alarm, CalAlarmAction action)
-{
- enum icalproperty_action ipa;
-
- g_return_if_fail (alarm != NULL);
- g_return_if_fail (action != CAL_ALARM_NONE);
- g_return_if_fail (action != CAL_ALARM_UNKNOWN);
-
- g_assert (alarm->icalcomp != NULL);
-
- switch (action) {
- case CAL_ALARM_AUDIO:
- ipa = ICAL_ACTION_AUDIO;
- break;
-
- case CAL_ALARM_DISPLAY:
- ipa = ICAL_ACTION_DISPLAY;
- break;
-
- case CAL_ALARM_EMAIL:
- ipa = ICAL_ACTION_EMAIL;
- break;
-
- case CAL_ALARM_PROCEDURE:
- ipa = ICAL_ACTION_PROCEDURE;
- break;
-
- default:
- g_assert_not_reached ();
- ipa = ICAL_ACTION_NONE;
- }
-
- if (alarm->action)
- icalproperty_set_action (alarm->action, ipa);
- else {
- alarm->action = icalproperty_new_action (ipa);
- icalcomponent_add_property (alarm->icalcomp, alarm->action);
- }
-}
-
-/**
- * cal_component_alarm_get_attach:
- * @alarm: An alarm.
- * @attach: Return value for the attachment; should be freed using icalattach_unref().
- *
- * Queries the attachment property of an alarm.
- **/
-void
-cal_component_alarm_get_attach (CalComponentAlarm *alarm, icalattach **attach)
-{
- g_return_if_fail (alarm != NULL);
- g_return_if_fail (attach != NULL);
-
- g_assert (alarm->icalcomp != NULL);
-
- if (alarm->attach) {
- *attach = icalproperty_get_attach (alarm->attach);
- icalattach_ref (*attach);
- } else
- *attach = NULL;
-}
-
-/**
- * cal_component_alarm_set_attach:
- * @alarm: An alarm.
- * @attach: Attachment property or NULL to remove an existing property.
- *
- * Sets the attachment property of an alarm.
- **/
-void
-cal_component_alarm_set_attach (CalComponentAlarm *alarm, icalattach *attach)
-{
- g_return_if_fail (alarm != NULL);
-
- g_assert (alarm->icalcomp != NULL);
-
- if (alarm->attach) {
- icalcomponent_remove_property (alarm->icalcomp, alarm->attach);
- icalproperty_free (alarm->attach);
- alarm->attach = NULL;
- }
-
- if (attach) {
- alarm->attach = icalproperty_new_attach (attach);
- icalcomponent_add_property (alarm->icalcomp, alarm->attach);
- }
-}
-
-/**
- * cal_component_alarm_get_description:
- * @alarm: An alarm.
- * @description: Return value for the description property and its parameters.
- *
- * Queries the description property of an alarm.
- **/
-void
-cal_component_alarm_get_description (CalComponentAlarm *alarm, CalComponentText *description)
-{
- g_return_if_fail (alarm != NULL);
- g_return_if_fail (description != NULL);
-
- g_assert (alarm->icalcomp != NULL);
-
- if (alarm->description.prop)
- description->value = icalproperty_get_description (alarm->description.prop);
- else
- description->value = NULL;
-
- if (alarm->description.altrep_param)
- description->altrep = icalparameter_get_altrep (alarm->description.altrep_param);
- else
- description->altrep = NULL;
-}
-
-/**
- * cal_component_alarm_set_description:
- * @alarm: An alarm.
- * @description: Description property and its parameters, or NULL for no description.
- *
- * Sets the description property of an alarm.
- **/
-void
-cal_component_alarm_set_description (CalComponentAlarm *alarm, CalComponentText *description)
-{
- g_return_if_fail (alarm != NULL);
-
- g_assert (alarm->icalcomp != NULL);
-
- if (alarm->description.prop) {
- icalcomponent_remove_property (alarm->icalcomp, alarm->description.prop);
- icalproperty_free (alarm->description.prop);
-
- alarm->description.prop = NULL;
- alarm->description.altrep_param = NULL;
- }
-
- if (!description)
- return;
-
- g_return_if_fail (description->value != NULL);
-
- alarm->description.prop = icalproperty_new_description (description->value);
- icalcomponent_add_property (alarm->icalcomp, alarm->description.prop);
-
- if (description->altrep) {
- alarm->description.altrep_param = icalparameter_new_altrep (
- (char *) description->altrep);
- icalproperty_add_parameter (alarm->description.prop,
- alarm->description.altrep_param);
- }
-}
-
-/**
- * cal_component_alarm_get_repeat:
- * @alarm: An alarm.
- * @repeat: Return value for the repeat/duration properties.
- *
- * Queries the repeat/duration properties of an alarm.
- **/
-void
-cal_component_alarm_get_repeat (CalComponentAlarm *alarm, CalAlarmRepeat *repeat)
-{
- g_return_if_fail (alarm != NULL);
- g_return_if_fail (repeat != NULL);
-
- g_assert (alarm->icalcomp != NULL);
-
- if (!(alarm->repeat && alarm->duration)) {
- repeat->repetitions = 0;
- memset (&repeat->duration, 0, sizeof (repeat->duration));
- return;
- }
-
- repeat->repetitions = icalproperty_get_repeat (alarm->repeat);
- repeat->duration = icalproperty_get_duration (alarm->duration);
-}
-
-/**
- * cal_component_alarm_set_repeat:
- * @alarm: An alarm.
- * @repeat: Repeat/duration values. To remove any repetitions from the alarm,
- * set the @repeat.repetitions to 0.
- *
- * Sets the repeat/duration values for an alarm.
- **/
-void
-cal_component_alarm_set_repeat (CalComponentAlarm *alarm, CalAlarmRepeat repeat)
-{
- g_return_if_fail (alarm != NULL);
- g_return_if_fail (repeat.repetitions >= 0);
-
- g_assert (alarm->icalcomp != NULL);
-
- /* Delete old properties */
-
- if (alarm->repeat) {
- icalcomponent_remove_property (alarm->icalcomp, alarm->repeat);
- icalproperty_free (alarm->repeat);
- alarm->repeat = NULL;
- }
-
- if (alarm->duration) {
- icalcomponent_remove_property (alarm->icalcomp, alarm->duration);
- icalproperty_free (alarm->duration);
- alarm->duration = NULL;
- }
-
- /* Set the new properties */
-
- if (repeat.repetitions == 0)
- return; /* For zero extra repetitions the properties should not exist */
-
- alarm->repeat = icalproperty_new_repeat (repeat.repetitions);
- icalcomponent_add_property (alarm->icalcomp, alarm->repeat);
-
- alarm->duration = icalproperty_new_duration (repeat.duration);
- icalcomponent_add_property (alarm->icalcomp, alarm->duration);
-}
-
-/**
- * cal_component_alarm_get_trigger:
- * @alarm: An alarm.
- * @trigger: Return value for the trigger time.
- *
- * Queries the trigger time for an alarm.
- **/
-void
-cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalAlarmTrigger *trigger)
-{
- icalparameter *param;
- struct icaltriggertype t;
- gboolean relative;
-
- g_return_if_fail (alarm != NULL);
- g_return_if_fail (trigger != NULL);
-
- g_assert (alarm->icalcomp != NULL);
-
- if (!alarm->trigger) {
- trigger->type = CAL_ALARM_TRIGGER_NONE;
- return;
- }
-
- /* Get trigger type */
-
- param = icalproperty_get_first_parameter (alarm->trigger, ICAL_VALUE_PARAMETER);
- if (param) {
- icalparameter_value value;
-
- value = icalparameter_get_value (param);
-
- switch (value) {
- case ICAL_VALUE_DURATION:
- relative = TRUE;
- break;
-
- case ICAL_VALUE_DATETIME:
- relative = FALSE;
- break;
-
- default:
- g_message ("cal_component_alarm_get_trigger(): Unknown value for trigger "
- "value %d; using RELATIVE", value);
-
- relative = TRUE;
- break;
- }
- } else
- relative = TRUE;
-
- /* Get trigger value and the RELATED parameter */
-
- t = icalproperty_get_trigger (alarm->trigger);
-
- if (relative) {
- trigger->u.rel_duration = t.duration;
-
- param = icalproperty_get_first_parameter (alarm->trigger, ICAL_RELATED_PARAMETER);
- if (param) {
- icalparameter_related rel;
-
- rel = icalparameter_get_related (param);
-
- switch (rel) {
- case ICAL_RELATED_START:
- trigger->type = CAL_ALARM_TRIGGER_RELATIVE_START;
- break;
-
- case ICAL_RELATED_END:
- trigger->type = CAL_ALARM_TRIGGER_RELATIVE_END;
- break;
-
- default:
- g_assert_not_reached ();
- }
- } else
- trigger->type = CAL_ALARM_TRIGGER_RELATIVE_START;
- } else {
- trigger->u.abs_time = t.time;
- trigger->type = CAL_ALARM_TRIGGER_ABSOLUTE;
- }
-}
-
-/**
- * cal_component_alarm_set_trigger:
- * @alarm: An alarm.
- * @trigger: Trigger time structure.
- *
- * Sets the trigger time of an alarm.
- **/
-void
-cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalAlarmTrigger trigger)
-{
- struct icaltriggertype t;
- icalparameter *param;
- icalparameter_value value_type;
- icalparameter_related related;
-
- g_return_if_fail (alarm != NULL);
- g_return_if_fail (trigger.type != CAL_ALARM_TRIGGER_NONE);
-
- g_assert (alarm->icalcomp != NULL);
-
- /* Delete old trigger */
-
- if (alarm->trigger) {
- icalcomponent_remove_property (alarm->icalcomp, alarm->trigger);
- icalproperty_free (alarm->trigger);
- alarm->trigger = NULL;
- }
-
- /* Set the value */
-
- related = ICAL_RELATED_START; /* Keep GCC happy */
-
- t.time = icaltime_null_time ();
- t.duration = icaldurationtype_null_duration ();
- switch (trigger.type) {
- case CAL_ALARM_TRIGGER_RELATIVE_START:
- t.duration = trigger.u.rel_duration;
- value_type = ICAL_VALUE_DURATION;
- related = ICAL_RELATED_START;
- break;
-
- case CAL_ALARM_TRIGGER_RELATIVE_END:
- t.duration = trigger.u.rel_duration;
- value_type = ICAL_VALUE_DURATION;
- related = ICAL_RELATED_END;
- break;
-
- case CAL_ALARM_TRIGGER_ABSOLUTE:
- t.time = trigger.u.abs_time;
- value_type = ICAL_VALUE_DATETIME;
- break;
-
- default:
- g_assert_not_reached ();
- return;
- }
-
- alarm->trigger = icalproperty_new_trigger (t);
- icalcomponent_add_property (alarm->icalcomp, alarm->trigger);
-
- /* Value parameters */
-
- param = icalproperty_get_first_parameter (alarm->trigger, ICAL_VALUE_PARAMETER);
- if (param)
- icalparameter_set_value (param, value_type);
- else {
- param = icalparameter_new_value (value_type);
- icalproperty_add_parameter (alarm->trigger, param);
- }
-
- /* Related parameter */
-
- if (trigger.type != CAL_ALARM_TRIGGER_ABSOLUTE) {
- param = icalproperty_get_first_parameter (alarm->trigger, ICAL_RELATED_PARAMETER);
-
- if (param)
- icalparameter_set_related (param, related);
- else {
- param = icalparameter_new_related (related);
- icalproperty_add_parameter (alarm->trigger, param);
- }
- }
-}
-
-/**
- * cal_component_alarm_get_icalcomponent
- * @alarm: An alarm.
- *
- * Get the icalcomponent associated with the given #CalComponentAlarm.
- *
- * Returns: the icalcomponent.
- */
-icalcomponent *
-cal_component_alarm_get_icalcomponent (CalComponentAlarm *alarm)
-{
- g_return_val_if_fail (alarm != NULL, NULL);
- return alarm->icalcomp;
-}
-
-/* Returns TRUE if both strings match, i.e. they are both NULL or the
- strings are equal. */
-static gboolean
-cal_component_strings_match (const gchar *string1,
- const gchar *string2)
-{
- if (string1 == NULL || string2 == NULL)
- return (string1 == string2) ? TRUE : FALSE;
-
- if (!strcmp (string1, string2))
- return TRUE;
-
- return FALSE;
-}
-
-
-/**
- * cal_component_event_dates_match:
- * @comp1: A calendar component object.
- * @comp2: A calendar component object.
- *
- * Checks if the DTSTART and DTEND properties of the 2 components match.
- * Note that the events may have different recurrence properties which are not
- * taken into account here.
- *
- * Returns: TRUE if the DTSTART and DTEND properties of the 2 components match.
- **/
-gboolean
-cal_component_event_dates_match (CalComponent *comp1,
- CalComponent *comp2)
-{
- CalComponentDateTime comp1_dtstart, comp1_dtend;
- CalComponentDateTime comp2_dtstart, comp2_dtend;
- gboolean retval = TRUE;
-
- cal_component_get_dtstart (comp1, &comp1_dtstart);
- cal_component_get_dtend (comp1, &comp1_dtend);
- cal_component_get_dtstart (comp2, &comp2_dtstart);
- cal_component_get_dtend (comp2, &comp2_dtend);
-
- /* If either value is NULL they must both be NULL to match. */
- if (comp1_dtstart.value == NULL || comp2_dtstart.value == NULL) {
- if (comp1_dtstart.value != comp2_dtstart.value) {
- retval = FALSE;
- goto out;
- }
- } else {
- if (icaltime_compare (*comp1_dtstart.value,
- *comp2_dtstart.value)) {
- retval = FALSE;
- goto out;
- }
- }
-
- if (comp1_dtend.value == NULL || comp2_dtend.value == NULL) {
- if (comp1_dtend.value != comp2_dtend.value) {
- retval = FALSE;
- goto out;
- }
- } else {
- if (icaltime_compare (*comp1_dtend.value,
- *comp2_dtend.value)) {
- retval = FALSE;
- goto out;
- }
- }
-
- /* Now check the timezones. */
- if (!cal_component_strings_match (comp1_dtstart.tzid,
- comp2_dtstart.tzid)) {
- retval = FALSE;
- goto out;
- }
-
- if (!cal_component_strings_match (comp1_dtend.tzid,
- comp2_dtend.tzid)) {
- retval = FALSE;
- }
-
- out:
-
- cal_component_free_datetime (&comp1_dtstart);
- cal_component_free_datetime (&comp1_dtend);
- cal_component_free_datetime (&comp2_dtstart);
- cal_component_free_datetime (&comp2_dtend);
-
- return retval;
-}
-
-
diff --git a/calendar/cal-util/cal-component.h b/calendar/cal-util/cal-component.h
deleted file mode 100644
index 3e9c505b46..0000000000
--- a/calendar/cal-util/cal-component.h
+++ /dev/null
@@ -1,442 +0,0 @@
-/* Evolution calendar - iCalendar component object
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 CAL_COMPONENT_H
-#define CAL_COMPONENT_H
-
-#include <libgnome/gnome-defs.h>
-#include <time.h>
-#include <gtk/gtkobject.h>
-#include <ical.h>
-
-BEGIN_GNOME_DECLS
-
-
-
-#define CAL_COMPONENT_TYPE (cal_component_get_type ())
-#define CAL_COMPONENT(obj) (GTK_CHECK_CAST ((obj), CAL_COMPONENT_TYPE, CalComponent))
-#define CAL_COMPONENT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CAL_COMPONENT_TYPE, \
- CalComponentClass))
-#define IS_CAL_COMPONENT(obj) (GTK_CHECK_TYPE ((obj), CAL_COMPONENT_TYPE))
-#define IS_CAL_COMPONENT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CAL_COMPONENT_TYPE))
-
-/* Types of calendar components to be stored by a CalComponent, as per RFC 2445.
- * We don't put the alarm component type here since we store alarms as separate
- * structures inside the other "real" components.
- */
-typedef enum {
- CAL_COMPONENT_NO_TYPE,
- CAL_COMPONENT_EVENT,
- CAL_COMPONENT_TODO,
- CAL_COMPONENT_JOURNAL,
- CAL_COMPONENT_FREEBUSY,
- CAL_COMPONENT_TIMEZONE
-} CalComponentVType;
-
-/* Field identifiers for a calendar component; these are used by the data model
- * for ETable.
- *
- * NOTE: These are also used in the ETable specification, and the column
- * numbers are saved in the user settings file. So don't reorder them!
- */
-typedef enum {
- CAL_COMPONENT_FIELD_CATEGORIES, /* concatenation of the categories list */
- CAL_COMPONENT_FIELD_CLASSIFICATION,
- CAL_COMPONENT_FIELD_COMPLETED,
- CAL_COMPONENT_FIELD_DTEND,
- CAL_COMPONENT_FIELD_DTSTART,
- CAL_COMPONENT_FIELD_DUE,
- CAL_COMPONENT_FIELD_GEO,
- CAL_COMPONENT_FIELD_PERCENT,
- CAL_COMPONENT_FIELD_PRIORITY,
- CAL_COMPONENT_FIELD_SUMMARY,
- CAL_COMPONENT_FIELD_TRANSPARENCY,
- CAL_COMPONENT_FIELD_URL,
- CAL_COMPONENT_FIELD_HAS_ALARMS, /* not a real field */
- CAL_COMPONENT_FIELD_ICON, /* not a real field */
- CAL_COMPONENT_FIELD_COMPLETE, /* not a real field */
- CAL_COMPONENT_FIELD_RECURRING, /* not a real field */
- CAL_COMPONENT_FIELD_OVERDUE, /* not a real field */
- CAL_COMPONENT_FIELD_COLOR, /* not a real field */
- CAL_COMPONENT_FIELD_STATUS,
- CAL_COMPONENT_FIELD_COMPONENT, /* not a real field */
-#if 0
- CAL_COMPONENT_FIELD_LOCATION,
-#endif
- CAL_COMPONENT_FIELD_NUM_FIELDS
-} CalComponentField;
-
-/* Structures and enumerations to return properties and their parameters */
-
-/* CLASSIFICATION property */
-typedef enum {
- CAL_COMPONENT_CLASS_NONE,
- CAL_COMPONENT_CLASS_PUBLIC,
- CAL_COMPONENT_CLASS_PRIVATE,
- CAL_COMPONENT_CLASS_CONFIDENTIAL,
- CAL_COMPONENT_CLASS_UNKNOWN
-} CalComponentClassification;
-
-/* Properties that have time and timezone information */
-typedef struct {
- /* Actual date/time value */
- struct icaltimetype *value;
-
- /* Timezone ID */
- const char *tzid;
-} CalComponentDateTime;
-
-/* Way in which a period of time is specified */
-typedef enum {
- CAL_COMPONENT_PERIOD_DATETIME,
- CAL_COMPONENT_PERIOD_DURATION
-} CalComponentPeriodType;
-
-/* Period of time, can have explicit start/end times or start/duration instead */
-typedef struct {
- CalComponentPeriodType type;
-
- struct icaltimetype start;
-
- union {
- struct icaltimetype end;
- struct icaldurationtype duration;
- } u;
-} CalComponentPeriod;
-
-/* The type of range */
-typedef enum {
- CAL_COMPONENT_RANGE_SINGLE,
- CAL_COMPONENT_RANGE_THISPRIOR,
- CAL_COMPONENT_RANGE_THISFUTURE,
-} CalComponentRangeType;
-
-typedef struct {
- CalComponentRangeType type;
-
- CalComponentDateTime datetime;
-} CalComponentRange;
-
-/* Text properties */
-typedef struct {
- /* Description string */
- const char *value;
-
- /* Alternate representation URI */
- const char *altrep;
-} CalComponentText;
-
-/* Time transparency */
-typedef enum {
- CAL_COMPONENT_TRANSP_NONE,
- CAL_COMPONENT_TRANSP_TRANSPARENT,
- CAL_COMPONENT_TRANSP_OPAQUE,
- CAL_COMPONENT_TRANSP_UNKNOWN
-} CalComponentTransparency;
-
-/* Organizer & Attendee */
-typedef struct {
- const char *value;
-
- const char *member;
- icalparameter_cutype cutype;
- icalparameter_role role;
- icalparameter_partstat status;
- gboolean rsvp;
-
- const char *delto;
- const char *delfrom;
- const char *sentby;
- const char *cn;
- const char *language;
-} CalComponentAttendee;
-
-typedef struct {
- const char *value;
- const char *sentby;
- const char *cn;
- const char *language;
-} CalComponentOrganizer;
-
-/* Main calendar component object */
-
-typedef struct _CalComponent CalComponent;
-typedef struct _CalComponentClass CalComponentClass;
-
-typedef struct _CalComponentPrivate CalComponentPrivate;
-
-struct _CalComponent {
- GtkObject object;
-
- /* Private data */
- CalComponentPrivate *priv;
-};
-
-struct _CalComponentClass {
- GtkObjectClass parent_class;
-};
-
-/* Calendar component */
-
-GtkType cal_component_get_type (void);
-
-char *cal_component_gen_uid (void);
-
-CalComponent *cal_component_new (void);
-
-CalComponent *cal_component_clone (CalComponent *comp);
-
-void cal_component_set_new_vtype (CalComponent *comp, CalComponentVType type);
-
-gboolean cal_component_set_icalcomponent (CalComponent *comp, icalcomponent *icalcomp);
-icalcomponent *cal_component_get_icalcomponent (CalComponent *comp);
-void cal_component_rescan (CalComponent *comp);
-void cal_component_strip_errors (CalComponent *comp);
-
-CalComponentVType cal_component_get_vtype (CalComponent *comp);
-
-char *cal_component_get_as_string (CalComponent *comp);
-
-void cal_component_commit_sequence (CalComponent *comp);
-void cal_component_abort_sequence (CalComponent *comp);
-
-void cal_component_get_uid (CalComponent *comp, const char **uid);
-void cal_component_set_uid (CalComponent *comp, const char *uid);
-
-void cal_component_get_categories (CalComponent *comp, const char **categories);
-void cal_component_set_categories (CalComponent *comp, const char *categories);
-void cal_component_get_categories_list (CalComponent *comp, GSList **categ_list);
-void cal_component_set_categories_list (CalComponent *comp, GSList *categ_list);
-
-void cal_component_get_classification (CalComponent *comp, CalComponentClassification *classif);
-void cal_component_set_classification (CalComponent *comp, CalComponentClassification classif);
-
-void cal_component_get_comment_list (CalComponent *comp, GSList **text_list);
-void cal_component_set_comment_list (CalComponent *comp, GSList *text_list);
-
-void cal_component_get_completed (CalComponent *comp, struct icaltimetype **t);
-void cal_component_set_completed (CalComponent *comp, struct icaltimetype *t);
-
-void cal_component_get_contact_list (CalComponent *comp, GSList **text_list);
-void cal_component_set_contact_list (CalComponent *comp, GSList *text_list);
-
-void cal_component_get_created (CalComponent *comp, struct icaltimetype **t);
-void cal_component_set_created (CalComponent *comp, struct icaltimetype *t);
-
-void cal_component_get_description_list (CalComponent *comp, GSList **text_list);
-void cal_component_set_description_list (CalComponent *comp, GSList *text_list);
-
-void cal_component_get_dtend (CalComponent *comp, CalComponentDateTime *dt);
-void cal_component_set_dtend (CalComponent *comp, CalComponentDateTime *dt);
-
-void cal_component_get_dtstamp (CalComponent *comp, struct icaltimetype *t);
-void cal_component_set_dtstamp (CalComponent *comp, struct icaltimetype *t);
-
-void cal_component_get_dtstart (CalComponent *comp, CalComponentDateTime *dt);
-void cal_component_set_dtstart (CalComponent *comp, CalComponentDateTime *dt);
-
-void cal_component_get_due (CalComponent *comp, CalComponentDateTime *dt);
-void cal_component_set_due (CalComponent *comp, CalComponentDateTime *dt);
-
-void cal_component_get_exdate_list (CalComponent *comp, GSList **exdate_list);
-void cal_component_set_exdate_list (CalComponent *comp, GSList *exdate_list);
-gboolean cal_component_has_exdates (CalComponent *comp);
-
-void cal_component_get_exrule_list (CalComponent *comp, GSList **recur_list);
-void cal_component_get_exrule_property_list (CalComponent *comp, GSList **recur_list);
-void cal_component_set_exrule_list (CalComponent *comp, GSList *recur_list);
-gboolean cal_component_has_exrules (CalComponent *comp);
-
-gboolean cal_component_has_exceptions (CalComponent *comp);
-
-void cal_component_get_geo (CalComponent *comp, struct icalgeotype **geo);
-void cal_component_set_geo (CalComponent *comp, struct icalgeotype *geo);
-
-void cal_component_get_last_modified (CalComponent *comp, struct icaltimetype **t);
-void cal_component_set_last_modified (CalComponent *comp, struct icaltimetype *t);
-
-void cal_component_get_organizer (CalComponent *comp, CalComponentOrganizer *organizer);
-void cal_component_set_organizer (CalComponent *comp, CalComponentOrganizer *organizer);
-gboolean cal_component_has_organizer (CalComponent *comp);
-
-void cal_component_get_percent (CalComponent *comp, int **percent);
-void cal_component_set_percent (CalComponent *comp, int *percent);
-
-void cal_component_get_priority (CalComponent *comp, int **priority);
-void cal_component_set_priority (CalComponent *comp, int *priority);
-
-void cal_component_get_recurid (CalComponent *comp, CalComponentRange *recur_id);
-void cal_component_set_recurid (CalComponent *comp, CalComponentRange *recur_id);
-
-void cal_component_get_rdate_list (CalComponent *comp, GSList **period_list);
-void cal_component_set_rdate_list (CalComponent *comp, GSList *period_list);
-gboolean cal_component_has_rdates (CalComponent *comp);
-
-void cal_component_get_rrule_list (CalComponent *comp, GSList **recur_list);
-void cal_component_get_rrule_property_list (CalComponent *comp, GSList **recur_list);
-void cal_component_set_rrule_list (CalComponent *comp, GSList *recur_list);
-gboolean cal_component_has_rrules (CalComponent *comp);
-
-gboolean cal_component_has_recurrences (CalComponent *comp);
-
-void cal_component_get_sequence (CalComponent *comp, int **sequence);
-void cal_component_set_sequence (CalComponent *comp, int *sequence);
-
-void cal_component_get_status (CalComponent *comp, icalproperty_status *status);
-void cal_component_set_status (CalComponent *comp, icalproperty_status status);
-
-void cal_component_get_summary (CalComponent *comp, CalComponentText *summary);
-void cal_component_set_summary (CalComponent *comp, CalComponentText *summary);
-
-void cal_component_get_transparency (CalComponent *comp, CalComponentTransparency *transp);
-void cal_component_set_transparency (CalComponent *comp, CalComponentTransparency transp);
-
-void cal_component_get_url (CalComponent *comp, const char **url);
-void cal_component_set_url (CalComponent *comp, const char *url);
-
-void cal_component_get_attendee_list (CalComponent *comp, GSList **attendee_list);
-void cal_component_set_attendee_list (CalComponent *comp, GSList *attendee_list);
-gboolean cal_component_has_attendees (CalComponent *comp);
-
-void cal_component_get_location (CalComponent *comp, const char **location);
-void cal_component_set_location (CalComponent *comp, const char *location);
-
-gboolean cal_component_event_dates_match (CalComponent *comp1, CalComponent *comp2);
-
-
-/* Functions to free returned values */
-
-void cal_component_free_categories_list (GSList *categ_list);
-void cal_component_free_datetime (CalComponentDateTime *dt);
-void cal_component_free_exdate_list (GSList *exdate_list);
-void cal_component_free_geo (struct icalgeotype *geo);
-void cal_component_free_icaltimetype (struct icaltimetype *t);
-void cal_component_free_percent (int *percent);
-void cal_component_free_priority (int *priority);
-void cal_component_free_period_list (GSList *period_list);
-void cal_component_free_recur_list (GSList *recur_list);
-void cal_component_free_sequence (int *sequence);
-void cal_component_free_text_list (GSList *text_list);
-void cal_component_free_attendee_list (GSList *attendee_list);
-
-/* Alarms */
-
-/* Opaque structure used to represent alarm subcomponents */
-typedef struct _CalComponentAlarm CalComponentAlarm;
-
-/* An alarm occurrence, i.e. a trigger instance */
-typedef struct {
- /* UID of the alarm that triggered */
- const char *auid;
-
- /* Trigger time, i.e. "5 minutes before the appointment" */
- time_t trigger;
-
- /* Actual event occurrence to which this trigger corresponds */
- time_t occur_start;
- time_t occur_end;
-} CalAlarmInstance;
-
-/* Alarm trigger instances for a particular component */
-typedef struct {
- /* The actual component */
- CalComponent *comp;
-
- /* List of CalAlarmInstance structures */
- GSList *alarms;
-} CalComponentAlarms;
-
-/* Alarm types */
-typedef enum {
- CAL_ALARM_NONE,
- CAL_ALARM_AUDIO,
- CAL_ALARM_DISPLAY,
- CAL_ALARM_EMAIL,
- CAL_ALARM_PROCEDURE,
- CAL_ALARM_UNKNOWN
-} CalAlarmAction;
-
-/* Whether a trigger is relative to the start or end of an event occurrence, or
- * whether it is specified to occur at an absolute time.
- */
-typedef enum {
- CAL_ALARM_TRIGGER_NONE,
- CAL_ALARM_TRIGGER_RELATIVE_START,
- CAL_ALARM_TRIGGER_RELATIVE_END,
- CAL_ALARM_TRIGGER_ABSOLUTE
-} CalAlarmTriggerType;
-
-typedef struct {
- CalAlarmTriggerType type;
-
- union {
- struct icaldurationtype rel_duration;
- struct icaltimetype abs_time;
- } u;
-} CalAlarmTrigger;
-
-typedef struct {
- /* Number of extra repetitions, zero for none */
- int repetitions;
-
- /* Interval between repetitions */
- struct icaldurationtype duration;
-} CalAlarmRepeat;
-
-gboolean cal_component_has_alarms (CalComponent *comp);
-void cal_component_add_alarm (CalComponent *comp, CalComponentAlarm *alarm);
-void cal_component_remove_alarm (CalComponent *comp, const char *auid);
-void cal_component_remove_all_alarms (CalComponent *comp);
-
-GList *cal_component_get_alarm_uids (CalComponent *comp);
-CalComponentAlarm *cal_component_get_alarm (CalComponent *comp, const char *auid);
-
-void cal_component_alarms_free (CalComponentAlarms *alarms);
-
-/* CalComponentAlarms */
-CalComponentAlarm *cal_component_alarm_new (void);
-CalComponentAlarm *cal_component_alarm_clone (CalComponentAlarm *alarm);
-void cal_component_alarm_free (CalComponentAlarm *alarm);
-
-const char *cal_component_alarm_get_uid (CalComponentAlarm *alarm);
-
-void cal_component_alarm_get_action (CalComponentAlarm *alarm, CalAlarmAction *action);
-void cal_component_alarm_set_action (CalComponentAlarm *alarm, CalAlarmAction action);
-
-void cal_component_alarm_get_attach (CalComponentAlarm *alarm, icalattach **attach);
-void cal_component_alarm_set_attach (CalComponentAlarm *alarm, icalattach *attach);
-
-void cal_component_alarm_get_description (CalComponentAlarm *alarm, CalComponentText *description);
-void cal_component_alarm_set_description (CalComponentAlarm *alarm, CalComponentText *description);
-
-void cal_component_alarm_get_repeat (CalComponentAlarm *alarm, CalAlarmRepeat *repeat);
-void cal_component_alarm_set_repeat (CalComponentAlarm *alarm, CalAlarmRepeat repeat);
-
-void cal_component_alarm_get_trigger (CalComponentAlarm *alarm, CalAlarmTrigger *trigger);
-void cal_component_alarm_set_trigger (CalComponentAlarm *alarm, CalAlarmTrigger trigger);
-
-icalcomponent *cal_component_alarm_get_icalcomponent (CalComponentAlarm *alarm);
-
-
-
-END_GNOME_DECLS
-
-#endif
diff --git a/calendar/cal-util/cal-recur.c b/calendar/cal-util/cal-recur.c
deleted file mode 100644
index e050004031..0000000000
--- a/calendar/cal-util/cal-recur.c
+++ /dev/null
@@ -1,3980 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Evolution calendar recurrence rule functions
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Author: Damon Chaplin <damon@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 <stdlib.h>
-#include <string.h>
-#include <cal-util/cal-recur.h>
-#include <cal-util/timeutil.h>
-
-
-/*
- * Introduction to The Recurrence Generation Functions:
- *
- * Note: This is pretty complicated. See the iCalendar spec (RFC 2445) for
- * the specification of the recurrence rules and lots of examples
- * (sections 4.3.10 & 4.8.5). We also want to support the older
- * vCalendar spec, though this should be easy since it is basically a
- * subset of iCalendar.
- *
- * o An iCalendar event can have any number of recurrence rules specifying
- * occurrences of the event, as well as dates & times of specific
- * occurrences. It can also have any number of recurrence rules and
- * specific dates & times specifying exceptions to the occurrences.
- * So we first merge all the occurrences generated, eliminating any
- * duplicates, then we generate all the exceptions and remove these to
- * form the final set of occurrences.
- *
- * o There are 7 frequencies of occurrences: YEARLY, MONTHLY, WEEKLY, DAILY,
- * HOURLY, MINUTELY & SECONDLY. The 'interval' property specifies the
- * multiples of the frequency which we step by. We generate a 'set' of
- * occurrences for each period defined by the frequency & interval.
- * So for a YEARLY frequency with an interval of 3, we generate a set of
- * occurrences for every 3rd year. We use complete years here - any
- * generated occurrences that occur before the event's start (or after its
- * end) are just discarded.
- *
- * o There are 8 frequency modifiers: BYMONTH, BYWEEKNO, BYYEARDAY, BYMONTHDAY,
- * BYDAY, BYHOUR, BYMINUTE & BYSECOND. These can either add extra occurrences
- * or filter out occurrences. For example 'FREQ=YEARLY;BYMONTH=1,2' produces
- * 2 occurrences for each year rather than the default 1. And
- * 'FREQ=DAILY;BYMONTH=1' filters out all occurrences except those in Jan.
- * If the modifier works on periods which are less than the recurrence
- * frequency, then extra occurrences are added, otherwise occurrences are
- * filtered. So we have 2 functions for each modifier - one to expand events
- * and the other to filter. We use a table of functions for each frequency
- * which points to the appropriate function to use for each modifier.
- *
- * o Any number of frequency modifiers can be used in a recurrence rule.
- * (Though the iCalendar spec says that BYWEEKNO can only be used in a YEARLY
- * rule, and some modifiers aren't appropriate for some frequencies - e.g.
- * BYMONTHDAY is not really useful in a WEEKLY frequency, and BYYEARDAY is
- * not useful in a MONTHLY or WEEKLY frequency).
- * The frequency modifiers are applied in the order given above. The first 5
- * modifier rules (BYMONTH, BYWEEKNO, BYYEARDAY, BYMONTHDAY & BYDAY) all
- * produce the days on which the occurrences take place, and so we have to
- * compute some of these in parallel rather than sequentially, or we may end
- * up with too many days.
- *
- * o Note that some expansion functions may produce days which are invalid,
- * e.g. 31st September, 30th Feb. These invalid days are removed before the
- * BYHOUR, BYMINUTE & BYSECOND modifier functions are applied.
- *
- * o After the set of occurrences for the frequency interval are generated,
- * the BYSETPOS property is used to select which of the occurrences are
- * finally output. If BYSETPOS is not specified then all the occurrences are
- * output.
- *
- *
- * FIXME: I think there are a few errors in this code:
- *
- * 1) I'm not sure it should be generating events in parallel like it says
- * above. That needs to be checked.
- *
- * 2) I didn't think about timezone changes when implementing this. I just
- * assumed all the occurrences of the event would be in local time.
- * But when clocks go back or forwards due to daylight-saving time, some
- * special handling may be needed, especially for the shorter frequencies.
- * e.g. for a MINUTELY frequency it should probably iterate over all the
- * minutes before and after clocks go back (i.e. some may be the same local
- * time but have different UTC offsets). For longer frequencies, if an
- * occurrence lands on the overlapping or non-existant time when clocks
- * go back/forward, then it may need to choose which of the times to use
- * or move the time forward or something. I'm not sure this is clear in the
- * spec.
- */
-
-/* This is the maximum year we will go up to (inclusive). Since we use time_t
- values we can't go past 2037 anyway, and some of our VTIMEZONEs may stop
- at 2037 as well. */
-#define MAX_YEAR 2037
-
-/* Define this for some debugging output. */
-#if 0
-#define CAL_OBJ_DEBUG 1
-#endif
-
-/* We will use icalrecurrencetype instead of this eventually. */
-typedef struct {
- icalrecurrencetype_frequency freq;
-
- int interval;
-
- /* Specifies the end of the recurrence, inclusive. No occurrences are
- generated after this date. If it is 0, the event recurs forever. */
- time_t enddate;
-
- /* WKST property - the week start day: 0 = Monday to 6 = Sunday. */
- gint week_start_day;
-
-
- /* NOTE: I've used GList's here, but it doesn't matter if we use
- other data structures like arrays. The code should be easy to
- change. So long as it is easy to see if the modifier is set. */
-
- /* For BYMONTH modifier. A list of GINT_TO_POINTERs, 0-11. */
- GList *bymonth;
-
- /* For BYWEEKNO modifier. A list of GINT_TO_POINTERs, [+-]1-53. */
- GList *byweekno;
-
- /* For BYYEARDAY modifier. A list of GINT_TO_POINTERs, [+-]1-366. */
- GList *byyearday;
-
- /* For BYMONTHDAY modifier. A list of GINT_TO_POINTERs, [+-]1-31. */
- GList *bymonthday;
-
- /* For BYDAY modifier. A list of GINT_TO_POINTERs, in pairs.
- The first of each pair is the weekday, 0 = Monday to 6 = Sunday.
- The second of each pair is the week number [+-]0-53. */
- GList *byday;
-
- /* For BYHOUR modifier. A list of GINT_TO_POINTERs, 0-23. */
- GList *byhour;
-
- /* For BYMINUTE modifier. A list of GINT_TO_POINTERs, 0-59. */
- GList *byminute;
-
- /* For BYSECOND modifier. A list of GINT_TO_POINTERs, 0-60. */
- GList *bysecond;
-
- /* For BYSETPOS modifier. A list of GINT_TO_POINTERs, +ve or -ve. */
- GList *bysetpos;
-} CalRecurrence;
-
-/* This is what we use to pass to all the filter functions. */
-typedef struct _RecurData RecurData;
-struct _RecurData {
- CalRecurrence *recur;
-
- /* This is used for the WEEKLY frequency. It is the offset from the
- week_start_day. */
- gint weekday_offset;
-
- /* This is used for fast lookup in BYMONTH filtering. */
- guint8 months[12];
-
- /* This is used for fast lookup in BYYEARDAY filtering. */
- guint8 yeardays[367], neg_yeardays[367]; /* Days are 1 - 366. */
-
- /* This is used for fast lookup in BYMONTHDAY filtering. */
- guint8 monthdays[32], neg_monthdays[32]; /* Days are 1 to 31. */
-
- /* This is used for fast lookup in BYDAY filtering. */
- guint8 weekdays[7];
-
- /* This is used for fast lookup in BYHOUR filtering. */
- guint8 hours[24];
-
- /* This is used for fast lookup in BYMINUTE filtering. */
- guint8 minutes[60];
-
- /* This is used for fast lookup in BYSECOND filtering. */
- guint8 seconds[62];
-};
-
-/* This is what we use to represent a date & time. */
-typedef struct _CalObjTime CalObjTime;
-struct _CalObjTime {
- guint16 year;
- guint8 month; /* 0 - 11 */
- guint8 day; /* 1 - 31 */
- guint8 hour; /* 0 - 23 */
- guint8 minute; /* 0 - 59 */
- guint8 second; /* 0 - 59 (maybe up to 61 for leap seconds) */
- guint8 flags; /* The meaning of this depends on where the
- CalObjTime is used. In most cases this is
- set to TRUE to indicate that this is an
- RDATE with an end or a duration set.
- In the exceptions code, this is set to TRUE
- to indicate that this is an EXDATE with a
- DATE value. */
-};
-
-/* This is what we use to represent specific recurrence dates.
- Note that we assume it starts with a CalObjTime when sorting. */
-typedef struct _CalObjRecurrenceDate CalObjRecurrenceDate;
-struct _CalObjRecurrenceDate {
- CalObjTime start;
- CalComponentPeriod *period;
-};
-
-/* The paramter we use to store the enddate in RRULE and EXRULE properties. */
-#define EVOLUTION_END_DATE_PARAMETER "X-EVOLUTION-ENDDATE"
-
-typedef gboolean (*CalObjFindStartFn) (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime);
-typedef gboolean (*CalObjFindNextFn) (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end);
-typedef GArray* (*CalObjFilterFn) (RecurData *recur_data,
- GArray *occs);
-
-typedef struct _CalRecurVTable CalRecurVTable;
-struct _CalRecurVTable {
- CalObjFindStartFn find_start_position;
- CalObjFindNextFn find_next_position;
-
- CalObjFilterFn bymonth_filter;
- CalObjFilterFn byweekno_filter;
- CalObjFilterFn byyearday_filter;
- CalObjFilterFn bymonthday_filter;
- CalObjFilterFn byday_filter;
- CalObjFilterFn byhour_filter;
- CalObjFilterFn byminute_filter;
- CalObjFilterFn bysecond_filter;
-};
-
-
-/* This is used to specify which parts of the CalObjTime to compare in
- cal_obj_time_compare(). */
-typedef enum {
- CALOBJ_YEAR,
- CALOBJ_MONTH,
- CALOBJ_DAY,
- CALOBJ_HOUR,
- CALOBJ_MINUTE,
- CALOBJ_SECOND
-} CalObjTimeComparison;
-
-static void cal_recur_generate_instances_of_rule (CalComponent *comp,
- icalproperty *prop,
- time_t start,
- time_t end,
- CalRecurInstanceFn cb,
- gpointer cb_data,
- CalRecurResolveTimezoneFn tz_cb,
- gpointer tz_cb_data,
- icaltimezone *default_timezone);
-
-static CalRecurrence * cal_recur_from_icalproperty (icalproperty *prop,
- gboolean exception,
- icaltimezone *zone,
- gboolean convert_end_date);
-static gint cal_recur_ical_weekday_to_weekday (enum icalrecurrencetype_weekday day);
-static void cal_recur_free (CalRecurrence *r);
-
-
-static gboolean cal_object_get_rdate_end (CalObjTime *occ,
- GArray *rdate_periods);
-static void cal_object_compute_duration (CalObjTime *start,
- CalObjTime *end,
- gint *days,
- gint *seconds);
-
-static gboolean generate_instances_for_chunk (CalComponent *comp,
- time_t comp_dtstart,
- icaltimezone *zone,
- GSList *rrules,
- GSList *rdates,
- GSList *exrules,
- GSList *exdates,
- gboolean single_rule,
- CalObjTime *event_start,
- time_t interval_start,
- CalObjTime *chunk_start,
- CalObjTime *chunk_end,
- gint duration_days,
- gint duration_seconds,
- gboolean convert_end_date,
- CalRecurInstanceFn cb,
- gpointer cb_data);
-
-static GArray* cal_obj_expand_recurrence (CalObjTime *event_start,
- icaltimezone *zone,
- CalRecurrence *recur,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- gboolean *finished);
-
-static GArray* cal_obj_generate_set_yearly (RecurData *recur_data,
- CalRecurVTable *vtable,
- CalObjTime *occ);
-static GArray* cal_obj_generate_set_monthly (RecurData *recur_data,
- CalRecurVTable *vtable,
- CalObjTime *occ);
-static GArray* cal_obj_generate_set_default (RecurData *recur_data,
- CalRecurVTable *vtable,
- CalObjTime *occ);
-
-
-static CalRecurVTable* cal_obj_get_vtable (icalrecurrencetype_frequency recur_type);
-static void cal_obj_initialize_recur_data (RecurData *recur_data,
- CalRecurrence *recur,
- CalObjTime *event_start);
-static void cal_obj_sort_occurrences (GArray *occs);
-static gint cal_obj_time_compare_func (const void *arg1,
- const void *arg2);
-static void cal_obj_remove_duplicates_and_invalid_dates (GArray *occs);
-static void cal_obj_remove_exceptions (GArray *occs,
- GArray *ex_occs);
-static GArray* cal_obj_bysetpos_filter (CalRecurrence *recur,
- GArray *occs);
-
-
-static gboolean cal_obj_yearly_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime);
-static gboolean cal_obj_yearly_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end);
-
-static gboolean cal_obj_monthly_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime);
-static gboolean cal_obj_monthly_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end);
-
-static gboolean cal_obj_weekly_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime);
-static gboolean cal_obj_weekly_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end);
-
-static gboolean cal_obj_daily_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime);
-static gboolean cal_obj_daily_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end);
-
-static gboolean cal_obj_hourly_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime);
-static gboolean cal_obj_hourly_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end);
-
-static gboolean cal_obj_minutely_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime);
-static gboolean cal_obj_minutely_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end);
-
-static gboolean cal_obj_secondly_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime);
-static gboolean cal_obj_secondly_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end);
-
-static GArray* cal_obj_bymonth_expand (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_bymonth_filter (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_byweekno_expand (RecurData *recur_data,
- GArray *occs);
-#if 0
-/* This isn't used at present. */
-static GArray* cal_obj_byweekno_filter (RecurData *recur_data,
- GArray *occs);
-#endif
-static GArray* cal_obj_byyearday_expand (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_byyearday_filter (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_bymonthday_expand (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_bymonthday_filter (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_byday_expand_yearly (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_byday_expand_monthly (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_byday_expand_weekly (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_byday_filter (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_byhour_expand (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_byhour_filter (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_byminute_expand (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_byminute_filter (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_bysecond_expand (RecurData *recur_data,
- GArray *occs);
-static GArray* cal_obj_bysecond_filter (RecurData *recur_data,
- GArray *occs);
-
-static void cal_obj_time_add_months (CalObjTime *cotime,
- gint months);
-static void cal_obj_time_add_days (CalObjTime *cotime,
- gint days);
-static void cal_obj_time_add_hours (CalObjTime *cotime,
- gint hours);
-static void cal_obj_time_add_minutes (CalObjTime *cotime,
- gint minutes);
-static void cal_obj_time_add_seconds (CalObjTime *cotime,
- gint seconds);
-static gint cal_obj_time_compare (CalObjTime *cotime1,
- CalObjTime *cotime2,
- CalObjTimeComparison type);
-static gint cal_obj_time_weekday (CalObjTime *cotime);
-static gint cal_obj_time_weekday_offset (CalObjTime *cotime,
- CalRecurrence *recur);
-static gint cal_obj_time_day_of_year (CalObjTime *cotime);
-static void cal_obj_time_find_first_week (CalObjTime *cotime,
- RecurData *recur_data);
-static void cal_object_time_from_time (CalObjTime *cotime,
- time_t t,
- icaltimezone *zone);
-static gint cal_obj_date_only_compare_func (const void *arg1,
- const void *arg2);
-
-
-
-static gboolean cal_recur_ensure_end_dates (CalComponent *comp,
- gboolean refresh,
- CalRecurResolveTimezoneFn tz_cb,
- gpointer tz_cb_data);
-static gboolean cal_recur_ensure_rule_end_date (CalComponent *comp,
- icalproperty *prop,
- gboolean exception,
- gboolean refresh,
- CalRecurResolveTimezoneFn tz_cb,
- gpointer tz_cb_data);
-static gboolean cal_recur_ensure_rule_end_date_cb (CalComponent *comp,
- time_t instance_start,
- time_t instance_end,
- gpointer data);
-static time_t cal_recur_get_rule_end_date (icalproperty *prop,
- icaltimezone *default_timezone);
-static void cal_recur_set_rule_end_date (icalproperty *prop,
- time_t end_date);
-
-
-#ifdef CAL_OBJ_DEBUG
-static char* cal_obj_time_to_string (CalObjTime *cotime);
-#endif
-
-
-CalRecurVTable cal_obj_yearly_vtable = {
- cal_obj_yearly_find_start_position,
- cal_obj_yearly_find_next_position,
-
- cal_obj_bymonth_expand,
- cal_obj_byweekno_expand,
- cal_obj_byyearday_expand,
- cal_obj_bymonthday_expand,
- cal_obj_byday_expand_yearly,
- cal_obj_byhour_expand,
- cal_obj_byminute_expand,
- cal_obj_bysecond_expand
-};
-
-CalRecurVTable cal_obj_monthly_vtable = {
- cal_obj_monthly_find_start_position,
- cal_obj_monthly_find_next_position,
-
- cal_obj_bymonth_filter,
- NULL, /* BYWEEKNO is only applicable to YEARLY frequency. */
- NULL, /* BYYEARDAY is not useful in a MONTHLY frequency. */
- cal_obj_bymonthday_expand,
- cal_obj_byday_expand_monthly,
- cal_obj_byhour_expand,
- cal_obj_byminute_expand,
- cal_obj_bysecond_expand
-};
-
-CalRecurVTable cal_obj_weekly_vtable = {
- cal_obj_weekly_find_start_position,
- cal_obj_weekly_find_next_position,
-
- cal_obj_bymonth_filter,
- NULL, /* BYWEEKNO is only applicable to YEARLY frequency. */
- NULL, /* BYYEARDAY is not useful in a WEEKLY frequency. */
- NULL, /* BYMONTHDAY is not useful in a WEEKLY frequency. */
- cal_obj_byday_expand_weekly,
- cal_obj_byhour_expand,
- cal_obj_byminute_expand,
- cal_obj_bysecond_expand
-};
-
-CalRecurVTable cal_obj_daily_vtable = {
- cal_obj_daily_find_start_position,
- cal_obj_daily_find_next_position,
-
- cal_obj_bymonth_filter,
- NULL, /* BYWEEKNO is only applicable to YEARLY frequency. */
- cal_obj_byyearday_filter,
- cal_obj_bymonthday_filter,
- cal_obj_byday_filter,
- cal_obj_byhour_expand,
- cal_obj_byminute_expand,
- cal_obj_bysecond_expand
-};
-
-CalRecurVTable cal_obj_hourly_vtable = {
- cal_obj_hourly_find_start_position,
- cal_obj_hourly_find_next_position,
-
- cal_obj_bymonth_filter,
- NULL, /* BYWEEKNO is only applicable to YEARLY frequency. */
- cal_obj_byyearday_filter,
- cal_obj_bymonthday_filter,
- cal_obj_byday_filter,
- cal_obj_byhour_filter,
- cal_obj_byminute_expand,
- cal_obj_bysecond_expand
-};
-
-CalRecurVTable cal_obj_minutely_vtable = {
- cal_obj_minutely_find_start_position,
- cal_obj_minutely_find_next_position,
-
- cal_obj_bymonth_filter,
- NULL, /* BYWEEKNO is only applicable to YEARLY frequency. */
- cal_obj_byyearday_filter,
- cal_obj_bymonthday_filter,
- cal_obj_byday_filter,
- cal_obj_byhour_filter,
- cal_obj_byminute_filter,
- cal_obj_bysecond_expand
-};
-
-CalRecurVTable cal_obj_secondly_vtable = {
- cal_obj_secondly_find_start_position,
- cal_obj_secondly_find_next_position,
-
- cal_obj_bymonth_filter,
- NULL, /* BYWEEKNO is only applicable to YEARLY frequency. */
- cal_obj_byyearday_filter,
- cal_obj_bymonthday_filter,
- cal_obj_byday_filter,
- cal_obj_byhour_filter,
- cal_obj_byminute_filter,
- cal_obj_bysecond_filter
-};
-
-/*
- * Calls the given callback function for each occurrence of the event that
- * intersects the range between the given start and end times (the end time is
- * not included). Note that the occurrences may start before the given start
- * time.
- *
- * If the callback routine returns FALSE the occurrence generation stops.
- *
- * Both start and end can be -1, in which case we start at the events first
- * instance and continue until it ends, or forever if it has no enddate.
- */
-void
-cal_recur_generate_instances (CalComponent *comp,
- time_t start,
- time_t end,
- CalRecurInstanceFn cb,
- gpointer cb_data,
- CalRecurResolveTimezoneFn tz_cb,
- gpointer tz_cb_data,
- icaltimezone *default_timezone)
-{
-#if 0
- g_print ("In cal_recur_generate_instances comp: %p\n", comp);
- g_print (" start: %li - %s", start, ctime (&start));
- g_print (" end : %li - %s", end, ctime (&end));
-#endif
- cal_recur_generate_instances_of_rule (comp, NULL, start, end,
- cb, cb_data, tz_cb, tz_cb_data,
- default_timezone);
-}
-
-
-/*
- * Calls the given callback function for each occurrence of the given
- * recurrence rule between the given start and end times. If the rule is NULL
- * it uses all the rules from the component.
- *
- * If the callback routine returns FALSE the occurrence generation stops.
- *
- * The use of the specific rule is for determining the end of a rule when
- * COUNT is set. The callback will count instances and store the enddate
- * when COUNT is reached.
- *
- * Both start and end can be -1, in which case we start at the events first
- * instance and continue until it ends, or forever if it has no enddate.
- */
-static void
-cal_recur_generate_instances_of_rule (CalComponent *comp,
- icalproperty *prop,
- time_t start,
- time_t end,
- CalRecurInstanceFn cb,
- gpointer cb_data,
- CalRecurResolveTimezoneFn tz_cb,
- gpointer tz_cb_data,
- icaltimezone *default_timezone)
-{
- CalComponentDateTime dtstart, dtend;
- time_t dtstart_time, dtend_time;
- GSList *rrules = NULL, *rdates = NULL, elem;
- GSList *exrules = NULL, *exdates = NULL;
- CalObjTime interval_start, interval_end, event_start, event_end;
- CalObjTime chunk_start, chunk_end;
- gint days, seconds, year;
- gboolean single_rule, convert_end_date = FALSE;
- icaltimezone *start_zone = NULL, *end_zone = NULL;
-
- g_return_if_fail (comp != NULL);
- g_return_if_fail (cb != NULL);
- g_return_if_fail (tz_cb != NULL);
- g_return_if_fail (start >= -1);
- g_return_if_fail (end >= -1);
-
- /* Get dtstart, dtend, recurrences, and exceptions. Note that
- cal_component_get_dtend() will convert a DURATION property to a
- DTEND so we don't need to worry about that. */
-
- cal_component_get_dtstart (comp, &dtstart);
- cal_component_get_dtend (comp, &dtend);
-
- if (!dtstart.value) {
- g_message ("cal_recur_generate_instances_of_rule(): bogus "
- "component, does not have DTSTART. Skipping...");
- goto out;
- }
-
- /* For DATE-TIME values with a TZID, we use the supplied callback to
- resolve the TZID. For DATE values and DATE-TIME values without a
- TZID (i.e. floating times) we use the default timezone. */
- if (dtstart.tzid && !dtstart.value->is_date) {
- start_zone = (*tz_cb) (dtstart.tzid, tz_cb_data);
- } else {
- start_zone = default_timezone;
-
- /* Flag that we need to convert the saved ENDDATE property
- to the default timezone. */
- convert_end_date = TRUE;
- }
-
- dtstart_time = icaltime_as_timet_with_zone (*dtstart.value,
- start_zone);
- if (start == -1)
- start = dtstart_time;
-
- if (dtend.value) {
- /* If both DTSTART and DTEND are DATE values, and they are the
- same day, we add 1 day to DTEND. This means that most
- events created with the old Evolution behavior will still
- work OK. I'm not sure what Outlook does in this case. */
- if (dtstart.value->is_date && dtend.value->is_date) {
- if (icaltime_compare_date_only (*dtstart.value,
- *dtend.value) == 0) {
- icaltime_adjust (dtend.value, 1, 0, 0, 0);
- }
- }
- } else {
- /* If there is no DTEND, then if DTSTART is a DATE-TIME value
- we use the same time (so we have a single point in time).
- If DTSTART is a DATE value we add 1 day. */
- dtend.value = g_new (struct icaltimetype, 1);
- *dtend.value = *dtstart.value;
-
- if (dtstart.value->is_date) {
- icaltime_adjust (dtend.value, 1, 0, 0, 0);
- }
- }
-
- if (dtend.tzid && !dtend.value->is_date) {
- end_zone = (*tz_cb) (dtend.tzid, tz_cb_data);
- } else {
- end_zone = default_timezone;
- }
-
- /* We don't do this any more, since Outlook assumes that the DTEND
- date is not included. */
-#if 0
- /* If DTEND is a DATE value, we add 1 day to it so that it includes
- the entire day. */
- if (dtend.value->is_date) {
- dtend.value->hour = 0;
- dtend.value->minute = 0;
- dtend.value->second = 0;
- icaltime_adjust (dtend.value, 1, 0, 0, 0);
- }
-#endif
- dtend_time = icaltime_as_timet_with_zone (*dtend.value, end_zone);
-
- /* If there is no recurrence, just call the callback if the event
- intersects the given interval. */
- if (!(cal_component_has_recurrences (comp)
- || cal_component_has_exceptions (comp))) {
- if ((end == -1 || dtstart_time < end) && dtend_time > start) {
- (* cb) (comp, dtstart_time, dtend_time, cb_data);
- }
-
- goto out;
- }
-
- /* If a specific recurrence rule is being used, set up a simple list,
- else get the recurrence rules from the component. */
- if (prop) {
- single_rule = TRUE;
-
- elem.data = prop;
- elem.next = NULL;
- rrules = &elem;
- } else {
- single_rule = FALSE;
-
- /* Make sure all the enddates for the rules are set. */
- cal_recur_ensure_end_dates (comp, FALSE, tz_cb, tz_cb_data);
-
- cal_component_get_rrule_property_list (comp, &rrules);
- cal_component_get_rdate_list (comp, &rdates);
- cal_component_get_exrule_property_list (comp, &exrules);
- cal_component_get_exdate_list (comp, &exdates);
- }
-
- /* Convert the interval start & end to CalObjTime. Note that if end
- is -1 interval_end won't be set, so don't use it!
- Also note that we use end - 1 since we want the interval to be
- inclusive as it makes the code simpler. We do all calculation
- in the timezone of the DTSTART. */
- cal_object_time_from_time (&interval_start, start, start_zone);
- if (end != -1)
- cal_object_time_from_time (&interval_end, end - 1, start_zone);
-
- cal_object_time_from_time (&event_start, dtstart_time, start_zone);
- cal_object_time_from_time (&event_end, dtend_time, start_zone);
-
- /* Calculate the duration of the event, which we use for all
- occurrences. We can't just subtract start from end since that may
- be affected by daylight-saving time. So we want a value of days
- + seconds. */
- cal_object_compute_duration (&event_start, &event_end,
- &days, &seconds);
-
- /* Take off the duration from interval_start, so we get occurrences
- that start just before the start time but overlap it. But only do
- that if the interval is after the event's start time. */
- if (start > dtstart_time) {
- cal_obj_time_add_days (&interval_start, -days);
- cal_obj_time_add_seconds (&interval_start, -seconds);
- }
-
- /* Expand the recurrence for each year between start & end, or until
- the callback returns 0 if end is 0. We do a year at a time to
- give the callback function a chance to break out of the loop, and
- so we don't get into problems with infinite recurrences. Since we
- have to work on complete sets of occurrences, if there is a yearly
- frequency it wouldn't make sense to break it into smaller chunks,
- since we would then be calculating the same sets several times.
- Though this does mean that we sometimes do a lot more work than
- is necessary, e.g. if COUNT is set to something quite low. */
- for (year = interval_start.year;
- (end == -1 || year <= interval_end.year) && year <= MAX_YEAR;
- year++) {
- chunk_start = interval_start;
- chunk_start.year = year;
- if (end != -1)
- chunk_end = interval_end;
- chunk_end.year = year;
-
- if (year != interval_start.year) {
- chunk_start.month = 0;
- chunk_start.day = 1;
- chunk_start.hour = 0;
- chunk_start.minute = 0;
- chunk_start.second = 0;
- }
- if (end == -1 || year != interval_end.year) {
- chunk_end.month = 11;
- chunk_end.day = 31;
- chunk_end.hour = 23;
- chunk_end.minute = 59;
- chunk_end.second = 61;
- chunk_end.flags = FALSE;
- }
-
- if (!generate_instances_for_chunk (comp, dtstart_time,
- start_zone,
- rrules, rdates,
- exrules, exdates,
- single_rule,
- &event_start,
- start,
- &chunk_start, &chunk_end,
- days, seconds,
- convert_end_date,
- cb, cb_data))
- break;
- }
-
- if (!prop) {
- cal_component_free_period_list (rdates);
- cal_component_free_exdate_list (exdates);
- }
-
- out:
- cal_component_free_datetime (&dtstart);
- cal_component_free_datetime (&dtend);
-}
-
-/* Builds a list of GINT_TO_POINTER() elements out of a short array from a
- * struct icalrecurrencetype.
- */
-static GList *
-array_to_list (short *array, int max_elements)
-{
- GList *l;
- int i;
-
- l = NULL;
-
- for (i = 0; i < max_elements && array[i] != ICAL_RECURRENCE_ARRAY_MAX; i++)
- l = g_list_prepend (l, GINT_TO_POINTER ((int) (array[i])));
- return g_list_reverse (l);
-}
-
-/**
- * cal_recur_from_icalproperty:
- * @prop: An RRULE or EXRULE #icalproperty.
- * @exception: TRUE if this is an EXRULE rather than an RRULE.
- * @zone: The DTSTART timezone, used for converting the UNTIL property if it
- * is given as a DATE value.
- * @convert_end_date: TRUE if the saved end date needs to be converted to the
- * given @zone timezone. This is needed if the DTSTART is a DATE or floating
- * time.
- *
- * Converts an #icalproperty to a #CalRecurrence. This should be
- * freed using the cal_recur_free() function.
- *
- * Return value: #CalRecurrence structure.
- **/
-static CalRecurrence *
-cal_recur_from_icalproperty (icalproperty *prop, gboolean exception,
- icaltimezone *zone, gboolean convert_end_date)
-{
- struct icalrecurrencetype ir;
- CalRecurrence *r;
- gint max_elements, i;
- GList *elem;
-
- g_return_val_if_fail (prop != NULL, NULL);
-
- r = g_new (CalRecurrence, 1);
-
- if (exception)
- ir = icalproperty_get_exrule (prop);
- else
- ir = icalproperty_get_rrule (prop);
-
- r->freq = ir.freq;
- r->interval = ir.interval;
-
- if (ir.count != 0) {
- /* If COUNT is set, we use the pre-calculated enddate.
- Note that this can be 0 if the RULE doesn't actually
- generate COUNT instances. */
- r->enddate = cal_recur_get_rule_end_date (prop, convert_end_date ? zone : NULL);
- } else {
- if (icaltime_is_null_time (ir.until)) {
- /* If neither COUNT or UNTIL is set, the event
- recurs forever. */
- r->enddate = 0;
- } else if (ir.until.is_date) {
- /* If UNTIL is a DATE, we stop at the end of
- the day, in local time (with the DTSTART timezone).
- Note that UNTIL is inclusive so we stop before
- midnight. */
- ir.until.hour = 23;
- ir.until.minute = 59;
- ir.until.second = 59;
- ir.until.is_date = FALSE;
-
- r->enddate = icaltime_as_timet_with_zone (ir.until,
- zone);
-#if 0
- g_print (" until: %li - %s", r->enddate, ctime (&r->enddate));
-#endif
-
- } else {
- /* If UNTIL is a DATE-TIME, it must be in UTC. */
- icaltimezone *utc_zone;
- utc_zone = icaltimezone_get_utc_timezone ();
- r->enddate = icaltime_as_timet_with_zone (ir.until,
- utc_zone);
- }
- }
-
- r->week_start_day = cal_recur_ical_weekday_to_weekday (ir.week_start);
-
- r->bymonth = array_to_list (ir.by_month,
- sizeof (ir.by_month) / sizeof (ir.by_month[0]));
- for (elem = r->bymonth; elem; elem = elem->next) {
- /* We need to convert from 1-12 to 0-11, i.e. subtract 1. */
- int month = GPOINTER_TO_INT (elem->data) - 1;
- elem->data = GINT_TO_POINTER (month);
- }
-
- r->byweekno = array_to_list (ir.by_week_no,
- sizeof (ir.by_week_no) / sizeof (ir.by_week_no[0]));
-
- r->byyearday = array_to_list (ir.by_year_day,
- sizeof (ir.by_year_day) / sizeof (ir.by_year_day[0]));
-
- r->bymonthday = array_to_list (ir.by_month_day,
- sizeof (ir.by_month_day) / sizeof (ir.by_month_day[0]));
-
- /* FIXME: libical only supports 8 values, out of possible 107 * 7. */
- r->byday = NULL;
- max_elements = sizeof (ir.by_day) / sizeof (ir.by_day[0]);
- for (i = 0; i < max_elements && ir.by_day[i] != ICAL_RECURRENCE_ARRAY_MAX; i++) {
- enum icalrecurrencetype_weekday day;
- gint weeknum, weekday;
-
- day = icalrecurrencetype_day_day_of_week (ir.by_day[i]);
- weeknum = icalrecurrencetype_day_position (ir.by_day[i]);
-
- weekday = cal_recur_ical_weekday_to_weekday (day);
-
- r->byday = g_list_prepend (r->byday,
- GINT_TO_POINTER (weeknum));
- r->byday = g_list_prepend (r->byday,
- GINT_TO_POINTER (weekday));
- }
-
- r->byhour = array_to_list (ir.by_hour,
- sizeof (ir.by_hour) / sizeof (ir.by_hour[0]));
-
- r->byminute = array_to_list (ir.by_minute,
- sizeof (ir.by_minute) / sizeof (ir.by_minute[0]));
-
- r->bysecond = array_to_list (ir.by_second,
- sizeof (ir.by_second) / sizeof (ir.by_second[0]));
-
- r->bysetpos = array_to_list (ir.by_set_pos,
- sizeof (ir.by_set_pos) / sizeof (ir.by_set_pos[0]));
-
- return r;
-}
-
-
-static gint
-cal_recur_ical_weekday_to_weekday (enum icalrecurrencetype_weekday day)
-{
- gint weekday;
-
- switch (day) {
- case ICAL_NO_WEEKDAY: /* Monday is the default in RFC2445. */
- case ICAL_MONDAY_WEEKDAY:
- weekday = 0;
- break;
- case ICAL_TUESDAY_WEEKDAY:
- weekday = 1;
- break;
- case ICAL_WEDNESDAY_WEEKDAY:
- weekday = 2;
- break;
- case ICAL_THURSDAY_WEEKDAY:
- weekday = 3;
- break;
- case ICAL_FRIDAY_WEEKDAY:
- weekday = 4;
- break;
- case ICAL_SATURDAY_WEEKDAY:
- weekday = 5;
- break;
- case ICAL_SUNDAY_WEEKDAY:
- weekday = 6;
- break;
- default:
- g_warning ("cal_recur_ical_weekday_to_weekday(): Unknown week day %d",
- day);
- weekday = 0;
- }
-
- return weekday;
-}
-
-
-/**
- * cal_recur_free:
- * @r: A #CalRecurrence structure.
- *
- * Frees a #CalRecurrence structure.
- **/
-static void
-cal_recur_free (CalRecurrence *r)
-{
- g_return_if_fail (r != NULL);
-
- g_list_free (r->bymonth);
- g_list_free (r->byweekno);
- g_list_free (r->byyearday);
- g_list_free (r->bymonthday);
- g_list_free (r->byday);
- g_list_free (r->byhour);
- g_list_free (r->byminute);
- g_list_free (r->bysecond);
- g_list_free (r->bysetpos);
-
- g_free (r);
-}
-
-/* Generates one year's worth of recurrence instances. Returns TRUE if all the
- * callback invocations returned TRUE, or FALSE when any one of them returns
- * FALSE, i.e. meaning that the instance generation should be stopped.
- *
- * This should only output instances whose start time is between chunk_start
- * and chunk_end (inclusive), or we may generate duplicates when we do the next
- * chunk. (This applies mainly to weekly recurrences, since weeks can span 2
- * years.)
- *
- * It should also only output instances that are on or after the event's
- * DTSTART property and that intersect the required interval, between
- * interval_start and interval_end.
- */
-static gboolean
-generate_instances_for_chunk (CalComponent *comp,
- time_t comp_dtstart,
- icaltimezone *zone,
- GSList *rrules,
- GSList *rdates,
- GSList *exrules,
- GSList *exdates,
- gboolean single_rule,
- CalObjTime *event_start,
- time_t interval_start,
- CalObjTime *chunk_start,
- CalObjTime *chunk_end,
- gint duration_days,
- gint duration_seconds,
- gboolean convert_end_date,
- CalRecurInstanceFn cb,
- gpointer cb_data)
-{
- GArray *occs, *ex_occs, *tmp_occs, *rdate_periods;
- CalObjTime cotime, *occ;
- GSList *elem;
- gint i;
- time_t start_time, end_time;
- struct icaltimetype start_tt, end_tt;
- gboolean cb_status = TRUE, rule_finished, finished = TRUE;
-
-#if 0
- g_print ("In generate_instances_for_chunk rrules: %p\n"
- " %i/%i/%i %02i:%02i:%02i - %i/%i/%i %02i:%02i:%02i\n",
- rrules,
- chunk_start->day, chunk_start->month + 1,
- chunk_start->year, chunk_start->hour,
- chunk_start->minute, chunk_start->second,
- chunk_end->day, chunk_end->month + 1,
- chunk_end->year, chunk_end->hour,
- chunk_end->minute, chunk_end->second);
-#endif
-
- occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
- ex_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
- rdate_periods = g_array_new (FALSE, FALSE,
- sizeof (CalObjRecurrenceDate));
-
- /* The original DTSTART property is included in the occurrence set,
- but not if we are just generating occurrences for a single rule. */
- if (!single_rule) {
- /* We add it if it is in this chunk. If it is after this chunk
- we set finished to FALSE, since we know we aren't finished
- yet. */
- if (cal_obj_time_compare_func (event_start, chunk_end) >= 0)
- finished = FALSE;
- else if (cal_obj_time_compare_func (event_start, chunk_start) >= 0)
- g_array_append_vals (occs, event_start, 1);
- }
-
- /* Expand each of the recurrence rules. */
- for (elem = rrules; elem; elem = elem->next) {
- icalproperty *prop;
- CalRecurrence *r;
-
- prop = elem->data;
- r = cal_recur_from_icalproperty (prop, FALSE, zone,
- convert_end_date);
-
- tmp_occs = cal_obj_expand_recurrence (event_start, zone, r,
- chunk_start,
- chunk_end,
- &rule_finished);
- cal_recur_free (r);
-
- /* If any of the rules return FALSE for finished, we know we
- have to carry on so we set finished to FALSE. */
- if (!rule_finished)
- finished = FALSE;
-
- g_array_append_vals (occs, tmp_occs->data, tmp_occs->len);
- g_array_free (tmp_occs, TRUE);
- }
-
- /* Add on specific RDATE occurrence dates. If they have an end time
- or duration set, flag them as RDATEs, and store a pointer to the
- period in the rdate_periods array. Otherwise we can just treat them
- as normal occurrences. */
- for (elem = rdates; elem; elem = elem->next) {
- CalComponentPeriod *p;
- CalObjRecurrenceDate rdate;
-
- p = elem->data;
-
- /* FIXME: We currently assume RDATEs are in the same timezone
- as DTSTART. We should get the RDATE timezone and convert
- to the DTSTART timezone first. */
- cotime.year = p->start.year;
- cotime.month = p->start.month - 1;
- cotime.day = p->start.day;
- cotime.hour = p->start.hour;
- cotime.minute = p->start.minute;
- cotime.second = p->start.second;
- cotime.flags = FALSE;
-
- /* If the rdate is after the current chunk we set finished
- to FALSE, and we skip it. */
- if (cal_obj_time_compare_func (&cotime, chunk_end) >= 0) {
- finished = FALSE;
- continue;
- }
-
- /* Check if the end date or duration is set. If it is we need
- to store it so we can get it later. (libical seems to set
- second to -1 to denote an unset time. See icalvalue.c)
- FIXME. */
- if (p->type != CAL_COMPONENT_PERIOD_DATETIME
- || p->u.end.second != -1) {
- cotime.flags = TRUE;
-
- rdate.start = cotime;
- rdate.period = p;
- g_array_append_val (rdate_periods, rdate);
- }
-
- g_array_append_val (occs, cotime);
- }
-
- /* Expand each of the exception rules. */
- for (elem = exrules; elem; elem = elem->next) {
- icalproperty *prop;
- CalRecurrence *r;
-
- prop = elem->data;
- r = cal_recur_from_icalproperty (prop, FALSE, zone,
- convert_end_date);
-
- tmp_occs = cal_obj_expand_recurrence (event_start, zone, r,
- chunk_start,
- chunk_end,
- &rule_finished);
- cal_recur_free (r);
-
- g_array_append_vals (ex_occs, tmp_occs->data, tmp_occs->len);
- g_array_free (tmp_occs, TRUE);
- }
-
- /* Add on specific exception dates. */
- for (elem = exdates; elem; elem = elem->next) {
- CalComponentDateTime *cdt;
-
- cdt = elem->data;
-
- /* FIXME: We currently assume EXDATEs are in the same timezone
- as DTSTART. We should get the EXDATE timezone and convert
- to the DTSTART timezone first. */
- cotime.year = cdt->value->year;
- cotime.month = cdt->value->month - 1;
- cotime.day = cdt->value->day;
-
- /* If the EXDATE has a DATE value, set the time to the start
- of the day and set flags to TRUE so we know to skip all
- occurrences on that date. */
- if (cdt->value->is_date) {
- cotime.hour = 0;
- cotime.minute = 0;
- cotime.second = 0;
- cotime.flags = TRUE;
- } else {
- cotime.hour = cdt->value->hour;
- cotime.minute = cdt->value->minute;
- cotime.second = cdt->value->second;
- cotime.flags = FALSE;
- }
-
- g_array_append_val (ex_occs, cotime);
- }
-
-
- /* Sort all the arrays. */
- cal_obj_sort_occurrences (occs);
- cal_obj_sort_occurrences (ex_occs);
-
- qsort (rdate_periods->data, rdate_periods->len,
- sizeof (CalObjRecurrenceDate), cal_obj_time_compare_func);
-
- /* Create the final array, by removing the exceptions from the
- occurrences, and removing any duplicates. */
- cal_obj_remove_exceptions (occs, ex_occs);
-
- /* Call the callback for each occurrence. If it returns 0 we break
- out of the loop. */
- for (i = 0; i < occs->len; i++) {
- /* Convert each CalObjTime into a start & end time_t, and
- check it is within the bounds of the event & interval. */
- occ = &g_array_index (occs, CalObjTime, i);
-#if 0
- g_print ("Checking occurrence: %s\n",
- cal_obj_time_to_string (occ));
-#endif
- start_tt = icaltime_null_time ();
- start_tt.year = occ->year;
- start_tt.month = occ->month + 1;
- start_tt.day = occ->day;
- start_tt.hour = occ->hour;
- start_tt.minute = occ->minute;
- start_tt.second = occ->second;
- start_time = icaltime_as_timet_with_zone (start_tt, zone);
-
- if (start_time == -1) {
- g_warning ("time_t out of range");
- finished = TRUE;
- break;
- }
-
- /* Check to ensure that the start time is at or after the
- event's DTSTART time, and that it is inside the chunk that
- we are currently working on. (Note that the chunk_end time
- is never after the interval end time, so this also tests
- that we don't go past the end of the required interval). */
- if (start_time < comp_dtstart
- || cal_obj_time_compare_func (occ, chunk_start) < 0
- || cal_obj_time_compare_func (occ, chunk_end) > 0) {
-#if 0
- g_print (" start time invalid\n");
-#endif
- continue;
- }
-
- if (occ->flags) {
- /* If it is an RDATE, we see if the end date or
- duration was set. If not, we use the same duration
- as the original occurrence. */
- if (!cal_object_get_rdate_end (occ, rdate_periods)) {
- cal_obj_time_add_days (occ, duration_days);
- cal_obj_time_add_seconds (occ,
- duration_seconds);
- }
- } else {
- cal_obj_time_add_days (occ, duration_days);
- cal_obj_time_add_seconds (occ, duration_seconds);
- }
-
- end_tt = icaltime_null_time ();
- end_tt.year = occ->year;
- end_tt.month = occ->month + 1;
- end_tt.day = occ->day;
- end_tt.hour = occ->hour;
- end_tt.minute = occ->minute;
- end_tt.second = occ->second;
- end_time = icaltime_as_timet_with_zone (end_tt, zone);
-
- if (end_time == -1) {
- g_warning ("time_t out of range");
- finished = TRUE;
- break;
- }
-
- /* Check that the end time is after the interval start, so we
- know that it intersects the required interval. */
- if (end_time <= interval_start) {
-#if 0
- g_print (" end time invalid\n");
-#endif
- continue;
- }
-
- cb_status = (*cb) (comp, start_time, end_time, cb_data);
- if (!cb_status)
- break;
- }
-
- g_array_free (occs, TRUE);
- g_array_free (ex_occs, TRUE);
- g_array_free (rdate_periods, TRUE);
-
- /* We return TRUE (i.e. carry on) only if the callback has always
- returned TRUE and we know that we have more occurrences to generate
- (i.e. finished is FALSE). */
- return cb_status && !finished;
-}
-
-
-/* This looks up the occurrence time in the sorted rdate_periods array, and
- tries to compute the end time of the occurrence. If no end time or duration
- is set it returns FALSE and the default duration will be used. */
-static gboolean
-cal_object_get_rdate_end (CalObjTime *occ,
- GArray *rdate_periods)
-{
- CalObjRecurrenceDate *rdate = NULL;
- CalComponentPeriod *p;
- gint lower, upper, middle, cmp = 0;
-
- lower = 0;
- upper = rdate_periods->len;
-
- while (lower < upper) {
- middle = (lower + upper) >> 1;
-
- rdate = &g_array_index (rdate_periods, CalObjRecurrenceDate,
- middle);
-
- cmp = cal_obj_time_compare_func (occ, &rdate->start);
-
- if (cmp == 0)
- break;
- else if (cmp < 0)
- upper = middle;
- else
- lower = middle + 1;
- }
-
- /* This should never happen. */
- if (cmp == 0) {
- g_warning ("Recurrence date not found");
- return FALSE;
- }
-
- p = rdate->period;
- if (p->type == CAL_COMPONENT_PERIOD_DATETIME) {
- /* FIXME: We currently assume RDATEs are in the same timezone
- as DTSTART. We should get the RDATE timezone and convert
- to the DTSTART timezone first. */
- occ->year = p->u.end.year;
- occ->month = p->u.end.month - 1;
- occ->day = p->u.end.day;
- occ->hour = p->u.end.hour;
- occ->minute = p->u.end.minute;
- occ->second = p->u.end.second;
- occ->flags = FALSE;
- } else {
- cal_obj_time_add_days (occ, p->u.duration.weeks * 7
- + p->u.duration.days);
- cal_obj_time_add_hours (occ, p->u.duration.hours);
- cal_obj_time_add_minutes (occ, p->u.duration.minutes);
- cal_obj_time_add_seconds (occ, p->u.duration.seconds);
- }
-
- return TRUE;
-}
-
-
-static void
-cal_object_compute_duration (CalObjTime *start,
- CalObjTime *end,
- gint *days,
- gint *seconds)
-{
- GDate start_date, end_date;
- gint start_seconds, end_seconds;
-
- g_date_clear (&start_date, 1);
- g_date_clear (&end_date, 1);
- g_date_set_dmy (&start_date, start->day, start->month + 1,
- start->year);
- g_date_set_dmy (&end_date, end->day, end->month + 1,
- end->year);
-
- *days = g_date_julian (&end_date) - g_date_julian (&start_date);
- start_seconds = start->hour * 3600 + start->minute * 60
- + start->second;
- end_seconds = end->hour * 3600 + end->minute * 60 + end->second;
-
- *seconds = end_seconds - start_seconds;
- if (*seconds < 0) {
- *days = *days - 1;
- *seconds += 24 * 60 * 60;
- }
-}
-
-
-/* Returns an unsorted GArray of CalObjTime's resulting from expanding the
- given recurrence rule within the given interval. Note that it doesn't
- clip the generated occurrences to the interval, i.e. if the interval
- starts part way through the year this function still returns all the
- occurrences for the year. Clipping is done later.
- The finished flag is set to FALSE if there are more occurrences to generate
- after the given interval.*/
-static GArray*
-cal_obj_expand_recurrence (CalObjTime *event_start,
- icaltimezone *zone,
- CalRecurrence *recur,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- gboolean *finished)
-{
- CalRecurVTable *vtable;
- CalObjTime *event_end = NULL, event_end_cotime;
- RecurData recur_data;
- CalObjTime occ, *cotime;
- GArray *all_occs, *occs;
- gint len;
-
- /* This is the resulting array of CalObjTime elements. */
- all_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- *finished = TRUE;
-
- vtable = cal_obj_get_vtable (recur->freq);
- if (!vtable)
- return all_occs;
-
- /* Calculate some useful data such as some fast lookup tables. */
- cal_obj_initialize_recur_data (&recur_data, recur, event_start);
-
- /* Compute the event_end, if the recur's enddate is set. */
- if (recur->enddate > 0) {
- cal_object_time_from_time (&event_end_cotime,
- recur->enddate, zone);
- event_end = &event_end_cotime;
-
- /* If the enddate is before the requested interval return. */
- if (cal_obj_time_compare_func (event_end, interval_start) < 0)
- return all_occs;
- }
-
- /* Set finished to FALSE if we know there will be more occurrences to
- do after this interval. */
- if (!interval_end || !event_end
- || cal_obj_time_compare_func (event_end, interval_end) > 0)
- *finished = FALSE;
-
- /* Get the first period based on the frequency and the interval that
- intersects the interval between start and end. */
- if ((*vtable->find_start_position) (event_start, event_end,
- &recur_data,
- interval_start, interval_end,
- &occ))
- return all_occs;
-
- /* Loop until the event ends or we go past the end of the required
- interval. */
- for (;;) {
- /* Generate the set of occurrences for this period. */
- switch (recur->freq) {
- case ICAL_YEARLY_RECURRENCE:
- occs = cal_obj_generate_set_yearly (&recur_data,
- vtable, &occ);
- break;
- case ICAL_MONTHLY_RECURRENCE:
- occs = cal_obj_generate_set_monthly (&recur_data,
- vtable, &occ);
- break;
- default:
- occs = cal_obj_generate_set_default (&recur_data,
- vtable, &occ);
- break;
- }
-
- /* Sort the occurrences and remove duplicates. */
- cal_obj_sort_occurrences (occs);
- cal_obj_remove_duplicates_and_invalid_dates (occs);
-
- /* Apply the BYSETPOS property. */
- occs = cal_obj_bysetpos_filter (recur, occs);
-
- /* Remove any occs after event_end. */
- len = occs->len - 1;
- if (event_end) {
- while (len >= 0) {
- cotime = &g_array_index (occs, CalObjTime,
- len);
- if (cal_obj_time_compare_func (cotime,
- event_end) <= 0)
- break;
- len--;
- }
- }
-
- /* Add the occurrences onto the main array. */
- if (len >= 0)
- g_array_append_vals (all_occs, occs->data, len + 1);
-
- g_array_free (occs, TRUE);
-
- /* Skip to the next period, or exit the loop if finished. */
- if ((*vtable->find_next_position) (&occ, event_end,
- &recur_data, interval_end))
- break;
- }
-
- return all_occs;
-}
-
-
-static GArray*
-cal_obj_generate_set_yearly (RecurData *recur_data,
- CalRecurVTable *vtable,
- CalObjTime *occ)
-{
- CalRecurrence *recur = recur_data->recur;
- GArray *occs_arrays[4], *occs, *occs2;
- gint num_occs_arrays = 0, i;
-
- /* This is a bit complicated, since the iCalendar spec says that
- several BYxxx modifiers can be used simultaneously. So we have to
- be quite careful when determining the days of the occurrences.
- The BYHOUR, BYMINUTE & BYSECOND modifiers are no problem at all.
-
- The modifiers we have to worry about are: BYMONTH, BYWEEKNO,
- BYYEARDAY, BYMONTHDAY & BYDAY. We can't do these sequentially
- since each filter will mess up the results of the previous one.
- But they aren't all completely independant, e.g. BYMONTHDAY and
- BYDAY are related to BYMONTH, and BYDAY is related to BYWEEKNO.
-
- BYDAY & BYMONTHDAY can also be applied independently, which makes
- it worse. So we assume that if BYMONTH or BYWEEKNO is used, then
- the BYDAY modifier applies to those, else it is applied
- independantly.
-
- We expand the occurrences in parallel into the occs_arrays[] array,
- and then merge them all into one GArray before expanding BYHOUR,
- BYMINUTE & BYSECOND. */
-
- if (recur->bymonth) {
- occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
- g_array_append_vals (occs, occ, 1);
-
- occs = (*vtable->bymonth_filter) (recur_data, occs);
-
- /* If BYMONTHDAY & BYDAY are both set we need to expand them
- in parallel and add the results. */
- if (recur->bymonthday && recur->byday) {
- /* Copy the occs array. */
- occs2 = g_array_new (FALSE, FALSE,
- sizeof (CalObjTime));
- g_array_append_vals (occs2, occs->data, occs->len);
-
- occs = (*vtable->bymonthday_filter) (recur_data, occs);
- /* Note that we explicitly call the monthly version
- of the BYDAY expansion filter. */
- occs2 = cal_obj_byday_expand_monthly (recur_data,
- occs2);
-
- /* Add the 2 resulting arrays together. */
- g_array_append_vals (occs, occs2->data, occs2->len);
- g_array_free (occs2, TRUE);
- } else {
- occs = (*vtable->bymonthday_filter) (recur_data, occs);
- /* Note that we explicitly call the monthly version
- of the BYDAY expansion filter. */
- occs = cal_obj_byday_expand_monthly (recur_data, occs);
- }
-
- occs_arrays[num_occs_arrays++] = occs;
- }
-
- if (recur->byweekno) {
- occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
- g_array_append_vals (occs, occ, 1);
-
- occs = (*vtable->byweekno_filter) (recur_data, occs);
- /* Note that we explicitly call the weekly version of the
- BYDAY expansion filter. */
- occs = cal_obj_byday_expand_weekly (recur_data, occs);
-
- occs_arrays[num_occs_arrays++] = occs;
- }
-
- if (recur->byyearday) {
- occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
- g_array_append_vals (occs, occ, 1);
-
- occs = (*vtable->byyearday_filter) (recur_data, occs);
-
- occs_arrays[num_occs_arrays++] = occs;
- }
-
- /* If BYMONTHDAY is set, and BYMONTH is not set, we need to
- expand BYMONTHDAY independantly. */
- if (recur->bymonthday && !recur->bymonth) {
- occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
- g_array_append_vals (occs, occ, 1);
-
- occs = (*vtable->bymonthday_filter) (recur_data, occs);
-
- occs_arrays[num_occs_arrays++] = occs;
- }
-
- /* If BYDAY is set, and BYMONTH and BYWEEKNO are not set, we need to
- expand BYDAY independantly. */
- if (recur->byday && !recur->bymonth && !recur->byweekno) {
- occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
- g_array_append_vals (occs, occ, 1);
-
- occs = (*vtable->byday_filter) (recur_data, occs);
-
- occs_arrays[num_occs_arrays++] = occs;
- }
-
- /* Add all the arrays together. If no filters were used we just
- create an array with one element. */
- if (num_occs_arrays > 0) {
- occs = occs_arrays[0];
- for (i = 1; i < num_occs_arrays; i++) {
- occs2 = occs_arrays[i];
- g_array_append_vals (occs, occs2->data, occs2->len);
- g_array_free (occs2, TRUE);
- }
- } else {
- occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
- g_array_append_vals (occs, occ, 1);
- }
-
- /* Now expand BYHOUR, BYMINUTE & BYSECOND. */
- occs = (*vtable->byhour_filter) (recur_data, occs);
- occs = (*vtable->byminute_filter) (recur_data, occs);
- occs = (*vtable->bysecond_filter) (recur_data, occs);
-
- return occs;
-}
-
-
-static GArray*
-cal_obj_generate_set_monthly (RecurData *recur_data,
- CalRecurVTable *vtable,
- CalObjTime *occ)
-{
- GArray *occs, *occs2;
-
- /* We start with just the one time in each set. */
- occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
- g_array_append_vals (occs, occ, 1);
-
- occs = (*vtable->bymonth_filter) (recur_data, occs);
-
- /* We need to combine the output of BYMONTHDAY & BYDAY, by doing them
- in parallel rather than sequentially. If we did them sequentially
- then we would lose the occurrences generated by BYMONTHDAY, and
- instead have repetitions of the occurrences from BYDAY. */
- if (recur_data->recur->bymonthday && recur_data->recur->byday) {
- occs2 = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
- g_array_append_vals (occs2, occs->data, occs->len);
-
- occs = (*vtable->bymonthday_filter) (recur_data, occs);
- occs2 = (*vtable->byday_filter) (recur_data, occs2);
-
- g_array_append_vals (occs, occs2->data, occs2->len);
- g_array_free (occs2, TRUE);
- } else {
- occs = (*vtable->bymonthday_filter) (recur_data, occs);
- occs = (*vtable->byday_filter) (recur_data, occs);
- }
-
- occs = (*vtable->byhour_filter) (recur_data, occs);
- occs = (*vtable->byminute_filter) (recur_data, occs);
- occs = (*vtable->bysecond_filter) (recur_data, occs);
-
- return occs;
-}
-
-
-static GArray*
-cal_obj_generate_set_default (RecurData *recur_data,
- CalRecurVTable *vtable,
- CalObjTime *occ)
-{
- GArray *occs;
-
-#if 0
- g_print ("Generating set for %i/%i/%i %02i:%02i:%02i\n",
- occ->day, occ->month + 1, occ->year, occ->hour, occ->minute,
- occ->second);
-#endif
-
- /* We start with just the one time in the set. */
- occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
- g_array_append_vals (occs, occ, 1);
-
- occs = (*vtable->bymonth_filter) (recur_data, occs);
- if (vtable->byweekno_filter)
- occs = (*vtable->byweekno_filter) (recur_data, occs);
- if (vtable->byyearday_filter)
- occs = (*vtable->byyearday_filter) (recur_data, occs);
- if (vtable->bymonthday_filter)
- occs = (*vtable->bymonthday_filter) (recur_data, occs);
- occs = (*vtable->byday_filter) (recur_data, occs);
-
- occs = (*vtable->byhour_filter) (recur_data, occs);
- occs = (*vtable->byminute_filter) (recur_data, occs);
- occs = (*vtable->bysecond_filter) (recur_data, occs);
-
- return occs;
-}
-
-
-
-/* Returns the function table corresponding to the recurrence frequency. */
-static CalRecurVTable* cal_obj_get_vtable (icalrecurrencetype_frequency recur_type)
-{
- CalRecurVTable* vtable;
-
- switch (recur_type) {
- case ICAL_YEARLY_RECURRENCE:
- vtable = &cal_obj_yearly_vtable;
- break;
- case ICAL_MONTHLY_RECURRENCE:
- vtable = &cal_obj_monthly_vtable;
- break;
- case ICAL_WEEKLY_RECURRENCE:
- vtable = &cal_obj_weekly_vtable;
- break;
- case ICAL_DAILY_RECURRENCE:
- vtable = &cal_obj_daily_vtable;
- break;
- case ICAL_HOURLY_RECURRENCE:
- vtable = &cal_obj_hourly_vtable;
- break;
- case ICAL_MINUTELY_RECURRENCE:
- vtable = &cal_obj_minutely_vtable;
- break;
- case ICAL_SECONDLY_RECURRENCE:
- vtable = &cal_obj_secondly_vtable;
- break;
- default:
- g_warning ("Unknown recurrence frequency");
- vtable = NULL;
- }
-
- return vtable;
-}
-
-
-/* This creates a number of fast lookup tables used when filtering with the
- modifier properties BYMONTH, BYYEARDAY etc. */
-static void
-cal_obj_initialize_recur_data (RecurData *recur_data,
- CalRecurrence *recur,
- CalObjTime *event_start)
-{
- GList *elem;
- gint month, yearday, monthday, weekday, week_num, hour, minute, second;
-
- /* Clear the entire RecurData. */
- memset (recur_data, 0, sizeof (RecurData));
-
- recur_data->recur = recur;
-
- /* Set the weekday, used for the WEEKLY frequency and the BYWEEKNO
- modifier. */
- recur_data->weekday_offset = cal_obj_time_weekday_offset (event_start,
- recur);
-
- /* Create an array of months from bymonths for fast lookup. */
- elem = recur->bymonth;
- while (elem) {
- month = GPOINTER_TO_INT (elem->data);
- recur_data->months[month] = 1;
- elem = elem->next;
- }
-
- /* Create an array of yeardays from byyearday for fast lookup.
- We create a second array to handle the negative values. The first
- element there corresponds to the last day of the year. */
- elem = recur->byyearday;
- while (elem) {
- yearday = GPOINTER_TO_INT (elem->data);
- if (yearday >= 0)
- recur_data->yeardays[yearday] = 1;
- else
- recur_data->neg_yeardays[-yearday] = 1;
- elem = elem->next;
- }
-
- /* Create an array of monthdays from bymonthday for fast lookup.
- We create a second array to handle the negative values. The first
- element there corresponds to the last day of the month. */
- elem = recur->bymonthday;
- while (elem) {
- monthday = GPOINTER_TO_INT (elem->data);
- if (monthday >= 0)
- recur_data->monthdays[monthday] = 1;
- else
- recur_data->neg_monthdays[-monthday] = 1;
- elem = elem->next;
- }
-
- /* Create an array of weekdays from byday for fast lookup. */
- elem = recur->byday;
- while (elem) {
- weekday = GPOINTER_TO_INT (elem->data);
- elem = elem->next;
- /* The week number is not used when filtering. */
- week_num = GPOINTER_TO_INT (elem->data);
- elem = elem->next;
-
- recur_data->weekdays[weekday] = 1;
- }
-
- /* Create an array of hours from byhour for fast lookup. */
- elem = recur->byhour;
- while (elem) {
- hour = GPOINTER_TO_INT (elem->data);
- recur_data->hours[hour] = 1;
- elem = elem->next;
- }
-
- /* Create an array of minutes from byminutes for fast lookup. */
- elem = recur->byminute;
- while (elem) {
- minute = GPOINTER_TO_INT (elem->data);
- recur_data->minutes[minute] = 1;
- elem = elem->next;
- }
-
- /* Create an array of seconds from byseconds for fast lookup. */
- elem = recur->bysecond;
- while (elem) {
- second = GPOINTER_TO_INT (elem->data);
- recur_data->seconds[second] = 1;
- elem = elem->next;
- }
-}
-
-
-static void
-cal_obj_sort_occurrences (GArray *occs)
-{
- qsort (occs->data, occs->len, sizeof (CalObjTime),
- cal_obj_time_compare_func);
-}
-
-
-static void
-cal_obj_remove_duplicates_and_invalid_dates (GArray *occs)
-{
- static const int days_in_month[12] = {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
-
- CalObjTime *occ, *prev_occ = NULL;
- gint len, i, j = 0, year, month, days;
- gboolean keep_occ;
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
- keep_occ = TRUE;
-
- if (prev_occ && cal_obj_time_compare_func (occ,
- prev_occ) == 0)
- keep_occ = FALSE;
-
- year = occ->year;
- month = occ->month;
- days = days_in_month[occ->month];
- /* If it is february and a leap year, add a day. */
- if (month == 1 && (year % 4 == 0
- && (year % 100 != 0
- || year % 400 == 0)))
- days++;
- if (occ->day > days)
- keep_occ = FALSE;
-
- if (keep_occ) {
- if (i != j)
- g_array_index (occs, CalObjTime, j)
- = g_array_index (occs, CalObjTime, i);
- j++;
- }
-
- prev_occ = occ;
- }
-
- g_array_set_size (occs, j);
-}
-
-
-/* Removes the exceptions from the ex_occs array from the occurrences in the
- occs array, and removes any duplicates. Both arrays are sorted. */
-static void
-cal_obj_remove_exceptions (GArray *occs,
- GArray *ex_occs)
-{
- CalObjTime *occ, *prev_occ = NULL, *ex_occ = NULL, *last_occ_kept;
- gint i, j = 0, cmp, ex_index, occs_len, ex_occs_len;
- gboolean keep_occ, current_time_is_exception = FALSE;
-
- if (occs->len == 0)
- return;
-
- ex_index = 0;
- occs_len = occs->len;
- ex_occs_len = ex_occs->len;
-
- if (ex_occs_len > 0)
- ex_occ = &g_array_index (ex_occs, CalObjTime, ex_index);
-
- for (i = 0; i < occs_len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
- keep_occ = TRUE;
-
- /* If the occurrence is a duplicate of the previous one, skip
- it. */
- if (prev_occ
- && cal_obj_time_compare_func (occ, prev_occ) == 0) {
- keep_occ = FALSE;
-
- /* If this occurrence is an RDATE with an end or
- duration set, and the previous occurrence in the
- array was kept, set the RDATE flag of the last one,
- so we still use the end date or duration. */
- if (occ->flags && !current_time_is_exception) {
- last_occ_kept = &g_array_index (occs,
- CalObjTime,
- j - 1);
- last_occ_kept->flags = TRUE;
- }
- } else {
- /* We've found a new occurrence time. Reset the flag
- to indicate that it hasn't been found in the
- exceptions array (yet). */
- current_time_is_exception = FALSE;
-
- if (ex_occ) {
- /* Step through the exceptions until we come
- to one that matches or follows this
- occurrence. */
- while (ex_occ) {
- /* If the exception is an EXDATE with
- a DATE value, we only have to
- compare the date. */
- if (ex_occ->flags)
- cmp = cal_obj_date_only_compare_func (ex_occ, occ);
- else
- cmp = cal_obj_time_compare_func (ex_occ, occ);
-
- if (cmp > 0)
- break;
-
- /* Move to the next exception, or set
- ex_occ to NULL when we reach the
- end of array. */
- ex_index++;
- if (ex_index < ex_occs_len)
- ex_occ = &g_array_index (ex_occs, CalObjTime, ex_index);
- else
- ex_occ = NULL;
-
- /* If the exception did match this
- occurrence we remove it, and set the
- flag to indicate that the current
- time is an exception. */
- if (cmp == 0) {
- current_time_is_exception = TRUE;
- keep_occ = FALSE;
- break;
- }
- }
- }
- }
-
- if (keep_occ) {
- /* We are keeping this occurrence, so we move it to
- the next free space, unless its position hasn't
- changed (i.e. all previous occurrences were also
- kept). */
- if (i != j)
- g_array_index (occs, CalObjTime, j)
- = g_array_index (occs, CalObjTime, i);
- j++;
- }
-
- prev_occ = occ;
- }
-
- g_array_set_size (occs, j);
-}
-
-
-
-static GArray*
-cal_obj_bysetpos_filter (CalRecurrence *recur,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- GList *elem;
- gint len, pos;
-
- /* If BYSETPOS has not been specified, or the array is empty, just
- return the array. */
- elem = recur->bysetpos;
- if (!elem || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- /* Iterate over the indices given in bysetpos, adding the corresponding
- element from occs to new_occs. */
- len = occs->len;
- while (elem) {
- pos = GPOINTER_TO_INT (elem->data);
-
- /* Negative values count back from the end of the array. */
- if (pos < 0)
- pos += len;
- /* Positive values need to be decremented since the array is
- 0-based. */
- else
- pos--;
-
- if (pos >= 0 && pos < len) {
- occ = &g_array_index (occs, CalObjTime, pos);
- g_array_append_vals (new_occs, occ, 1);
- }
- elem = elem->next;
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-
-
-/* Finds the first year from the event_start, counting in multiples of the
- recurrence interval, that intersects the given interval. It returns TRUE
- if there is no intersection. */
-static gboolean
-cal_obj_yearly_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime)
-{
- *cotime = *event_start;
-
- /* Move on to the next interval, if the event starts before the
- given interval. */
- if (cotime->year < interval_start->year) {
- gint years = interval_start->year - cotime->year
- + recur_data->recur->interval - 1;
- years -= years % recur_data->recur->interval;
- /* NOTE: The day may now be invalid, e.g. 29th Feb. */
- cotime->year += years;
- }
-
- if ((event_end && cotime->year > event_end->year)
- || (interval_end && cotime->year > interval_end->year))
- return TRUE;
-
- return FALSE;
-}
-
-
-static gboolean
-cal_obj_yearly_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end)
-{
- /* NOTE: The day may now be invalid, e.g. 29th Feb. */
- cotime->year += recur_data->recur->interval;
-
- if ((event_end && cotime->year > event_end->year)
- || (interval_end && cotime->year > interval_end->year))
- return TRUE;
-
- return FALSE;
-}
-
-
-
-static gboolean
-cal_obj_monthly_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime)
-{
- *cotime = *event_start;
-
- /* Move on to the next interval, if the event starts before the
- given interval. */
- if (cal_obj_time_compare (cotime, interval_start, CALOBJ_MONTH) < 0) {
- gint months = (interval_start->year - cotime->year) * 12
- + interval_start->month - cotime->month
- + recur_data->recur->interval - 1;
- months -= months % recur_data->recur->interval;
- /* NOTE: The day may now be invalid, e.g. 31st Sep. */
- cal_obj_time_add_months (cotime, months);
- }
-
- if (event_end && cal_obj_time_compare (cotime, event_end,
- CALOBJ_MONTH) > 0)
- return TRUE;
- if (interval_end && cal_obj_time_compare (cotime, interval_end,
- CALOBJ_MONTH) > 0)
- return TRUE;
-
- return FALSE;
-}
-
-
-static gboolean
-cal_obj_monthly_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end)
-{
- /* NOTE: The day may now be invalid, e.g. 31st Sep. */
- cal_obj_time_add_months (cotime, recur_data->recur->interval);
-
- if (event_end && cal_obj_time_compare (cotime, event_end,
- CALOBJ_MONTH) > 0)
- return TRUE;
- if (interval_end && cal_obj_time_compare (cotime, interval_end,
- CALOBJ_MONTH) > 0)
- return TRUE;
-
- return FALSE;
-}
-
-
-
-static gboolean
-cal_obj_weekly_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime)
-{
- GDate event_start_date, interval_start_date;
- guint32 event_start_julian, interval_start_julian;
- gint interval_start_weekday_offset;
- CalObjTime week_start;
-
- if (event_end && cal_obj_time_compare (event_end, interval_start,
- CALOBJ_DAY) < 0)
- return TRUE;
- if (interval_end && cal_obj_time_compare (event_start, interval_end,
- CALOBJ_DAY) > 0)
- return TRUE;
-
- *cotime = *event_start;
-
- /* Convert the event start and interval start to GDates, so we can
- easily find the number of days between them. */
- g_date_clear (&event_start_date, 1);
- g_date_set_dmy (&event_start_date, event_start->day,
- event_start->month + 1, event_start->year);
- g_date_clear (&interval_start_date, 1);
- g_date_set_dmy (&interval_start_date, interval_start->day,
- interval_start->month + 1, interval_start->year);
-
- /* Calculate the start of the weeks corresponding to the event start
- and interval start. */
- event_start_julian = g_date_julian (&event_start_date);
- event_start_julian -= recur_data->weekday_offset;
-
- interval_start_julian = g_date_julian (&interval_start_date);
- interval_start_weekday_offset = cal_obj_time_weekday_offset (interval_start, recur_data->recur);
- interval_start_julian -= interval_start_weekday_offset;
-
- /* We want to find the first full week using the recurrence interval
- that intersects the given interval dates. */
- if (event_start_julian < interval_start_julian) {
- gint weeks = (interval_start_julian - event_start_julian) / 7;
- weeks += recur_data->recur->interval - 1;
- weeks -= weeks % recur_data->recur->interval;
- cal_obj_time_add_days (cotime, weeks * 7);
- }
-
- week_start = *cotime;
- cal_obj_time_add_days (&week_start, -recur_data->weekday_offset);
-
- if (event_end && cal_obj_time_compare (&week_start, event_end,
- CALOBJ_DAY) > 0)
- return TRUE;
- if (interval_end && cal_obj_time_compare (&week_start, interval_end,
- CALOBJ_DAY) > 0)
- return TRUE;
-
- return FALSE;
-}
-
-
-static gboolean
-cal_obj_weekly_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end)
-{
- CalObjTime week_start;
-
- cal_obj_time_add_days (cotime, recur_data->recur->interval * 7);
-
- /* Return TRUE if the start of this week is after the event finishes
- or is after the end of the required interval. */
- week_start = *cotime;
- cal_obj_time_add_days (&week_start, -recur_data->weekday_offset);
-
-#ifdef CAL_OBJ_DEBUG
- g_print ("Next day: %s\n", cal_obj_time_to_string (cotime));
- g_print ("Week Start: %s\n", cal_obj_time_to_string (&week_start));
-#endif
-
- if (event_end && cal_obj_time_compare (&week_start, event_end,
- CALOBJ_DAY) > 0)
- return TRUE;
- if (interval_end && cal_obj_time_compare (&week_start, interval_end,
- CALOBJ_DAY) > 0) {
-#ifdef CAL_OBJ_DEBUG
- g_print ("Interval end reached: %s\n",
- cal_obj_time_to_string (interval_end));
-#endif
- return TRUE;
- }
-
- return FALSE;
-}
-
-
-static gboolean
-cal_obj_daily_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime)
-{
- GDate event_start_date, interval_start_date;
- guint32 event_start_julian, interval_start_julian, days;
-
- if (interval_end && cal_obj_time_compare (event_start, interval_end,
- CALOBJ_DAY) > 0)
- return TRUE;
- if (event_end && cal_obj_time_compare (event_end, interval_start,
- CALOBJ_DAY) < 0)
- return TRUE;
-
- *cotime = *event_start;
-
- /* Convert the event start and interval start to GDates, so we can
- easily find the number of days between them. */
- g_date_clear (&event_start_date, 1);
- g_date_set_dmy (&event_start_date, event_start->day,
- event_start->month + 1, event_start->year);
- g_date_clear (&interval_start_date, 1);
- g_date_set_dmy (&interval_start_date, interval_start->day,
- interval_start->month + 1, interval_start->year);
-
- event_start_julian = g_date_julian (&event_start_date);
- interval_start_julian = g_date_julian (&interval_start_date);
-
- if (event_start_julian < interval_start_julian) {
- days = interval_start_julian - event_start_julian
- + recur_data->recur->interval - 1;
- days -= days % recur_data->recur->interval;
- cal_obj_time_add_days (cotime, days);
- }
-
- if (event_end && cal_obj_time_compare (cotime, event_end,
- CALOBJ_DAY) > 0)
- return TRUE;
- if (interval_end && cal_obj_time_compare (cotime, interval_end,
- CALOBJ_DAY) > 0)
- return TRUE;
-
- return FALSE;
-}
-
-
-static gboolean
-cal_obj_daily_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end)
-{
- cal_obj_time_add_days (cotime, recur_data->recur->interval);
-
- if (event_end && cal_obj_time_compare (cotime, event_end,
- CALOBJ_DAY) > 0)
- return TRUE;
- if (interval_end && cal_obj_time_compare (cotime, interval_end,
- CALOBJ_DAY) > 0)
- return TRUE;
-
- return FALSE;
-}
-
-
-static gboolean
-cal_obj_hourly_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime)
-{
- GDate event_start_date, interval_start_date;
- guint32 event_start_julian, interval_start_julian, hours;
-
- if (interval_end && cal_obj_time_compare (event_start, interval_end,
- CALOBJ_HOUR) > 0)
- return TRUE;
- if (event_end && cal_obj_time_compare (event_end, interval_start,
- CALOBJ_HOUR) < 0)
- return TRUE;
-
- *cotime = *event_start;
-
- if (cal_obj_time_compare (event_start, interval_start,
- CALOBJ_HOUR) < 0) {
- /* Convert the event start and interval start to GDates, so we
- can easily find the number of days between them. */
- g_date_clear (&event_start_date, 1);
- g_date_set_dmy (&event_start_date, event_start->day,
- event_start->month + 1, event_start->year);
- g_date_clear (&interval_start_date, 1);
- g_date_set_dmy (&interval_start_date, interval_start->day,
- interval_start->month + 1,
- interval_start->year);
-
- event_start_julian = g_date_julian (&event_start_date);
- interval_start_julian = g_date_julian (&interval_start_date);
-
- hours = (interval_start_julian - event_start_julian) * 24;
- hours += interval_start->hour - event_start->hour;
- hours += recur_data->recur->interval - 1;
- hours -= hours % recur_data->recur->interval;
- cal_obj_time_add_hours (cotime, hours);
- }
-
- if (event_end && cal_obj_time_compare (cotime, event_end,
- CALOBJ_HOUR) > 0)
- return TRUE;
- if (interval_end && cal_obj_time_compare (cotime, interval_end,
- CALOBJ_HOUR) > 0)
- return TRUE;
-
- return FALSE;
-}
-
-
-static gboolean
-cal_obj_hourly_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end)
-{
- cal_obj_time_add_hours (cotime, recur_data->recur->interval);
-
- if (event_end && cal_obj_time_compare (cotime, event_end,
- CALOBJ_HOUR) > 0)
- return TRUE;
- if (interval_end && cal_obj_time_compare (cotime, interval_end,
- CALOBJ_HOUR) > 0)
- return TRUE;
-
- return FALSE;
-}
-
-
-static gboolean
-cal_obj_minutely_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime)
-{
- GDate event_start_date, interval_start_date;
- guint32 event_start_julian, interval_start_julian, minutes;
-
- if (interval_end && cal_obj_time_compare (event_start, interval_end,
- CALOBJ_MINUTE) > 0)
- return TRUE;
- if (event_end && cal_obj_time_compare (event_end, interval_start,
- CALOBJ_MINUTE) < 0)
- return TRUE;
-
- *cotime = *event_start;
-
- if (cal_obj_time_compare (event_start, interval_start,
- CALOBJ_MINUTE) < 0) {
- /* Convert the event start and interval start to GDates, so we
- can easily find the number of days between them. */
- g_date_clear (&event_start_date, 1);
- g_date_set_dmy (&event_start_date, event_start->day,
- event_start->month + 1, event_start->year);
- g_date_clear (&interval_start_date, 1);
- g_date_set_dmy (&interval_start_date, interval_start->day,
- interval_start->month + 1,
- interval_start->year);
-
- event_start_julian = g_date_julian (&event_start_date);
- interval_start_julian = g_date_julian (&interval_start_date);
-
- minutes = (interval_start_julian - event_start_julian)
- * 24 * 60;
- minutes += (interval_start->hour - event_start->hour) * 24;
- minutes += interval_start->minute - event_start->minute;
- minutes += recur_data->recur->interval - 1;
- minutes -= minutes % recur_data->recur->interval;
- cal_obj_time_add_minutes (cotime, minutes);
- }
-
- if (event_end && cal_obj_time_compare (cotime, event_end,
- CALOBJ_MINUTE) > 0)
- return TRUE;
- if (interval_end && cal_obj_time_compare (cotime, interval_end,
- CALOBJ_MINUTE) > 0)
- return TRUE;
-
- return FALSE;
-}
-
-
-static gboolean
-cal_obj_minutely_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end)
-{
- cal_obj_time_add_minutes (cotime, recur_data->recur->interval);
-
- if (event_end && cal_obj_time_compare (cotime, event_end,
- CALOBJ_MINUTE) > 0)
- return TRUE;
- if (interval_end && cal_obj_time_compare (cotime, interval_end,
- CALOBJ_MINUTE) > 0)
- return TRUE;
-
- return FALSE;
-}
-
-
-static gboolean
-cal_obj_secondly_find_start_position (CalObjTime *event_start,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_start,
- CalObjTime *interval_end,
- CalObjTime *cotime)
-{
- GDate event_start_date, interval_start_date;
- guint32 event_start_julian, interval_start_julian, seconds;
-
- if (interval_end && cal_obj_time_compare (event_start, interval_end,
- CALOBJ_SECOND) > 0)
- return TRUE;
- if (event_end && cal_obj_time_compare (event_end, interval_start,
- CALOBJ_SECOND) < 0)
- return TRUE;
-
- *cotime = *event_start;
-
- if (cal_obj_time_compare (event_start, interval_start,
- CALOBJ_SECOND) < 0) {
- /* Convert the event start and interval start to GDates, so we
- can easily find the number of days between them. */
- g_date_clear (&event_start_date, 1);
- g_date_set_dmy (&event_start_date, event_start->day,
- event_start->month + 1, event_start->year);
- g_date_clear (&interval_start_date, 1);
- g_date_set_dmy (&interval_start_date, interval_start->day,
- interval_start->month + 1,
- interval_start->year);
-
- event_start_julian = g_date_julian (&event_start_date);
- interval_start_julian = g_date_julian (&interval_start_date);
-
- seconds = (interval_start_julian - event_start_julian)
- * 24 * 60 * 60;
- seconds += (interval_start->hour - event_start->hour)
- * 24 * 60;
- seconds += (interval_start->minute - event_start->minute) * 60;
- seconds += interval_start->second - event_start->second;
- seconds += recur_data->recur->interval - 1;
- seconds -= seconds % recur_data->recur->interval;
- cal_obj_time_add_seconds (cotime, seconds);
- }
-
- if (event_end && cal_obj_time_compare (cotime, event_end,
- CALOBJ_SECOND) >= 0)
- return TRUE;
- if (interval_end && cal_obj_time_compare (cotime, interval_end,
- CALOBJ_SECOND) >= 0)
- return TRUE;
-
- return FALSE;
-}
-
-
-static gboolean
-cal_obj_secondly_find_next_position (CalObjTime *cotime,
- CalObjTime *event_end,
- RecurData *recur_data,
- CalObjTime *interval_end)
-{
- cal_obj_time_add_seconds (cotime, recur_data->recur->interval);
-
- if (event_end && cal_obj_time_compare (cotime, event_end,
- CALOBJ_SECOND) >= 0)
- return TRUE;
- if (interval_end && cal_obj_time_compare (cotime, interval_end,
- CALOBJ_SECOND) >= 0)
- return TRUE;
-
- return FALSE;
-}
-
-
-
-
-
-/* If the BYMONTH rule is specified it expands each occurrence in occs, by
- using each of the months in the bymonth list. */
-static GArray*
-cal_obj_bymonth_expand (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- GList *elem;
- gint len, i;
-
- /* If BYMONTH has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->bymonth || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
-
- elem = recur_data->recur->bymonth;
- while (elem) {
- /* NOTE: The day may now be invalid, e.g. 31st Feb. */
- occ->month = GPOINTER_TO_INT (elem->data);
- g_array_append_vals (new_occs, occ, 1);
- elem = elem->next;
- }
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-/* If the BYMONTH rule is specified it filters out all occurrences in occs
- which do not match one of the months in the bymonth list. */
-static GArray*
-cal_obj_bymonth_filter (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- gint len, i;
-
- /* If BYMONTH has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->bymonth || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
- if (recur_data->months[occ->month])
- g_array_append_vals (new_occs, occ, 1);
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-
-static GArray*
-cal_obj_byweekno_expand (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ, year_start_cotime, year_end_cotime, cotime;
- GList *elem;
- gint len, i, weekno;
-
- /* If BYWEEKNO has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->byweekno || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
-
- /* Find the day that would correspond to week 1 (note that
- week 1 is the first week starting from the specified week
- start day that has 4 days in the new year). */
- year_start_cotime = *occ;
- cal_obj_time_find_first_week (&year_start_cotime,
- recur_data);
-
- /* Find the day that would correspond to week 1 of the next
- year, which we use for -ve week numbers. */
- year_end_cotime = *occ;
- year_end_cotime.year++;
- cal_obj_time_find_first_week (&year_end_cotime,
- recur_data);
-
- /* Now iterate over the week numbers in byweekno, generating a
- new occurrence for each one. */
- elem = recur_data->recur->byweekno;
- while (elem) {
- weekno = GPOINTER_TO_INT (elem->data);
- if (weekno > 0) {
- cotime = year_start_cotime;
- cal_obj_time_add_days (&cotime,
- (weekno - 1) * 7);
- } else {
- cotime = year_end_cotime;
- cal_obj_time_add_days (&cotime, weekno * 7);
- }
-
- /* Skip occurrences if they fall outside the year. */
- if (cotime.year == occ->year)
- g_array_append_val (new_occs, cotime);
- elem = elem->next;
- }
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-#if 0
-/* This isn't used at present. */
-static GArray*
-cal_obj_byweekno_filter (RecurData *recur_data,
- GArray *occs)
-{
-
- return occs;
-}
-#endif
-
-
-static GArray*
-cal_obj_byyearday_expand (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ, year_start_cotime, year_end_cotime, cotime;
- GList *elem;
- gint len, i, dayno;
-
- /* If BYYEARDAY has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->byyearday || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
-
- /* Find the day that would correspond to day 1. */
- year_start_cotime = *occ;
- year_start_cotime.month = 0;
- year_start_cotime.day = 1;
-
- /* Find the day that would correspond to day 1 of the next
- year, which we use for -ve day numbers. */
- year_end_cotime = *occ;
- year_end_cotime.year++;
- year_end_cotime.month = 0;
- year_end_cotime.day = 1;
-
- /* Now iterate over the day numbers in byyearday, generating a
- new occurrence for each one. */
- elem = recur_data->recur->byyearday;
- while (elem) {
- dayno = GPOINTER_TO_INT (elem->data);
- if (dayno > 0) {
- cotime = year_start_cotime;
- cal_obj_time_add_days (&cotime, dayno - 1);
- } else {
- cotime = year_end_cotime;
- cal_obj_time_add_days (&cotime, dayno);
- }
-
- /* Skip occurrences if they fall outside the year. */
- if (cotime.year == occ->year)
- g_array_append_val (new_occs, cotime);
- elem = elem->next;
- }
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-/* Note: occs must not contain invalid dates, e.g. 31st September. */
-static GArray*
-cal_obj_byyearday_filter (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- gint yearday, len, i, days_in_year;
-
- /* If BYYEARDAY has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->byyearday || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
- yearday = cal_obj_time_day_of_year (occ);
- if (recur_data->yeardays[yearday]) {
- g_array_append_vals (new_occs, occ, 1);
- } else {
- days_in_year = g_date_is_leap_year (occ->year)
- ? 366 : 365;
- if (recur_data->neg_yeardays[days_in_year + 1
- - yearday])
- g_array_append_vals (new_occs, occ, 1);
- }
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-
-static GArray*
-cal_obj_bymonthday_expand (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ, month_start_cotime, month_end_cotime, cotime;
- GList *elem;
- gint len, i, dayno;
-
- /* If BYMONTHDAY has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->bymonthday || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
-
- /* Find the day that would correspond to day 1. */
- month_start_cotime = *occ;
- month_start_cotime.day = 1;
-
- /* Find the day that would correspond to day 1 of the next
- month, which we use for -ve day numbers. */
- month_end_cotime = *occ;
- month_end_cotime.month++;
- month_end_cotime.day = 1;
-
- /* Now iterate over the day numbers in bymonthday, generating a
- new occurrence for each one. */
- elem = recur_data->recur->bymonthday;
- while (elem) {
- dayno = GPOINTER_TO_INT (elem->data);
- if (dayno > 0) {
- cotime = month_start_cotime;
- cal_obj_time_add_days (&cotime, dayno - 1);
- } else {
- cotime = month_end_cotime;
- cal_obj_time_add_days (&cotime, dayno);
- }
-
- /* Skip occurrences if they fall outside the month. */
- if (cotime.month == occ->month)
- g_array_append_val (new_occs, cotime);
- elem = elem->next;
- }
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-static GArray*
-cal_obj_bymonthday_filter (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- gint len, i, days_in_month;
-
- /* If BYMONTHDAY has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->bymonthday || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
- if (recur_data->monthdays[occ->day]) {
- g_array_append_vals (new_occs, occ, 1);
- } else {
- days_in_month = time_days_in_month (occ->year,
- occ->month);
- if (recur_data->neg_monthdays[days_in_month + 1
- - occ->day])
- g_array_append_vals (new_occs, occ, 1);
- }
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-
-static GArray*
-cal_obj_byday_expand_yearly (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- GList *elem;
- gint len, i, weekday, week_num;
- gint first_weekday, last_weekday, offset;
- guint16 year;
-
- /* If BYDAY has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->byday || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
-
- elem = recur_data->recur->byday;
- while (elem) {
- weekday = GPOINTER_TO_INT (elem->data);
- elem = elem->next;
- week_num = GPOINTER_TO_INT (elem->data);
- elem = elem->next;
-
- year = occ->year;
- if (week_num == 0) {
- /* Expand to every Mon/Tue/etc. in the year. */
- occ->month = 0;
- occ->day = 1;
- first_weekday = cal_obj_time_weekday (occ);
- offset = (weekday + 7 - first_weekday) % 7;
- cal_obj_time_add_days (occ, offset);
-
- while (occ->year == year) {
- g_array_append_vals (new_occs, occ, 1);
- cal_obj_time_add_days (occ, 7);
- }
-
- } else if (week_num > 0) {
- /* Add the nth Mon/Tue/etc. in the year. */
- occ->month = 0;
- occ->day = 1;
- first_weekday = cal_obj_time_weekday (occ);
- offset = (weekday + 7 - first_weekday) % 7;
- offset += (week_num - 1) * 7;
- cal_obj_time_add_days (occ, offset);
- if (occ->year == year)
- g_array_append_vals (new_occs, occ, 1);
-
- } else {
- /* Add the -nth Mon/Tue/etc. in the year. */
- occ->month = 11;
- occ->day = 31;
- last_weekday = cal_obj_time_weekday (occ);
- offset = (last_weekday + 7 - weekday) % 7;
- offset += (week_num - 1) * 7;
- cal_obj_time_add_days (occ, -offset);
- if (occ->year == year)
- g_array_append_vals (new_occs, occ, 1);
- }
-
- /* Reset the year, as we may have gone past the end. */
- occ->year = year;
- }
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-static GArray*
-cal_obj_byday_expand_monthly (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- GList *elem;
- gint len, i, weekday, week_num;
- gint first_weekday, last_weekday, offset;
- guint16 year;
- guint8 month;
-
- /* If BYDAY has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->byday || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
-
- elem = recur_data->recur->byday;
- while (elem) {
- weekday = GPOINTER_TO_INT (elem->data);
- elem = elem->next;
- week_num = GPOINTER_TO_INT (elem->data);
- elem = elem->next;
-
- year = occ->year;
- month = occ->month;
- if (week_num == 0) {
- /* Expand to every Mon/Tue/etc. in the month.*/
- occ->day = 1;
- first_weekday = cal_obj_time_weekday (occ);
- offset = (weekday + 7 - first_weekday) % 7;
- cal_obj_time_add_days (occ, offset);
-
- while (occ->year == year
- && occ->month == month) {
- g_array_append_vals (new_occs, occ, 1);
- cal_obj_time_add_days (occ, 7);
- }
-
- } else if (week_num > 0) {
- /* Add the nth Mon/Tue/etc. in the month. */
- occ->day = 1;
- first_weekday = cal_obj_time_weekday (occ);
- offset = (weekday + 7 - first_weekday) % 7;
- offset += (week_num - 1) * 7;
- cal_obj_time_add_days (occ, offset);
- if (occ->year == year && occ->month == month)
- g_array_append_vals (new_occs, occ, 1);
-
- } else {
- /* Add the -nth Mon/Tue/etc. in the month. */
- occ->day = time_days_in_month (occ->year,
- occ->month);
- last_weekday = cal_obj_time_weekday (occ);
-
- /* This calculates the number of days to step
- backwards from the last day of the month
- to the weekday we want. */
- offset = (last_weekday + 7 - weekday) % 7;
-
- /* This adds on the weeks. */
- offset += (-week_num - 1) * 7;
-
- cal_obj_time_add_days (occ, -offset);
- if (occ->year == year && occ->month == month)
- g_array_append_vals (new_occs, occ, 1);
- }
-
- /* Reset the year & month, as we may have gone past
- the end. */
- occ->year = year;
- occ->month = month;
- }
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-/* Note: occs must not contain invalid dates, e.g. 31st September. */
-static GArray*
-cal_obj_byday_expand_weekly (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- GList *elem;
- gint len, i, weekday, week_num;
- gint weekday_offset, new_weekday_offset;
-
- /* If BYDAY has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->byday || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
-
- elem = recur_data->recur->byday;
- while (elem) {
- weekday = GPOINTER_TO_INT (elem->data);
- elem = elem->next;
-
- /* FIXME: Currently we just ignore this, but maybe we
- should skip all elements where week_num != 0.
- The spec isn't clear about this. */
- week_num = GPOINTER_TO_INT (elem->data);
- elem = elem->next;
-
- weekday_offset = cal_obj_time_weekday_offset (occ, recur_data->recur);
- new_weekday_offset = (weekday + 7 - recur_data->recur->week_start_day) % 7;
- cal_obj_time_add_days (occ, new_weekday_offset - weekday_offset);
- g_array_append_vals (new_occs, occ, 1);
- }
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-/* Note: occs must not contain invalid dates, e.g. 31st September. */
-static GArray*
-cal_obj_byday_filter (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- gint len, i, weekday;
-
- /* If BYDAY has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->byday || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
- weekday = cal_obj_time_weekday (occ);
-
- /* See if the weekday on its own is set. */
- if (recur_data->weekdays[weekday])
- g_array_append_vals (new_occs, occ, 1);
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-
-/* If the BYHOUR rule is specified it expands each occurrence in occs, by
- using each of the hours in the byhour list. */
-static GArray*
-cal_obj_byhour_expand (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- GList *elem;
- gint len, i;
-
- /* If BYHOUR has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->byhour || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
-
- elem = recur_data->recur->byhour;
- while (elem) {
- occ->hour = GPOINTER_TO_INT (elem->data);
- g_array_append_vals (new_occs, occ, 1);
- elem = elem->next;
- }
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-/* If the BYHOUR rule is specified it filters out all occurrences in occs
- which do not match one of the hours in the byhour list. */
-static GArray*
-cal_obj_byhour_filter (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- gint len, i;
-
- /* If BYHOUR has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->byhour || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
- if (recur_data->hours[occ->hour])
- g_array_append_vals (new_occs, occ, 1);
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-
-/* If the BYMINUTE rule is specified it expands each occurrence in occs, by
- using each of the minutes in the byminute list. */
-static GArray*
-cal_obj_byminute_expand (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- GList *elem;
- gint len, i;
-
- /* If BYMINUTE has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->byminute || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
-
- elem = recur_data->recur->byminute;
- while (elem) {
- occ->minute = GPOINTER_TO_INT (elem->data);
- g_array_append_vals (new_occs, occ, 1);
- elem = elem->next;
- }
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-/* If the BYMINUTE rule is specified it filters out all occurrences in occs
- which do not match one of the minutes in the byminute list. */
-static GArray*
-cal_obj_byminute_filter (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- gint len, i;
-
- /* If BYMINUTE has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->byminute || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
- if (recur_data->minutes[occ->minute])
- g_array_append_vals (new_occs, occ, 1);
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-
-/* If the BYSECOND rule is specified it expands each occurrence in occs, by
- using each of the seconds in the bysecond list. */
-static GArray*
-cal_obj_bysecond_expand (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- GList *elem;
- gint len, i;
-
- /* If BYSECOND has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->bysecond || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
-
- elem = recur_data->recur->bysecond;
- while (elem) {
- occ->second = GPOINTER_TO_INT (elem->data);
- g_array_append_vals (new_occs, occ, 1);
- elem = elem->next;
- }
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-/* If the BYSECOND rule is specified it filters out all occurrences in occs
- which do not match one of the seconds in the bysecond list. */
-static GArray*
-cal_obj_bysecond_filter (RecurData *recur_data,
- GArray *occs)
-{
- GArray *new_occs;
- CalObjTime *occ;
- gint len, i;
-
- /* If BYSECOND has not been specified, or the array is empty, just
- return the array. */
- if (!recur_data->recur->bysecond || occs->len == 0)
- return occs;
-
- new_occs = g_array_new (FALSE, FALSE, sizeof (CalObjTime));
-
- len = occs->len;
- for (i = 0; i < len; i++) {
- occ = &g_array_index (occs, CalObjTime, i);
- if (recur_data->seconds[occ->second])
- g_array_append_vals (new_occs, occ, 1);
- }
-
- g_array_free (occs, TRUE);
-
- return new_occs;
-}
-
-
-
-
-
-/* Adds a positive or negative number of months to the given CalObjTime,
- updating the year appropriately so we end up with a valid month.
- Note that the day may be invalid, e.g. 30th Feb. */
-static void
-cal_obj_time_add_months (CalObjTime *cotime,
- gint months)
-{
- guint month, years;
-
- /* We use a guint to avoid overflow on the guint8. */
- month = cotime->month + months;
- cotime->month = month % 12;
- if (month > 0) {
- cotime->year += month / 12;
- } else {
- years = month / 12;
- if (cotime->month != 0) {
- cotime->month += 12;
- years -= 1;
- }
- cotime->year += years;
- }
-}
-
-
-/* Adds a positive or negative number of days to the given CalObjTime,
- updating the month and year appropriately so we end up with a valid day. */
-static void
-cal_obj_time_add_days (CalObjTime *cotime,
- gint days)
-{
- gint day, days_in_month;
-
- /* We use a guint to avoid overflow on the guint8. */
- day = cotime->day;
- day += days;
-
- if (days >= 0) {
- for (;;) {
- days_in_month = time_days_in_month (cotime->year,
- cotime->month);
- if (day <= days_in_month)
- break;
-
- cotime->month++;
- if (cotime->month >= 12) {
- cotime->year++;
- cotime->month = 0;
- }
-
- day -= days_in_month;
- }
-
- cotime->day = (guint8) day;
- } else {
- while (day <= 0) {
- if (cotime->month == 0) {
- cotime->year--;
- cotime->month = 11;
- } else {
- cotime->month--;
- }
-
- days_in_month = time_days_in_month (cotime->year,
- cotime->month);
- day += days_in_month;
- }
-
- cotime->day = (guint8) day;
- }
-}
-
-
-/* Adds a positive or negative number of hours to the given CalObjTime,
- updating the day, month & year appropriately so we end up with a valid
- time. */
-static void
-cal_obj_time_add_hours (CalObjTime *cotime,
- gint hours)
-{
- gint hour, days;
-
- /* We use a gint to avoid overflow on the guint8. */
- hour = cotime->hour + hours;
- cotime->hour = hour % 24;
- if (hour >= 0) {
- if (hour >= 24)
- cal_obj_time_add_days (cotime, hour / 24);
- } else {
- days = hour / 24;
- if (cotime->hour != 0) {
- cotime->hour += 24;
- days -= 1;
- }
- cal_obj_time_add_days (cotime, days);
- }
-}
-
-
-/* Adds a positive or negative number of minutes to the given CalObjTime,
- updating the rest of the CalObjTime appropriately. */
-static void
-cal_obj_time_add_minutes (CalObjTime *cotime,
- gint minutes)
-{
- gint minute, hours;
-
- /* We use a gint to avoid overflow on the guint8. */
- minute = cotime->minute + minutes;
- cotime->minute = minute % 60;
- if (minute >= 0) {
- if (minute >= 60)
- cal_obj_time_add_hours (cotime, minute / 60);
- } else {
- hours = minute / 60;
- if (cotime->minute != 0) {
- cotime->minute += 60;
- hours -= 1;
- }
- cal_obj_time_add_hours (cotime, hours);
- }
-}
-
-
-/* Adds a positive or negative number of seconds to the given CalObjTime,
- updating the rest of the CalObjTime appropriately. */
-static void
-cal_obj_time_add_seconds (CalObjTime *cotime,
- gint seconds)
-{
- gint second, minutes;
-
- /* We use a gint to avoid overflow on the guint8. */
- second = cotime->second + seconds;
- cotime->second = second % 60;
- if (second >= 0) {
- if (second >= 60)
- cal_obj_time_add_minutes (cotime, second / 60);
- } else {
- minutes = second / 60;
- if (cotime->second != 0) {
- cotime->second += 60;
- minutes -= 1;
- }
- cal_obj_time_add_minutes (cotime, minutes);
- }
-}
-
-
-/* Compares 2 CalObjTimes. Returns -1 if the cotime1 is before cotime2, 0 if
- they are the same, or 1 if cotime1 is after cotime2. The comparison type
- specifies which parts of the times we are interested in, e.g. if CALOBJ_DAY
- is used we only want to know if the days are different. */
-static gint
-cal_obj_time_compare (CalObjTime *cotime1,
- CalObjTime *cotime2,
- CalObjTimeComparison type)
-{
- if (cotime1->year < cotime2->year)
- return -1;
- if (cotime1->year > cotime2->year)
- return 1;
-
- if (type == CALOBJ_YEAR)
- return 0;
-
- if (cotime1->month < cotime2->month)
- return -1;
- if (cotime1->month > cotime2->month)
- return 1;
-
- if (type == CALOBJ_MONTH)
- return 0;
-
- if (cotime1->day < cotime2->day)
- return -1;
- if (cotime1->day > cotime2->day)
- return 1;
-
- if (type == CALOBJ_DAY)
- return 0;
-
- if (cotime1->hour < cotime2->hour)
- return -1;
- if (cotime1->hour > cotime2->hour)
- return 1;
-
- if (type == CALOBJ_HOUR)
- return 0;
-
- if (cotime1->minute < cotime2->minute)
- return -1;
- if (cotime1->minute > cotime2->minute)
- return 1;
-
- if (type == CALOBJ_MINUTE)
- return 0;
-
- if (cotime1->second < cotime2->second)
- return -1;
- if (cotime1->second > cotime2->second)
- return 1;
-
- return 0;
-}
-
-
-/* This is the same as the above function, but without the comparison type.
- It is used for qsort(). */
-static gint
-cal_obj_time_compare_func (const void *arg1,
- const void *arg2)
-{
- CalObjTime *cotime1, *cotime2;
- gint retval;
-
- cotime1 = (CalObjTime*) arg1;
- cotime2 = (CalObjTime*) arg2;
-
- if (cotime1->year < cotime2->year)
- retval = -1;
- else if (cotime1->year > cotime2->year)
- retval = 1;
-
- else if (cotime1->month < cotime2->month)
- retval = -1;
- else if (cotime1->month > cotime2->month)
- retval = 1;
-
- else if (cotime1->day < cotime2->day)
- retval = -1;
- else if (cotime1->day > cotime2->day)
- retval = 1;
-
- else if (cotime1->hour < cotime2->hour)
- retval = -1;
- else if (cotime1->hour > cotime2->hour)
- retval = 1;
-
- else if (cotime1->minute < cotime2->minute)
- retval = -1;
- else if (cotime1->minute > cotime2->minute)
- retval = 1;
-
- else if (cotime1->second < cotime2->second)
- retval = -1;
- else if (cotime1->second > cotime2->second)
- retval = 1;
-
- else
- retval = 0;
-
-#if 0
- g_print ("%s - ", cal_obj_time_to_string (cotime1));
- g_print ("%s : %i\n", cal_obj_time_to_string (cotime2), retval);
-#endif
-
- return retval;
-}
-
-
-static gint
-cal_obj_date_only_compare_func (const void *arg1,
- const void *arg2)
-{
- CalObjTime *cotime1, *cotime2;
-
- cotime1 = (CalObjTime*) arg1;
- cotime2 = (CalObjTime*) arg2;
-
- if (cotime1->year < cotime2->year)
- return -1;
- if (cotime1->year > cotime2->year)
- return 1;
-
- if (cotime1->month < cotime2->month)
- return -1;
- if (cotime1->month > cotime2->month)
- return 1;
-
- if (cotime1->day < cotime2->day)
- return -1;
- if (cotime1->day > cotime2->day)
- return 1;
-
- return 0;
-}
-
-
-/* Returns the weekday of the given CalObjTime, from 0 (Mon) - 6 (Sun). */
-static gint
-cal_obj_time_weekday (CalObjTime *cotime)
-{
- GDate date;
- gint weekday;
-
- g_date_clear (&date, 1);
- g_date_set_dmy (&date, cotime->day, cotime->month + 1, cotime->year);
-
- /* This results in a value of 0 (Monday) - 6 (Sunday). */
- weekday = g_date_weekday (&date) - 1;
-
- return weekday;
-}
-
-
-/* Returns the weekday of the given CalObjTime, from 0 - 6. The week start
- day is Monday by default, but can be set in the recurrence rule. */
-static gint
-cal_obj_time_weekday_offset (CalObjTime *cotime,
- CalRecurrence *recur)
-{
- GDate date;
- gint weekday, offset;
-
- g_date_clear (&date, 1);
- g_date_set_dmy (&date, cotime->day, cotime->month + 1, cotime->year);
-
- /* This results in a value of 0 (Monday) - 6 (Sunday). */
- weekday = g_date_weekday (&date) - 1;
-
- /* This calculates the offset of our day from the start of the week.
- We just add on a week (to avoid any possible negative values) and
- then subtract the specified week start day, then convert it into a
- value from 0-6. */
- offset = (weekday + 7 - recur->week_start_day) % 7;
-
- return offset;
-}
-
-
-/* Returns the day of the year of the given CalObjTime, from 1 - 366. */
-static gint
-cal_obj_time_day_of_year (CalObjTime *cotime)
-{
- GDate date;
-
- g_date_clear (&date, 1);
- g_date_set_dmy (&date, cotime->day, cotime->month + 1, cotime->year);
-
- return g_date_day_of_year (&date);
-}
-
-
-/* Finds the first week in the given CalObjTime's year, using the same weekday
- as the event start day (i.e. from the RecurData).
- The first week of the year is the first week starting from the specified
- week start day that has 4 days in the new year. It may be in the previous
- year. */
-static void
-cal_obj_time_find_first_week (CalObjTime *cotime,
- RecurData *recur_data)
-{
- GDate date;
- gint weekday, week_start_day, first_full_week_start_offset, offset;
-
- /* Find out the weekday of the 1st of the year, 0 (Mon) - 6 (Sun). */
- g_date_clear (&date, 1);
- g_date_set_dmy (&date, 1, 1, cotime->year);
- weekday = g_date_weekday (&date) - 1;
-
- /* Calculate the first day of the year that starts a new week, i.e. the
- first week_start_day after weekday, using 0 = 1st Jan.
- e.g. if the 1st Jan is a Tuesday (1) and week_start_day is a
- Monday (0), the result will be (0 + 7 - 1) % 7 = 6 (7th Jan). */
- week_start_day = recur_data->recur->week_start_day;
- first_full_week_start_offset = (week_start_day + 7 - weekday) % 7;
-
- /* Now see if we have to move backwards 1 week, i.e. if the week
- starts on or after Jan 5th (since the previous week has 4 days in
- this year and so will be the first week of the year). */
- if (first_full_week_start_offset >= 4)
- first_full_week_start_offset -= 7;
-
- /* Now add the days to get to the event's weekday. */
- offset = first_full_week_start_offset + recur_data->weekday_offset;
-
- /* Now move the cotime to the appropriate day. */
- cotime->month = 0;
- cotime->day = 1;
- cal_obj_time_add_days (cotime, offset);
-}
-
-
-static void
-cal_object_time_from_time (CalObjTime *cotime,
- time_t t,
- icaltimezone *zone)
-{
- struct icaltimetype tt;
-
- tt = icaltime_from_timet_with_zone (t, FALSE, zone);
-
- cotime->year = tt.year;
- cotime->month = tt.month - 1;
- cotime->day = tt.day;
- cotime->hour = tt.hour;
- cotime->minute = tt.minute;
- cotime->second = tt.second;
- cotime->flags = FALSE;
-}
-
-
-/* Debugging function to convert a CalObjTime to a string. It uses a static
- buffer so beware. */
-#ifdef CAL_OBJ_DEBUG
-static char*
-cal_obj_time_to_string (CalObjTime *cotime)
-{
- static char buffer[20];
- char *weekdays[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun",
- " " };
- gint weekday;
-
- weekday = cal_obj_time_weekday (cotime);
-
- sprintf (buffer, "%s %02i/%02i/%04i %02i:%02i:%02i",
- weekdays[weekday],
- cotime->day, cotime->month + 1, cotime->year,
- cotime->hour, cotime->minute, cotime->second);
- return buffer;
-}
-#endif
-
-
-/* This recalculates the end dates for recurrence & exception rules which use
- the COUNT property. If refresh is TRUE it will recalculate all enddates
- for rules which use COUNT. If refresh is FALSE, it will only calculate
- the enddate if it hasn't already been set. It returns TRUE if the component
- was changed, i.e. if the component should be saved at some point.
- We store the enddate in the "X-EVOLUTION-ENDDATE" parameter of the RRULE
- or EXRULE. */
-static gboolean
-cal_recur_ensure_end_dates (CalComponent *comp,
- gboolean refresh,
- CalRecurResolveTimezoneFn tz_cb,
- gpointer tz_cb_data)
-{
- GSList *rrules, *exrules, *elem;
- gboolean changed = FALSE;
-
- /* Do the RRULEs. */
- cal_component_get_rrule_property_list (comp, &rrules);
- for (elem = rrules; elem; elem = elem->next) {
- changed |= cal_recur_ensure_rule_end_date (comp, elem->data,
- FALSE, refresh,
- tz_cb, tz_cb_data);
- }
-
- /* Do the EXRULEs. */
- cal_component_get_exrule_property_list (comp, &exrules);
- for (elem = exrules; elem; elem = elem->next) {
- changed |= cal_recur_ensure_rule_end_date (comp, elem->data,
- TRUE, refresh,
- tz_cb, tz_cb_data);
- }
-
- return changed;
-}
-
-
-typedef struct _CalRecurEnsureEndDateData CalRecurEnsureEndDateData;
-struct _CalRecurEnsureEndDateData {
- gint count;
- gint instances;
- time_t end_date;
-};
-
-
-static gboolean
-cal_recur_ensure_rule_end_date (CalComponent *comp,
- icalproperty *prop,
- gboolean exception,
- gboolean refresh,
- CalRecurResolveTimezoneFn tz_cb,
- gpointer tz_cb_data)
-{
- struct icalrecurrencetype rule;
- CalRecurEnsureEndDateData cb_data;
-
- if (exception)
- rule = icalproperty_get_exrule (prop);
- else
- rule = icalproperty_get_rrule (prop);
-
- /* If the rule doesn't use COUNT just return. */
- if (rule.count == 0)
- return FALSE;
-
- /* If refresh is FALSE, we check if the enddate is already set, and
- if it is we just return. */
- if (!refresh) {
- if (cal_recur_get_rule_end_date (prop, NULL) != -1)
- return FALSE;
- }
-
- /* Calculate the end date. Note that we initialize end_date to 0, so
- if the RULE doesn't generate COUNT instances we save a time_t of 0.
- Also note that we use the UTC timezone as the default timezone.
- In get_end_date() if the DTSTART is a DATE or floating time, we will
- convert the ENDDATE to the current timezone. */
- cb_data.count = rule.count;
- cb_data.instances = 0;
- cb_data.end_date = 0;
- cal_recur_generate_instances_of_rule (comp, prop, -1, -1,
- cal_recur_ensure_rule_end_date_cb,
- &cb_data, tz_cb, tz_cb_data,
- icaltimezone_get_utc_timezone ());
-
- /* Store the end date in the "X-EVOLUTION-ENDDATE" parameter of the
- rule. */
- cal_recur_set_rule_end_date (prop, cb_data.end_date);
-
- return TRUE;
-}
-
-
-static gboolean
-cal_recur_ensure_rule_end_date_cb (CalComponent *comp,
- time_t instance_start,
- time_t instance_end,
- gpointer data)
-{
- CalRecurEnsureEndDateData *cb_data;
-
- cb_data = (CalRecurEnsureEndDateData*) data;
-
- cb_data->instances++;
-
- if (cb_data->instances == cb_data->count) {
- cb_data->end_date = instance_start;
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/* If default_timezone is set, the saved ENDDATE parameter is assumed to be
- in that timezone. This is used when the DTSTART is a DATE or floating
- value, since the RRULE end date will change depending on the timezone that
- it is evaluated in. */
-static time_t
-cal_recur_get_rule_end_date (icalproperty *prop,
- icaltimezone *default_timezone)
-{
- icalparameter *param;
- const char *xname, *xvalue;
- icalvalue *value;
- struct icaltimetype icaltime;
- icaltimezone *zone;
-
- param = icalproperty_get_first_parameter (prop, ICAL_X_PARAMETER);
- while (param) {
- xname = icalparameter_get_xname (param);
- if (xname && !strcmp (xname, EVOLUTION_END_DATE_PARAMETER)) {
- xvalue = icalparameter_get_x (param);
- value = icalvalue_new_from_string (ICAL_DATETIME_VALUE,
- xvalue);
- if (value) {
- icaltime = icalvalue_get_datetime (value);
- icalvalue_free (value);
-
- zone = default_timezone ? default_timezone :
- icaltimezone_get_utc_timezone ();
- return icaltime_as_timet_with_zone (icaltime,
- zone);
- }
- }
-
- param = icalproperty_get_next_parameter (prop,
- ICAL_X_PARAMETER);
- }
-
- return -1;
-}
-
-
-static void
-cal_recur_set_rule_end_date (icalproperty *prop,
- time_t end_date)
-{
- icalparameter *param;
- icalvalue *value;
- icaltimezone *utc_zone;
- struct icaltimetype icaltime;
- const char *end_date_string, *xname;
-
- /* We save the value as a UTC DATE-TIME. */
- utc_zone = icaltimezone_get_utc_timezone ();
- icaltime = icaltime_from_timet_with_zone (end_date, FALSE, utc_zone);
- value = icalvalue_new_datetime (icaltime);
- end_date_string = icalvalue_as_ical_string (value);
- icalvalue_free (value);
-
- /* If we already have an X-EVOLUTION-ENDDATE parameter, set the value
- to the new date-time. */
- param = icalproperty_get_first_parameter (prop, ICAL_X_PARAMETER);
- while (param) {
- xname = icalparameter_get_xname (param);
- if (xname && !strcmp (xname, EVOLUTION_END_DATE_PARAMETER)) {
- icalparameter_set_x (param, end_date_string);
- return;
- }
- param = icalproperty_get_next_parameter (prop, ICAL_X_PARAMETER);
- }
-
- /* Create a new X-EVOLUTION-ENDDATE and add it to the property. */
- param = icalparameter_new_x (end_date_string);
- icalparameter_set_xname (param, EVOLUTION_END_DATE_PARAMETER);
- icalproperty_add_parameter (prop, param);
-}
-
diff --git a/calendar/cal-util/cal-recur.h b/calendar/cal-util/cal-recur.h
deleted file mode 100644
index 6ffeb2cb8a..0000000000
--- a/calendar/cal-util/cal-recur.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Evolution calendar recurrence rule functions
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Author: Damon Chaplin <damon@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 CAL_RECUR_H
-#define CAL_RECUR_H
-
-#include <libgnome/gnome-defs.h>
-#include <glib.h>
-#include <cal-util/cal-component.h>
-
-BEGIN_GNOME_DECLS
-
-typedef gboolean (* CalRecurInstanceFn) (CalComponent *comp,
- time_t instance_start,
- time_t instance_end,
- gpointer data);
-
-typedef icaltimezone* (* CalRecurResolveTimezoneFn) (const char *tzid,
- gpointer data);
-
-/*
- * Calls the given callback function for each occurrence of the event that
- * intersects the range between the given start and end times (the end time is
- * not included). Note that the occurrences may start before the given start
- * time.
- *
- * If the callback routine returns FALSE the occurrence generation stops.
- *
- * Both start and end can be -1, in which case we start at the events first
- * instance and continue until it ends, or forever if it has no enddate.
- *
- * The tz_cb is used to resolve references to timezones. It is passed a TZID
- * and should return the icaltimezone* corresponding to that TZID. We need to
- * do this as we access timezones in different ways on the client & server.
- *
- * The default_timezone argument is used for DTSTART or DTEND properties that
- * are DATE values or do not have a TZID (i.e. floating times).
- */
-void cal_recur_generate_instances (CalComponent *comp,
- time_t start,
- time_t end,
- CalRecurInstanceFn cb,
- gpointer cb_data,
- CalRecurResolveTimezoneFn tz_cb,
- gpointer tz_cb_data,
- icaltimezone *default_timezone);
-
-END_GNOME_DECLS
-
-#endif
diff --git a/calendar/cal-util/cal-util.c b/calendar/cal-util/cal-util.c
deleted file mode 100644
index d4a86e1a8f..0000000000
--- a/calendar/cal-util/cal-util.c
+++ /dev/null
@@ -1,615 +0,0 @@
-/* Evolution calendar utilities and types
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnome/gnome-util.h>
-#include "cal-util.h"
-
-
-
-/**
- * cal_obj_instance_list_free:
- * @list: List of #CalObjInstance structures.
- *
- * Frees a list of #CalObjInstance structures.
- **/
-void
-cal_obj_instance_list_free (GList *list)
-{
- CalObjInstance *i;
- GList *l;
-
- for (l = list; l; l = l->next) {
- i = l->data;
-
- g_assert (i != NULL);
- g_assert (i->uid != NULL);
-
- g_free (i->uid);
- g_free (i);
- }
-
- g_list_free (list);
-}
-
-/**
- * cal_obj_uid_list_free:
- * @list: List of strings with unique identifiers.
- *
- * Frees a list of unique identifiers for calendar objects.
- **/
-void
-cal_obj_uid_list_free (GList *list)
-{
- GList *l;
-
- for (l = list; l; l = l->next) {
- char *uid;
-
- uid = l->data;
-
- g_assert (uid != NULL);
- g_free (uid);
- }
-
- g_list_free (list);
-}
-
-icalcomponent *
-cal_util_new_top_level (void)
-{
- icalcomponent *icalcomp;
- icalproperty *prop;
-
- icalcomp = icalcomponent_new (ICAL_VCALENDAR_COMPONENT);
-
- /* RFC 2445, section 4.7.1 */
- prop = icalproperty_new_calscale ("GREGORIAN");
- icalcomponent_add_property (icalcomp, prop);
-
- /* RFC 2445, section 4.7.3 */
- prop = icalproperty_new_prodid ("-//Ximian//NONSGML Evolution Calendar//EN");
- icalcomponent_add_property (icalcomp, prop);
-
- /* RFC 2445, section 4.7.4. This is the iCalendar spec version, *NOT*
- * the product version! Do not change this!
- */
- prop = icalproperty_new_version ("2.0");
- icalcomponent_add_property (icalcomp, prop);
-
- return icalcomp;
-}
-
-/* Computes the range of time in which recurrences should be generated for a
- * component in order to compute alarm trigger times.
- */
-static void
-compute_alarm_range (CalComponent *comp, GList *alarm_uids, time_t start, time_t end,
- time_t *alarm_start, time_t *alarm_end)
-{
- GList *l;
- time_t repeat_time;
-
- *alarm_start = start;
- *alarm_end = end;
-
- repeat_time = 0;
-
- for (l = alarm_uids; l; l = l->next) {
- const char *auid;
- CalComponentAlarm *alarm;
- CalAlarmTrigger trigger;
- struct icaldurationtype *dur;
- time_t dur_time;
- CalAlarmRepeat repeat;
-
- auid = l->data;
- alarm = cal_component_get_alarm (comp, auid);
- g_assert (alarm != NULL);
-
- cal_component_alarm_get_trigger (alarm, &trigger);
- cal_component_alarm_get_repeat (alarm, &repeat);
- cal_component_alarm_free (alarm);
-
- switch (trigger.type) {
- case CAL_ALARM_TRIGGER_NONE:
- case CAL_ALARM_TRIGGER_ABSOLUTE:
- break;
-
- case CAL_ALARM_TRIGGER_RELATIVE_START:
- case CAL_ALARM_TRIGGER_RELATIVE_END:
- dur = &trigger.u.rel_duration;
- dur_time = icaldurationtype_as_int (*dur);
-
- if (repeat.repetitions != 0) {
- int rdur;
-
- rdur = repeat.repetitions * icaldurationtype_as_int (repeat.duration);
- repeat_time = MAX (repeat_time, rdur);
- }
-
- if (dur->is_neg)
- /* If the duration is negative then dur_time
- * will be negative as well; that is why we
- * subtract to expand the range.
- */
- *alarm_end = MAX (*alarm_end, end - dur_time);
- else
- *alarm_start = MIN (*alarm_start, start - dur_time);
-
- break;
-
- default:
- g_assert_not_reached ();
- }
- }
-
- *alarm_start -= repeat_time;
-
- g_assert (*alarm_start <= *alarm_end);
-}
-
-/* Closure data to generate alarm occurrences */
-struct alarm_occurrence_data {
- /* These are the info we have */
- GList *alarm_uids;
- time_t start;
- time_t end;
-
- /* This is what we compute */
- GSList *triggers;
- int n_triggers;
-};
-
-static void
-add_trigger (struct alarm_occurrence_data *aod, const char *auid, time_t trigger,
- time_t occur_start, time_t occur_end)
-{
- CalAlarmInstance *instance;
-
- instance = g_new (CalAlarmInstance, 1);
- instance->auid = auid;
- instance->trigger = trigger;
- instance->occur_start = occur_start;
- instance->occur_end = occur_end;
-
- aod->triggers = g_slist_prepend (aod->triggers, instance);
- aod->n_triggers++;
-}
-
-/* Callback used from cal_recur_generate_instances(); generates triggers for all
- * of a component's RELATIVE alarms.
- */
-static gboolean
-add_alarm_occurrences_cb (CalComponent *comp, time_t start, time_t end, gpointer data)
-{
- struct alarm_occurrence_data *aod;
- GList *l;
-
- aod = data;
-
- for (l = aod->alarm_uids; l; l = l->next) {
- const char *auid;
- CalComponentAlarm *alarm;
- CalAlarmTrigger trigger;
- CalAlarmRepeat repeat;
- struct icaldurationtype *dur;
- time_t dur_time;
- time_t occur_time, trigger_time;
-
- auid = l->data;
- alarm = cal_component_get_alarm (comp, auid);
- g_assert (alarm != NULL);
-
- cal_component_alarm_get_trigger (alarm, &trigger);
- cal_component_alarm_get_repeat (alarm, &repeat);
- cal_component_alarm_free (alarm);
-
- if (trigger.type != CAL_ALARM_TRIGGER_RELATIVE_START
- && trigger.type != CAL_ALARM_TRIGGER_RELATIVE_END)
- continue;
-
- dur = &trigger.u.rel_duration;
- dur_time = icaldurationtype_as_int (*dur);
-
- if (trigger.type == CAL_ALARM_TRIGGER_RELATIVE_START)
- occur_time = start;
- else
- occur_time = end;
-
- /* If dur->is_neg is true then dur_time will already be
- * negative. So we do not need to test for dur->is_neg here; we
- * can simply add the dur_time value to the occur_time and get
- * the correct result.
- */
-
- trigger_time = occur_time + dur_time;
-
- /* Add repeating alarms */
-
- if (repeat.repetitions != 0) {
- int i;
- time_t repeat_time;
-
- repeat_time = icaldurationtype_as_int (repeat.duration);
-
- for (i = 0; i < repeat.repetitions; i++) {
- time_t t;
-
- t = trigger_time + (i + 1) * repeat_time;
-
- if (t >= aod->start && t < aod->end)
- add_trigger (aod, auid, t, start, end);
- }
- }
-
- /* Add the trigger itself */
-
- if (trigger_time >= aod->start && trigger_time < aod->end)
- add_trigger (aod, auid, trigger_time, start, end);
- }
-
- return TRUE;
-}
-
-/* Generates the absolute triggers for a component */
-static void
-generate_absolute_triggers (CalComponent *comp, struct alarm_occurrence_data *aod,
- CalRecurResolveTimezoneFn resolve_tzid,
- gpointer user_data,
- icaltimezone *default_timezone)
-{
- GList *l;
- CalComponentDateTime dt_start, dt_end;
-
- cal_component_get_dtstart (comp, &dt_start);
- cal_component_get_dtend (comp, &dt_end);
-
- for (l = aod->alarm_uids; l; l = l->next) {
- const char *auid;
- CalComponentAlarm *alarm;
- CalAlarmRepeat repeat;
- CalAlarmTrigger trigger;
- time_t abs_time;
- time_t occur_start, occur_end;
- icaltimezone *zone;
-
- auid = l->data;
- alarm = cal_component_get_alarm (comp, auid);
- g_assert (alarm != NULL);
-
- cal_component_alarm_get_trigger (alarm, &trigger);
- cal_component_alarm_get_repeat (alarm, &repeat);
- cal_component_alarm_free (alarm);
-
- if (trigger.type != CAL_ALARM_TRIGGER_ABSOLUTE)
- continue;
-
- /* Absolute triggers are always in UTC; see RFC 2445 section 4.8.6.3 */
- zone = icaltimezone_get_utc_timezone ();
-
- abs_time = icaltime_as_timet_with_zone (trigger.u.abs_time, zone);
-
- /* No particular occurrence, so just use the times from the component */
-
- if (dt_start.value) {
- if (dt_start.tzid && !dt_start.value->is_date)
- zone = (* resolve_tzid) (dt_start.tzid, user_data);
- else
- zone = default_timezone;
-
- occur_start = icaltime_as_timet_with_zone (*dt_start.value, zone);
- } else
- occur_start = -1;
-
- if (dt_end.value) {
- if (dt_end.tzid && !dt_end.value->is_date)
- zone = (* resolve_tzid) (dt_end.tzid, user_data);
- else
- zone = default_timezone;
-
- occur_end = icaltime_as_timet_with_zone (*dt_end.value, zone);
- } else
- occur_end = -1;
-
- /* Add repeating alarms */
-
- if (repeat.repetitions != 0) {
- int i;
- time_t repeat_time;
-
- repeat_time = icaldurationtype_as_int (repeat.duration);
-
- for (i = 0; i < repeat.repetitions; i++) {
- time_t t;
-
- t = abs_time + (i + 1) * repeat_time;
-
- if (t >= aod->start && t < aod->end)
- add_trigger (aod, auid, t, occur_start, occur_end);
- }
- }
-
- /* Add the trigger itself */
-
- if (abs_time >= aod->start && abs_time < aod->end)
- add_trigger (aod, auid, abs_time, occur_start, occur_end);
- }
-
- cal_component_free_datetime (&dt_start);
- cal_component_free_datetime (&dt_end);
-}
-
-/* Compares two alarm instances; called from g_slist_sort() */
-static gint
-compare_alarm_instance (gconstpointer a, gconstpointer b)
-{
- const CalAlarmInstance *aia, *aib;
-
- aia = a;
- aib = b;
-
- if (aia->trigger < aib->trigger)
- return -1;
- else if (aia->trigger > aib->trigger)
- return 1;
- else
- return 0;
-}
-
-/**
- * cal_util_generate_alarms_for_comp
- * @comp: the CalComponent to generate alarms from
- * @start: start time
- * @end: end time
- * @resolve_tzid: callback for resolving timezones
- * @user_data: data to be passed to the resolve_tzid callback
- * @default_timezone: the timezone used to resolve DATE and floating DATE-TIME
- * values.
- *
- * Generates alarm instances for a calendar component. Returns the instances
- * structure, or NULL if no alarm instances occurred in the specified time
- * range.
- */
-CalComponentAlarms *
-cal_util_generate_alarms_for_comp (CalComponent *comp,
- time_t start,
- time_t end,
- CalRecurResolveTimezoneFn resolve_tzid,
- gpointer user_data,
- icaltimezone *default_timezone)
-{
- GList *alarm_uids;
- time_t alarm_start, alarm_end;
- struct alarm_occurrence_data aod;
- CalComponentAlarms *alarms;
-
- if (!cal_component_has_alarms (comp))
- return NULL;
-
- alarm_uids = cal_component_get_alarm_uids (comp);
- compute_alarm_range (comp, alarm_uids, start, end, &alarm_start, &alarm_end);
-
- aod.alarm_uids = alarm_uids;
- aod.start = start;
- aod.end = end;
- aod.triggers = NULL;
- aod.n_triggers = 0;
-
- cal_recur_generate_instances (comp, alarm_start, alarm_end,
- add_alarm_occurrences_cb, &aod,
- resolve_tzid, user_data,
- default_timezone);
-
- /* We add the ABSOLUTE triggers separately */
- generate_absolute_triggers (comp, &aod, resolve_tzid, user_data, default_timezone);
-
- if (aod.n_triggers == 0)
- return NULL;
-
- /* Create the component alarm instances structure */
-
- alarms = g_new (CalComponentAlarms, 1);
- alarms->comp = comp;
- gtk_object_ref (GTK_OBJECT (alarms->comp));
- alarms->alarms = g_slist_sort (aod.triggers, compare_alarm_instance);
-
- return alarms;
-}
-
-/**
- * cal_util_generate_alarms_for_list
- * @comps: list of CalComponent's
- * @start: start time
- * @end: end time
- * @comp_alarms: list to be returned
- * @resolve_tzid: callback for resolving timezones
- * @user_data: data to be passed to the resolve_tzid callback
- * @default_timezone: the timezone used to resolve DATE and floating DATE-TIME
- * values.
- *
- * Iterates through all the components in the comps list and generates alarm
- * instances for them; putting them in the comp_alarms list.
- *
- * Returns: the number of elements it added to that list.
- */
-int
-cal_util_generate_alarms_for_list (GList *comps,
- time_t start,
- time_t end,
- GSList **comp_alarms,
- CalRecurResolveTimezoneFn resolve_tzid,
- gpointer user_data,
- icaltimezone *default_timezone)
-{
- GList *l;
- int n;
-
- n = 0;
-
- for (l = comps; l; l = l->next) {
- CalComponent *comp;
- CalComponentAlarms *alarms;
-
- comp = CAL_COMPONENT (l->data);
- alarms = cal_util_generate_alarms_for_comp (comp, start, end, resolve_tzid, user_data, default_timezone);
-
- if (alarms) {
- *comp_alarms = g_slist_prepend (*comp_alarms, alarms);
- n++;
- }
- }
-
- return n;
-}
-
-
-/* Converts an iCalendar PRIORITY value to a translated string. Any unknown
- priority value (i.e. not 0-9) will be returned as "" (undefined). */
-char *
-cal_util_priority_to_string (int priority)
-{
- char *retval;
-
- if (priority <= 0)
- retval = "";
- else if (priority <= 4)
- retval = _("High");
- else if (priority == 5)
- retval = _("Normal");
- else if (priority <= 9)
- retval = _("Low");
- else
- retval = "";
-
- return retval;
-}
-
-
-/* Converts a translated priority string to an iCalendar priority value.
- Returns -1 if the priority string is not valid. */
-int
-cal_util_priority_from_string (const char *string)
-{
- int priority;
-
- /* An empty string is the same as 'None'. */
- if (!string || !string[0] || !g_strcasecmp (string, _("Undefined")))
- priority = 0;
- else if (!g_strcasecmp (string, _("High")))
- priority = 3;
- else if (!g_strcasecmp (string, _("Normal")))
- priority = 5;
- else if (!g_strcasecmp (string, _("Low")))
- priority = 7;
- else
- priority = -1;
-
- return priority;
-}
-
-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;
-}
-
-/* callback for icalcomponent_foreach_tzid */
-typedef struct {
- icalcomponent *vcal_comp;
- CalComponent *comp;
-} ForeachTzidData;
-
-static void
-add_timezone_cb (icalparameter *param, void *data)
-{
- icaltimezone *tz;
- const char *tzid;
- icalcomponent *vtz_comp;
- ForeachTzidData *f_data = (ForeachTzidData *) data;
-
- tzid = icalparameter_get_tzid (param);
- if (!tzid)
- return;
-
- tz = icalcomponent_get_timezone (f_data->vcal_comp, tzid);
- if (tz)
- return;
-
- tz = icalcomponent_get_timezone (cal_component_get_icalcomponent (f_data->comp),
- tzid);
- if (!tz) {
- tz = icaltimezone_get_builtin_timezone_from_tzid (tzid);
- if (!tz)
- return;
- }
-
- vtz_comp = icaltimezone_get_component (tz);
- if (!vtz_comp)
- return;
-
- icalcomponent_add_component (f_data->vcal_comp,
- icalcomponent_new_clone (vtz_comp));
-}
-
-/* Adds VTIMEZONE components to a VCALENDAR for all tzid's
- * in the given CalComponent. */
-void
-cal_util_add_timezones_from_component (icalcomponent *vcal_comp,
- CalComponent *comp)
-{
- ForeachTzidData f_data;
-
- g_return_if_fail (vcal_comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
-
- f_data.vcal_comp = vcal_comp;
- f_data.comp = comp;
- icalcomponent_foreach_tzid (cal_component_get_icalcomponent (comp),
- add_timezone_cb, &f_data);
-}
diff --git a/calendar/cal-util/cal-util.h b/calendar/cal-util/cal-util.h
deleted file mode 100644
index e1afc1c3a0..0000000000
--- a/calendar/cal-util/cal-util.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Evolution calendar utilities and types
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 CAL_UTIL_H
-#define CAL_UTIL_H
-
-#include <libgnome/gnome-defs.h>
-#include <ical.h>
-#include <time.h>
-#include <glib.h>
-#include <cal-util/cal-component.h>
-#include <cal-util/cal-recur.h>
-
-BEGIN_GNOME_DECLS
-
-
-
-/* Instance of a calendar object. This can be an actual occurrence, a
- * recurrence, or an alarm trigger of a `real' calendar object.
- */
-typedef struct {
- char *uid; /* UID of the object */
- time_t start; /* Start time of instance */
- time_t end; /* End time of instance */
-} CalObjInstance;
-
-void cal_obj_instance_list_free (GList *list);
-
-/* Used for multiple UID queries */
-typedef enum {
- CALOBJ_TYPE_EVENT = 1 << 0,
- CALOBJ_TYPE_TODO = 1 << 1,
- CALOBJ_TYPE_JOURNAL = 1 << 2,
- CALOBJ_TYPE_ANY = 0x07
-} CalObjType;
-
-/* Used for mode stuff */
-typedef enum {
- CAL_MODE_INVALID = -1,
- CAL_MODE_LOCAL = 1 << 0,
- CAL_MODE_REMOTE = 1 << 1,
- CAL_MODE_ANY = 0x07
-} CalMode;
-
-void cal_obj_uid_list_free (GList *list);
-
-icalcomponent *cal_util_new_top_level (void);
-
-CalComponentAlarms *cal_util_generate_alarms_for_comp (CalComponent *comp,
- time_t start,
- time_t end,
- CalRecurResolveTimezoneFn resolve_tzid,
- gpointer user_data,
- icaltimezone *default_timezone);
-int cal_util_generate_alarms_for_list (GList *comps,
- time_t start,
- time_t end,
- GSList **comp_alarms,
- CalRecurResolveTimezoneFn resolve_tzid,
- gpointer user_data,
- icaltimezone *default_timezone);
-
-icaltimezone *cal_util_resolve_tzid (const char *tzid, gpointer data);
-
-char *cal_util_priority_to_string (int priority);
-int cal_util_priority_from_string (const char *string);
-
-char *cal_util_expand_uri (char *uri, gboolean tasks);
-
-void cal_util_add_timezones_from_component (icalcomponent *vcal_comp,
- CalComponent *comp);
-
-END_GNOME_DECLS
-
-#endif
-
diff --git a/calendar/cal-util/test-recur.c b/calendar/cal-util/test-recur.c
deleted file mode 100644
index 5078a1db94..0000000000
--- a/calendar/cal-util/test-recur.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * Author :
- * Damon Chaplin <damon@ximian.com>
- *
- * Copyright 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
- */
-
-/*
- * This tests the recurrence rule expansion functions.
- *
- * NOTE: currently it starts from the event start date and continues
- * until all recurrence rules/dates end or we reach MAX_OCCURRENCES
- * occurrences. So it does not test generating occurrences for a specific
- * interval. A nice addition might be to do this automatically and compare
- * the results from the complete set to ensure they match.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <gtk/gtkmain.h>
-#include <cal-util/cal-recur.h>
-
-
-/* Since events can recur infinitely, we set a limit to the number of
- occurrences we output. */
-#define MAX_OCCURRENCES 1000
-
-static void usage (void);
-static icalcomponent* scan_ics_file (char *filename);
-static char* get_line (char *s,
- size_t size,
- void *data);
-static void generate_occurrences (icalcomponent *comp);
-static gboolean occurrence_cb (CalComponent *comp,
- time_t instance_start,
- time_t instance_end,
- gpointer data);
-
-
-int
-main (int argc,
- char *argv[])
-{
- gchar *filename;
- icalcomponent *icalcomp;
-
- gtk_init (&argc, &argv);
-
- if (argc != 2)
- usage ();
-
- filename = argv[1];
-
- icalcomp = scan_ics_file (filename);
- if (icalcomp)
- generate_occurrences (icalcomp);
-
- return 0;
-}
-
-
-static void
-usage (void)
-{
- g_print ("Usage: test-recur <filename>\n");
- exit (1);
-}
-
-
-static icalcomponent*
-scan_ics_file (char *filename)
-{
- FILE *fp;
- icalcomponent *icalcomp;
- icalparser *parser;
-
- g_print ("Opening file: %s\n", filename);
- fp = fopen (filename, "r");
-
- if (!fp) {
- g_print ("Can't open file: %s\n", filename);
- return NULL;
- }
-
- parser = icalparser_new ();
- icalparser_set_gen_data (parser, fp);
-
- icalcomp = icalparser_parse (parser, get_line);
- icalparser_free (parser);
-
- return icalcomp;
-}
-
-
-/* Callback used from icalparser_parse() */
-static char *
-get_line (char *s,
- size_t size,
- void *data)
-{
- return fgets (s, size, (FILE*) data);
-}
-
-
-/* This resolves any TZIDs in the components. The VTIMEZONEs must be in the
- file we are reading. */
-static icaltimezone*
-resolve_tzid_cb (const char *tzid,
- gpointer user_data)
-{
- icalcomponent *vcalendar_comp = user_data;
-
- if (!tzid || !tzid[0])
- return NULL;
- else if (!strcmp (tzid, "UTC"))
- return icaltimezone_get_utc_timezone ();
-
- return icalcomponent_get_timezone (vcalendar_comp, tzid);
-}
-
-
-static void
-generate_occurrences (icalcomponent *icalcomp)
-{
- icalcompiter iter;
- icaltimezone *default_timezone;
-
- /* This is the timezone we will use for DATE and floating values. */
- default_timezone = icaltimezone_get_utc_timezone ();
-
- for (iter = icalcomponent_begin_component (icalcomp, ICAL_ANY_COMPONENT);
- icalcompiter_deref (&iter) != NULL;
- icalcompiter_next (&iter)) {
- icalcomponent *tmp_icalcomp;
- CalComponent *comp;
- icalcomponent_kind kind;
- gint occurrences;
-
- tmp_icalcomp = icalcompiter_deref (&iter);
- kind = icalcomponent_isa (tmp_icalcomp);
-
- if (!(kind == ICAL_VEVENT_COMPONENT
- || kind == ICAL_VTODO_COMPONENT
- || kind == ICAL_VJOURNAL_COMPONENT))
- continue;
-
- comp = cal_component_new ();
-
- if (!cal_component_set_icalcomponent (comp, tmp_icalcomp))
- continue;
-
- g_print ("#############################################################################\n");
- g_print ("%s\n\n", icalcomponent_as_ical_string (tmp_icalcomp));
- g_print ("Instances:\n");
-
- occurrences = 0;
- /* I use specific times when I am trying to pin down a bug seen
- in one of the calendar views. */
-#if 0
- cal_recur_generate_instances (comp, 982022400, 982108800,
- occurrence_cb, &occurrences,
- resolve_tzid_cb, icalcomp,
- default_timezone);
-#else
- cal_recur_generate_instances (comp, -1, -1,
- occurrence_cb, &occurrences,
- resolve_tzid_cb, icalcomp,
- default_timezone);
-#endif
-
- /* Print the component again so we can see the
- X-EVOLUTION-ENDDATE parameter (only set if COUNT is used).
- */
- g_print ("#############################################################################\n");
-#if 0
- g_print ("%s\n\n", icalcomponent_as_ical_string (tmp_icalcomp));
-#endif
- }
-}
-
-
-static gboolean
-occurrence_cb (CalComponent *comp,
- time_t instance_start,
- time_t instance_end,
- gpointer data)
-{
- char start[32], finish[32];
- gint *occurrences;
-
- occurrences = (gint*) data;
-
- strcpy (start, ctime (&instance_start));
- start[24] = '\0';
- strcpy (finish, ctime (&instance_end));
- finish[24] = '\0';
-
- g_print ("%s - %s\n", start, finish);
-
- (*occurrences)++;
- return (*occurrences == MAX_OCCURRENCES) ? FALSE : TRUE;
-}
diff --git a/calendar/cal-util/timeutil.c b/calendar/cal-util/timeutil.c
deleted file mode 100644
index 75e04611a3..0000000000
--- a/calendar/cal-util/timeutil.c
+++ /dev/null
@@ -1,577 +0,0 @@
-/* Miscellaneous time-related utilities
- *
- * Copyright (C) 2000, 2001 Ximian, Inc.
- *
- * Authors: Federico Mena <federico@ximian.com>
- * Miguel de Icaza <miguel@ximian.com>
- * Damon Chaplin <damon@ximian.com>
- */
-
-#include <string.h>
-#include <ctype.h>
-#include <glib.h>
-#include <ical.h>
-#include "timeutil.h"
-
-
-
-#define REFORMATION_DAY 639787 /* First day of the reformation, counted from 1 Jan 1 */
-#define MISSING_DAYS 11 /* They corrected out 11 days */
-#define THURSDAY 4 /* First day of reformation */
-#define SATURDAY 6 /* Offset value; 1 Jan 1 was a Saturday */
-
-
-/* Number of days in a month, using 0 (Jan) to 11 (Dec). For leap years,
- add 1 to February (month 1). */
-static const int days_in_month[12] = {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-
-
-/**************************************************************************
- * time_t manipulation functions.
- *
- * NOTE: these use the Unix timezone functions like mktime() and localtime()
- * and so should not be used in Evolution. New Evolution code should use
- * icaltimetype values rather than time_t values wherever possible.
- **************************************************************************/
-
-/* Adds a day onto the time, using local time.
- Note that if clocks go forward due to daylight savings time, there are
- some non-existent local times, so the hour may be changed to make it a
- valid time. This also means that it may not be wise to keep calling
- time_add_day() to step through a certain period - if the hour gets changed
- to make it valid time, any further calls to time_add_day() will also return
- this hour, which may not be what you want. */
-time_t
-time_add_day (time_t time, int days)
-{
- struct tm *tm;
-
- tm = localtime (&time);
- tm->tm_mday += days;
- tm->tm_isdst = -1;
-
- return mktime (tm);
-}
-
-time_t
-time_add_week (time_t time, int weeks)
-{
- return time_add_day (time, weeks * 7);
-}
-
-/* Returns the start of the day, according to the local time. */
-time_t
-time_day_begin (time_t t)
-{
- struct tm tm;
-
- tm = *localtime (&t);
- tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
- tm.tm_isdst = -1;
-
- return mktime (&tm);
-}
-
-/* Returns the end of the day, according to the local time. */
-time_t
-time_day_end (time_t t)
-{
- struct tm tm;
-
- tm = *localtime (&t);
- tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
- tm.tm_mday++;
- tm.tm_isdst = -1;
-
- return mktime (&tm);
-}
-
-
-/**************************************************************************
- * time_t manipulation functions, using timezones in libical.
- *
- * NOTE: these are only here to make the transition to the timezone
- * functions easier. New code should use icaltimetype values rather than
- * time_t values wherever possible.
- **************************************************************************/
-
-
-/* Adds or subtracts a number of days to/from the given time_t value, using
- the given timezone.
- NOTE: this function is only here to make the transition to the timezone
- functions easier. New code should use icaltimetype values and
- icaltime_adjust() to add or subtract days, hours, minutes & seconds. */
-time_t
-time_add_day_with_zone (time_t time, int days, icaltimezone *zone)
-{
- struct icaltimetype tt;
-
- /* Convert to an icaltimetype. */
- tt = icaltime_from_timet_with_zone (time, FALSE, zone);
-
- /* Add/subtract the number of days. */
- icaltime_adjust (&tt, days, 0, 0, 0);
-
- /* Convert back to a time_t. */
- return icaltime_as_timet_with_zone (tt, zone);
-}
-
-
-/* Adds or subtracts a number of weeks to/from the given time_t value, using
- the given timezone.
- NOTE: this function is only here to make the transition to the timezone
- functions easier. New code should use icaltimetype values and
- icaltime_adjust() to add or subtract days, hours, minutes & seconds. */
-time_t
-time_add_week_with_zone (time_t time, int weeks, icaltimezone *zone)
-{
- return time_add_day_with_zone (time, weeks * 7, zone);
-}
-
-
-/* Adds or subtracts a number of months to/from the given time_t value, using
- the given timezone.
-
- If the day would be off the end of the month (e.g. adding 1 month to
- 30th January, would lead to an invalid day, 30th February), it moves it
- down to the last day in the month, e.g. 28th Feb (or 29th in a leap year.)
-
- NOTE: this function is only here to make the transition to the timezone
- functions easier. New code should use icaltimetype values and
- icaltime_adjust() to add or subtract days, hours, minutes & seconds. */
-time_t
-time_add_month_with_zone (time_t time, int months, icaltimezone *zone)
-{
- struct icaltimetype tt;
- int day, days_in_month;
-
- /* Convert to an icaltimetype. */
- tt = icaltime_from_timet_with_zone (time, FALSE, zone);
-
- /* Add on the number of months. */
- tt.month += months;
-
- /* Save the day, and set it to 1, so we don't overflow into the next
- month. */
- day = tt.day;
- tt.day = 1;
-
- /* Normalize it, fixing any month overflow. */
- tt = icaltime_normalize (tt);
-
- /* If we go past the end of a month, set it to the last day. */
- days_in_month = time_days_in_month (tt.year, tt.month - 1);
- if (day > days_in_month)
- day = days_in_month;
-
- tt.day = day;
-
- /* Convert back to a time_t. */
- return icaltime_as_timet_with_zone (tt, zone);
-}
-
-
-/* Returns the start of the year containing the given time_t, using the given
- timezone.
- NOTE: this function is only here to make the transition to the timezone
- functions easier. New code should use icaltimetype values and
- icaltime_adjust() to add or subtract days, hours, minutes & seconds. */
-time_t
-time_year_begin_with_zone (time_t time, icaltimezone *zone)
-{
- struct icaltimetype tt;
-
- /* Convert to an icaltimetype. */
- tt = icaltime_from_timet_with_zone (time, FALSE, zone);
-
- /* Set it to the start of the year. */
- tt.month = 1;
- tt.day = 1;
- tt.hour = 0;
- tt.minute = 0;
- tt.second = 0;
-
- /* Convert back to a time_t. */
- return icaltime_as_timet_with_zone (tt, zone);
-}
-
-
-/* Returns the start of the month containing the given time_t, using the given
- timezone.
- NOTE: this function is only here to make the transition to the timezone
- functions easier. New code should use icaltimetype values and
- icaltime_adjust() to add or subtract days, hours, minutes & seconds. */
-time_t
-time_month_begin_with_zone (time_t time, icaltimezone *zone)
-{
- struct icaltimetype tt;
-
- /* Convert to an icaltimetype. */
- tt = icaltime_from_timet_with_zone (time, FALSE, zone);
-
- /* Set it to the start of the month. */
- tt.day = 1;
- tt.hour = 0;
- tt.minute = 0;
- tt.second = 0;
-
- /* Convert back to a time_t. */
- return icaltime_as_timet_with_zone (tt, zone);
-}
-
-
-/* Returns the start of the week containing the given time_t, using the given
- timezone. week_start_day should use the same values as mktime(),
- i.e. 0 (Sun) to 6 (Sat).
- NOTE: this function is only here to make the transition to the timezone
- functions easier. New code should use icaltimetype values and
- icaltime_adjust() to add or subtract days, hours, minutes & seconds. */
-time_t
-time_week_begin_with_zone (time_t time, int week_start_day, icaltimezone *zone)
-{
- struct icaltimetype tt;
- int weekday, offset;
-
- /* Convert to an icaltimetype. */
- tt = icaltime_from_timet_with_zone (time, FALSE, zone);
-
- /* Get the weekday. */
- weekday = time_day_of_week (tt.day, tt.month - 1, tt.year);
-
- /* Calculate the current offset from the week start day. */
- offset = (weekday + 7 - week_start_day) % 7;
-
- /* Set it to the start of the month. */
- tt.day -= offset;
- tt.hour = 0;
- tt.minute = 0;
- tt.second = 0;
-
- /* Normalize it, to fix any overflow. */
- tt = icaltime_normalize (tt);
-
- /* Convert back to a time_t. */
- return icaltime_as_timet_with_zone (tt, zone);
-}
-
-
-/* Returns the start of the day containing the given time_t, using the given
- timezone.
- NOTE: this function is only here to make the transition to the timezone
- functions easier. New code should use icaltimetype values and
- icaltime_adjust() to add or subtract days, hours, minutes & seconds. */
-time_t
-time_day_begin_with_zone (time_t time, icaltimezone *zone)
-{
- struct icaltimetype tt;
-
- /* Convert to an icaltimetype. */
- tt = icaltime_from_timet_with_zone (time, FALSE, zone);
-
- /* Set it to the start of the day. */
- tt.hour = 0;
- tt.minute = 0;
- tt.second = 0;
-
- /* Convert back to a time_t. */
- return icaltime_as_timet_with_zone (tt, zone);
-}
-
-
-/* Returns the end of the day containing the given time_t, using the given
- timezone. (The end of the day is the start of the next day.)
- NOTE: this function is only here to make the transition to the timezone
- functions easier. New code should use icaltimetype values and
- icaltime_adjust() to add or subtract days, hours, minutes & seconds. */
-time_t
-time_day_end_with_zone (time_t time, icaltimezone *zone)
-{
- struct icaltimetype tt;
-
- /* Convert to an icaltimetype. */
- tt = icaltime_from_timet_with_zone (time, FALSE, zone);
-
- /* Set it to the start of the next day. */
- tt.day++;
- tt.hour = 0;
- tt.minute = 0;
- tt.second = 0;
-
- /* Normalize it, to fix any overflow. */
- tt = icaltime_normalize (tt);
-
- /* Convert back to a time_t. */
- return icaltime_as_timet_with_zone (tt, zone);
-}
-
-/**
- * time_to_gdate_with_zone:
- * @date: Destination #GDate value.
- * @time: A time value.
- * @zone: Desired timezone for destination @date, or NULL if the UTC timezone
- * is desired.
- *
- * Converts a time_t value to a #GDate structure using the specified timezone.
- * This is analogous to g_date_set_time() but takes the timezone into account.
- **/
-void
-time_to_gdate_with_zone (GDate *date, time_t time, icaltimezone *zone)
-{
- struct icaltimetype tt;
-
- g_return_if_fail (date != NULL);
- g_return_if_fail (time != -1);
-
- tt = icaltime_from_timet_with_zone (time, FALSE,
- zone ? zone : icaltimezone_get_utc_timezone ());
-
- g_date_set_dmy (date, tt.day, tt.month, tt.year);
-}
-
-
-/**************************************************************************
- * General time functions.
- **************************************************************************/
-
-
-/* Returns the number of days in the month. Year is the normal year, e.g. 2001.
- Month is 0 (Jan) to 11 (Dec). */
-int
-time_days_in_month (int year, int month)
-{
- int days;
-
- g_return_val_if_fail (year >= 1900, 0);
- g_return_val_if_fail ((month >= 0) && (month < 12), 0);
-
- days = days_in_month[month];
- if (month == 1 && time_is_leap_year (year))
- days++;
-
- return days;
-}
-
-
-/* Returns the 1-based day number within the year of the specified date.
- Year is the normal year, e.g. 2001. Month is 0 to 11. */
-int
-time_day_of_year (int day, int month, int year)
-{
- int i;
-
- for (i = 0; i < month; i++) {
- day += days_in_month[i];
-
- if (i == 1 && time_is_leap_year (year))
- day++;
- }
-
- return day;
-}
-
-
-/* Returns the day of the week for the specified date, 0 (Sun) to 6 (Sat).
- For the days that were removed on the Gregorian reformation, it returns
- Thursday. Year is the normal year, e.g. 2001. Month is 0 to 11. */
-int
-time_day_of_week (int day, int month, int year)
-{
- int n;
-
- n = (year - 1) * 365 + time_leap_years_up_to (year - 1)
- + time_day_of_year (day, month, year);
-
- if (n < REFORMATION_DAY)
- return (n - 1 + SATURDAY) % 7;
-
- if (n >= (REFORMATION_DAY + MISSING_DAYS))
- return (n - 1 + SATURDAY - MISSING_DAYS) % 7;
-
- return THURSDAY;
-}
-
-
-/* Returns whether the specified year is a leap year. Year is the normal year,
- e.g. 2001. */
-gboolean
-time_is_leap_year (int year)
-{
- if (year <= 1752)
- return !(year % 4);
- else
- return (!(year % 4) && (year % 100)) || !(year % 400);
-}
-
-
-/* Returns the number of leap years since year 1 up to (but not including) the
- specified year. Year is the normal year, e.g. 2001. */
-int
-time_leap_years_up_to (int year)
-{
- /* There is normally a leap year every 4 years, except at the turn of
- centuries since 1700. But there is a leap year on centuries since 1700
- which are divisible by 400. */
- return (year / 4
- - ((year > 1700) ? (year / 100 - 17) : 0)
- + ((year > 1600) ? ((year - 1600) / 400) : 0));
-}
-
-
-/**
- * isodate_from_time_t:
- * @t: A time value.
- *
- * Creates an ISO 8601 UTC representation from a time value.
- *
- * Return value: String with the ISO 8601 representation of the UTC time.
- **/
-char *
-isodate_from_time_t (time_t t)
-{
- gchar *ret;
-
- ret = g_malloc (17); /* 4+2+2+1+2+2+2+1 + 1 */
- strftime (ret, 17, "%Y%m%dT%H%M%SZ", gmtime (&t));
-
- return ret;
-}
-
-/**
- * time_from_isodate:
- * @str: Date/time value in ISO 8601 format.
- *
- * Converts an ISO 8601 UTC time string into a time_t value.
- *
- * Return value: Time_t corresponding to the specified ISO string.
- * Note that we only allow UTC times at present.
- **/
-time_t
-time_from_isodate (const char *str)
-{
- struct icaltimetype tt = icaltime_null_time ();
- icaltimezone *utc_zone;
- int len, i;
-
- g_return_val_if_fail (str != NULL, -1);
-
- /* yyyymmdd[Thhmmss[Z]] */
-
- len = strlen (str);
-
- if (!(len == 8 || len == 15 || len == 16))
- return -1;
-
- for (i = 0; i < len; i++)
- if (!((i != 8 && i != 15 && isdigit (str[i]))
- || (i == 8 && str[i] == 'T')
- || (i == 15 && str[i] == 'Z')))
- return -1;
-
-#define digit_at(x,y) (x[y] - '0')
-
- tt.year = digit_at (str, 0) * 1000
- + digit_at (str, 1) * 100
- + digit_at (str, 2) * 10
- + digit_at (str, 3);
-
- tt.month = digit_at (str, 4) * 10
- + digit_at (str, 5);
-
- tt.day = digit_at (str, 6) * 10
- + digit_at (str, 7);
-
- if (len > 8) {
- tt.hour = digit_at (str, 9) * 10
- + digit_at (str, 10);
- tt.minute = digit_at (str, 11) * 10
- + digit_at (str, 12);
- tt.second = digit_at (str, 13) * 10
- + digit_at (str, 14);
- }
-
- utc_zone = icaltimezone_get_utc_timezone ();
-
- return icaltime_as_timet_with_zone (tt, utc_zone);
-}
-
-struct tm
-icaltimetype_to_tm (struct icaltimetype *itt)
-{
- struct tm tm;
-
- memset (&tm, 0, sizeof (struct tm));
-
- if (!itt->is_date) {
- tm.tm_sec = itt->second;
- tm.tm_min = itt->minute;
- tm.tm_hour = itt->hour;
- }
-
- tm.tm_mday = itt->day;
- tm.tm_mon = itt->month - 1;
- tm.tm_year = itt->year - 1900;
- tm.tm_wday = time_day_of_week (itt->day, itt->month - 1, itt->year);
- tm.tm_isdst = -1;
-
- return tm;
-}
-
-/**
- * icaltimetype_to_tm_with_zone:
- * @itt: A time value.
- * @from_zone: Source timezone.
- * @to_zone: Destination timezone.
- *
- * Converts a time value from one timezone to another, and returns a struct tm
- * representation of the time.
- *
- * Return value: The converted time as a struct tm. All fields will be
- * set properly except for tm.tm_yday.
- **/
-struct tm
-icaltimetype_to_tm_with_zone (struct icaltimetype *itt,
- icaltimezone *from_zone,
- icaltimezone *to_zone)
-{
- struct tm tm;
- struct icaltimetype itt_copy;
-
- memset (&tm, 0, sizeof (tm));
- tm.tm_isdst = -1;
-
- g_return_val_if_fail (itt != NULL, tm);
-
- itt_copy = *itt;
-
- icaltimezone_convert_time (&itt_copy, from_zone, to_zone);
- tm = icaltimetype_to_tm (&itt_copy);
-
- return tm;
-}
-
-struct icaltimetype
-tm_to_icaltimetype (struct tm *tm, gboolean is_date)
-{
- struct icaltimetype itt;
-
- memset (&itt, 0, sizeof (struct icaltimetype));
-
- if (!is_date) {
- itt.second = tm->tm_sec;
- itt.minute = tm->tm_min;
- itt.hour = tm->tm_hour;
- }
-
- itt.day = tm->tm_mday;
- itt.month = tm->tm_mon + 1;
- itt.year = tm->tm_year+ 1900;
-
- itt.is_utc = 0;
- itt.is_date = is_date;
-
- return itt;
-}
-
diff --git a/calendar/cal-util/timeutil.h b/calendar/cal-util/timeutil.h
deleted file mode 100644
index 77a8f180e1..0000000000
--- a/calendar/cal-util/timeutil.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/* Miscellaneous time-related utilities
- *
- * Copyright (C) 1998 The Free Software Foundation
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Federico Mena <federico@ximian.com>
- * Miguel de Icaza <miguel@ximian.com>
- * Damon Chaplin <damon@ximian.com>
- */
-
-#ifndef TIMEUTIL_H
-#define TIMEUTIL_H
-
-
-#include <time.h>
-#include <ical.h>
-#include <glib.h>
-
-
-/**************************************************************************
- * General time functions.
- **************************************************************************/
-
-/* Returns the number of days in the month. Year is the normal year, e.g. 2001.
- Month is 0 (Jan) to 11 (Dec). */
-int time_days_in_month (int year, int month);
-
-/* Returns the 1-based day number within the year of the specified date.
- Year is the normal year, e.g. 2001. Month is 0 to 11. */
-int time_day_of_year (int day, int month, int year);
-
-/* Returns the day of the week for the specified date, 0 (Sun) to 6 (Sat).
- For the days that were removed on the Gregorian reformation, it returns
- Thursday. Year is the normal year, e.g. 2001. Month is 0 to 11. */
-int time_day_of_week (int day, int month, int year);
-
-/* Returns whether the specified year is a leap year. Year is the normal year,
- e.g. 2001. */
-gboolean time_is_leap_year (int year);
-
-/* Returns the number of leap years since year 1 up to (but not including) the
- specified year. Year is the normal year, e.g. 2001. */
-int time_leap_years_up_to (int year);
-
-/* Convert to or from an ISO 8601 representation of a time, in UTC,
- e.g. "20010708T183000Z". */
-char *isodate_from_time_t (time_t t);
-time_t time_from_isodate (const char *str);
-
-
-/**************************************************************************
- * time_t manipulation functions.
- *
- * NOTE: these use the Unix timezone functions like mktime() and localtime()
- * and so should not be used in Evolution. New Evolution code should use
- * icaltimetype values rather than time_t values wherever possible.
- **************************************************************************/
-
-/* Add or subtract a number of days, weeks or months. */
-time_t time_add_day (time_t time, int days);
-time_t time_add_week (time_t time, int weeks);
-
-/* Returns the beginning or end of the day. */
-time_t time_day_begin (time_t t);
-time_t time_day_end (time_t t);
-
-
-/**************************************************************************
- * time_t manipulation functions, using timezones in libical.
- *
- * NOTE: these are only here to make the transition to the timezone
- * functions easier. New code should use icaltimetype values rather than
- * time_t values wherever possible.
- **************************************************************************/
-
-/* Adds or subtracts a number of days to/from the given time_t value, using
- the given timezone. */
-time_t time_add_day_with_zone (time_t time, int days, icaltimezone *zone);
-
-/* Adds or subtracts a number of weeks to/from the given time_t value, using
- the given timezone. */
-time_t time_add_week_with_zone (time_t time, int weeks, icaltimezone *zone);
-
-/* Adds or subtracts a number of months to/from the given time_t value, using
- the given timezone. */
-time_t time_add_month_with_zone (time_t time, int months, icaltimezone *zone);
-
-/* Returns the start of the year containing the given time_t, using the given
- timezone. */
-time_t time_year_begin_with_zone (time_t time, icaltimezone *zone);
-
-/* Returns the start of the month containing the given time_t, using the given
- timezone. */
-time_t time_month_begin_with_zone (time_t time, icaltimezone *zone);
-
-/* Returns the start of the week containing the given time_t, using the given
- timezone. week_start_day should use the same values as mktime(),
- i.e. 0 (Sun) to 6 (Sat). */
-time_t time_week_begin_with_zone (time_t time, int week_start_day,
- icaltimezone *zone);
-
-/* Returns the start of the day containing the given time_t, using the given
- timezone. */
-time_t time_day_begin_with_zone (time_t time, icaltimezone *zone);
-
-/* Returns the end of the day containing the given time_t, using the given
- timezone. (The end of the day is the start of the next day.) */
-time_t time_day_end_with_zone (time_t time, icaltimezone *zone);
-
-void time_to_gdate_with_zone (GDate *date, time_t time, icaltimezone *zone);
-
-/**************************************************************************
- * struct tm manipulation
- **************************************************************************/
-
-struct tm icaltimetype_to_tm (struct icaltimetype *itt);
-struct tm icaltimetype_to_tm_with_zone (struct icaltimetype *itt,
- icaltimezone *from_zone,
- icaltimezone *to_zone);
-struct icaltimetype tm_to_icaltimetype (struct tm *tm, gboolean is_date);
-
-#endif
diff --git a/calendar/calendar.error.xml b/calendar/calendar.error.xml
new file mode 100644
index 0000000000..ee526b60cb
--- /dev/null
+++ b/calendar/calendar.error.xml
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<error-list domain="calendar">
+
+ <error id="prompt-cancel-meeting" type="question" default="GTK_RESPONSE_YES">
+ <_primary>Would you like to send all the participants a cancelation notice?</_primary>
+ <_secondary>If you do not send a cancelation notice, the other participants may not know the meeting is canceled.</_secondary>
+ <button _label="Do _not Send" response="GTK_RESPONSE_NO"/>
+ <button _label="_Send Notice" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-meeting" type="question" default="GTK_RESPONSE_NO">
+ <_primary>Are you sure you want to delete this meeting?</_primary>
+ <_secondary>All information on this meeting will be deleted and can not be restored.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-cancel-task" type="question" default="GTK_RESPONSE_YES">
+ <_primary>Would you like to send all the participants a cancelation notice?</_primary>
+ <_secondary>If you do not send a cancelation notice, the other participants may not know the task has been deleted.</_secondary>
+ <button _label="Do _not Send" response="GTK_RESPONSE_NO"/>
+ <button _label="_Send Notice" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-task" type="question" default="GTK_RESPONSE_NO">
+ <_primary>Are you sure you want to delete this task?</_primary>
+ <_secondary>All information on this task will be deleted and can not be restored.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-cancel-memo" type="question" default="GTK_RESPONSE_YES">
+ <_primary>Would you like to send a cancelation notice for this memo?</_primary>
+ <_secondary>If you do not send a cancelation notice, the other participants may not know the memo has been deleted.</_secondary>
+ <button _label="Do _not Send" response="GTK_RESPONSE_NO"/>
+ <button _label="_Send Notice" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-memo" type="question" default="GTK_RESPONSE_NO">
+ <_primary>Are you sure you want to delete this memo?</_primary>
+ <_secondary>All information on this memo will be deleted and can not be restored.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-titled-meeting" type="question" default="GTK_RESPONSE_NO">
+ <_primary>Are you sure you want to delete the meeting titled '{0}'?</_primary>
+ <_secondary>All information on this meeting will be deleted and can not be restored.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-titled-appointment" type="question" default="GTK_RESPONSE_NO">
+ <_primary>Are you sure you want to delete the appointment titled '{0}'?</_primary>
+ <_secondary>All information on this appointment will be deleted and can not be restored.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-appointment" type="question" default="GTK_RESPONSE_YES">
+ <_primary>Are you sure you want to delete this appointment?</_primary>
+ <_secondary>All information on this appointment will be deleted and can not be restored.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-named-task" type="question" default="GTK_RESPONSE_NO">
+ <_primary>Are you sure you want to delete the '{0}' task?</_primary>
+ <_secondary>All information on this task will be deleted and can not be restored.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-named-memo" type="question" default="GTK_RESPONSE_NO">
+ <_primary>Are you sure you want to delete the memo '{0}'?</_primary>
+ <_secondary>All information in this memo will be deleted and can not be restored.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-appointments" type="question" default="GTK_RESPONSE_NO">
+ <_primary>Are you sure you want to delete these {0} appointments?</_primary>
+ <_secondary>All information on these appointments will be deleted and can not be restored.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-tasks" type="question" default="GTK_RESPONSE_NO">
+ <_primary>Are you sure you want to delete these {0} tasks?</_primary>
+ <_secondary>All information on these tasks will be deleted and can not be restored.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-memos" type="question" default="GTK_RESPONSE_NO">
+ <_primary>Are you sure you want to delete these {0} memos?</_primary>
+ <_secondary>All information in these memos will be deleted and can not be restored.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-save-meeting-dragged-or-resized" type="warning" default="GTK_RESPONSE_CANCEL">
+ <_primary>Would you like to save your changes to this meeting?</_primary>
+ <_secondary>You have changed this meeting, but not yet saved it.</_secondary>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Save Changes" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-save-meeting" type="warning" default="GTK_RESPONSE_YES">
+ <_primary>Would you like to save your changes to this meeting?</_primary>
+ <_secondary>You have changed this meeting, but not yet saved it.</_secondary>
+ <button _label="_Discard Changes" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Save Changes" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-save-appointment" type="warning" default="GTK_RESPONSE_YES">
+ <_primary>Would you like to save your changes to this appointment?</_primary>
+ <_secondary>You have changed this appointment, but not yet saved it.</_secondary>
+ <button _label="_Discard Changes" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Save Changes" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-save-task" type="warning" default="GTK_RESPONSE_YES">
+ <_primary>Would you like to save your changes to this task?</_primary>
+ <_secondary>You have changed this task, but not yet saved it.</_secondary>
+ <button _label="_Discard Changes" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Save Changes" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-save-memo" type="warning" default="GTK_RESPONSE_YES">
+ <_primary>Would you like to save your changes to this memo?</_primary>
+ <_secondary>You have made changes to this memo, but not yet saved them.</_secondary>
+ <button _label="_Discard Changes" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Save Changes" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-meeting-invite" type="question" default="GTK_RESPONSE_YES">
+ <_primary>Would you like to send meeting invitations to participants?</_primary>
+ <_secondary>Email invitations will be sent to all participants and allow them to reply.</_secondary>
+ <button _label="Do _not Send" response="GTK_RESPONSE_NO"/>
+ <button _label="_Send" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-send-updated-meeting-info" type="question" default="GTK_RESPONSE_YES">
+ <_primary>Would you like to send updated meeting information to participants?</_primary>
+ <_secondary>Sending updated information allows other participants to keep their calendars up to date.</_secondary>
+ <button _label="Do _not Send" response="GTK_RESPONSE_NO"/>
+ <button _label="_Send" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-send-updated-meeting-info-dragged-or-resized" type="question" default="GTK_RESPONSE_CANCEL">
+ <_primary>Would you like to send updated meeting information to participants?</_primary>
+ <_secondary>Sending updated information allows other participants to keep their calendars up to date.</_secondary>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="Do _not Send" response="GTK_RESPONSE_NO"/>
+ <button _label="_Send" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-send-task" type="question" default="GTK_RESPONSE_YES">
+ <_primary>Would you like to send this task to participants?</_primary>
+ <_secondary>Email invitations will be sent to all participants and allow them to accept this task.</_secondary>
+ <button _label="Do _not Send" response="GTK_RESPONSE_NO"/>
+ <button _label="_Send" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="ask-send-task-pending-download" type="question" default="GTK_RESPONSE_YES">
+ <_primary>Download in progress. Do you want to save the task?</_primary>
+ <_secondary xml:space="preserve">Some attachments are being downloaded. Saving the task would result in the loss of these attachments.</_secondary>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Save" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="ask-send-event-pending-download" type="question" default="GTK_RESPONSE_YES">
+ <_primary>Download in progress. Do you want to save the appointment?</_primary>
+ <_secondary xml:space="preserve">Some attachments are being downloaded. Saving the appointment would result in the loss of these attachments.</_secondary>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Save" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-send-updated-task-info" type="question" default="GTK_RESPONSE_YES">
+ <_primary>Would you like to send updated task information to participants?</_primary>
+ <_secondary>Sending updated information allows other participants to keep their task lists up to date.</_secondary>
+ <button _label="Do _not Send" response="GTK_RESPONSE_NO"/>
+ <button _label="_Send" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="editor-error" type="error">
+ <_primary>Editor could not be loaded.</_primary>
+ <secondary>{0}.</secondary>
+ </error>
+
+ <error id="prompt-delete-calendar" type="question" default="GTK_RESPONSE_CANCEL">
+ <_primary>Delete calendar '{0}'?</_primary>
+ <_secondary>This calendar will be removed permanently.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_CANCEL"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-task-list" type="question" default="GTK_RESPONSE_CANCEL">
+ <_primary>Delete task list '{0}'?</_primary>
+ <_secondary>This task list will be removed permanently.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_CANCEL"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-memo-list" type="question" default="GTK_RESPONSE_CANCEL">
+ <_primary>Delete memo list '{0}'?</_primary>
+ <_secondary>This memo list will be removed permanently.</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_NO"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-remote-calendar" type="question" default="GTK_RESPONSE_CANCEL">
+ <_primary>Delete remote calendar '{0}'?</_primary>
+ <_secondary>This will permanently remove the calendar '{0}' from the server. Are you sure you want to proceed?</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Delete From Server" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-remote-task-list" type="question" default="GTK_RESPONSE_CANCEL">
+ <_primary>Delete remote task list '{0}'?</_primary>
+ <_secondary>This will permanently remove the task list '{0}' from the server. Are you sure you want to proceed?</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Delete From Server" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-remote-memo-list" type="question" default="GTK_RESPONSE_CANCEL">
+ <_primary>Delete remote memo list '{0}'?</_primary>
+ <_secondary>This will permanently remove the memo list '{0}' from the server. Are you sure you want to proceed?</_secondary>
+ <button _label="Do _Not Delete" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Delete From Server" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-save-no-subject-calendar" type="question" default="GTK_RESPONSE_YES">
+ <_primary>Are you sure you want to save the appointment without a summary?</_primary>
+ <_secondary>Adding a meaningful summary to your appointment will give you an idea of what your appointment is about.</_secondary>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Save" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-save-no-subject-task" type="question" default="GTK_RESPONSE_YES">
+ <_primary>Are you sure you want to save the task without a summary?</_primary>
+ <_secondary>Adding a meaningful summary to your task will give you an idea of what your task is about.</_secondary>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Save" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-send-no-subject-memo" type="question" default="GTK_RESPONSE_CANCEL">
+ <_primary>Are you sure you want to save the memo without a summary?</_primary>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button _label="_Save" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-no-contents-offline-calendar" type="error" default="GTK_RESPONSE_YES">
+ <!-- Translators: {0} is the name of the calendar. -->
+ <_primary>Error loading calendar '{0}'</_primary>
+ <_secondary>The calendar is not marked for offline usage.</_secondary>
+ </error>
+
+ <error id="prompt-read-only-cal-editor" type="error" default="GTK_RESPONSE_YES">
+ <_primary>Cannot save event</_primary>
+ <!-- Translators: {0} is the name of the calendar source -->
+ <_secondary>'{0}' is a read-only calendar and cannot be modified. Please select a different calendar that can accept appointments.</_secondary>
+ </error>
+
+ <error id="prompt-no-task-assignment-editor" type="error" default="GTK_RESPONSE_YES">
+ <_primary>Cannot save task</_primary>
+ <!-- Translators: {0} is the name of the calendar source -->
+ <_secondary>'{0}' does not support assigned tasks, please select a different task list.</_secondary>
+ </error>
+
+ <error id="prompt-no-contents-offline-tasks" type="error" default="GTK_RESPONSE_YES">
+ <!-- Translators: {0} is the name of the task list. -->
+ <_primary>Error loading task list '{0}'</_primary>
+ <_secondary>The task list is not marked for offline usage.</_secondary>
+ </error>
+
+ <error id="prompt-no-contents-offline-memos" type="error" default="GTK_RESPONSE_YES">
+ <!-- Translators: {0} is the name of the memo list. -->
+ <_primary>Error loading memo list '{0}'</_primary>
+ <_secondary>The memo list is not marked for offline usage.</_secondary>
+ </error>
+
+ <error id="failed-open-calendar" type="error" default="GTK_RESPONSE_YES">
+ <!-- Translators: {0} is the name of the calendar. -->
+ <_primary>Error loading calendar '{0}'</_primary>
+ <secondary>{1}</secondary>
+ </error>
+
+ <error id="failed-open-tasks" type="error" default="GTK_RESPONSE_YES">
+ <!-- Translators: {0} is the name of the task list. -->
+ <_primary>Error loading task list '{0}'</_primary>
+ <secondary>{1}</secondary>
+ </error>
+
+ <error id="failed-open-memos" type="error" default="GTK_RESPONSE_YES">
+ <!-- Translators: {0} is the name of the memo list. -->
+ <_primary>Error loading memo list '{0}'</_primary>
+ <secondary>{1}</secondary>
+ </error>
+
+ <error id="search-error-generic" type="error">
+ <secondary>{0}</secondary>
+ </error>
+
+</error-list>
diff --git a/calendar/conduits/.cvsignore b/calendar/conduits/.cvsignore
deleted file mode 100644
index b840c21800..0000000000
--- a/calendar/conduits/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Makefile.in
-Makefile \ No newline at end of file
diff --git a/calendar/conduits/Makefile.am b/calendar/conduits/Makefile.am
deleted file mode 100644
index 906ea61971..0000000000
--- a/calendar/conduits/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = calendar todo
diff --git a/calendar/conduits/calendar/.cvsignore b/calendar/conduits/calendar/.cvsignore
deleted file mode 100644
index e8ba6ad844..0000000000
--- a/calendar/conduits/calendar/.cvsignore
+++ /dev/null
@@ -1,9 +0,0 @@
-Makefile.in
-Makefile
-.deps
-e-calendar.conduit
-*.lo
-.libs
-libecalendar_conduit.la
-e-calendar-conduit-control-applet
-e-calendar-conduit-control-applet.desktop
diff --git a/calendar/conduits/calendar/Makefile.am b/calendar/conduits/calendar/Makefile.am
deleted file mode 100644
index 3ddaf94ee7..0000000000
--- a/calendar/conduits/calendar/Makefile.am
+++ /dev/null
@@ -1,42 +0,0 @@
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/calendar \
- -I$(top_builddir)/calendar/cal-client \
- -I$(top_srcdir)/libical/src/libical \
- -I$(top_builddir)/libical/src/libical \
- -I$(top_srcdir)/e-util \
- -I$(top_builddir)/e-util \
- $(EVOLUTION_CALENDAR_CONDUIT_CFLAGS)
-
-# Calendar Conduit
-e_calendar_conduitsdir=$(libdir)/gnome-pilot/conduits
-e_calendar_conduits_LTLIBRARIES = libecalendar_conduit.la
-
-libecalendar_conduit_la_SOURCES = \
- calendar-conduit.c
-
-libecalendar_conduit_la_LDFLAGS = -module -avoid-version
-libecalendar_conduit_la_LIBADD = \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/calendar/cal-client/libcal-client-static.la \
- $(top_builddir)/calendar/cal-util/libcal-util-static.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/libical/src/libical/libical-static.la \
- $(top_builddir)/libwombat/libwombat-static.la \
- $(top_builddir)/e-util/libeconduit-static.la \
- $(EVOLUTION_CALENDAR_CONDUIT_LIBS)
-
-e-calendar.conduit: e-calendar.conduit.in Makefile
- sed -e 's^\@prefix\@^$(prefix)^g' \
- -e 's^\@datadir\@^$(datadir)^g' \
- < $(srcdir)/e-calendar.conduit.in > e-calendar.conduit.tmp \
- && mv e-calendar.conduit.tmp e-calendar.conduit
-
-Conduitdir = $(datadir)/gnome-pilot/conduits/
-Conduit_DATA = e-calendar.conduit
-
-EXTRA_DIST = \
- e-calendar.conduit.in
-
-install-data-local:
- $(mkinstalldirs) $(Conduitdir)
diff --git a/calendar/conduits/calendar/calendar-conduit.c b/calendar/conduits/calendar/calendar-conduit.c
deleted file mode 100644
index 6ebaca44d4..0000000000
--- a/calendar/conduits/calendar/calendar-conduit.c
+++ /dev/null
@@ -1,1858 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Evolution calendar - Calendar Conduit
- *
- * Copyright (C) 1998 Free Software Foundation
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Eskil Heyn Olsen <deity@eskil.dk>
- * JP Rosevear <jpr@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 <bonobo.h>
-#include <bonobo-conf/bonobo-config-database.h>
-#include <cal-client/cal-client-types.h>
-#include <cal-client/cal-client.h>
-#include <cal-util/timeutil.h>
-#include <pi-source.h>
-#include <pi-socket.h>
-#include <pi-dlp.h>
-#include <pi-datebook.h>
-#include <gpilotd/gnome-pilot-conduit.h>
-#include <gpilotd/gnome-pilot-conduit-sync-abs.h>
-#include <libgpilotdCM/gnome-pilot-conduit-management.h>
-#include <libgpilotdCM/gnome-pilot-conduit-config.h>
-#include <e-pilot-map.h>
-#include <e-pilot-settings.h>
-#include <e-pilot-util.h>
-
-GnomePilotConduit * conduit_get_gpilot_conduit (guint32);
-void conduit_destroy_gpilot_conduit (GnomePilotConduit*);
-
-#define CONDUIT_VERSION "0.1.6"
-#ifdef G_LOG_DOMAIN
-#undef G_LOG_DOMAIN
-#endif
-#define G_LOG_DOMAIN "ecalconduit"
-
-#define DEBUG_CALCONDUIT 1
-/* #undef DEBUG_CALCONDUIT */
-
-#ifdef DEBUG_CALCONDUIT
-#define LOG(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, e)
-#else
-#define LOG(e...)
-#endif
-
-#define WARN(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, e)
-#define INFO(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, e)
-
-#define PILOT_MAX_ADVANCE 99
-
-typedef struct _ECalLocalRecord ECalLocalRecord;
-typedef struct _ECalConduitCfg ECalConduitCfg;
-typedef struct _ECalConduitGui ECalConduitGui;
-typedef struct _ECalConduitContext ECalConduitContext;
-
-/* Local Record */
-struct _ECalLocalRecord {
- /* The stuff from gnome-pilot-conduit-standard-abs.h
- Must be first in the structure, or instances of this
- structure cannot be used by gnome-pilot-conduit-standard-abs.
- */
- GnomePilotDesktopRecord local;
-
- /* The corresponding Comp object */
- CalComponent *comp;
-
- /* pilot-link appointment structure */
- struct Appointment *appt;
-};
-
-static void
-calconduit_destroy_record (ECalLocalRecord *local)
-{
- gtk_object_unref (GTK_OBJECT (local->comp));
- free_Appointment (local->appt);
- g_free (local->appt);
- g_free (local);
-}
-
-/* Configuration */
-struct _ECalConduitCfg {
- guint32 pilot_id;
- GnomePilotConduitSyncType sync_type;
-
- gboolean secret;
- gboolean multi_day_split;
-
- gchar *last_uri;
-};
-
-static ECalConduitCfg *
-calconduit_load_configuration (guint32 pilot_id)
-{
- ECalConduitCfg *c;
- GnomePilotConduitManagement *management;
- GnomePilotConduitConfig *config;
- gchar prefix[256];
-
- c = g_new0 (ECalConduitCfg, 1);
- g_assert (c != NULL);
-
- /* Pilot ID */
- c->pilot_id = pilot_id;
-
- /* Sync Type */
- management = gnome_pilot_conduit_management_new ("e_calendar_conduit", GNOME_PILOT_CONDUIT_MGMT_ID);
- config = gnome_pilot_conduit_config_new (management, pilot_id);
- if (!gnome_pilot_conduit_config_is_enabled (config, &c->sync_type))
- c->sync_type = GnomePilotConduitSyncTypeNotSet;
- gtk_object_unref (GTK_OBJECT (config));
- gtk_object_unref (GTK_OBJECT (management));
-
- /* Custom settings */
- g_snprintf (prefix, 255, "/gnome-pilot.d/e-calendar-conduit/Pilot_%u/", pilot_id);
- gnome_config_push_prefix (prefix);
-
- c->secret = gnome_config_get_bool ("secret=FALSE");
- c->multi_day_split = gnome_config_get_bool ("multi_day_split=TRUE");
- c->last_uri = gnome_config_get_string ("last_uri");
-
- gnome_config_pop_prefix ();
-
- return c;
-}
-
-static void
-calconduit_save_configuration (ECalConduitCfg *c)
-{
- gchar prefix[256];
-
- g_snprintf (prefix, 255, "/gnome-pilot.d/e-calendar-conduit/Pilot_%u/", c->pilot_id);
- gnome_config_push_prefix (prefix);
-
- gnome_config_set_bool ("secret", c->secret);
- gnome_config_set_bool ("multi_day_split", c->multi_day_split);
- gnome_config_set_string ("last_uri", c->last_uri);
-
- gnome_config_pop_prefix ();
-
- gnome_config_sync ();
- gnome_config_drop_all ();
-}
-
-static ECalConduitCfg*
-calconduit_dupe_configuration (ECalConduitCfg *c)
-{
- ECalConduitCfg *retval;
-
- g_return_val_if_fail (c != NULL, NULL);
-
- retval = g_new0 (ECalConduitCfg, 1);
- retval->pilot_id = c->pilot_id;
- retval->sync_type = c->sync_type;
- retval->secret = c->secret;
- retval->multi_day_split = c->multi_day_split;
- retval->last_uri = g_strdup (c->last_uri);
-
- return retval;
-}
-
-static void
-calconduit_destroy_configuration (ECalConduitCfg *c)
-{
- g_return_if_fail (c != NULL);
-
- g_free (c->last_uri);
- g_free (c);
-}
-
-/* Gui */
-struct _ECalConduitGui {
- GtkWidget *multi_day_split;
-};
-
-static ECalConduitGui *
-e_cal_gui_new (EPilotSettings *ps)
-{
- ECalConduitGui *gui;
- GtkWidget *lbl;
- gint rows;
-
- g_return_val_if_fail (ps != NULL, NULL);
- g_return_val_if_fail (E_IS_PILOT_SETTINGS (ps), NULL);
-
- gtk_table_resize (GTK_TABLE (ps), E_PILOT_SETTINGS_TABLE_ROWS + 1, E_PILOT_SETTINGS_TABLE_COLS);
-
- gui = g_new0 (ECalConduitGui, 1);
-
- rows = E_PILOT_SETTINGS_TABLE_ROWS;
- lbl = gtk_label_new (_("Split Multi-Day Events:"));
- gui->multi_day_split = gtk_check_button_new ();
- gtk_table_attach_defaults (GTK_TABLE (ps), lbl, 0, 1, rows, rows + 1);
- gtk_table_attach_defaults (GTK_TABLE (ps), gui->multi_day_split, 1, 2, rows, rows + 1);
- gtk_widget_show (lbl);
- gtk_widget_show (gui->multi_day_split);
-
- return gui;
-}
-
-static void
-e_cal_gui_fill_widgets (ECalConduitGui *gui, ECalConduitCfg *cfg)
-{
- g_return_if_fail (gui != NULL);
- g_return_if_fail (cfg != NULL);
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gui->multi_day_split),
- cfg->multi_day_split);
-}
-
-static void
-e_cal_gui_fill_config (ECalConduitGui *gui, ECalConduitCfg *cfg)
-{
- g_return_if_fail (gui != NULL);
- g_return_if_fail (cfg != NULL);
-
- cfg->multi_day_split = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gui->multi_day_split));
-}
-
-static void
-e_cal_gui_destroy (ECalConduitGui *gui)
-{
- g_free (gui);
-}
-
-/* Context */
-struct _ECalConduitContext {
- GnomePilotDBInfo *dbi;
-
- ECalConduitCfg *cfg;
- ECalConduitCfg *new_cfg;
- ECalConduitGui *gui;
- GtkWidget *ps;
-
- struct AppointmentAppInfo ai;
-
- CalClient *client;
-
- icaltimezone *timezone;
- GList *uids;
- GList *changed;
- GHashTable *changed_hash;
- GList *locals;
-
- EPilotMap *map;
-};
-
-static ECalConduitContext *
-e_calendar_context_new (guint32 pilot_id)
-{
- ECalConduitContext *ctxt;
-
- ctxt = g_new0 (ECalConduitContext, 1);
- g_assert (ctxt != NULL);
-
- ctxt->cfg = calconduit_load_configuration (pilot_id);
- ctxt->new_cfg = calconduit_dupe_configuration (ctxt->cfg);
- ctxt->ps = NULL;
- ctxt->dbi = NULL;
- ctxt->client = NULL;
- ctxt->timezone = NULL;
- ctxt->uids = NULL;
- ctxt->changed = NULL;
- ctxt->changed_hash = NULL;
- ctxt->locals = NULL;
- ctxt->map = NULL;
-
- return ctxt;
-}
-
-static gboolean
-e_calendar_context_foreach_change (gpointer key, gpointer value, gpointer data)
-{
- g_free (key);
-
- return TRUE;
-}
-
-static void
-e_calendar_context_destroy (ECalConduitContext *ctxt)
-{
- GList *l;
-
- g_return_if_fail (ctxt != NULL);
-
- if (ctxt->cfg != NULL)
- calconduit_destroy_configuration (ctxt->cfg);
- if (ctxt->new_cfg != NULL)
- calconduit_destroy_configuration (ctxt->new_cfg);
- if (ctxt->gui != NULL)
- e_cal_gui_destroy (ctxt->gui);
-
- if (ctxt->client != NULL)
- gtk_object_unref (GTK_OBJECT (ctxt->client));
-
- if (ctxt->uids != NULL)
- cal_obj_uid_list_free (ctxt->uids);
-
- if (ctxt->changed != NULL)
- cal_client_change_list_free (ctxt->changed);
-
- if (ctxt->changed_hash != NULL) {
- g_hash_table_foreach_remove (ctxt->changed_hash, e_calendar_context_foreach_change, NULL);
- g_hash_table_destroy (ctxt->changed_hash);
- }
-
- if (ctxt->locals != NULL) {
- for (l = ctxt->locals; l != NULL; l = l->next)
- calconduit_destroy_record (l->data);
- g_list_free (ctxt->locals);
- }
-
- if (ctxt->map != NULL)
- e_pilot_map_destroy (ctxt->map);
-}
-
-/* Debug routines */
-static char *
-print_local (ECalLocalRecord *local)
-{
- static char buff[ 4096 ];
-
- if (local == NULL) {
- sprintf (buff, "[NULL]");
- return buff;
- }
-
- if (local->appt && local->appt->description) {
- g_snprintf (buff, 4096, "[%ld %ld '%s' '%s']",
- mktime (&local->appt->begin),
- mktime (&local->appt->end),
- local->appt->description ?
- local->appt->description : "",
- local->appt->note ?
- local->appt->note : "");
- return buff;
- }
-
- return "";
-}
-
-static char *print_remote (GnomePilotRecord *remote)
-{
- static char buff[ 4096 ];
- struct Appointment appt;
-
- if (remote == NULL) {
- sprintf (buff, "[NULL]");
- return buff;
- }
-
- memset (&appt, 0, sizeof (struct Appointment));
- unpack_Appointment (&appt, remote->record, remote->length);
-
- g_snprintf (buff, 4096, "[%ld %ld '%s' '%s']",
- mktime (&appt.begin),
- mktime (&appt.end),
- appt.description ?
- appt.description : "",
- appt.note ?
- appt.note : "");
-
- free_Appointment (&appt);
-
- return buff;
-}
-
-/* Calendar Server routines */
-static void
-start_calendar_server_cb (CalClient *cal_client,
- CalClientOpenStatus status,
- gpointer data)
-{
- gboolean *success = data;
-
- if (status == CAL_CLIENT_OPEN_SUCCESS) {
- *success = TRUE;
- } else {
- *success = FALSE;
- WARN ("Failed to open calendar!\n");
- }
-
- gtk_main_quit (); /* end the sub event loop */
-}
-
-static int
-start_calendar_server (ECalConduitContext *ctxt)
-{
- gboolean success = FALSE;
-
- g_return_val_if_fail (ctxt != NULL, -2);
-
- ctxt->client = cal_client_new ();
-
- gtk_signal_connect (GTK_OBJECT (ctxt->client), "cal_opened",
- start_calendar_server_cb, &success);
-
- if (!cal_client_open_default_calendar (ctxt->client, FALSE))
- return -1;
-
- /* run a sub event loop to turn cal-client's async load
- notification into a synchronous call */
- gtk_main ();
-
- if (success)
- return 0;
-
- return -1;
-}
-
-/* Utility routines */
-static icaltimezone *
-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);
-
- return timezone;
-}
-
-static icaltimezone *
-get_default_timezone (void)
-{
- Bonobo_ConfigDatabase db;
- icaltimezone *timezone = NULL;
- char *location;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev);
-
- if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) {
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- CORBA_exception_free (&ev);
-
- location = bonobo_config_get_string_with_default (db,
- "/Calendar/Display/Timezone", "UTC", NULL);
- if (!location || !location[0]) {
- g_free (location);
- location = g_strdup ("UTC");
- }
-
- timezone = icaltimezone_get_builtin_timezone (location);
- g_free (location);
-
- bonobo_object_release_unref (db, NULL);
-
- return timezone;
-}
-
-
-static char *
-map_name (ECalConduitContext *ctxt)
-{
- char *filename;
-
- filename = g_strdup_printf ("%s/evolution/local/Calendar/pilot-map-calendar-%d.xml", g_get_home_dir (), ctxt->cfg->pilot_id);
-
- return filename;
-}
-
-static icalrecurrencetype_weekday
-get_ical_day (int day)
-{
- switch (day) {
- case 0:
- return ICAL_SUNDAY_WEEKDAY;
- case 1:
- return ICAL_MONDAY_WEEKDAY;
- case 2:
- return ICAL_TUESDAY_WEEKDAY;
- case 3:
- return ICAL_WEDNESDAY_WEEKDAY;
- case 4:
- return ICAL_THURSDAY_WEEKDAY;
- case 5:
- return ICAL_FRIDAY_WEEKDAY;
- case 6:
- return ICAL_SATURDAY_WEEKDAY;
- }
-
- return ICAL_NO_WEEKDAY;
-}
-
-static int
-get_pilot_day (icalrecurrencetype_weekday wd)
-{
- switch (wd) {
- case ICAL_SUNDAY_WEEKDAY:
- return 0;
- case ICAL_MONDAY_WEEKDAY:
- return 1;
- case ICAL_TUESDAY_WEEKDAY:
- return 2;
- case ICAL_WEDNESDAY_WEEKDAY:
- return 3;
- case ICAL_THURSDAY_WEEKDAY:
- return 4;
- case ICAL_FRIDAY_WEEKDAY:
- return 5;
- case ICAL_SATURDAY_WEEKDAY:
- return 6;
- default:
- return -1;
- }
-}
-
-static gboolean
-is_empty_time (struct tm time)
-{
- if (time.tm_sec || time.tm_min || time.tm_hour
- || time.tm_mday || time.tm_mon || time.tm_year)
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-is_all_day (CalClient *client, CalComponentDateTime *dt_start, CalComponentDateTime *dt_end)
-{
- time_t dt_start_time, dt_end_time;
- icaltimezone *timezone;
-
- if (dt_start->value->is_date && dt_end->value->is_date)
- return TRUE;
-
- timezone = get_timezone (client, dt_start->tzid);
- dt_start_time = icaltime_as_timet_with_zone (*dt_start->value, timezone);
- dt_end_time = icaltime_as_timet_with_zone (*dt_end->value, get_timezone (client, dt_end->tzid));
-
- if (dt_end_time == time_add_day_with_zone (dt_start_time, 1, timezone))
- return TRUE;
-
- return FALSE;
-}
-
-static gboolean
-process_multi_day (ECalConduitContext *ctxt, CalClientChange *ccc, GList **multi_uid, GList **multi_ccc)
-{
- CalComponentDateTime dt_start, dt_end;
- icaltimezone *tz_start, *tz_end;
- time_t event_start, event_end, day_end;
- struct icaltimetype *old_start_value, *old_end_value;
- const char *uid;
- gboolean is_date = FALSE;
- gboolean last = FALSE;
- gboolean ret = TRUE;
-
- *multi_ccc = NULL;
- *multi_uid = NULL;
-
- if (ccc->type == CAL_CLIENT_CHANGE_DELETED)
- return FALSE;
-
- /* Start time */
- cal_component_get_dtstart (ccc->comp, &dt_start);
- if (dt_start.value->is_date)
- tz_start = ctxt->timezone;
- else
- tz_start = get_timezone (ctxt->client, dt_start.tzid);
- event_start = icaltime_as_timet_with_zone (*dt_start.value, tz_start);
-
- cal_component_get_dtend (ccc->comp, &dt_end);
- if (dt_end.value->is_date)
- tz_end = ctxt->timezone;
- else
- tz_end = get_timezone (ctxt->client, dt_end.tzid);
- event_end = icaltime_as_timet_with_zone (*dt_end.value, tz_end);
-
- day_end = time_day_end_with_zone (event_start, ctxt->timezone);
- if (day_end >= event_end) {
- ret = FALSE;
- goto cleanup;
- } else if (cal_component_has_recurrences (ccc->comp) || !ctxt->cfg->multi_day_split) {
- ret = TRUE;
- goto cleanup;
- }
-
- if (dt_start.value->is_date && dt_end.value->is_date)
- is_date = TRUE;
-
- old_start_value = dt_start.value;
- old_end_value = dt_end.value;
- while (!last) {
- CalComponent *clone = cal_component_clone (ccc->comp);
- char *new_uid = cal_component_gen_uid ();
- struct icaltimetype start_value, end_value;
- CalClientChange *c = g_new0 (CalClientChange, 1);
-
- if (day_end >= event_end) {
- day_end = event_end;
- last = TRUE;
- }
-
- cal_component_set_uid (clone, new_uid);
-
- start_value = icaltime_from_timet_with_zone (event_start, is_date, tz_start);
- dt_start.value = &start_value;
- cal_component_set_dtstart (clone, &dt_start);
-
- end_value = icaltime_from_timet_with_zone (day_end, is_date, tz_end);
- dt_end.value = &end_value;
- cal_component_set_dtend (clone, &dt_end);
-
- cal_client_update_object (ctxt->client, clone);
-
- 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);
-
- event_start = day_end;
- day_end = time_day_end_with_zone (event_start, ctxt->timezone);
- }
- dt_start.value = old_start_value;
- dt_end.value = old_end_value;
-
- cal_component_get_uid (ccc->comp, &uid);
- cal_client_remove_object (ctxt->client, uid);
- ccc->type = CAL_CLIENT_CHANGE_DELETED;
-
- cleanup:
- cal_component_free_datetime (&dt_start);
- cal_component_free_datetime (&dt_end);
-
- return ret;
-}
-
-static short
-nth_weekday (int pos, icalrecurrencetype_weekday weekday)
-{
- g_assert ((pos > 0 && pos <= 5) || (pos == -1));
-
- return ((abs (pos) * 8) + weekday) * (pos < 0 ? -1 : 1);
-}
-
-static GList *
-next_changed_item (ECalConduitContext *ctxt, GList *changes)
-{
- CalClientChange *ccc;
- GList *l;
-
- for (l = changes; l != NULL; l = l->next) {
- const char *uid;
-
- ccc = l->data;
-
- cal_component_get_uid (ccc->comp, &uid);
- if (g_hash_table_lookup (ctxt->changed_hash, uid))
- return l;
- }
-
- return NULL;
-}
-
-static void
-compute_status (ECalConduitContext *ctxt, ECalLocalRecord *local, const char *uid)
-{
- CalClientChange *ccc;
-
- local->local.archived = FALSE;
- local->local.secret = FALSE;
-
- ccc = g_hash_table_lookup (ctxt->changed_hash, uid);
-
- if (ccc == NULL) {
- local->local.attr = GnomePilotRecordNothing;
- return;
- }
-
- switch (ccc->type) {
- case CAL_CLIENT_CHANGE_ADDED:
- local->local.attr = GnomePilotRecordNew;
- break;
-
- case CAL_CLIENT_CHANGE_MODIFIED:
- local->local.attr = GnomePilotRecordModified;
- break;
-
- case CAL_CLIENT_CHANGE_DELETED:
- local->local.attr = GnomePilotRecordDeleted;
- break;
- }
-}
-
-static GnomePilotRecord
-local_record_to_pilot_record (ECalLocalRecord *local,
- ECalConduitContext *ctxt)
-{
- GnomePilotRecord p;
- static char record[0xffff];
-
- g_assert (local->comp != NULL);
- g_assert (local->appt != NULL );
-
- p.ID = local->local.ID;
- p.category = local->local.category;
- p.attr = local->local.attr;
- p.archived = local->local.archived;
- p.secret = local->local.secret;
-
- /* Generate pilot record structure */
- p.record = record;
- p.length = pack_Appointment (local->appt, p.record, 0xffff);
-
- return p;
-}
-
-/*
- * converts a CalComponent object to a ECalLocalRecord
- */
-static void
-local_record_from_comp (ECalLocalRecord *local, CalComponent *comp, ECalConduitContext *ctxt)
-{
- const char *uid;
- CalComponentText summary;
- GSList *d_list = NULL, *edl = NULL, *l;
- CalComponentText *description;
- CalComponentDateTime dt_start, dt_end;
- CalComponentClassification classif;
- icaltimezone *default_tz = ctxt->timezone;
- int i;
-
- g_return_if_fail (local != NULL);
- g_return_if_fail (comp != NULL);
-
- local->comp = comp;
- gtk_object_ref (GTK_OBJECT (comp));
-
- cal_component_get_uid (local->comp, &uid);
- local->local.ID = e_pilot_map_lookup_pid (ctxt->map, uid, TRUE);
- compute_status (ctxt, local, uid);
-
- local->appt = g_new0 (struct Appointment, 1);
-
- /* Handle the fields and category we don't sync by making sure
- * we don't overwrite them
- */
- if (local->local.ID != 0) {
- struct Appointment appt;
- char record[0xffff];
- int cat = 0;
-
- if (dlp_ReadRecordById (ctxt->dbi->pilot_socket,
- ctxt->dbi->db_handle,
- local->local.ID, &record,
- NULL, NULL, NULL, &cat) > 0) {
- local->local.category = cat;
- memset (&appt, 0, sizeof (struct Appointment));
- unpack_Appointment (&appt, record, 0xffff);
- local->appt->alarm = appt.alarm;
- local->appt->advance = appt.advance;
- local->appt->advanceUnits = appt.advanceUnits;
- free_Appointment (&appt);
- }
- }
-
- /* STOP: don't replace these with g_strdup, since free_Appointment
- uses free to deallocate */
- cal_component_get_summary (comp, &summary);
- if (summary.value)
- local->appt->description = e_pilot_utf8_to_pchar (summary.value);
-
- cal_component_get_description_list (comp, &d_list);
- if (d_list) {
- description = (CalComponentText *) d_list->data;
- if (description && description->value)
- local->appt->note = e_pilot_utf8_to_pchar (description->value);
- else
- local->appt->note = NULL;
- } else {
- local->appt->note = NULL;
- }
-
- /* Start/End */
- cal_component_get_dtstart (comp, &dt_start);
- cal_component_get_dtend (comp, &dt_end);
- if (dt_start.value) {
- icaltimezone_convert_time (dt_start.value,
- get_timezone (ctxt->client, dt_start.tzid),
- default_tz);
- local->appt->begin = icaltimetype_to_tm (dt_start.value);
- }
-
- if (dt_start.value && dt_end.value) {
- if (is_all_day (ctxt->client, &dt_start, &dt_end)) {
- local->appt->event = 1;
- } else {
- icaltimezone_convert_time (dt_end.value,
- get_timezone (ctxt->client, dt_end.tzid),
- default_tz);
- local->appt->end = icaltimetype_to_tm (dt_end.value);
- local->appt->event = 0;
- }
- } else {
- local->appt->event = 1;
- }
- cal_component_free_datetime (&dt_start);
- cal_component_free_datetime (&dt_end);
-
- /* Recurrence Rules */
- local->appt->repeatType = repeatNone;
-
- if (cal_component_has_rrules (comp)) {
- GSList *list;
- struct icalrecurrencetype *recur;
-
- cal_component_get_rrule_list (comp, &list);
- recur = list->data;
-
- switch (recur->freq) {
- case ICAL_DAILY_RECURRENCE:
- local->appt->repeatType = repeatDaily;
- break;
- case ICAL_WEEKLY_RECURRENCE:
- local->appt->repeatType = repeatWeekly;
- for (i = 0; i <= 7 && recur->by_day[i] != ICAL_RECURRENCE_ARRAY_MAX; i++) {
- icalrecurrencetype_weekday wd;
-
- wd = icalrecurrencetype_day_day_of_week (recur->by_day[i]);
- local->appt->repeatDays[get_pilot_day (wd)] = 1;
- }
-
- break;
- case ICAL_MONTHLY_RECURRENCE:
- if (recur->by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
- local->appt->repeatType = repeatMonthlyByDate;
- break;
- }
-
- /* FIX ME Not going to work with -ve by_day */
- local->appt->repeatType = repeatMonthlyByDay;
- switch (icalrecurrencetype_day_position (recur->by_day[0])) {
- case 1:
- local->appt->repeatDay = dom1stSun;
- break;
- case 2:
- local->appt->repeatDay = dom2ndSun;
- break;
- case 3:
- local->appt->repeatDay = dom3rdSun;
- break;
- case 4:
- local->appt->repeatDay = dom4thSun;
- break;
- case 5:
- local->appt->repeatDay = domLastSun;
- break;
- }
- local->appt->repeatDay += get_pilot_day (icalrecurrencetype_day_day_of_week (recur->by_day[0]));
- break;
- case ICAL_YEARLY_RECURRENCE:
- local->appt->repeatType = repeatYearly;
- break;
- default:
- break;
- }
-
- if (local->appt->repeatType != repeatNone) {
- local->appt->repeatFrequency = recur->interval;
- }
-
- if (icaltime_is_null_time (recur->until)) {
- local->appt->repeatForever = 1;
- } else {
- local->appt->repeatForever = 0;
- icaltimezone_convert_time (&recur->until,
- icaltimezone_get_utc_timezone (),
- default_tz);
- local->appt->repeatEnd = icaltimetype_to_tm (&recur->until);
- }
-
- cal_component_free_recur_list (list);
- }
-
- /* Exceptions */
- cal_component_get_exdate_list (comp, &edl);
- local->appt->exceptions = g_slist_length (edl);
- local->appt->exception = g_new0 (struct tm, local->appt->exceptions);
- for (l = edl, i = 0; l != NULL; l = l->next, i++) {
- CalComponentDateTime *dt = l->data;
-
- icaltimezone_convert_time (dt->value,
- icaltimezone_get_utc_timezone (),
- default_tz);
- *local->appt->exception = icaltimetype_to_tm (dt->value);
- }
- cal_component_free_exdate_list (edl);
-
- /* Alarm */
- local->appt->alarm = 0;
- if (cal_component_has_alarms (comp)) {
- GList *uids, *l;
- CalComponentAlarm *alarm;
- CalAlarmTrigger trigger;
-
- uids = cal_component_get_alarm_uids (comp);
- for (l = uids; l != NULL; l = l->next) {
- alarm = cal_component_get_alarm (comp, l->data);
- cal_component_alarm_get_trigger (alarm, &trigger);
-
- if ((trigger.type == CAL_ALARM_TRIGGER_RELATIVE_START
- && trigger.u.rel_duration.is_neg)) {
- local->appt->advanceUnits = advMinutes;
- local->appt->advance =
- trigger.u.rel_duration.minutes
- + trigger.u.rel_duration.hours * 60
- + trigger.u.rel_duration.days * 60 * 24
- + trigger.u.rel_duration.weeks * 7 * 60 * 24;
-
- if (local->appt->advance > PILOT_MAX_ADVANCE) {
- local->appt->advanceUnits = advHours;
- local->appt->advance =
- trigger.u.rel_duration.minutes / 60
- + trigger.u.rel_duration.hours
- + trigger.u.rel_duration.days * 24
- + trigger.u.rel_duration.weeks * 7 * 24;
- }
- if (local->appt->advance > PILOT_MAX_ADVANCE) {
- local->appt->advanceUnits = advDays;
- local->appt->advance =
- trigger.u.rel_duration.minutes / (60 * 24)
- + trigger.u.rel_duration.hours / 24
- + trigger.u.rel_duration.days
- + trigger.u.rel_duration.weeks * 7;
- }
- if (local->appt->advance > PILOT_MAX_ADVANCE)
- local->appt->advance = PILOT_MAX_ADVANCE;
-
- local->appt->alarm = 1;
- break;
- }
- cal_component_alarm_free (alarm);
- }
- cal_obj_uid_list_free (uids);
- }
-
- cal_component_get_classification (comp, &classif);
-
- if (classif == CAL_COMPONENT_CLASS_PRIVATE)
- local->local.secret = 1;
- else
- local->local.secret = 0;
-
- local->local.archived = 0;
-}
-
-static void
-local_record_from_uid (ECalLocalRecord *local,
- const char *uid,
- ECalConduitContext *ctxt)
-{
- CalComponent *comp;
- CalClientGetStatus status;
-
- g_assert(local!=NULL);
-
- status = cal_client_get_object (ctxt->client, uid, &comp);
-
- if (status == CAL_CLIENT_GET_SUCCESS) {
- local_record_from_comp (local, comp, ctxt);
- gtk_object_unref (GTK_OBJECT (comp));
- } else if (status == CAL_CLIENT_GET_NOT_FOUND) {
- comp = cal_component_new ();
- cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT);
- cal_component_set_uid (comp, uid);
- local_record_from_comp (local, comp, ctxt);
- gtk_object_unref (GTK_OBJECT (comp));
- } else {
- INFO ("Object did not exist");
- }
-}
-
-static CalComponent *
-comp_from_remote_record (GnomePilotConduitSyncAbs *conduit,
- GnomePilotRecord *remote,
- CalComponent *in_comp,
- icaltimezone *timezone)
-{
- CalComponent *comp;
- struct Appointment appt;
- struct icaltimetype now = icaltime_from_timet_with_zone (time (NULL), FALSE, timezone), it;
- struct icalrecurrencetype recur;
- CalComponentText summary = {NULL, NULL};
- CalComponentDateTime dt = {NULL, NULL};
- GSList *edl = NULL;
- char *txt;
- int pos, i;
-
- g_return_val_if_fail (remote != NULL, NULL);
-
- memset (&appt, 0, sizeof (struct Appointment));
- unpack_Appointment (&appt, remote->record, remote->length);
-
- if (in_comp == NULL) {
- comp = cal_component_new ();
- cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT);
- cal_component_set_created (comp, &now);
- } else {
- comp = cal_component_clone (in_comp);
- }
-
- cal_component_set_last_modified (comp, &now);
-
- summary.value = txt = e_pilot_utf8_from_pchar (appt.description);
- cal_component_set_summary (comp, &summary);
- free (txt);
-
- /* The iCal description field */
- if (!appt.note) {
- cal_component_set_description_list (comp, NULL);
- } else {
- GSList l;
- CalComponentText text;
-
- text.value = txt = e_pilot_utf8_from_pchar (appt.note);
- text.altrep = NULL;
- l.data = &text;
- l.next = NULL;
-
- cal_component_set_description_list (comp, &l);
- free (txt);
- }
-
- if (appt.event && !is_empty_time (appt.begin)) {
- it = tm_to_icaltimetype (&appt.begin, TRUE);
- dt.value = &it;
- dt.tzid = NULL;
- cal_component_set_dtstart (comp, &dt);
- cal_component_set_dtend (comp, &dt);
- } else {
- dt.tzid = icaltimezone_get_tzid (timezone);
-
- if (!is_empty_time (appt.begin)) {
- it = tm_to_icaltimetype (&appt.begin, FALSE);
- dt.value = &it;
- cal_component_set_dtstart (comp, &dt);
- }
-
- if (!is_empty_time (appt.end)) {
- it = tm_to_icaltimetype (&appt.end, FALSE);
- dt.value = &it;
- cal_component_set_dtend (comp, &dt);
- }
- }
-
- /* Recurrence information */
- icalrecurrencetype_clear (&recur);
-
- switch (appt.repeatType) {
- case repeatNone:
- recur.freq = ICAL_NO_RECURRENCE;
- break;
-
- case repeatDaily:
- recur.freq = ICAL_DAILY_RECURRENCE;
- recur.interval = appt.repeatFrequency;
- break;
-
- case repeatWeekly:
- recur.freq = ICAL_WEEKLY_RECURRENCE;
- recur.interval = appt.repeatFrequency;
-
- pos = 0;
- for (i = 0; i < 7; i++) {
- if (appt.repeatDays[i])
- recur.by_day[pos++] = get_ical_day (i);
- }
-
- break;
-
- case repeatMonthlyByDay:
- recur.freq = ICAL_MONTHLY_RECURRENCE;
- recur.interval = appt.repeatFrequency;
- if (appt.repeatDay < domLastSun)
- recur.by_day[0] = nth_weekday ((appt.repeatDay / 7) + 1,
- get_ical_day (appt.repeatDay % 7));
- else
- recur.by_day[0] = nth_weekday (-1, get_ical_day (appt.repeatDay % 7));
- break;
-
- case repeatMonthlyByDate:
- recur.freq = ICAL_MONTHLY_RECURRENCE;
- recur.interval = appt.repeatFrequency;
- recur.by_month_day[0] = appt.begin.tm_mday;
- break;
-
- case repeatYearly:
- recur.freq = ICAL_YEARLY_RECURRENCE;
- recur.interval = appt.repeatFrequency;
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- if (recur.freq != ICAL_NO_RECURRENCE) {
- GSList *list = NULL;
-
- /* recurrence start of week */
- recur.week_start = get_ical_day (appt.repeatWeekstart);
-
- if (!appt.repeatForever) {
- recur.until = tm_to_icaltimetype (&appt.repeatEnd, TRUE);
- }
-
- list = g_slist_append (list, &recur);
- cal_component_set_rrule_list (comp, list);
- g_slist_free (list);
- } else {
- cal_component_set_rrule_list (comp, NULL);
- }
-
- /* Exceptions */
- for (i = 0; i < appt.exceptions; i++) {
- struct tm ex;
- CalComponentDateTime *dt = g_new0 (CalComponentDateTime, 1);
-
- dt->value = g_new0 (struct icaltimetype, 1);
- dt->tzid = NULL;
-
- ex = appt.exception[i];
- *dt->value = tm_to_icaltimetype (&ex, TRUE);
-
- edl = g_slist_prepend (edl, dt);
- }
- cal_component_set_exdate_list (comp, edl);
- cal_component_free_exdate_list (edl);
-
- /* Alarm */
- if (appt.alarm) {
- CalComponentAlarm *alarm = NULL;
- CalAlarmTrigger trigger;
- gboolean found = FALSE;
-
- if (cal_component_has_alarms (comp)) {
- GList *uids, *l;
-
- uids = cal_component_get_alarm_uids (comp);
- for (l = uids; l != NULL; l = l->next) {
- alarm = cal_component_get_alarm (comp, l->data);
- cal_component_alarm_get_trigger (alarm, &trigger);
- if ((trigger.type == CAL_ALARM_TRIGGER_RELATIVE_START
- && trigger.u.rel_duration.is_neg)) {
- found = TRUE;
- break;
- }
- cal_component_alarm_free (alarm);
- }
- cal_obj_uid_list_free (uids);
- }
- if (!found)
- alarm = cal_component_alarm_new ();
-
- memset (&trigger, 0, sizeof (CalAlarmTrigger));
- trigger.type = CAL_ALARM_TRIGGER_RELATIVE_START;
- trigger.u.rel_duration.is_neg = 1;
- switch (appt.advanceUnits) {
- case advMinutes:
- trigger.u.rel_duration.minutes = appt.advance;
- break;
- case advHours:
- trigger.u.rel_duration.hours = appt.advance;
- break;
- case advDays:
- trigger.u.rel_duration.days = appt.advance;
- break;
- }
- cal_component_alarm_set_trigger (alarm, trigger);
- cal_component_alarm_set_action (alarm, CAL_ALARM_DISPLAY);
-
- if (!found)
- cal_component_add_alarm (comp, alarm);
- cal_component_alarm_free (alarm);
- }
-
- cal_component_set_transparency (comp, CAL_COMPONENT_TRANSP_NONE);
-
- if (remote->attr & dlpRecAttrSecret)
- cal_component_set_classification (comp, CAL_COMPONENT_CLASS_PRIVATE);
- else
- cal_component_set_classification (comp, CAL_COMPONENT_CLASS_PUBLIC);
-
- cal_component_commit_sequence (comp);
-
- free_Appointment (&appt);
-
- return comp;
-}
-
-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);
- int map_count;
- const char *uri;
-
- /* If there are objects but no log */
- map_count = g_hash_table_size (ctxt->map->pid_map);
- if (map_count == 0)
- gnome_pilot_conduit_standard_set_slow (conduit, TRUE);
-
- /* Or if the URI's don't match */
- uri = cal_client_get_uri (ctxt->client);
- LOG(" Current URI %s (%s)\n", uri, ctxt->cfg->last_uri ? ctxt->cfg->last_uri : "<NONE>");
- if (ctxt->cfg->last_uri != NULL && strcmp (ctxt->cfg->last_uri, uri)) {
- gnome_pilot_conduit_standard_set_slow (conduit, TRUE);
- e_pilot_map_clear (ctxt->map);
- }
-
- if (gnome_pilot_conduit_standard_get_slow (conduit)) {
- ctxt->map->write_touched_only = TRUE;
- LOG (" doing slow sync\n");
- } else {
- LOG (" doing fast sync\n");
- }
-}
-
-/* Pilot syncing callbacks */
-static gint
-pre_sync (GnomePilotConduit *conduit,
- GnomePilotDBInfo *dbi,
- ECalConduitContext *ctxt)
-{
- GnomePilotConduitSyncAbs *abs_conduit;
- GList *removed = NULL, *added = NULL, *l;
- int len;
- unsigned char *buf;
- char *filename, *change_id;
- gint num_records, add_records = 0, mod_records = 0, del_records = 0;
-
- abs_conduit = GNOME_PILOT_CONDUIT_SYNC_ABS (conduit);
-
- LOG ("---------------------------------------------------------\n");
- LOG ("pre_sync: Calendar Conduit v.%s", CONDUIT_VERSION);
-
- ctxt->dbi = dbi;
- ctxt->client = NULL;
-
- if (start_calendar_server (ctxt) != 0) {
- WARN(_("Could not start wombat server"));
- gnome_pilot_conduit_error (conduit, _("Could not start wombat"));
- return -1;
- }
-
- /* Get the timezone */
- ctxt->timezone = get_default_timezone ();
- if (ctxt->timezone == NULL)
- return -1;
- LOG (" 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);
-
- /* 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);
-
- /* 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);
- 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;
-
- if (process_multi_day (ctxt, ccc, &multi_uid, &multi_ccc)) {
- ctxt->uids = g_list_concat (ctxt->uids, multi_uid);
-
- added = g_list_concat (added, multi_ccc);
- removed = g_list_prepend (removed, ccc);
- }
- }
-
- /* Remove the events that were split up */
- g_list_concat (ctxt->changed, added);
- for (l = removed; l != NULL; l = l->next) {
- CalClientChange *ccc = l->data;
- const char *uid;
-
- cal_component_get_uid (ccc->comp, &uid);
- if (e_pilot_map_lookup_pid (ctxt->map, uid, FALSE) == 0) {
- ctxt->changed = g_list_remove (ctxt->changed, ccc);
- gtk_object_unref (GTK_OBJECT (ccc->comp));
- g_free (ccc);
- }
- }
- g_list_free (removed);
-
- for (l = ctxt->changed; l != NULL; l = l->next) {
- CalClientChange *ccc = l->data;
- const char *uid;
-
- cal_component_get_uid (ccc->comp, &uid);
- if (!e_pilot_map_uid_is_archived (ctxt->map, uid)) {
-
- g_hash_table_insert (ctxt->changed_hash, g_strdup (uid), ccc);
-
- switch (ccc->type) {
- case CAL_CLIENT_CHANGE_ADDED:
- add_records++;
- break;
- case CAL_CLIENT_CHANGE_MODIFIED:
- mod_records++;
- break;
- case CAL_CLIENT_CHANGE_DELETED:
- del_records++;
- break;
- }
- } else if (ccc->type == CAL_CLIENT_CHANGE_DELETED) {
- e_pilot_map_remove_by_uid (ctxt->map, uid);
- }
- }
-
- /* Set the count information */
- num_records = cal_client_get_n_objects (ctxt->client, CALOBJ_TYPE_EVENT);
- 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);
- gnome_pilot_conduit_sync_abs_set_num_deleted_local_records(abs_conduit, del_records);
-
- buf = (unsigned char*)g_malloc (0xffff);
- len = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0,
- (unsigned char *)buf, 0xffff);
-
- if (len < 0) {
- WARN (_("Could not read pilot's Calendar application block"));
- WARN ("dlp_ReadAppBlock(...) = %d", len);
- gnome_pilot_conduit_error (conduit,
- _("Could not read pilot's Calendar application block"));
- return -1;
- }
- unpack_AppointmentAppInfo (&(ctxt->ai), buf, len);
- g_free (buf);
-
- check_for_slow_setting (conduit, ctxt);
- if (ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyToPilot
- || ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyFromPilot)
- ctxt->map->write_touched_only = TRUE;
-
- return 0;
-}
-
-static gint
-post_sync (GnomePilotConduit *conduit,
- GnomePilotDBInfo *dbi,
- ECalConduitContext *ctxt)
-{
- GList *changed;
- gchar *filename, *change_id;
-
- LOG ("post_sync: Calendar Conduit v.%s", CONDUIT_VERSION);
-
- g_free (ctxt->cfg->last_uri);
- ctxt->cfg->last_uri = g_strdup (cal_client_get_uri (ctxt->client));
- calconduit_save_configuration (ctxt->cfg);
-
- filename = map_name (ctxt);
- e_pilot_map_write (filename, ctxt->map);
- g_free (filename);
-
- /* FIX ME ugly hack - our changes musn't count, this does introduce
- * 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);
- g_free (change_id);
-
- LOG ("---------------------------------------------------------\n");
-
- return 0;
-}
-
-static gint
-set_pilot_id (GnomePilotConduitSyncAbs *conduit,
- ECalLocalRecord *local,
- guint32 ID,
- ECalConduitContext *ctxt)
-{
- const char *uid;
-
- LOG ("set_pilot_id: setting to %d\n", ID);
-
- cal_component_get_uid (local->comp, &uid);
- e_pilot_map_insert (ctxt->map, ID, uid, FALSE);
-
- return 0;
-}
-
-static gint
-set_status_cleared (GnomePilotConduitSyncAbs *conduit,
- ECalLocalRecord *local,
- ECalConduitContext *ctxt)
-{
- const char *uid;
-
- LOG ("set_status_cleared: clearing status\n");
-
- cal_component_get_uid (local->comp, &uid);
- g_hash_table_remove (ctxt->changed_hash, uid);
-
- return 0;
-}
-
-static gint
-for_each (GnomePilotConduitSyncAbs *conduit,
- ECalLocalRecord **local,
- ECalConduitContext *ctxt)
-{
- static GList *uids, *iterator;
- static int count;
-
- g_return_val_if_fail (local != NULL, -1);
-
- if (*local == NULL) {
- LOG ("beginning for_each");
-
- uids = ctxt->uids;
- count = 0;
-
- if (uids != NULL) {
- LOG ("iterating over %d records", g_list_length (uids));
-
- *local = g_new0 (ECalLocalRecord, 1);
- local_record_from_uid (*local, uids->data, ctxt);
- g_list_prepend (ctxt->locals, *local);
-
- iterator = uids;
- } else {
- LOG ("no events");
- (*local) = NULL;
- return 0;
- }
- } else {
- count++;
- if (g_list_next (iterator)) {
- iterator = g_list_next (iterator);
-
- *local = g_new0 (ECalLocalRecord, 1);
- local_record_from_uid (*local, iterator->data, ctxt);
- g_list_prepend (ctxt->locals, *local);
- } else {
- LOG ("for_each ending");
-
- /* Tell the pilot the iteration is over */
- *local = NULL;
-
- return 0;
- }
- }
-
- return 0;
-}
-
-static gint
-for_each_modified (GnomePilotConduitSyncAbs *conduit,
- ECalLocalRecord **local,
- ECalConduitContext *ctxt)
-{
- static GList *iterator;
- static int count;
-
- g_return_val_if_fail (local != NULL, -1);
-
- if (*local == NULL) {
- LOG ("for_each_modified beginning\n");
-
- iterator = ctxt->changed;
-
- count = 0;
-
- LOG ("iterating over %d records", g_hash_table_size (ctxt->changed_hash));
-
- iterator = next_changed_item (ctxt, iterator);
- if (iterator != NULL) {
- CalClientChange *ccc = iterator->data;
-
- *local = g_new0 (ECalLocalRecord, 1);
- local_record_from_comp (*local, ccc->comp, ctxt);
- g_list_prepend (ctxt->locals, *local);
- } else {
- LOG ("no events");
-
- *local = NULL;
- }
- } else {
- count++;
- iterator = g_list_next (iterator);
- if (iterator && (iterator = next_changed_item (ctxt, iterator))) {
- CalClientChange *ccc = iterator->data;
-
- *local = g_new0 (ECalLocalRecord, 1);
- local_record_from_comp (*local, ccc->comp, ctxt);
- g_list_prepend (ctxt->locals, *local);
- } else {
- LOG ("for_each_modified ending");
-
- /* Signal the iteration is over */
- *local = NULL;
- }
- }
-
- return 0;
-}
-
-static gint
-compare (GnomePilotConduitSyncAbs *conduit,
- ECalLocalRecord *local,
- GnomePilotRecord *remote,
- ECalConduitContext *ctxt)
-{
- /* used by the quick compare */
- GnomePilotRecord local_pilot;
- int retval = 0;
-
- LOG ("compare: local=%s remote=%s...\n",
- print_local (local), print_remote (remote));
-
- g_return_val_if_fail (local!=NULL,-1);
- g_return_val_if_fail (remote!=NULL,-1);
-
- local_pilot = local_record_to_pilot_record (local, ctxt);
-
- if (remote->length != local_pilot.length
- || memcmp (local_pilot.record, remote->record, remote->length))
- retval = 1;
-
- if (retval == 0)
- LOG (" equal");
- else
- LOG (" not equal");
-
- return retval;
-}
-
-static gint
-add_record (GnomePilotConduitSyncAbs *conduit,
- GnomePilotRecord *remote,
- ECalConduitContext *ctxt)
-{
- CalComponent *comp;
- const char *uid;
- int retval = 0;
-
- g_return_val_if_fail (remote != NULL, -1);
-
- LOG ("add_record: adding %s to desktop\n", print_remote (remote));
-
- comp = comp_from_remote_record (conduit, remote, NULL, ctxt->timezone);
- update_comp (conduit, comp, ctxt);
-
- cal_component_get_uid (comp, &uid);
- e_pilot_map_insert (ctxt->map, remote->ID, uid, FALSE);
-
- gtk_object_unref (GTK_OBJECT (comp));
-
- return retval;
-}
-
-static gint
-replace_record (GnomePilotConduitSyncAbs *conduit,
- ECalLocalRecord *local,
- GnomePilotRecord *remote,
- ECalConduitContext *ctxt)
-{
- CalComponent *new_comp;
- int retval = 0;
-
- g_return_val_if_fail (remote != NULL, -1);
-
- LOG ("replace_record: replace %s with %s\n",
- print_local (local), print_remote (remote));
-
- new_comp = comp_from_remote_record (conduit, remote, local->comp, ctxt->timezone);
- gtk_object_unref (GTK_OBJECT (local->comp));
- local->comp = new_comp;
- update_comp (conduit, local->comp, ctxt);
-
- return retval;
-}
-
-static gint
-delete_record (GnomePilotConduitSyncAbs *conduit,
- ECalLocalRecord *local,
- ECalConduitContext *ctxt)
-{
- const char *uid;
-
- g_return_val_if_fail (local != NULL, -1);
- g_assert (local->comp != NULL);
-
- cal_component_get_uid (local->comp, &uid);
-
- LOG ("delete_record: deleting %s\n", uid);
-
- e_pilot_map_remove_by_uid (ctxt->map, uid);
- cal_client_remove_object (ctxt->client, uid);
-
- return 0;
-}
-
-static gint
-archive_record (GnomePilotConduitSyncAbs *conduit,
- ECalLocalRecord *local,
- gboolean archive,
- ECalConduitContext *ctxt)
-{
- const char *uid;
- int retval = 0;
-
- g_return_val_if_fail (local != NULL, -1);
-
- LOG ("archive_record: %s\n", archive ? "yes" : "no");
-
- cal_component_get_uid (local->comp, &uid);
- e_pilot_map_insert (ctxt->map, local->local.ID, uid, archive);
-
- return retval;
-}
-
-static gint
-match (GnomePilotConduitSyncAbs *conduit,
- GnomePilotRecord *remote,
- ECalLocalRecord **local,
- ECalConduitContext *ctxt)
-{
- const char *uid;
-
- LOG ("match: looking for local copy of %s\n",
- print_remote (remote));
-
- g_return_val_if_fail (local != NULL, -1);
- g_return_val_if_fail (remote != NULL, -1);
-
- *local = NULL;
- uid = e_pilot_map_lookup_uid (ctxt->map, remote->ID, TRUE);
-
- if (!uid)
- return 0;
-
- LOG (" matched\n");
-
- *local = g_new0 (ECalLocalRecord, 1);
- local_record_from_uid (*local, uid, ctxt);
-
- return 0;
-}
-
-static gint
-free_match (GnomePilotConduitSyncAbs *conduit,
- ECalLocalRecord *local,
- ECalConduitContext *ctxt)
-{
- LOG ("free_match: freeing\n");
-
- g_return_val_if_fail (local != NULL, -1);
-
- calconduit_destroy_record (local);
-
- return 0;
-}
-
-static gint
-prepare (GnomePilotConduitSyncAbs *conduit,
- ECalLocalRecord *local,
- GnomePilotRecord *remote,
- ECalConduitContext *ctxt)
-{
- LOG ("prepare: encoding local %s\n", print_local (local));
-
- *remote = local_record_to_pilot_record (local, ctxt);
-
- return 0;
-}
-
-/* Pilot Settings Callbacks */
-static void
-fill_widgets (ECalConduitContext *ctxt)
-{
- e_pilot_settings_set_secret (E_PILOT_SETTINGS (ctxt->ps),
- ctxt->cfg->secret);
-
- e_cal_gui_fill_widgets (ctxt->gui, ctxt->cfg);
-}
-
-static gint
-create_settings_window (GnomePilotConduit *conduit,
- GtkWidget *parent,
- ECalConduitContext *ctxt)
-{
- LOG ("create_settings_window");
-
- ctxt->ps = e_pilot_settings_new ();
- ctxt->gui = e_cal_gui_new (E_PILOT_SETTINGS (ctxt->ps));
-
- gtk_container_add (GTK_CONTAINER (parent), ctxt->ps);
- gtk_widget_show (ctxt->ps);
-
- fill_widgets (ctxt);
-
- return 0;
-}
-static void
-display_settings (GnomePilotConduit *conduit, ECalConduitContext *ctxt)
-{
- LOG ("display_settings");
-
- fill_widgets (ctxt);
-}
-
-static void
-save_settings (GnomePilotConduit *conduit, ECalConduitContext *ctxt)
-{
- LOG ("save_settings");
-
- ctxt->new_cfg->secret =
- e_pilot_settings_get_secret (E_PILOT_SETTINGS (ctxt->ps));
- e_cal_gui_fill_config (ctxt->gui, ctxt->new_cfg);
-
- calconduit_save_configuration (ctxt->new_cfg);
-}
-
-static void
-revert_settings (GnomePilotConduit *conduit, ECalConduitContext *ctxt)
-{
- LOG ("revert_settings");
-
- calconduit_save_configuration (ctxt->cfg);
- calconduit_destroy_configuration (ctxt->new_cfg);
- ctxt->new_cfg = calconduit_dupe_configuration (ctxt->cfg);
-}
-
-static ORBit_MessageValidationResult
-accept_all_cookies (CORBA_unsigned_long request_id,
- CORBA_Principal *principal,
- CORBA_char *operation)
-{
- /* allow ALL cookies */
- return ORBIT_MESSAGE_ALLOW_ALL;
-}
-
-
-GnomePilotConduit *
-conduit_get_gpilot_conduit (guint32 pilot_id)
-{
- GtkObject *retval;
- ECalConduitContext *ctxt;
-
- LOG ("in calendar's conduit_get_gpilot_conduit\n");
-
- /* we need to find wombat with oaf, so make sure oaf
- is initialized here. once the desktop is converted
- to oaf and gpilotd is built with oaf, this can go away */
- if (!oaf_is_initialized ()) {
- char *argv[ 1 ] = {"hi"};
- oaf_init (1, argv);
-
- if (bonobo_init (CORBA_OBJECT_NIL,
- CORBA_OBJECT_NIL,
- CORBA_OBJECT_NIL) == FALSE)
- g_error (_("Could not initialize Bonobo"));
-
- ORBit_set_request_validation_handler (accept_all_cookies);
- }
-
- retval = gnome_pilot_conduit_sync_abs_new ("DatebookDB", 0x64617465);
- g_assert (retval != NULL);
-
- ctxt = e_calendar_context_new (pilot_id);
- gtk_object_set_data (GTK_OBJECT (retval), "calconduit_context", ctxt);
-
- /* Sync signals */
- gtk_signal_connect (retval, "pre_sync", (GtkSignalFunc) pre_sync, ctxt);
- gtk_signal_connect (retval, "post_sync", (GtkSignalFunc) post_sync, ctxt);
-
- gtk_signal_connect (retval, "set_pilot_id", (GtkSignalFunc) set_pilot_id, ctxt);
- gtk_signal_connect (retval, "set_status_cleared", (GtkSignalFunc) set_status_cleared, ctxt);
-
- gtk_signal_connect (retval, "for_each", (GtkSignalFunc) for_each, ctxt);
- gtk_signal_connect (retval, "for_each_modified", (GtkSignalFunc) for_each_modified, ctxt);
- gtk_signal_connect (retval, "compare", (GtkSignalFunc) compare, ctxt);
-
- gtk_signal_connect (retval, "add_record", (GtkSignalFunc) add_record, ctxt);
- gtk_signal_connect (retval, "replace_record", (GtkSignalFunc) replace_record, ctxt);
- gtk_signal_connect (retval, "delete_record", (GtkSignalFunc) delete_record, ctxt);
- gtk_signal_connect (retval, "archive_record", (GtkSignalFunc) archive_record, ctxt);
-
- gtk_signal_connect (retval, "match", (GtkSignalFunc) match, ctxt);
- gtk_signal_connect (retval, "free_match", (GtkSignalFunc) free_match, ctxt);
-
- gtk_signal_connect (retval, "prepare", (GtkSignalFunc) prepare, ctxt);
-
- /* Gui Settings */
- gtk_signal_connect (retval, "create_settings_window", (GtkSignalFunc) create_settings_window, ctxt);
- gtk_signal_connect (retval, "display_settings", (GtkSignalFunc) display_settings, ctxt);
- gtk_signal_connect (retval, "save_settings", (GtkSignalFunc) save_settings, ctxt);
- gtk_signal_connect (retval, "revert_settings", (GtkSignalFunc) revert_settings, ctxt);
-
- return GNOME_PILOT_CONDUIT (retval);
-}
-
-void
-conduit_destroy_gpilot_conduit (GnomePilotConduit *conduit)
-{
- GtkObject *obj = GTK_OBJECT (conduit);
- ECalConduitContext *ctxt;
-
- ctxt = gtk_object_get_data (obj, "calconduit_context");
- e_calendar_context_destroy (ctxt);
-
- gtk_object_destroy (obj);
-}
diff --git a/calendar/conduits/calendar/e-calendar.conduit.in b/calendar/conduits/calendar/e-calendar.conduit.in
deleted file mode 100644
index e75d889234..0000000000
--- a/calendar/conduits/calendar/e-calendar.conduit.in
+++ /dev/null
@@ -1,9 +0,0 @@
-<gnome-pilot-conduit version="1.0">
- <conduit id="e_calendar_conduit" type="shlib" location="@prefix@/lib/gnome-pilot/conduits/libecalendar_conduit.so"/>
- <name value="ECalendar"/>
- <conduit-attribute name="description" value="Synchronizes Calendar with Evolution"/>
- <conduit-attribute name="default-synctype" value="synchronize"/>
- <conduit-attribute name="valid-synctypes" value="synchronize copy_from_pilot copy_to_pilot"/>
- <conduit-attribute name="settings" value="TRUE"/>
- <conduit-attribute name="icon" value="@datadir@/images/evolution/conduits/48_evo-calendar-conduit.png"/>
-</gnome-pilot-conduit>
diff --git a/calendar/conduits/todo/.cvsignore b/calendar/conduits/todo/.cvsignore
deleted file mode 100644
index 3ee063c770..0000000000
--- a/calendar/conduits/todo/.cvsignore
+++ /dev/null
@@ -1,9 +0,0 @@
-Makefile.in
-Makefile
-.deps
-.libs
-*.lo
-*.la
-e-todo-conduit-control-applet
-e-todo-conduit-control-applet.desktop
-e-todo.conduit
diff --git a/calendar/conduits/todo/Makefile.am b/calendar/conduits/todo/Makefile.am
deleted file mode 100644
index 7c0822debc..0000000000
--- a/calendar/conduits/todo/Makefile.am
+++ /dev/null
@@ -1,42 +0,0 @@
-INCLUDES = \
- -I$(top_srcdir) \
- -I$(top_srcdir)/calendar \
- -I$(top_builddir)/calendar/cal-client \
- -I$(top_srcdir)/libical/src/libical \
- -I$(top_builddir)/libical/src/libical \
- -I$(top_srcdir)/e-util \
- -I$(top_builddir)/e-util \
- $(EVOLUTION_CALENDAR_CONDUIT_CFLAGS)
-
-# ToDo Conduit
-e_todo_conduitsdir=$(libdir)/gnome-pilot/conduits
-e_todo_conduits_LTLIBRARIES = libetodo_conduit.la
-
-libetodo_conduit_la_SOURCES = \
- todo-conduit.c
-
-libetodo_conduit_la_LDFLAGS = -module -avoid-version
-libetodo_conduit_la_LIBADD = \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/calendar/cal-client/libcal-client-static.la \
- $(top_builddir)/calendar/cal-util/libcal-util-static.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/libical/src/libical/libical-static.la \
- $(top_builddir)/libwombat/libwombat-static.la \
- $(top_builddir)/e-util/libeconduit-static.la \
- $(EVOLUTION_CALENDAR_CONDUIT_LIBS)
-
-e-todo.conduit: e-todo.conduit.in Makefile
- sed -e 's^\@prefix\@^$(prefix)^g' \
- -e 's^\@datadir\@^$(datadir)^g' \
- < $(srcdir)/e-todo.conduit.in > e-todo.conduit.tmp \
- && mv e-todo.conduit.tmp e-todo.conduit
-
-Conduitdir = $(datadir)/gnome-pilot/conduits/
-Conduit_DATA = e-todo.conduit
-
-EXTRA_DIST = \
- e-todo.conduit.in
-
-install-data-local:
- $(mkinstalldirs) $(Conduitdir)
diff --git a/calendar/conduits/todo/e-todo.conduit.in b/calendar/conduits/todo/e-todo.conduit.in
deleted file mode 100644
index a7bea27a8f..0000000000
--- a/calendar/conduits/todo/e-todo.conduit.in
+++ /dev/null
@@ -1,9 +0,0 @@
-<gnome-pilot-conduit version="1.0">
- <conduit id="e_todo_conduit" type="shlib" location="@prefix@/lib/gnome-pilot/conduits/libetodo_conduit.so"/>
- <name value="EToDo"/>
- <conduit-attribute name="description" value="Synchronizes ToDo List with Evolution"/>
- <conduit-attribute name="default-synctype" value="synchronize"/>
- <conduit-attribute name="valid-synctypes" value="synchronize copy_from_pilot copy_to_pilot"/>
- <conduit-attribute name="settings" value="TRUE"/>
- <conduit-attribute name="icon" value="@datadir@/images/evolution/conduits/48_evo-todo-conduit.png"/>
-</gnome-pilot-conduit>
diff --git a/calendar/conduits/todo/todo-conduit.c b/calendar/conduits/todo/todo-conduit.c
deleted file mode 100644
index 42c8b3c865..0000000000
--- a/calendar/conduits/todo/todo-conduit.c
+++ /dev/null
@@ -1,1435 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Evolution calendar - ToDo Conduit
- *
- * Copyright (C) 1998 Free Software Foundation
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Eskil Heyn Olsen <deity@eskil.dk>
- * JP Rosevear <jpr@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 <liboaf/liboaf.h>
-#include <bonobo.h>
-#include <bonobo-conf/bonobo-config-database.h>
-#include <cal-client/cal-client-types.h>
-#include <cal-client/cal-client.h>
-#include <cal-util/timeutil.h>
-#include <pi-source.h>
-#include <pi-socket.h>
-#include <pi-dlp.h>
-#include <pi-todo.h>
-#include <libical/src/libical/icaltypes.h>
-#include <gpilotd/gnome-pilot-conduit.h>
-#include <gpilotd/gnome-pilot-conduit-sync-abs.h>
-#include <libgpilotdCM/gnome-pilot-conduit-management.h>
-#include <libgpilotdCM/gnome-pilot-conduit-config.h>
-#include <e-pilot-map.h>
-#include <e-pilot-settings.h>
-#include <e-pilot-util.h>
-
-GnomePilotConduit * conduit_get_gpilot_conduit (guint32);
-void conduit_destroy_gpilot_conduit (GnomePilotConduit*);
-
-#define CONDUIT_VERSION "0.1.4"
-#ifdef G_LOG_DOMAIN
-#undef G_LOG_DOMAIN
-#endif
-#define G_LOG_DOMAIN "etodoconduit"
-
-#define DEBUG_TODOCONDUIT 1
-/* #undef DEBUG_TODOCONDUIT */
-
-#ifdef DEBUG_TODOCONDUIT
-#define LOG(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, e)
-#else
-#define LOG(e...)
-#endif
-
-#define WARN(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, e)
-#define INFO(e...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, e)
-
-typedef struct _EToDoLocalRecord EToDoLocalRecord;
-typedef struct _EToDoConduitCfg EToDoConduitCfg;
-typedef struct _EToDoConduitGui EToDoConduitGui;
-typedef struct _EToDoConduitContext EToDoConduitContext;
-
-/* Local Record */
-struct _EToDoLocalRecord {
- /* The stuff from gnome-pilot-conduit-standard-abs.h
- Must be first in the structure, or instances of this
- structure cannot be used by gnome-pilot-conduit-standard-abs.
- */
- GnomePilotDesktopRecord local;
-
- /* The corresponding Comp object */
- CalComponent *comp;
-
- /* pilot-link todo structure */
- struct ToDo *todo;
-};
-
-static void
-todoconduit_destroy_record (EToDoLocalRecord *local)
-{
- gtk_object_unref (GTK_OBJECT (local->comp));
- free_ToDo (local->todo);
- g_free (local->todo);
- g_free (local);
-}
-
-/* Configuration */
-struct _EToDoConduitCfg {
- guint32 pilot_id;
- GnomePilotConduitSyncType sync_type;
-
- gboolean secret;
- gint priority;
-
- gchar *last_uri;
-};
-
-static EToDoConduitCfg *
-todoconduit_load_configuration (guint32 pilot_id)
-{
- EToDoConduitCfg *c;
- GnomePilotConduitManagement *management;
- GnomePilotConduitConfig *config;
- gchar prefix[256];
- g_snprintf (prefix, 255, "/gnome-pilot.d/e-todo-conduit/Pilot_%u/",
- pilot_id);
-
- c = g_new0 (EToDoConduitCfg,1);
- g_assert (c != NULL);
-
- c->pilot_id = pilot_id;
-
- management = gnome_pilot_conduit_management_new ("e_todo_conduit", GNOME_PILOT_CONDUIT_MGMT_ID);
- config = gnome_pilot_conduit_config_new (management, pilot_id);
- if (!gnome_pilot_conduit_config_is_enabled (config, &c->sync_type))
- c->sync_type = GnomePilotConduitSyncTypeNotSet;
- gtk_object_unref (GTK_OBJECT (config));
- gtk_object_unref (GTK_OBJECT (management));
-
- /* Custom settings */
- gnome_config_push_prefix (prefix);
-
- c->secret = gnome_config_get_bool ("secret=FALSE");
- c->priority = gnome_config_get_int ("priority=3");
- c->last_uri = gnome_config_get_string ("last_uri");
-
- gnome_config_pop_prefix ();
-
- return c;
-}
-
-static void
-todoconduit_save_configuration (EToDoConduitCfg *c)
-{
- gchar prefix[256];
-
- g_snprintf (prefix, 255, "/gnome-pilot.d/e-todo-conduit/Pilot_%u/",
- c->pilot_id);
-
- gnome_config_push_prefix (prefix);
- gnome_config_set_bool ("secret", c->secret);
- gnome_config_set_int ("priority", c->priority);
- gnome_config_set_string ("last_uri", c->last_uri);
- gnome_config_pop_prefix ();
-
- gnome_config_sync ();
- gnome_config_drop_all ();
-}
-
-static EToDoConduitCfg*
-todoconduit_dupe_configuration (EToDoConduitCfg *c)
-{
- EToDoConduitCfg *retval;
-
- g_return_val_if_fail (c != NULL, NULL);
-
- retval = g_new0 (EToDoConduitCfg, 1);
- retval->sync_type = c->sync_type;
- retval->pilot_id = c->pilot_id;
-
- retval->secret = c->secret;
- retval->priority = c->priority;
- retval->last_uri = g_strdup (c->last_uri);
-
- return retval;
-}
-
-static void
-todoconduit_destroy_configuration (EToDoConduitCfg *c)
-{
- g_return_if_fail (c != NULL);
-
- g_free (c->last_uri);
- g_free (c);
-}
-
-/* Gui */
-struct _EToDoConduitGui {
- GtkWidget *priority;
-};
-
-static EToDoConduitGui *
-e_todo_gui_new (EPilotSettings *ps)
-{
- EToDoConduitGui *gui;
- GtkWidget *lbl;
- GtkObject *adj;
- gint rows;
-
- g_return_val_if_fail (ps != NULL, NULL);
- g_return_val_if_fail (E_IS_PILOT_SETTINGS (ps), NULL);
-
- gtk_table_resize (GTK_TABLE (ps), E_PILOT_SETTINGS_TABLE_ROWS + 1, E_PILOT_SETTINGS_TABLE_COLS);
-
- gui = g_new0 (EToDoConduitGui, 1);
-
- rows = E_PILOT_SETTINGS_TABLE_ROWS;
- lbl = gtk_label_new (_("Default Priority:"));
- gtk_misc_set_alignment (GTK_MISC (lbl), 0.0, 0.5);
- adj = gtk_adjustment_new (1, 1, 5, 1, 5, 5);
- gui->priority = gtk_spin_button_new (GTK_ADJUSTMENT (adj), 1.0, 0);
- gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (gui->priority), TRUE);
- gtk_table_attach_defaults (GTK_TABLE (ps), lbl, 0, 1, rows, rows + 1);
- gtk_table_attach_defaults (GTK_TABLE (ps), gui->priority, 1, 2, rows, rows + 1);
- gtk_widget_show (lbl);
- gtk_widget_show (gui->priority);
-
- return gui;
-}
-
-static void
-e_todo_gui_fill_widgets (EToDoConduitGui *gui, EToDoConduitCfg *cfg)
-{
- g_return_if_fail (gui != NULL);
- g_return_if_fail (cfg != NULL);
-
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (gui->priority), cfg->priority);
-}
-
-static void
-e_todo_gui_fill_config (EToDoConduitGui *gui, EToDoConduitCfg *cfg)
-{
- g_return_if_fail (gui != NULL);
- g_return_if_fail (cfg != NULL);
-
- cfg->priority = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (gui->priority));
-}
-
-static void
-e_todo_gui_destroy (EToDoConduitGui *gui)
-{
- g_free (gui);
-}
-
-/* Context */
-struct _EToDoConduitContext {
- GnomePilotDBInfo *dbi;
-
- EToDoConduitCfg *cfg;
- EToDoConduitCfg *new_cfg;
- EToDoConduitGui *gui;
- GtkWidget *ps;
-
- struct ToDoAppInfo ai;
-
- CalClient *client;
-
- icaltimezone *timezone;
- GList *uids;
- GList *changed;
- GHashTable *changed_hash;
- GList *locals;
-
- EPilotMap *map;
-};
-
-static EToDoConduitContext *
-e_todo_context_new (guint32 pilot_id)
-{
- EToDoConduitContext *ctxt = g_new0 (EToDoConduitContext, 1);
-
- ctxt->cfg = todoconduit_load_configuration (pilot_id);
- ctxt->new_cfg = todoconduit_dupe_configuration (ctxt->cfg);
- ctxt->gui = NULL;
- ctxt->ps = NULL;
- ctxt->client = NULL;
- ctxt->uids = NULL;
- ctxt->changed_hash = NULL;
- ctxt->changed = NULL;
- ctxt->locals = NULL;
- ctxt->map = NULL;
-
- return ctxt;
-}
-
-static gboolean
-e_todo_context_foreach_change (gpointer key, gpointer value, gpointer data)
-{
- g_free (key);
-
- return TRUE;
-}
-
-static void
-e_todo_context_destroy (EToDoConduitContext *ctxt)
-{
- GList *l;
-
- g_return_if_fail (ctxt != NULL);
-
- if (ctxt->cfg != NULL)
- todoconduit_destroy_configuration (ctxt->cfg);
- if (ctxt->new_cfg != NULL)
- todoconduit_destroy_configuration (ctxt->new_cfg);
- if (ctxt->gui != NULL)
- e_todo_gui_destroy (ctxt->gui);
-
- if (ctxt->client != NULL)
- gtk_object_unref (GTK_OBJECT (ctxt->client));
-
- if (ctxt->uids != NULL)
- cal_obj_uid_list_free (ctxt->uids);
-
- if (ctxt->changed_hash != NULL) {
- g_hash_table_foreach_remove (ctxt->changed_hash, e_todo_context_foreach_change, NULL);
- g_hash_table_destroy (ctxt->changed_hash);
- }
-
- if (ctxt->locals != NULL) {
- for (l = ctxt->locals; l != NULL; l = l->next)
- todoconduit_destroy_record (l->data);
- g_list_free (ctxt->locals);
- }
-
- if (ctxt->changed != NULL)
- cal_client_change_list_free (ctxt->changed);
-
- if (ctxt->map != NULL)
- e_pilot_map_destroy (ctxt->map);
-
- g_free (ctxt);
-}
-
-/* Debug routines */
-static char *
-print_local (EToDoLocalRecord *local)
-{
- static char buff[ 4096 ];
-
- if (local == NULL) {
- sprintf (buff, "[NULL]");
- return buff;
- }
-
- if (local->todo && local->todo->description) {
- g_snprintf (buff, 4096, "[%d %ld %d %d '%s' '%s']",
- local->todo->indefinite,
- mktime (& local->todo->due),
- local->todo->priority,
- local->todo->complete,
- local->todo->description ?
- local->todo->description : "",
- local->todo->note ?
- local->todo->note : "");
- return buff;
- }
-
- return "";
-}
-
-static char *print_remote (GnomePilotRecord *remote)
-{
- static char buff[ 4096 ];
- struct ToDo todo;
-
- if (remote == NULL) {
- sprintf (buff, "[NULL]");
- return buff;
- }
-
- memset (&todo, 0, sizeof (struct ToDo));
- unpack_ToDo (&todo, remote->record, remote->length);
-
- g_snprintf (buff, 4096, "[%d %ld %d %d '%s' '%s']",
- todo.indefinite,
- mktime (&todo.due),
- todo.priority,
- todo.complete,
- todo.description ?
- todo.description : "",
- todo.note ?
- todo.note : "");
-
- free_ToDo (&todo);
-
- return buff;
-}
-
-
-/* Calendar Server routines */
-static void
-start_calendar_server_cb (CalClient *cal_client,
- CalClientOpenStatus status,
- gpointer data)
-{
- gboolean *success = data;
-
- if (status == CAL_CLIENT_OPEN_SUCCESS) {
- *success = TRUE;
- } else {
- *success = FALSE;
- WARN ("Failed to open calendar!\n");
- }
-
- gtk_main_quit (); /* end the sub event loop */
-}
-
-static int
-start_calendar_server (EToDoConduitContext *ctxt)
-{
- gboolean success = FALSE;
-
- g_return_val_if_fail (ctxt != NULL, -2);
-
- ctxt->client = cal_client_new ();
-
- gtk_signal_connect (GTK_OBJECT (ctxt->client), "cal_opened",
- start_calendar_server_cb, &success);
-
- if (!cal_client_open_default_tasks (ctxt->client, FALSE))
- return -1;
-
- /* run a sub event loop to turn cal-client's async load
- notification into a synchronous call */
- gtk_main ();
-
- if (success)
- return 0;
-
- return -1;
-}
-
-/* Utility routines */
-static icaltimezone *
-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);
-
- return timezone;
-}
-
-static icaltimezone *
-get_default_timezone (void)
-{
- Bonobo_ConfigDatabase db;
- icaltimezone *timezone = NULL;
- char *location;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
-
- db = bonobo_get_object ("wombat:", "Bonobo/ConfigDatabase", &ev);
-
- if (BONOBO_EX (&ev) || db == CORBA_OBJECT_NIL) {
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- CORBA_exception_free (&ev);
-
- location = bonobo_config_get_string_with_default (db,
- "/Calendar/Display/Timezone", "UTC", NULL);
- if (!location || !location[0]) {
- g_free (location);
- location = g_strdup ("UTC");
- }
-
- timezone = icaltimezone_get_builtin_timezone (location);
- g_free (location);
-
- bonobo_object_release_unref (db, NULL);
-
- return timezone;
-}
-
-static char *
-map_name (EToDoConduitContext *ctxt)
-{
- char *filename;
-
- filename = g_strdup_printf ("%s/evolution/local/Tasks/pilot-map-todo-%d.xml", g_get_home_dir (), ctxt->cfg->pilot_id);
-
- return filename;
-}
-
-static gboolean
-is_empty_time (struct tm time)
-{
- if (time.tm_sec || time.tm_min || time.tm_hour
- || time.tm_mday || time.tm_mon || time.tm_year)
- return FALSE;
-
- return TRUE;
-}
-
-static GList *
-next_changed_item (EToDoConduitContext *ctxt, GList *changes)
-{
- CalClientChange *ccc;
- GList *l;
-
- for (l = changes; l != NULL; l = l->next) {
- const char *uid;
-
- ccc = l->data;
-
- cal_component_get_uid (ccc->comp, &uid);
- if (g_hash_table_lookup (ctxt->changed_hash, uid))
- return l;
- }
-
- return NULL;
-}
-
-static void
-compute_status (EToDoConduitContext *ctxt, EToDoLocalRecord *local, const char *uid)
-{
- CalClientChange *ccc;
-
- local->local.archived = FALSE;
- local->local.secret = FALSE;
-
- ccc = g_hash_table_lookup (ctxt->changed_hash, uid);
-
- if (ccc == NULL) {
- local->local.attr = GnomePilotRecordNothing;
- return;
- }
-
- switch (ccc->type) {
- case CAL_CLIENT_CHANGE_ADDED:
- local->local.attr = GnomePilotRecordNew;
- break;
- case CAL_CLIENT_CHANGE_MODIFIED:
- local->local.attr = GnomePilotRecordModified;
- break;
- case CAL_CLIENT_CHANGE_DELETED:
- local->local.attr = GnomePilotRecordDeleted;
- break;
- }
-}
-
-static GnomePilotRecord
-local_record_to_pilot_record (EToDoLocalRecord *local,
- EToDoConduitContext *ctxt)
-{
- GnomePilotRecord p;
- static char record[0xffff];
-
- g_assert (local->comp != NULL);
- g_assert (local->todo != NULL );
-
- LOG ("local_record_to_pilot_record\n");
-
- p.ID = local->local.ID;
- p.category = local->local.category;
- p.attr = local->local.attr;
- p.archived = local->local.archived;
- p.secret = local->local.secret;
-
- /* Generate pilot record structure */
- p.record = record;
- p.length = pack_ToDo (local->todo, p.record, 0xffff);
-
- return p;
-}
-
-/*
- * converts a CalComponent object to a EToDoLocalRecord
- */
-static void
-local_record_from_comp (EToDoLocalRecord *local, CalComponent *comp, EToDoConduitContext *ctxt)
-{
- const char *uid;
- int *priority;
- icalproperty_status status;
- CalComponentText summary;
- GSList *d_list = NULL;
- CalComponentText *description;
- CalComponentDateTime due;
- CalComponentClassification classif;
- icaltimezone *default_tz = get_default_timezone ();
-
- LOG ("local_record_from_comp\n");
-
- g_return_if_fail (local != NULL);
- g_return_if_fail (comp != NULL);
-
- local->comp = comp;
- gtk_object_ref (GTK_OBJECT (comp));
-
- cal_component_get_uid (local->comp, &uid);
- local->local.ID = e_pilot_map_lookup_pid (ctxt->map, uid, TRUE);
-
- compute_status (ctxt, local, uid);
-
- local->todo = g_new0 (struct ToDo,1);
-
- /* Don't overwrite the category */
- if (local->local.ID != 0) {
- char record[0xffff];
- int cat = 0;
-
- if (dlp_ReadRecordById (ctxt->dbi->pilot_socket,
- ctxt->dbi->db_handle,
- local->local.ID, &record,
- NULL, NULL, NULL, &cat) > 0) {
- local->local.category = cat;
- }
- }
-
- /* STOP: don't replace these with g_strdup, since free_ToDo
- uses free to deallocate */
- cal_component_get_summary (comp, &summary);
- if (summary.value)
- local->todo->description = e_pilot_utf8_to_pchar (summary.value);
-
- cal_component_get_description_list (comp, &d_list);
- if (d_list) {
- description = (CalComponentText *) d_list->data;
- if (description && description->value)
- local->todo->note = e_pilot_utf8_to_pchar (description->value);
- else
- local->todo->note = NULL;
- } else {
- local->todo->note = NULL;
- }
-
- cal_component_get_due (comp, &due);
- if (due.value) {
- icaltimezone_convert_time (due.value,
- get_timezone (ctxt->client, due.tzid),
- default_tz);
- local->todo->due = icaltimetype_to_tm (due.value);
- local->todo->indefinite = 0;
- } else {
- local->todo->indefinite = 1;
- }
- cal_component_free_datetime (&due);
-
- cal_component_get_status (comp, &status);
- if (status == ICAL_STATUS_COMPLETED)
- local->todo->complete = 1;
- else
- local->todo->complete = 0;
-
- cal_component_get_priority (comp, &priority);
- if (priority && *priority != 0) {
- if (*priority <= 3)
- local->todo->priority = 1;
- else if (*priority == 4)
- local->todo->priority = 2;
- else if (*priority == 5)
- local->todo->priority = 3;
- else if (*priority <= 7)
- local->todo->priority = 4;
- else
- local->todo->priority = 5;
-
- cal_component_free_priority (priority);
- } else {
- local->todo->priority = ctxt->cfg->priority;
- }
-
- cal_component_get_classification (comp, &classif);
-
- if (classif == CAL_COMPONENT_CLASS_PRIVATE)
- local->local.secret = 1;
- else
- local->local.secret = 0;
-
- local->local.archived = 0;
-}
-
-static void
-local_record_from_uid (EToDoLocalRecord *local,
- const char *uid,
- EToDoConduitContext *ctxt)
-{
- CalComponent *comp;
- CalClientGetStatus status;
-
- g_assert(local!=NULL);
-
- status = cal_client_get_object (ctxt->client, uid, &comp);
-
- if (status == CAL_CLIENT_GET_SUCCESS) {
- local_record_from_comp (local, comp, ctxt);
- gtk_object_unref (GTK_OBJECT (comp));
- } else if (status == CAL_CLIENT_GET_NOT_FOUND) {
- comp = cal_component_new ();
- cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO);
- cal_component_set_uid (comp, uid);
- local_record_from_comp (local, comp, ctxt);
- gtk_object_unref (GTK_OBJECT (comp));
- } else {
- INFO ("Object did not exist");
- }
-
-
-}
-
-
-static CalComponent *
-comp_from_remote_record (GnomePilotConduitSyncAbs *conduit,
- GnomePilotRecord *remote,
- CalComponent *in_comp,
- icaltimezone *timezone)
-{
- CalComponent *comp;
- struct ToDo todo;
- CalComponentText summary = {NULL, NULL};
- CalComponentDateTime dt = {NULL, icaltimezone_get_tzid (timezone)};
- struct icaltimetype due, now;
- icaltimezone *utc_zone;
- int priority;
- char *txt;
-
- g_return_val_if_fail (remote != NULL, NULL);
-
- memset (&todo, 0, sizeof (struct ToDo));
- unpack_ToDo (&todo, remote->record, remote->length);
-
- utc_zone = icaltimezone_get_utc_timezone ();
- now = icaltime_from_timet_with_zone (time (NULL), FALSE,
- utc_zone);
-
- if (in_comp == NULL) {
- comp = cal_component_new ();
- cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO);
- cal_component_set_created (comp, &now);
- } else {
- comp = cal_component_clone (in_comp);
- }
-
- cal_component_set_last_modified (comp, &now);
-
- summary.value = txt = e_pilot_utf8_from_pchar (todo.description);
- cal_component_set_summary (comp, &summary);
- free (txt);
-
- /* The iCal description field */
- if (!todo.note) {
- cal_component_set_comment_list (comp, NULL);
- } else {
- GSList l;
- CalComponentText text;
-
- text.value = txt = e_pilot_utf8_from_pchar (todo.note);
- text.altrep = NULL;
- l.data = &text;
- l.next = NULL;
-
- cal_component_set_description_list (comp, &l);
- free (txt);
- }
-
- if (todo.complete) {
- int percent = 100;
-
- cal_component_set_completed (comp, &now);
- cal_component_set_percent (comp, &percent);
- cal_component_set_status (comp, ICAL_STATUS_COMPLETED);
- } else {
- int *percent = NULL;
- icalproperty_status status;
-
- cal_component_set_completed (comp, NULL);
-
- cal_component_get_percent (comp, &percent);
- if (percent == NULL || *percent == 100) {
- int p = 0;
- cal_component_set_percent (comp, &p);
- }
- if (percent != NULL)
- cal_component_free_percent (percent);
-
- cal_component_get_status (comp, &status);
- if (status == ICAL_STATUS_COMPLETED)
- cal_component_set_status (comp, ICAL_STATUS_NEEDSACTION);
- }
-
- if (!is_empty_time (todo.due)) {
- due = tm_to_icaltimetype (&todo.due, FALSE);
- dt.value = &due;
- cal_component_set_due (comp, &dt);
- }
-
- switch (todo.priority) {
- case 1:
- priority = 3;
- break;
- case 2:
- priority = 4;
- break;
- case 3:
- priority = 5;
- break;
- case 4:
- priority = 7;
- break;
- default:
- priority = 9;
- }
-
- cal_component_set_priority (comp, &priority);
- cal_component_set_transparency (comp, CAL_COMPONENT_TRANSP_NONE);
-
- if (remote->attr & dlpRecAttrSecret)
- cal_component_set_classification (comp, CAL_COMPONENT_CLASS_PRIVATE);
- else
- cal_component_set_classification (comp, CAL_COMPONENT_CLASS_PUBLIC);
-
- cal_component_commit_sequence (comp);
-
- free_ToDo(&todo);
-
- return comp;
-}
-
-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);
- int map_count;
- const char *uri;
-
- /* If there are no objects or objects but no log */
- map_count = g_hash_table_size (ctxt->map->pid_map);
- if (map_count == 0)
- gnome_pilot_conduit_standard_set_slow (conduit, TRUE);
-
- /* Or if the URI's don't match */
- uri = cal_client_get_uri (ctxt->client);
- LOG(" Current URI %s (%s)\n", uri, ctxt->cfg->last_uri ? ctxt->cfg->last_uri : "<NONE>");
- if (ctxt->cfg->last_uri != NULL && strcmp (ctxt->cfg->last_uri, uri)) {
- gnome_pilot_conduit_standard_set_slow (conduit, TRUE);
- e_pilot_map_clear (ctxt->map);
- }
-
- if (gnome_pilot_conduit_standard_get_slow (conduit)) {
- ctxt->map->write_touched_only = TRUE;
- LOG (" doing slow sync\n");
- } else {
- LOG (" doing fast sync\n");
- }
-}
-
-/* Pilot syncing callbacks */
-static gint
-pre_sync (GnomePilotConduit *conduit,
- GnomePilotDBInfo *dbi,
- EToDoConduitContext *ctxt)
-{
- GnomePilotConduitSyncAbs *abs_conduit;
- GList *l;
- int len;
- unsigned char *buf;
- char *filename, *change_id;
- gint num_records, add_records = 0, mod_records = 0, del_records = 0;
-
- abs_conduit = GNOME_PILOT_CONDUIT_SYNC_ABS (conduit);
-
- LOG ("---------------------------------------------------------\n");
- LOG ("pre_sync: ToDo Conduit v.%s", CONDUIT_VERSION);
- g_message ("ToDo Conduit v.%s", CONDUIT_VERSION);
-
- ctxt->dbi = dbi;
- ctxt->client = NULL;
-
- if (start_calendar_server (ctxt) != 0) {
- WARN(_("Could not start wombat server"));
- gnome_pilot_conduit_error (conduit, _("Could not start wombat"));
- return -1;
- }
-
- /* Get the timezone */
- ctxt->timezone = get_default_timezone ();
- if (ctxt->timezone == NULL)
- return -1;
- LOG (" Using timezone: %s", icaltimezone_get_tzid (ctxt->timezone));
-
- /* 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);
-
- /* 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);
- ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal);
- g_free (change_id);
-
- for (l = ctxt->changed; l != NULL; l = l->next) {
- CalClientChange *ccc = l->data;
- const char *uid;
-
- cal_component_get_uid (ccc->comp, &uid);
- if (!e_pilot_map_uid_is_archived (ctxt->map, uid)) {
-
- g_hash_table_insert (ctxt->changed_hash, g_strdup (uid), ccc);
-
- switch (ccc->type) {
- case CAL_CLIENT_CHANGE_ADDED:
- add_records++;
- break;
- case CAL_CLIENT_CHANGE_MODIFIED:
- mod_records++;
- break;
- case CAL_CLIENT_CHANGE_DELETED:
- del_records++;
- break;
- }
- } else if (ccc->type == CAL_CLIENT_CHANGE_DELETED) {
- e_pilot_map_remove_by_uid (ctxt->map, uid);
- }
- }
-
- /* Set the count information */
- num_records = cal_client_get_n_objects (ctxt->client, CALOBJ_TYPE_TODO);
- 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);
- gnome_pilot_conduit_sync_abs_set_num_deleted_local_records(abs_conduit, del_records);
-
- buf = (unsigned char*)g_malloc (0xffff);
- len = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0,
- (unsigned char *)buf, 0xffff);
-
- if (len < 0) {
- WARN (_("Could not read pilot's ToDo application block"));
- WARN ("dlp_ReadAppBlock(...) = %d", len);
- gnome_pilot_conduit_error (conduit,
- _("Could not read pilot's ToDo application block"));
- return -1;
- }
- unpack_ToDoAppInfo (&(ctxt->ai), buf, len);
- g_free (buf);
-
- check_for_slow_setting (conduit, ctxt);
- if (ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyToPilot
- || ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyFromPilot)
- ctxt->map->write_touched_only = TRUE;
-
- return 0;
-}
-
-static gint
-post_sync (GnomePilotConduit *conduit,
- GnomePilotDBInfo *dbi,
- EToDoConduitContext *ctxt)
-{
- GList *changed;
- gchar *filename, *change_id;
-
- LOG ("post_sync: ToDo Conduit v.%s", CONDUIT_VERSION);
-
- g_free (ctxt->cfg->last_uri);
- ctxt->cfg->last_uri = g_strdup (cal_client_get_uri (ctxt->client));
- todoconduit_save_configuration (ctxt->cfg);
-
- filename = map_name (ctxt);
- e_pilot_map_write (filename, ctxt->map);
- g_free (filename);
-
- /* FIX ME ugly hack - our changes musn't count, this does introduce
- * 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);
- g_free (change_id);
-
- LOG ("---------------------------------------------------------\n");
-
- return 0;
-}
-
-static gint
-set_pilot_id (GnomePilotConduitSyncAbs *conduit,
- EToDoLocalRecord *local,
- guint32 ID,
- EToDoConduitContext *ctxt)
-{
- const char *uid;
-
- LOG ("set_pilot_id: setting to %d\n", ID);
-
- cal_component_get_uid (local->comp, &uid);
- e_pilot_map_insert (ctxt->map, ID, uid, FALSE);
-
- return 0;
-}
-
-static gint
-set_status_cleared (GnomePilotConduitSyncAbs *conduit,
- EToDoLocalRecord *local,
- EToDoConduitContext *ctxt)
-{
- const char *uid;
-
- LOG ("set_status_cleared: clearing status\n");
-
- cal_component_get_uid (local->comp, &uid);
- g_hash_table_remove (ctxt->changed_hash, uid);
-
- return 0;
-}
-
-static gint
-for_each (GnomePilotConduitSyncAbs *conduit,
- EToDoLocalRecord **local,
- EToDoConduitContext *ctxt)
-{
- static GList *uids, *iterator;
- static int count;
-
- g_return_val_if_fail (local != NULL, -1);
-
- if (*local == NULL) {
- LOG ("beginning for_each");
-
- uids = ctxt->uids;
- count = 0;
-
- if (uids != NULL) {
- LOG ("iterating over %d records", g_list_length (uids));
-
- *local = g_new0 (EToDoLocalRecord, 1);
- local_record_from_uid (*local, uids->data, ctxt);
- g_list_prepend (ctxt->locals, *local);
-
- iterator = uids;
- } else {
- LOG ("no events");
- (*local) = NULL;
- return 0;
- }
- } else {
- count++;
- if (g_list_next (iterator)) {
- iterator = g_list_next (iterator);
-
- *local = g_new0 (EToDoLocalRecord, 1);
- local_record_from_uid (*local, iterator->data, ctxt);
- g_list_prepend (ctxt->locals, *local);
- } else {
- LOG ("for_each ending");
-
- /* Tell the pilot the iteration is over */
- *local = NULL;
-
- return 0;
- }
- }
-
- return 0;
-}
-
-static gint
-for_each_modified (GnomePilotConduitSyncAbs *conduit,
- EToDoLocalRecord **local,
- EToDoConduitContext *ctxt)
-{
- static GList *iterator;
- static int count;
-
- g_return_val_if_fail (local != NULL, 0);
-
- if (*local == NULL) {
- LOG ("for_each_modified beginning\n");
-
- iterator = ctxt->changed;
-
- count = 0;
-
- LOG ("iterating over %d records", g_hash_table_size (ctxt->changed_hash));
-
- iterator = next_changed_item (ctxt, iterator);
- if (iterator != NULL) {
- CalClientChange *ccc = iterator->data;
-
- *local = g_new0 (EToDoLocalRecord, 1);
- local_record_from_comp (*local, ccc->comp, ctxt);
- g_list_prepend (ctxt->locals, *local);
- } else {
- LOG ("no events");
-
- *local = NULL;
- }
- } else {
- count++;
- iterator = g_list_next (iterator);
- if (iterator && (iterator = next_changed_item (ctxt, iterator))) {
- CalClientChange *ccc = iterator->data;
-
- *local = g_new0 (EToDoLocalRecord, 1);
- local_record_from_comp (*local, ccc->comp, ctxt);
- g_list_prepend (ctxt->locals, *local);
- } else {
- LOG ("for_each_modified ending");
-
- /* Signal the iteration is over */
- *local = NULL;
- }
- }
-
- return 0;
-}
-
-static gint
-compare (GnomePilotConduitSyncAbs *conduit,
- EToDoLocalRecord *local,
- GnomePilotRecord *remote,
- EToDoConduitContext *ctxt)
-{
- /* used by the quick compare */
- GnomePilotRecord local_pilot;
- int retval = 0;
-
- LOG ("compare: local=%s remote=%s...\n",
- print_local (local), print_remote (remote));
-
- g_return_val_if_fail (local!=NULL,-1);
- g_return_val_if_fail (remote!=NULL,-1);
-
- local_pilot = local_record_to_pilot_record (local, ctxt);
-
- if (remote->length != local_pilot.length
- || memcmp (local_pilot.record, remote->record, remote->length))
- retval = 1;
-
- if (retval == 0)
- LOG (" equal");
- else
- LOG (" not equal");
-
- return retval;
-}
-
-static gint
-add_record (GnomePilotConduitSyncAbs *conduit,
- GnomePilotRecord *remote,
- EToDoConduitContext *ctxt)
-{
- CalComponent *comp;
- const char *uid;
- int retval = 0;
-
- g_return_val_if_fail (remote != NULL, -1);
-
- LOG ("add_record: adding %s to desktop\n", print_remote (remote));
-
- comp = comp_from_remote_record (conduit, remote, NULL, ctxt->timezone);
- update_comp (conduit, comp, ctxt);
-
- cal_component_get_uid (comp, &uid);
- e_pilot_map_insert (ctxt->map, remote->ID, uid, FALSE);
-
- gtk_object_unref (GTK_OBJECT (comp));
-
- return retval;
-}
-
-static gint
-replace_record (GnomePilotConduitSyncAbs *conduit,
- EToDoLocalRecord *local,
- GnomePilotRecord *remote,
- EToDoConduitContext *ctxt)
-{
- CalComponent *new_comp;
- int retval = 0;
-
- g_return_val_if_fail (remote != NULL, -1);
-
- LOG ("replace_record: replace %s with %s\n",
- print_local (local), print_remote (remote));
-
- new_comp = comp_from_remote_record (conduit, remote, local->comp, ctxt->timezone);
- gtk_object_unref (GTK_OBJECT (local->comp));
- local->comp = new_comp;
- update_comp (conduit, local->comp, ctxt);
-
- return retval;
-}
-
-static gint
-delete_record (GnomePilotConduitSyncAbs *conduit,
- EToDoLocalRecord *local,
- EToDoConduitContext *ctxt)
-{
- const char *uid;
-
- g_return_val_if_fail (local != NULL, -1);
- g_return_val_if_fail (local->comp != NULL, -1);
-
- cal_component_get_uid (local->comp, &uid);
-
- LOG ("delete_record: deleting %s\n", uid);
-
- e_pilot_map_remove_by_uid (ctxt->map, uid);
- cal_client_remove_object (ctxt->client, uid);
-
- return 0;
-}
-
-static gint
-archive_record (GnomePilotConduitSyncAbs *conduit,
- EToDoLocalRecord *local,
- gboolean archive,
- EToDoConduitContext *ctxt)
-{
- const char *uid;
- int retval = 0;
-
- g_return_val_if_fail (local != NULL, -1);
-
- LOG ("archive_record: %s\n", archive ? "yes" : "no");
-
- cal_component_get_uid (local->comp, &uid);
- e_pilot_map_insert (ctxt->map, local->local.ID, uid, archive);
-
- return retval;
-}
-
-static gint
-match (GnomePilotConduitSyncAbs *conduit,
- GnomePilotRecord *remote,
- EToDoLocalRecord **local,
- EToDoConduitContext *ctxt)
-{
- const char *uid;
-
- LOG ("match: looking for local copy of %s\n",
- print_remote (remote));
-
- g_return_val_if_fail (local != NULL, -1);
- g_return_val_if_fail (remote != NULL, -1);
-
- *local = NULL;
- uid = e_pilot_map_lookup_uid (ctxt->map, remote->ID, TRUE);
-
- if (!uid)
- return 0;
-
- LOG (" matched\n");
-
- *local = g_new0 (EToDoLocalRecord, 1);
- local_record_from_uid (*local, uid, ctxt);
-
- return 0;
-}
-
-static gint
-free_match (GnomePilotConduitSyncAbs *conduit,
- EToDoLocalRecord *local,
- EToDoConduitContext *ctxt)
-{
- LOG ("free_match: freeing\n");
-
- g_return_val_if_fail (local != NULL, -1);
-
- todoconduit_destroy_record (local);
-
- return 0;
-}
-
-static gint
-prepare (GnomePilotConduitSyncAbs *conduit,
- EToDoLocalRecord *local,
- GnomePilotRecord *remote,
- EToDoConduitContext *ctxt)
-{
- LOG ("prepare: encoding local %s\n", print_local (local));
-
- *remote = local_record_to_pilot_record (local, ctxt);
-
- return 0;
-}
-
-/* Pilot Settings Callbacks */
-static void
-fill_widgets (EToDoConduitContext *ctxt)
-{
- e_pilot_settings_set_secret (E_PILOT_SETTINGS (ctxt->ps),
- ctxt->cfg->secret);
-
- e_todo_gui_fill_widgets (ctxt->gui, ctxt->cfg);
-}
-
-static gint
-create_settings_window (GnomePilotConduit *conduit,
- GtkWidget *parent,
- EToDoConduitContext *ctxt)
-{
- LOG ("create_settings_window");
-
- ctxt->ps = e_pilot_settings_new ();
- ctxt->gui = e_todo_gui_new (E_PILOT_SETTINGS (ctxt->ps));
-
- gtk_container_add (GTK_CONTAINER (parent), ctxt->ps);
- gtk_widget_show (ctxt->ps);
-
- fill_widgets (ctxt);
-
- return 0;
-}
-static void
-display_settings (GnomePilotConduit *conduit, EToDoConduitContext *ctxt)
-{
- LOG ("display_settings");
-
- fill_widgets (ctxt);
-}
-
-static void
-save_settings (GnomePilotConduit *conduit, EToDoConduitContext *ctxt)
-{
- LOG ("save_settings");
-
- ctxt->new_cfg->secret = e_pilot_settings_get_secret (E_PILOT_SETTINGS (ctxt->ps));
- e_todo_gui_fill_config (ctxt->gui, ctxt->new_cfg);
-
- todoconduit_save_configuration (ctxt->new_cfg);
-}
-
-static void
-revert_settings (GnomePilotConduit *conduit, EToDoConduitContext *ctxt)
-{
- LOG ("revert_settings");
-
- todoconduit_save_configuration (ctxt->cfg);
- todoconduit_destroy_configuration (ctxt->new_cfg);
- ctxt->new_cfg = todoconduit_dupe_configuration (ctxt->cfg);
-}
-
-static ORBit_MessageValidationResult
-accept_all_cookies (CORBA_unsigned_long request_id,
- CORBA_Principal *principal,
- CORBA_char *operation)
-{
- /* allow ALL cookies */
- return ORBIT_MESSAGE_ALLOW_ALL;
-}
-
-
-GnomePilotConduit *
-conduit_get_gpilot_conduit (guint32 pilot_id)
-{
- GtkObject *retval;
- EToDoConduitContext *ctxt;
-
- LOG ("in todo's conduit_get_gpilot_conduit\n");
-
- /* we need to find wombat with oaf, so make sure oaf
- is initialized here. once the desktop is converted
- to oaf and gpilotd is built with oaf, this can go away */
- if (!oaf_is_initialized ()) {
- char *argv[ 1 ] = {"hi"};
- oaf_init (1, argv);
-
- if (bonobo_init (CORBA_OBJECT_NIL,
- CORBA_OBJECT_NIL,
- CORBA_OBJECT_NIL) == FALSE)
- g_error (_("Could not initialize Bonobo"));
-
- ORBit_set_request_validation_handler (accept_all_cookies);
- }
-
- retval = gnome_pilot_conduit_sync_abs_new ("ToDoDB", 0x746F646F);
- g_assert (retval != NULL);
-
- ctxt = e_todo_context_new (pilot_id);
- gtk_object_set_data (GTK_OBJECT (retval), "todoconduit_context", ctxt);
-
- gtk_signal_connect (retval, "pre_sync", (GtkSignalFunc) pre_sync, ctxt);
- gtk_signal_connect (retval, "post_sync", (GtkSignalFunc) post_sync, ctxt);
-
- gtk_signal_connect (retval, "set_pilot_id", (GtkSignalFunc) set_pilot_id, ctxt);
- gtk_signal_connect (retval, "set_status_cleared", (GtkSignalFunc) set_status_cleared, ctxt);
-
- gtk_signal_connect (retval, "for_each", (GtkSignalFunc) for_each, ctxt);
- gtk_signal_connect (retval, "for_each_modified", (GtkSignalFunc) for_each_modified, ctxt);
- gtk_signal_connect (retval, "compare", (GtkSignalFunc) compare, ctxt);
-
- gtk_signal_connect (retval, "add_record", (GtkSignalFunc) add_record, ctxt);
- gtk_signal_connect (retval, "replace_record", (GtkSignalFunc) replace_record, ctxt);
- gtk_signal_connect (retval, "delete_record", (GtkSignalFunc) delete_record, ctxt);
- gtk_signal_connect (retval, "archive_record", (GtkSignalFunc) archive_record, ctxt);
-
- gtk_signal_connect (retval, "match", (GtkSignalFunc) match, ctxt);
- gtk_signal_connect (retval, "free_match", (GtkSignalFunc) free_match, ctxt);
-
- gtk_signal_connect (retval, "prepare", (GtkSignalFunc) prepare, ctxt);
-
- /* Gui Settings */
- gtk_signal_connect (retval, "create_settings_window", (GtkSignalFunc) create_settings_window, ctxt);
- gtk_signal_connect (retval, "display_settings", (GtkSignalFunc) display_settings, ctxt);
- gtk_signal_connect (retval, "save_settings", (GtkSignalFunc) save_settings, ctxt);
- gtk_signal_connect (retval, "revert_settings", (GtkSignalFunc) revert_settings, ctxt);
-
- return GNOME_PILOT_CONDUIT (retval);
-}
-
-void
-conduit_destroy_gpilot_conduit (GnomePilotConduit *conduit)
-{
- GtkObject *obj = GTK_OBJECT (conduit);
- EToDoConduitContext *ctxt;
-
- ctxt = gtk_object_get_data (obj, "todoconduit_context");
- e_todo_context_destroy (ctxt);
-
- gtk_object_destroy (obj);
-}
diff --git a/calendar/gui/.cvsignore b/calendar/gui/.cvsignore
deleted file mode 100644
index cd98cc234e..0000000000
--- a/calendar/gui/.cvsignore
+++ /dev/null
@@ -1,24 +0,0 @@
-Makefile.in
-Makefile
-.deps
-_libs
-.libs
-.pure
-evolution-calendar
-evolution-calendar.pure
-evolution-calendar.h
-evolution-calendar-common.c
-evolution-calendar-skels.c
-evolution-calendar-stubs.c
-*.lo
-Evolution-Addressbook-SelectNames-common.c
-Evolution-Addressbook-SelectNames-skels.c
-Evolution-Addressbook-SelectNames-stubs.c
-Evolution-Addressbook-SelectNames.h
-Evolution-Composer-common.c
-Evolution-Composer-skels.c
-Evolution-Composer-stubs.c
-Evolution-Composer.h
-GNOME_Evolution_Calendar_Control.oaf
-GNOME_Evolution_Calendar.oaf
-GNOME_Evolution_Calendar_gnomecal.oaf
diff --git a/calendar/gui/GNOME_Evolution_Calendar.oaf.in b/calendar/gui/GNOME_Evolution_Calendar.oaf.in
deleted file mode 100644
index 68fd2a07d0..0000000000
--- a/calendar/gui/GNOME_Evolution_Calendar.oaf.in
+++ /dev/null
@@ -1,179 +0,0 @@
-<oaf_info>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_iTip_ControlFactory"
- type="exe"
- location="evolution-calendar">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory for the calendar iTip view control"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_iTip_Control"
- type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_iTip_ControlFactory">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:Bonobo/Control:1.0"/>
- <item value="IDL:Bonobo/PersistStream:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="bonobo:supported_mime_types" type="stringv">
- <item value="text/calendar"/>
- <item value="text/x-calendar"/>
- </oaf_attribute>
-
- <oaf_attribute name="name" type="string"
- _value="Evolution calendar iTip/iMip viewer"/>
- <oaf_attribute name="description" type="string"
- _value="Factory for the calendar iTip view control"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ShellComponent"
- type="exe"
- location="evolution-calendar">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/ShellComponent:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Evolution component for handling the calendar."/>
-
- <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_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ControlFactory"
- type="exe"
- location="evolution-calendar">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory for the sample Calendar control"/>
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_Control"
- type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_ControlFactory">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:BonoboControl/calendar-control:1.0"/>
- <item value="IDL:Bonobo/Control:1.0"/>
- <item value="IDL:Bonobo/PropertyBag:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="bonobo:supported_mime_types" type="stringv">
- <item value="text/calendar"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="A sample Bonobo control which displays an calendar."/>
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Tasks_ControlFactory"
- type="exe"
- location="evolution-calendar">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory for the Evolution Tasks control"/>
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Tasks_Control"
- type="factory"
- location="OAFIID:GNOME_Evolution_Tasks_ControlFactory">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:BonoboControl/tasks-control:1.0"/>
- <item value="IDL:Bonobo/Control:1.0"/>
- <item value="IDL:Bonobo/PropertyBag:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="bonobo:supported_mime_types" type="stringv">
- <item value="text/calendar"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="A Bonobo control which displays a task list."/>
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_CompEditorFactory_Factory"
- type="exe"
- location="evolution-calendar">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory to create a component editor factory"/>
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_CompEditorFactory"
- type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_CompEditorFactory_Factory">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/Calendar/CompEditorFactory:1.0"/>
- <item value="IDL:Bonobo/Unknown:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory to centralize calendar component editor dialogs"/>
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ConfigControlFactory"
- type="exe"
- location="evolution-calendar">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_ConfigControl"
- type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_ConfigControlFactory">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/Evolution/ConfigControl:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="evolution:config_item:title" type="string"
- _value="Calendar and Tasks"/>
-
- <oaf_attribute name="evolution:config_item:description" type="string"
- _value="Configure your timezone, Calendar and Task List here "/>
-
- <oaf_attribute name="evolution:config_item:icon_name" type="string"
- value="evolution-calendar.png"/>
-
- <oaf_attribute name="evolution:config_item:type" type="stringv">
- <item value="calendar"/>
- <item value="tasks"/>
- </oaf_attribute>
-
- <oaf_attribute name="evolution:config_item:priority" type="string" value="-7"/>
-
- <oaf_attribute name="description" type="string"
- _value="Configuration control for the Evolution Calendar."/>
-
-</oaf_server>
-
-</oaf_info>
-
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index 28d8e02aeb..64ef0f35ea 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -1,104 +1,115 @@
-## CORBA stuff
+SUBDIRS = dialogs
-IDLS = \
- $(top_srcdir)/composer/Evolution-Composer.idl \
- $(top_srcdir)/calendar/idl/evolution-calendar.idl \
- $(top_srcdir)/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl
+privsolib_LTLIBRARIES = libevolution-calendar.la
-IDL_GENERATED = \
- Evolution-Composer.h \
- Evolution-Composer-common.c \
- Evolution-Composer-skels.c \
- Evolution-Composer-stubs.c \
- Evolution-Addressbook-SelectNames.h \
- Evolution-Addressbook-SelectNames-common.c \
- Evolution-Addressbook-SelectNames-skels.c \
- Evolution-Addressbook-SelectNames-stubs.c \
- evolution-calendar.h \
- evolution-calendar-common.c \
- evolution-calendar-skels.c \
- evolution-calendar-stubs.c
+ecalendarincludedir = $(privincludedir)/calendar/gui
-$(IDL_GENERATED): $(IDLS)
- $(ORBIT_IDL) -I $(srcdir) -I $(datadir)/idl `$(GNOME_CONFIG) --cflags idl` \
- $(srcdir)/../../composer/Evolution-Composer.idl
- $(ORBIT_IDL) -I $(srcdir) -I $(datadir)/idl `$(GNOME_CONFIG) --cflags idl` \
- $(top_srcdir)/calendar/idl/evolution-calendar.idl
- $(ORBIT_IDL) -I $(srcdir) -I $(datadir)/idl `$(GNOME_CONFIG) --cflags idl` \
- $(top_srcdir)/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl
-
-BUILT_SOURCES = $(IDL_GENERATED)
-
-SUBDIRS = alarm-notify dialogs
-
-help_base = $(datadir)/gnome/help/cal
-
-bin_PROGRAMS = evolution-calendar
-
-INCLUDES = \
- -DG_LOG_DOMAIN=\"calendar-gui\" \
- -I$(top_builddir)/shell \
- -I$(top_srcdir)/shell \
- -I$(top_srcdir) \
- -I$(top_srcdir)/calendar \
- -I$(top_srcdir)/calendar/cal-client \
- -I$(top_builddir)/calendar/cal-client \
- -I$(top_srcdir)/libical/src/libical \
- -I$(top_builddir)/libical/src/libical \
- -I$(top_srcdir)/addressbook/backend \
- -I$(top_builddir)/addressbook/backend \
- -I$(top_srcdir)/widgets \
- -I$(includedir) \
- -DEVOLUTION_DATADIR=\""$(datadir)"\" \
- -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
- -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
- -DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \
- -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
- -DEVOLUTION_IMAGESDIR=\""$(datadir)"/images/evolution\" \
- $(EVOLUTION_CALENDAR_CFLAGS)
-
-iconsdir = $(datadir)/images/evolution
-
-gladedir = $(datadir)/evolution/glade
-glade_DATA = \
- e-itip-control.glade \
- goto-dialog.glade
-
-etspecdir = $(datadir)/evolution/etspec/
-etspec_DATA = e-calendar-table.etspec e-meeting-time-sel.etspec
-
-evolution_calendar_SOURCES = \
- $(IDL_GENERATED) \
- cal-search-bar.c \
- cal-search-bar.h \
+ecalendarinclude_HEADERS = \
+ calendar-config.h \
+ calendar-config-keys.h \
+ calendar-view.h \
+ comp-util.h \
+ e-alarm-list.h \
+ e-cal-config.h \
+ e-cal-event.h \
+ e-cal-list-view.h \
+ e-cal-model-calendar.h \
+ e-cal-model.h \
+ e-calendar-selector.h \
+ e-calendar-view.h \
+ e-cell-date-edit-text.h \
+ e-date-time-list.h \
+ e-day-view-layout.h \
+ e-day-view-main-item.h \
+ e-day-view-time-item.h \
+ e-day-view-top-item.h \
+ e-day-view.h \
+ e-meeting-attendee.h \
+ e-meeting-list-view.h \
+ e-meeting-store.h \
+ e-meeting-time-sel.h \
+ e-meeting-time-sel-item.h \
+ e-meeting-types.h \
+ e-meeting-utils.h \
+ e-select-names-editable.h \
+ e-select-names-renderer.h \
+ e-week-view-event-item.h \
+ e-week-view-layout.h \
+ e-week-view-main-item.h \
+ e-week-view-titles-item.h \
+ e-week-view.h \
+ e-weekday-chooser.h \
+ e-timezone-entry.h \
+ gnome-cal.h \
+ itip-utils.h \
+ misc.h \
+ tag-calendar.h
+
+search_files = tasktypes.xml memotypes.xml caltypes.xml
+
+ruledir = $(privdatadir)
+rule_DATA = $(search_files)
+
+libevolution_calendar_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DG_LOG_DOMAIN=\"calendar-gui\" \
+ -I$(top_builddir)/shell \
+ -I$(top_srcdir)/shell \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/calendar \
+ -DEVOLUTION_RULEDIR=\"$(ruledir)\" \
+ -DEVOLUTION_UIDIR=\""$(uidir)"\" \
+ -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
+ -DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \
+ -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
+ -DEVOLUTION_UIDIR=\""$(uidir)"\" \
+ -DEVOLUTION_PRIVDATADIR=\""${privdatadir}"\" \
+ -DPREFIX=\""$(prefix)"\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS) \
+ $(LIBSOUP_CFLAGS)
+
+etspec_DATA = \
+ e-calendar-table.etspec \
+ e-meeting-time-sel.etspec \
+ e-cal-list-view.etspec \
+ e-memo-table.etspec
+
+libevolution_calendar_la_SOURCES = \
calendar-config.c \
calendar-config.h \
- calendar-commands.c \
- calendar-commands.h \
- calendar-model.c \
- calendar-model.h \
- calendar-offline-handler.c \
- calendar-offline-handler.h \
+ calendar-config-keys.h \
calendar-view.c \
calendar-view.h \
- calendar-view-factory.c \
- calendar-view-factory.h \
- comp-editor-factory.c \
- comp-editor-factory.h \
comp-util.c \
comp-util.h \
- config-control-factory.c \
- config-control-factory.h \
- control-factory.c \
- control-factory.h \
- component-factory.c \
- component-factory.h \
- e-calendar-table.h \
- e-calendar-table.c \
+ e-alarm-list.c \
+ e-alarm-list.h \
+ e-cal-component-preview.c \
+ e-cal-component-preview.h \
+ e-cal-config.c \
+ e-cal-config.h \
+ e-cal-event.c \
+ e-cal-event.h \
+ e-cal-model-calendar.c \
+ e-cal-model-calendar.h \
+ e-cal-model.c \
+ e-cal-model.h \
+ e-cal-list-view.c \
+ e-cal-list-view.h \
+ e-cal-model-memos.c \
+ e-cal-model-memos.h \
+ e-cal-model-tasks.c \
+ e-cal-model-tasks.h \
+ e-calendar-selector.c \
+ e-calendar-selector.h \
+ e-calendar-view.c \
+ e-calendar-view.h \
e-cell-date-edit-text.h \
e-cell-date-edit-text.c \
- e-comp-editor-registry.c \
- e-comp-editor-registry.h \
+ e-date-time-list.c \
+ e-date-time-list.h \
e-day-view-layout.c \
e-day-view-layout.h \
e-day-view-main-item.c \
@@ -109,12 +120,12 @@ evolution_calendar_SOURCES = \
e-day-view-top-item.h \
e-day-view.c \
e-day-view.h \
- e-itip-control.h \
- e-itip-control.c \
e-meeting-attendee.c \
e-meeting-attendee.h \
- e-meeting-model.c \
- e-meeting-model.h \
+ e-meeting-list-view.c \
+ e-meeting-list-view.h \
+ e-meeting-store.c \
+ e-meeting-store.h \
e-meeting-time-sel.c \
e-meeting-time-sel.h \
e-meeting-time-sel-item.c \
@@ -122,6 +133,20 @@ evolution_calendar_SOURCES = \
e-meeting-types.h \
e-meeting-utils.c \
e-meeting-utils.h \
+ e-memo-list-selector.c \
+ e-memo-list-selector.h \
+ e-memo-table.c \
+ e-memo-table.h \
+ e-month-view.c \
+ e-month-view.h \
+ e-select-names-editable.c \
+ e-select-names-editable.h \
+ e-select-names-renderer.c \
+ e-select-names-renderer.h \
+ e-task-list-selector.c \
+ e-task-list-selector.h \
+ e-task-table.c \
+ e-task-table.h \
e-week-view-event-item.c \
e-week-view-event-item.h \
e-week-view-layout.c \
@@ -132,84 +157,63 @@ evolution_calendar_SOURCES = \
e-week-view-titles-item.h \
e-week-view.c \
e-week-view.h \
- e-tasks.c \
- e-tasks.h \
+ e-weekday-chooser.c \
+ e-weekday-chooser.h \
e-timezone-entry.c \
e-timezone-entry.h \
gnome-cal.c \
gnome-cal.h \
- goto.c \
- goto.h \
- itip-control-factory.c \
- itip-control-factory.h \
itip-utils.c \
itip-utils.h \
- main.c \
misc.c \
misc.h \
print.c \
print.h \
tag-calendar.c \
tag-calendar.h \
- tasks-control-factory.c \
- tasks-control-factory.h \
- tasks-control.c \
- tasks-control.h \
- tasks-migrate.c \
- tasks-migrate.h \
- weekday-picker.c \
- weekday-picker.h
-
-evolution_calendar_LDADD = \
- alarm-notify/libalarm.a \
- $(DB3_LDADD) \
- $(top_builddir)/widgets/menus/libmenus.la \
- $(top_builddir)/shell/libeshell.la \
- $(top_builddir)/calendar/cal-client/libcal-client.la \
- $(top_builddir)/calendar/cal-util/libcal-util.la \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/libical/src/libical/libical-evolution.la \
- $(top_builddir)/libwombat/libwombat.la \
- $(top_builddir)/addressbook/backend/ebook/libebook.la \
- $(top_builddir)/camel/libcamel.la \
- $(top_builddir)/libversit/libversit.a \
- $(top_builddir)/e-util/ename/libename.la \
- dialogs/libcal-dialogs.a \
- $(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.a \
- $(top_builddir)/widgets/misc/libemiscwidgets.a \
- $(EVOLUTION_CALENDAR_LIBS)
-
-evolution_calendar_LDFLAGS = -export-dynamic
-
-oafdir = $(datadir)/oaf
-oaf_in_files = \
- GNOME_Evolution_Calendar.oaf.in
-
-oaf_DATA = $(oaf_in_files:.oaf.in=.oaf)
-
-@XML_I18N_MERGE_OAF_RULE@
+ ea-calendar.c \
+ ea-calendar.h \
+ ea-calendar-helpers.c \
+ ea-calendar-helpers.h \
+ ea-cal-view.c \
+ ea-cal-view.h \
+ ea-cal-view-event.c \
+ ea-cal-view-event.h \
+ ea-day-view.c \
+ ea-day-view.h \
+ ea-day-view-main-item.c \
+ ea-day-view-main-item.h \
+ ea-day-view-cell.c \
+ ea-day-view-cell.h \
+ ea-week-view.c \
+ ea-week-view.h \
+ ea-week-view-main-item.c \
+ ea-week-view-main-item.h \
+ ea-week-view-cell.c \
+ ea-week-view-cell.h \
+ ea-jump-button.c \
+ ea-jump-button.h \
+ ea-gnome-calendar.c \
+ ea-gnome-calendar.h
+
+libevolution_calendar_la_LIBADD = \
+ $(top_builddir)/composer/libevolution-mail-composer.la \
+ $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \
+ $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \
+ $(top_builddir)/shell/libevolution-shell.la \
+ $(top_builddir)/calendar/gui/dialogs/libcal-dialogs.la \
+ $(top_builddir)/calendar/importers/libevolution-calendar-importers.la \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_LIBS) \
+ $(LIBSOUP_LIBS)
+
+libevolution_calendar_la_LDFLAGS = -avoid-version $(NO_UNDEFINED)
EXTRA_DIST = \
- $(glade_DATA) \
+ $(ui_DATA) \
$(etspec_DATA) \
- $(oaf_in_files)
-
-install-data-local:
- $(mkinstalldirs) $(DESTDIR)$(help_base)/C
- $(mkinstalldirs) $(Conduitsdir)
-
-if ENABLE_PURIFY
-PLINK = $(LIBTOOL) --mode=link $(PURIFY) $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
-
-all-local: evolution-calendar.pure
-
-evolution-calendar.pure: evolution-calendar
- @rm -f evolution-calendar.pure
- $(PLINK) $(evolution_calendar_LDFLAGS) $(evolution_calendar_OBJECTS) $(evolution_calendar_LDADD) $(LIBS)
-
-endif
-
-CLEANFILES = $(BUILT_SOURCES)
+ $(search_files)
-dist-hook:
- cd $(distdir); rm -f $(BUILT_SOURCES)
+-include $(top_srcdir)/git.mk
diff --git a/calendar/gui/alarm-notify/.cvsignore b/calendar/gui/alarm-notify/.cvsignore
deleted file mode 100644
index 479589e914..0000000000
--- a/calendar/gui/alarm-notify/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-.deps
-.libs
-.pure
-Makefile
-Makefile.in
-evolution-calendar-stubs.c
-evolution-calendar-skels.c
-evolution-calendar-common.c
-evolution-calendar.h
-evolution-alarm-notify
-GNOME_Evolution_Calendar_AlarmNotify.oaf
diff --git a/calendar/gui/alarm-notify/GNOME_Evolution_Calendar_AlarmNotify.oaf.in b/calendar/gui/alarm-notify/GNOME_Evolution_Calendar_AlarmNotify.oaf.in
deleted file mode 100644
index 86f5c71493..0000000000
--- a/calendar/gui/alarm-notify/GNOME_Evolution_Calendar_AlarmNotify.oaf.in
+++ /dev/null
@@ -1,24 +0,0 @@
-<oaf_info>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_AlarmNotify_Factory"
- type="exe"
- location="evolution-alarm-notify">
-
- <oaf_attribute name="repo_ids" type="stringv">
- <item value="IDL:GNOME/ObjectFactory:1.0"/>
- </oaf_attribute>
-
- <oaf_attribute name="description" type="string"
- _value="Factory for the alarm notification service"/>
-
-</oaf_server>
-
-<oaf_server iid="OAFIID:GNOME_Evolution_Calendar_AlarmNotify"
- type="factory"
- location="OAFIID:GNOME_Evolution_Calendar_AlarmNotify_Factory">
-
- <oaf_attribute name="description" type="string"
- _value="Alarm notification service"/>
-</oaf_server>
-
-</oaf_info>
diff --git a/calendar/gui/alarm-notify/Makefile.am b/calendar/gui/alarm-notify/Makefile.am
deleted file mode 100644
index 6d77398ade..0000000000
--- a/calendar/gui/alarm-notify/Makefile.am
+++ /dev/null
@@ -1,83 +0,0 @@
-CORBA_GENERATED = \
- evolution-calendar.h \
- evolution-calendar-common.c \
- evolution-calendar-skels.c \
- evolution-calendar-stubs.c
-
-idls = $(top_srcdir)/calendar/idl/evolution-calendar.idl
-
-idl_flags = `$(GNOME_CONFIG) --cflags idl` -I $(datadir)/idl
-
-$(CORBA_GENERATED): $(idls)
- $(ORBIT_IDL) $(idl_flags) $(top_srcdir)/calendar/idl/evolution-calendar.idl
-
-bin_PROGRAMS = evolution-alarm-notify
-
-noinst_LIBRARIES = libalarm.a
-
-libalarm_a_SOURCES = \
- alarm.c \
- alarm.h
-
-INCLUDES = \
- -DG_LOG_DOMAIN=\"evolution-alarm-notify\" \
- -I$(top_srcdir) \
- -I$(top_srcdir)/calendar \
- -I$(top_builddir)/calendar \
- -I$(top_srcdir)/libical/src/libical \
- -I$(top_builddir)/libical/src/libical \
- -I$(top_srcdir)/widgets \
- -I$(includedir) \
- -DEVOLUTION_DATADIR=\""$(datadir)"\" \
- -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
- -DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \
- -DEVOLUTION_LOCALEDIR=\""$(localedir)"\" \
- $(EVOLUTION_CALENDAR_CFLAGS)
-
-iconsdir = $(datadir)/images/evolution
-
-gladedir = $(datadir)/evolution/glade
-
-glade_DATA = \
- alarm-notify.glade
-
-evolution_alarm_notify_SOURCES = \
- $(CORBA_GENERATED) \
- alarm-notify.c \
- alarm-notify.h \
- alarm-notify-dialog.c \
- alarm-notify-dialog.h \
- alarm-queue.c \
- alarm-queue.h \
- config-data.c \
- config-data.h \
- notify-main.c \
- save.c \
- save.h
-
-evolution_alarm_notify_LDADD = \
- libalarm.a \
- $(top_builddir)/calendar/cal-client/libcal-client.la \
- $(top_builddir)/calendar/cal-util/libcal-util.la \
- $(top_builddir)/libical/src/libical/libical-evolution.la \
- $(top_builddir)/libwombat/libwombat.la \
- $(top_builddir)/e-util/libeutil.la \
- $(EVOLUTION_CALENDAR_LIBS)
-
-evolution_alarm_notify_LDFLAGS = -export-dynamic
-
-oafdir = $(datadir)/oaf
-oaf_in_files = \
- GNOME_Evolution_Calendar_AlarmNotify.oaf.in
-
-oaf_DATA = $(oaf_in_files:.oaf.in=.oaf)
-
-@XML_I18N_MERGE_OAF_RULE@
-
-EXTRA_DIST = \
- $(oaf_DATA) \
- $(oaf_in_files) \
- $(glade_DATA)
-
-BUILT_SOURCES = $(CORBA_GENERATED)
-CLEANFILES = $(BUILT_SOURCES)
diff --git a/calendar/gui/alarm-notify/alarm-notify-dialog.c b/calendar/gui/alarm-notify/alarm-notify-dialog.c
deleted file mode 100644
index 2ad6783cf9..0000000000
--- a/calendar/gui/alarm-notify/alarm-notify-dialog.c
+++ /dev/null
@@ -1,412 +0,0 @@
-/* Evolution calendar - alarm notification dialog
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 <stdio.h>
-#include <string.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkspinbutton.h>
-#include <gtk/gtksignal.h>
-#include <gtk/gtkwindow.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-winhints.h>
-#include <libgnomeui/gnome-window-icon.h>
-#include <glade/glade.h>
-#include <e-util/e-time-utils.h>
-#include <gal/util/e-unicode-i18n.h>
-#include <gal/widgets/e-unicode.h>
-#include <gal/widgets/e-scroll-frame.h>
-#include <gtkhtml/gtkhtml.h>
-#include <gtkhtml/gtkhtml-stream.h>
-#include "cal-util/timeutil.h"
-#include "alarm-notify-dialog.h"
-#include "config-data.h"
-
-
-GtkWidget *make_html_display (gchar *widget_name, char *s1, char *s2, int scroll, int shadow);
-
-/* The useful contents of the alarm notify dialog */
-typedef struct {
- GladeXML *xml;
-
- GtkWidget *dialog;
- GtkWidget *close;
- GtkWidget *snooze;
- GtkWidget *edit;
- GtkWidget *heading;
- GtkWidget *message;
- GtkWidget *snooze_time;
- GtkWidget *html;
-
- AlarmNotifyFunc func;
- gpointer func_data;
-} AlarmNotify;
-
-
-
-/* Callback used when the notify dialog is destroyed */
-static void
-dialog_destroy_cb (GtkObject *object, gpointer data)
-{
- AlarmNotify *an;
-
- an = data;
- gtk_object_unref (GTK_OBJECT (an->xml));
- g_free (an);
-}
-
-/* Delete_event handler for the alarm notify dialog */
-static gint
-delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
-{
- AlarmNotify *an;
-
- an = data;
- g_assert (an->func != NULL);
-
- (* an->func) (ALARM_NOTIFY_CLOSE, -1, an->func_data);
-
- gtk_widget_destroy (widget);
- return TRUE;
-}
-
-/* Callback for the close button */
-static void
-close_clicked_cb (GtkWidget *widget, gpointer data)
-{
- AlarmNotify *an;
-
- an = data;
- g_assert (an->func != NULL);
-
- (* an->func) (ALARM_NOTIFY_CLOSE, -1, an->func_data);
-
- gtk_widget_destroy (an->dialog);
-}
-
-/* Callback for the snooze button */
-static void
-snooze_clicked_cb (GtkWidget *widget, gpointer data)
-{
- AlarmNotify *an;
- int snooze_time;
-
- an = data;
- g_assert (an->func != NULL);
-
- snooze_time = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (an->snooze_time));
- (* an->func) (ALARM_NOTIFY_SNOOZE, snooze_time, an->func_data);
-
- gtk_widget_destroy (an->dialog);
-}
-
-/* Callback for the edit button */
-static void
-edit_clicked_cb (GtkWidget *widget, gpointer data)
-{
- AlarmNotify *an;
-
- an = data;
- g_assert (an->func != NULL);
-
- (* an->func) (ALARM_NOTIFY_EDIT, -1, an->func_data);
-
- gtk_widget_destroy (an->dialog);
-}
-
-static void
-url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *stream, gpointer data)
-{
-
- if (!strncmp ("file:///", url, strlen ("file:///"))) {
- FILE *fp;
- const char *filename = url + strlen ("file://");
- char buf[4096];
- size_t len;
-
- fp = fopen (filename, "r");
-
- if (fp == NULL) {
- g_warning ("Error opening image: %s\n", url);
- gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR);
- return;
- }
-
- while ((len = fread (buf, 1, sizeof(buf), fp)) > 0)
- gtk_html_stream_write (stream, buf, len);
-
- if (feof (fp)) {
- fclose (fp);
- gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
- return;
- }
-
- fclose (fp);
- }
-
- g_warning ("Error loading image");
- gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR);
- return;
-}
-
-GtkWidget *
-make_html_display (gchar *widget_name, char *s1, char *s2, int scroll, int shadow)
-{
- GtkWidget *html, *frame;
-
- gtk_widget_push_visual(gdk_rgb_get_visual());
- gtk_widget_push_colormap(gdk_rgb_get_cmap());
-
- html = gtk_html_new();
-
- gtk_html_set_default_content_type (GTK_HTML (html),
- "charset=utf-8");
- gtk_html_load_empty (GTK_HTML (html));
-
- gtk_signal_connect (GTK_OBJECT (html), "url_requested",
- GTK_SIGNAL_FUNC (url_requested_cb),
- NULL);
-
- gtk_widget_pop_colormap();
- gtk_widget_pop_visual();
-
- frame = e_scroll_frame_new(NULL, NULL);
-
- e_scroll_frame_set_policy(E_SCROLL_FRAME(frame),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
-
-
- e_scroll_frame_set_shadow_type (E_SCROLL_FRAME (frame),
- GTK_SHADOW_IN);
-
- gtk_widget_set_usize (frame, 300, 200);
-
- gtk_container_add(GTK_CONTAINER (frame), html);
-
- gtk_widget_show_all(frame);
-
- gtk_object_set_user_data(GTK_OBJECT (frame), html);
- return frame;
-}
-
-static void
-write_times (GtkHTMLStream *stream, char *start, char *end)
-{
- if (start)
- gtk_html_stream_printf (stream, "<b>%s</b> %s<br>", U_("Starting:"), start);
- if (end)
- gtk_html_stream_printf (stream, "<b>%s</b> %s<br>", U_("Ending:"), end);
-
-}
-
-/* Converts a time_t to a string, relative to the specified timezone */
-static char *
-timet_to_str_with_zone (time_t t, icaltimezone *zone)
-{
- struct icaltimetype itt;
- struct tm tm;
- char buf[256];
-
- if (t == -1)
- return g_strdup (_("invalid time"));
-
- itt = icaltime_from_timet_with_zone (t, FALSE, zone);
- tm = icaltimetype_to_tm (&itt);
-
- e_time_format_date_and_time (&tm, config_data_get_24_hour_format (),
- FALSE, FALSE, buf, sizeof (buf));
- return g_strdup (buf);
-}
-
-/* Creates a heading for the alarm notification dialog */
-static void
-write_html_heading (GtkHTMLStream *stream, const char *message,
- CalComponentVType vtype, time_t occur_start, time_t occur_end)
-{
- char *buf;
- char *start, *end;
- char *bg_path = "file://" EVOLUTION_ICONSDIR "/bcg.png";
- char *image_path = "file://" EVOLUTION_ICONSDIR "/alarm.png";
- icaltimezone *current_zone;
-
- /* Stringize the times */
-
- current_zone = config_data_get_timezone ();
-
- buf = timet_to_str_with_zone (occur_start, current_zone);
- start = e_utf8_from_locale_string (buf);
- g_free (buf);
-
- buf = timet_to_str_with_zone (occur_end, current_zone);
- end = e_utf8_from_locale_string (buf);
- g_free (buf);
-
- /* Write the header */
-
- gtk_html_stream_printf (stream,
- "<HTML><BODY background=\"%s\">"
- "<TABLE WIDTH=\"100%%\">"
- "<TR>"
- "<TD><IMG SRC=\"%s\" ALIGN=\"top\" BORDER=\"0\"></TD>"
- "<TD><H1>%s</H1></TD>"
- "</TR>"
- "</TABLE>",
- bg_path,
- image_path,
- U_("Evolution Alarm"));
-
- gtk_html_stream_printf (stream, "<br><br><font size=\"+2\">%s</font><br><br>", message);
-
- /* Write the times */
-
- switch (vtype) {
- case CAL_COMPONENT_EVENT:
- write_times (stream, start, end);
- break;
-
- case CAL_COMPONENT_TODO:
- write_times (stream, start, end);
- break;
-
- default:
- /* Only VEVENTs and VTODOs can have alarms */
- g_assert_not_reached ();
- break;
- }
-
- g_free (start);
- g_free (end);
-}
-
-/**
- * alarm_notify_dialog:
- * @trigger: Trigger time for the alarm.
- * @occur_start: Start of occurrence time for the event.
- * @occur_end: End of occurrence time for the event.
- * @vtype: Type of the component which corresponds to the alarm.
- * @message; Message to display in the dialog; usually comes from the component.
- * @func: Function to be called when a dialog action is invoked.
- * @func_data: Closure data for @func.
- *
- * Runs the alarm notification dialog. The specified @func will be used to
- * notify the client about result of the actions in the dialog.
- *
- * Return value: TRUE on success, FALSE if the dialog could not be created.
- **/
-gboolean
-alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end,
- CalComponentVType vtype, const char *message,
- AlarmNotifyFunc func, gpointer func_data)
-{
- AlarmNotify *an;
- GtkHTMLStream *stream;
- icaltimezone *current_zone;
- char *buf, *title;
-
- g_return_val_if_fail (trigger != -1, FALSE);
-
- /* Only VEVENTs or VTODOs can have alarms */
- g_return_val_if_fail (vtype == CAL_COMPONENT_EVENT || vtype == CAL_COMPONENT_TODO, FALSE);
- g_return_val_if_fail (message != NULL, FALSE);
- g_return_val_if_fail (func != NULL, FALSE);
-
- an = g_new0 (AlarmNotify, 1);
-
- an->func = func;
- an->func_data = func_data;
-
- an->xml = glade_xml_new (EVOLUTION_GLADEDIR "/alarm-notify.glade", NULL);
- if (!an->xml) {
- g_message ("alarm_notify_dialog(): Could not load the Glade XML file!");
- g_free (an);
- return FALSE;
- }
-
- an->dialog = glade_xml_get_widget (an->xml, "alarm-notify");
- an->close = glade_xml_get_widget (an->xml, "close");
- an->snooze = glade_xml_get_widget (an->xml, "snooze");
- an->edit = glade_xml_get_widget (an->xml, "edit");
- an->heading = glade_xml_get_widget (an->xml, "heading");
- an->message = glade_xml_get_widget (an->xml, "message");
- an->snooze_time = glade_xml_get_widget (an->xml, "snooze-time");
- an->html = gtk_object_get_user_data (GTK_OBJECT (glade_xml_get_widget (an->xml, "frame")));
-
- if (!(an->dialog && an->close && an->snooze && an->edit && an->heading && an->message
- && an->snooze_time)) {
- g_message ("alarm_notify_dialog(): Could not find all widgets in Glade file!");
- gtk_object_unref (GTK_OBJECT (an->xml));
- g_free (an);
- return FALSE;
- }
-
- gtk_object_set_data (GTK_OBJECT (an->dialog), "alarm-notify", an);
- gtk_signal_connect (GTK_OBJECT (an->dialog), "destroy",
- GTK_SIGNAL_FUNC (dialog_destroy_cb), an);
-
- /* Title */
-
- current_zone = config_data_get_timezone ();
-
- buf = timet_to_str_with_zone (trigger, current_zone);
- title = g_strdup_printf (_("Alarm on %s"), buf);
- g_free (buf);
-
- gtk_window_set_title (GTK_WINDOW (an->dialog), title);
- g_free (title);
-
- /* html heading */
- stream = gtk_html_begin (GTK_HTML (an->html));
- write_html_heading (stream, message, vtype, occur_start, occur_end);
- gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
-
- /* Connect actions */
-
- gtk_signal_connect (GTK_OBJECT (an->dialog), "delete_event",
- GTK_SIGNAL_FUNC (delete_event_cb),
- an);
-
- gtk_signal_connect (GTK_OBJECT (an->close), "clicked",
- GTK_SIGNAL_FUNC (close_clicked_cb),
- an);
-
- gtk_signal_connect (GTK_OBJECT (an->snooze), "clicked",
- GTK_SIGNAL_FUNC (snooze_clicked_cb),
- an);
-
- gtk_signal_connect (GTK_OBJECT (an->edit), "clicked",
- GTK_SIGNAL_FUNC (edit_clicked_cb),
- an);
-
- /* Run! */
-
- if (!GTK_WIDGET_REALIZED (an->dialog))
- gtk_widget_realize (an->dialog);
-
- gnome_win_hints_set_state (an->dialog, WIN_STATE_STICKY);
- gnome_win_hints_set_layer (an->dialog, WIN_LAYER_ONTOP);
- gnome_window_icon_set_from_file (GTK_WINDOW (an->dialog), EVOLUTION_ICONSDIR "/alarm.png");
-
- gtk_widget_show (an->dialog);
- return TRUE;
-}
-
diff --git a/calendar/gui/alarm-notify/alarm-notify-dialog.h b/calendar/gui/alarm-notify/alarm-notify-dialog.h
deleted file mode 100644
index 812463de8d..0000000000
--- a/calendar/gui/alarm-notify/alarm-notify-dialog.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Evolution calendar - alarm notification dialog
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 ALARM_NOTIFY_DIALOG_H
-#define ALARM_NOTIFY_DIALOG_H
-
-#include <time.h>
-#include <glib.h>
-#include <cal-util/cal-component.h>
-
-
-
-typedef enum {
- ALARM_NOTIFY_CLOSE,
- ALARM_NOTIFY_SNOOZE,
- ALARM_NOTIFY_EDIT
-} AlarmNotifyResult;
-
-typedef void (* AlarmNotifyFunc) (AlarmNotifyResult result, int snooze_mins, gpointer data);
-
-gboolean alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end,
- CalComponentVType vtype, const char *message,
- AlarmNotifyFunc func, gpointer func_data);
-
-
-
-#endif
diff --git a/calendar/gui/alarm-notify/alarm-notify.c b/calendar/gui/alarm-notify/alarm-notify.c
deleted file mode 100644
index a2b3d1ae9d..0000000000
--- a/calendar/gui/alarm-notify/alarm-notify.c
+++ /dev/null
@@ -1,478 +0,0 @@
-/* Evolution calendar - Alarm notification service object
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <cal-client/cal-client.h>
-#include "alarm-notify.h"
-#include "alarm-queue.h"
-#include "save.h"
-#include "e-util/e-url.h"
-
-
-
-/* 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 */
- GHashTable *uri_client_hash;
-};
-
-
-
-static void alarm_notify_class_init (AlarmNotifyClass *class);
-static void alarm_notify_init (AlarmNotify *an);
-static void alarm_notify_destroy (GtkObject *object);
-
-static void AlarmNotify_addCalendar (PortableServer_Servant servant,
- const CORBA_char *str_uri,
- CORBA_Environment *ev);
-static void AlarmNotify_removeCalendar (PortableServer_Servant servant,
- const CORBA_char *str_uri,
- CORBA_Environment *ev);
-
-
-static BonoboXObjectClass *parent_class;
-
-
-
-BONOBO_X_TYPE_FUNC_FULL (AlarmNotify,
- GNOME_Evolution_Calendar_AlarmNotify,
- BONOBO_X_OBJECT_TYPE,
- alarm_notify);
-
-/* Class initialization function for the alarm notify service */
-static void
-alarm_notify_class_init (AlarmNotifyClass *class)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) class;
-
- parent_class = gtk_type_class (BONOBO_X_OBJECT_TYPE);
-
- class->epv.addCalendar = AlarmNotify_addCalendar;
- class->epv.removeCalendar = AlarmNotify_removeCalendar;
-
- object_class->destroy = alarm_notify_destroy;
-}
-
-/* Object initialization function for the alarm notify system */
-static void
-alarm_notify_init (AlarmNotify *an)
-{
- AlarmNotifyPrivate *priv;
-
- 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);
- gtk_object_unref (GTK_OBJECT (lc->client));
- e_uri_free (lc->uri);
- g_free (lc);
-}
-
-/* Destroy handler for the alarm notify system */
-static void
-alarm_notify_destroy (GtkObject *object)
-{
- AlarmNotify *an;
- AlarmNotifyPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_ALARM_NOTIFY (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 (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-
-
-/* CORBA servant implementation */
-
-/* Looks for a canonicalized URI inside an array of URIs; returns the index
- * within the array or -1 if not found.
- */
-static int
-find_uri_index (GPtrArray *uris, const char *str_uri)
-{
- int i;
-
- for (i = 0; i < uris->len; i++) {
- char *uri;
-
- uri = uris->pdata[i];
- if (strcmp (uri, str_uri) == 0)
- break;
- }
-
- if (i == uris->len)
- return -1;
- else
- return i;
-}
-
-/* Frees an array of URIs and the URIs within it. */
-static void
-free_uris (GPtrArray *uris)
-{
- int i;
-
- for (i = 0; i < uris->len; i++) {
- char *uri;
-
- uri = uris->pdata[i];
- g_free (uri);
- }
-
- g_ptr_array_free (uris, TRUE);
-}
-
-/* Adds an URI to the list of calendars to load on startup */
-static void
-add_uri_to_load (EUri *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;
- }
-
- /* Look for the URI in the list of calendars to load */
-
- i = find_uri_index (loaded_uris, str_uri);
-
- /* We only need to add the URI if we didn't find it among the list of
- * calendars.
- */
- if (i != -1) {
- g_free (str_uri);
- free_uris (loaded_uris);
- return;
- }
-
- g_ptr_array_add (loaded_uris, str_uri);
- save_calendars_to_load (loaded_uris);
-
- free_uris (loaded_uris);
-}
-
-/* Removes an URI from the list of calendars to load on startup */
-static void
-remove_uri_to_load (EUri *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) {
- free_uris (loaded_uris);
- return;
- }
-
- loaded_uri = loaded_uris->pdata[i];
- g_free (loaded_uri);
-
- g_ptr_array_remove_index (loaded_uris, i);
- save_calendars_to_load (loaded_uris);
-
- free_uris (loaded_uris);
-}
-
-/* AlarmNotify::addCalendar method */
-static void
-AlarmNotify_addCalendar (PortableServer_Servant servant,
- const CORBA_char *str_uri,
- CORBA_Environment *ev)
-{
- AlarmNotify *an;
-
- an = ALARM_NOTIFY (bonobo_object_from_servant (servant));
- alarm_notify_add_calendar (an, str_uri, TRUE, ev);
-}
-
-/* AlarmNotify::removeCalendar method */
-static void
-AlarmNotify_removeCalendar (PortableServer_Servant servant,
- const CORBA_char *str_uri,
- CORBA_Environment *ev)
-{
- AlarmNotify *an;
- AlarmNotifyPrivate *priv;
- LoadedClient *lc;
- EUri *uri;
- char *orig_str;
- gboolean found;
-
- 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;
- }
-
- remove_uri_to_load (uri);
-
- found = g_hash_table_lookup_extended (priv->uri_client_hash, str_uri,
- (gpointer *) &orig_str,
- (gpointer *) &lc);
- e_uri_free (uri);
-
- if (!lc) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_AlarmNotify_NotFound,
- NULL);
- return;
- }
-
- 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);
- gtk_signal_disconnect_by_data (GTK_OBJECT (lc->client), lc);
- if (lc->timeout_id != -1)
- g_source_remove (lc->timeout_id);
- alarm_queue_remove_client (lc->client);
- gtk_object_unref (GTK_OBJECT (lc->client));
- e_uri_free (lc->uri);
- g_free (lc);
-}
-
-
-
-/**
- * alarm_notify_new:
- *
- * Creates a new #AlarmNotify object.
- *
- * Return value: A newly-created #AlarmNotify, or NULL if its corresponding
- * CORBA object could not be created.
- **/
-AlarmNotify *
-alarm_notify_new (void)
-{
- AlarmNotify *an;
-
- an = gtk_type_new (TYPE_ALARM_NOTIFY);
- 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.
- * @uri: URI of the calendar to load.
- * @load_afterwards: Whether this calendar should be loaded in the future
- * when the alarm daemon starts up.
- * @ev: CORBA environment for exceptions.
- *
- * Tells the alarm notification service to load a calendar and start monitoring
- * its alarms. It can optionally be made to save the URI of this calendar so
- * that it can be loaded in the future when the alarm daemon starts up.
- **/
-void
-alarm_notify_add_calendar (AlarmNotify *an, const char *str_uri, gboolean load_afterwards,
- CORBA_Environment *ev)
-{
- AlarmNotifyPrivate *priv;
- EUri *uri;
- CalClient *client;
- LoadedClient *lc;
- char *s;
-
- g_return_if_fail (an != NULL);
- g_return_if_fail (IS_ALARM_NOTIFY (an));
- g_return_if_fail (str_uri != NULL);
- g_return_if_fail (ev != NULL);
-
- 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;
- }
-
- if (g_hash_table_lookup_extended (priv->uri_client_hash, str_uri, &s, &lc)) {
- g_hash_table_remove (priv->uri_client_hash, str_uri);
-
- gtk_signal_disconnect_by_data (GTK_OBJECT (lc->client), lc);
- if (lc->timeout_id != -1)
- g_source_remove (lc->timeout_id);
- alarm_queue_remove_client (lc->client);
- gtk_object_unref (GTK_OBJECT (lc->client));
- e_uri_free (lc->uri);
-
- g_free (lc);
- g_free (s);
- }
-
- client = cal_client_new ();
-
- if (client) {
- /* we only add the URI to load_afterwards if we open it
- correctly */
- lc = g_new (LoadedClient, 1);
-
- gtk_signal_connect (GTK_OBJECT (client), "cal_opened",
- GTK_SIGNAL_FUNC (cal_opened_cb),
- lc);
-
- if (cal_client_open_calendar (client, str_uri, FALSE)) {
- lc->client = client;
- lc->uri = uri;
- lc->refcount = 1;
- lc->timeout_id = -1;
- g_hash_table_insert (priv->uri_client_hash,
- g_strdup (str_uri), lc);
- } else {
- g_free (lc);
- gtk_object_unref (GTK_OBJECT (client));
- client = NULL;
- }
- }
-
- if (!client) {
- e_uri_free (uri);
-
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError,
- NULL);
- return;
- }
-}
diff --git a/calendar/gui/alarm-notify/alarm-notify.glade b/calendar/gui/alarm-notify/alarm-notify.glade
deleted file mode 100644
index e71828ca53..0000000000
--- a/calendar/gui/alarm-notify/alarm-notify.glade
+++ /dev/null
@@ -1,220 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>Evolution Calendar</name>
- <program_name>evolution-calendar</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
-</project>
-
-<widget>
- <class>GtkWindow</class>
- <name>alarm-notify</name>
- <title></title>
- <type>GTK_WINDOW_DIALOG</type>
- <position>GTK_WIN_POS_CENTER</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>False</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox2</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox3</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox5</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>heading</name>
- <label></label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>True</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>message</name>
- <label></label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>True</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>frame</name>
- <creation_function>make_html_display</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 11 Oct 2001 08:19:04 GMT</last_modification_time>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox4</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>close</name>
- <can_focus>True</can_focus>
- <label>C_lose</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>snooze</name>
- <can_focus>True</can_focus>
- <label>Snoo_ze</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>edit</name>
- <can_focus>True</can_focus>
- <label>_Edit appointment</label>
- <relief>GTK_RELIEF_NORMAL</relief>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHSeparator</class>
- <name>hseparator1</name>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox4</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label4</name>
- <label>Snooze time (minutes)</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkSpinButton</class>
- <name>snooze-time</name>
- <can_focus>True</can_focus>
- <climb_rate>1</climb_rate>
- <digits>0</digits>
- <numeric>False</numeric>
- <update_policy>GTK_UPDATE_ALWAYS</update_policy>
- <snap>False</snap>
- <wrap>False</wrap>
- <value>5</value>
- <lower>1</lower>
- <upper>1440</upper>
- <step>1</step>
- <page>5</page>
- <page_size>5</page_size>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/calendar/gui/alarm-notify/alarm-notify.h b/calendar/gui/alarm-notify/alarm-notify.h
deleted file mode 100644
index 858c3a7d87..0000000000
--- a/calendar/gui/alarm-notify/alarm-notify.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Evolution calendar - Alarm notification service object
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 ALARM_NOTIFY_H
-#define ALARM_NOTIFY_H
-
-#include <bonobo/bonobo-xobject.h>
-#include "evolution-calendar.h"
-
-
-
-#define TYPE_ALARM_NOTIFY (alarm_notify_get_type ())
-#define ALARM_NOTIFY(obj) (GTK_CHECK_CAST ((obj), TYPE_ALARM_NOTIFY, AlarmNotify))
-#define ALARM_NOTIFY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_ALARM_NOTIFY, \
- AlarmNotifyClass))
-#define IS_ALARM_NOTIFY(obj) (GTK_CHECK_TYPE ((obj), TYPE_ALARM_NOTIFY))
-#define IS_ALARM_NOTIFY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_ALARM_NOTIFY))
-
-typedef struct _AlarmNotify AlarmNotify;
-typedef struct _AlarmNotifyClass AlarmNotifyClass;
-
-typedef struct _AlarmNotifyPrivate AlarmNotifyPrivate;
-
-struct _AlarmNotify {
- BonoboXObject xobject;
-
- /* Private data */
- AlarmNotifyPrivate *priv;
-};
-
-struct _AlarmNotifyClass {
- BonoboXObjectClass parent_class;
-
- POA_GNOME_Evolution_Calendar_AlarmNotify__epv epv;
-};
-
-GtkType alarm_notify_get_type (void);
-
-AlarmNotify *alarm_notify_new (void);
-
-void alarm_notify_add_calendar (AlarmNotify *an, const char *str_uri, gboolean load_afterwards,
- CORBA_Environment *ev);
-
-
-
-
-#endif
diff --git a/calendar/gui/alarm-notify/alarm-queue.c b/calendar/gui/alarm-notify/alarm-queue.c
deleted file mode 100644
index 6782c91a2d..0000000000
--- a/calendar/gui/alarm-notify/alarm-queue.c
+++ /dev/null
@@ -1,1038 +0,0 @@
-/* Evolution calendar - Alarm queueing engine
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-#include <liboaf/liboaf.h>
-#include <bonobo/bonobo-object.h>
-#include <gtk/gtksignal.h>
-#include <gtk/gtkbox.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkcheckbutton.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnome/gnome-exec.h>
-#include <libgnome/gnome-sound.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <libgnomeui/gnome-dialog-util.h>
-#include <libgnomeui/gnome-stock.h>
-#include <libgnomeui/gnome-uidefs.h>
-#include <cal-util/timeutil.h>
-#include "alarm.h"
-#include "alarm-notify-dialog.h"
-#include "alarm-queue.h"
-#include "config-data.h"
-#include "save.h"
-
-
-
-/* Whether the queueing system has been initialized */
-static gboolean alarm_queue_inited;
-
-/* When the alarm queue system is inited, this gets set to the last time an
- * alarm notification was issued. This lets us present any notifications that
- * should have happened while the alarm daemon was not running.
- */
-static time_t saved_notification_time;
-
-/* Clients we are monitoring for alarms */
-static GHashTable *client_alarms_hash = NULL;
-
-/* Structure that stores a client we are monitoring */
-typedef struct {
- /* Monitored client */
- CalClient *client;
-
- /* Number of times this client has been registered */
- int refcount;
-
- /* Hash table of component UID -> CompQueuedAlarms. If an element is
- * present here, then it means its cqa->queued_alarms contains at least
- * one queued alarm. When all the alarms for a component have been
- * dequeued, the CompQueuedAlarms structure is removed from the hash
- * table. Thus a CQA exists <=> it has queued alarms.
- */
- GHashTable *uid_alarms_hash;
-} ClientAlarms;
-
-/* Pair of a CalComponentAlarms and the mapping from queued alarm IDs to the
- * actual alarm instance structures.
- */
-typedef struct {
- /* The parent client alarms structure */
- ClientAlarms *parent_client;
-
- /* The actual component and its alarm instances */
- CalComponentAlarms *alarms;
-
- /* List of QueuedAlarm structures */
- GSList *queued_alarms;
-} CompQueuedAlarms;
-
-/* Pair of a queued alarm ID and the alarm trigger instance it refers to */
-typedef struct {
- /* Alarm ID from alarm.h */
- gpointer alarm_id;
-
- /* Instance from our parent CompQueuedAlarms->alarms->alarms list */
- CalAlarmInstance *instance;
-
- /* Whether this is a snoozed queued alarm or a normal one */
- guint snooze : 1;
-} QueuedAlarm;
-
-/* Alarm ID for the midnight refresh function */
-static gpointer midnight_refresh_id = NULL;
-
-static void display_notification (time_t trigger, CompQueuedAlarms *cqa,
- gpointer alarm_id, gboolean use_description);
-static void audio_notification (time_t trigger, CompQueuedAlarms *cqa, gpointer alarm_id);
-static void mail_notification (time_t trigger, CompQueuedAlarms *cqa, gpointer alarm_id);
-static void procedure_notification (time_t trigger, CompQueuedAlarms *cqa, gpointer alarm_id);
-
-
-
-/* Alarm queue engine */
-
-static void load_alarms_for_today (ClientAlarms *ca);
-static void midnight_refresh_cb (gpointer alarm_id, time_t trigger, gpointer data);
-
-/* Queues an alarm trigger for midnight so that we can load the next day's worth
- * of alarms.
- */
-static void
-queue_midnight_refresh (void)
-{
- time_t midnight;
- icaltimezone *zone;
-
- g_assert (midnight_refresh_id == NULL);
-
- zone = config_data_get_timezone ();
-
- midnight = time_day_end_with_zone (time (NULL), zone);
-
- midnight_refresh_id = alarm_add (midnight, midnight_refresh_cb, NULL, NULL);
- if (!midnight_refresh_id) {
- g_message ("queue_midnight_refresh(): Could not set up the midnight refresh alarm!");
- /* FIXME: what to do? */
- }
-}
-
-/* Loads a client's alarms; called from g_hash_table_foreach() */
-static void
-add_client_alarms_cb (gpointer key, gpointer value, gpointer data)
-{
- ClientAlarms *ca;
-
- ca = value;
- load_alarms_for_today (ca);
-}
-
-/* Loads the alarms for the new day every midnight */
-static void
-midnight_refresh_cb (gpointer alarm_id, time_t trigger, gpointer data)
-{
- /* Re-load the alarms for all clients */
-
- g_hash_table_foreach (client_alarms_hash, add_client_alarms_cb, NULL);
-
- /* Re-schedule the midnight update */
-
- midnight_refresh_id = NULL;
- queue_midnight_refresh ();
-}
-
-/* Looks up a client in the client alarms hash table */
-static ClientAlarms *
-lookup_client (CalClient *client)
-{
- return g_hash_table_lookup (client_alarms_hash, client);
-}
-
-/* Looks up a queued alarm based on its alarm ID */
-static QueuedAlarm *
-lookup_queued_alarm (CompQueuedAlarms *cqa, gpointer alarm_id)
-{
- GSList *l;
- QueuedAlarm *qa;
-
- qa = NULL;
-
- for (l = cqa->queued_alarms; l; l = l->next) {
- qa = l->data;
- if (qa->alarm_id == alarm_id)
- return qa;
- }
-
- /* not found, might have been updated/removed */
- return NULL;
-}
-
-/* Removes an alarm from the list of alarms of a component. If the alarm was
- * the last one listed for the component, it removes the component itself.
- */
-static void
-remove_queued_alarm (CompQueuedAlarms *cqa, gpointer alarm_id)
-{
- QueuedAlarm *qa;
- const char *uid;
- GSList *l;
-
- qa = NULL;
-
- for (l = cqa->queued_alarms; l; l = l->next) {
- qa = l->data;
- if (qa->alarm_id == alarm_id)
- break;
- }
-
- if (!l)
- return;
-
- cqa->queued_alarms = g_slist_remove_link (cqa->queued_alarms, l);
- g_slist_free_1 (l);
-
- g_free (qa);
-
- /* If this was the last queued alarm for this component, remove the
- * component itself.
- */
-
- if (cqa->queued_alarms != NULL)
- return;
-
- cal_component_get_uid (cqa->alarms->comp, &uid);
- g_hash_table_remove (cqa->parent_client->uid_alarms_hash, uid);
- cqa->parent_client = NULL;
-
- cal_component_alarms_free (cqa->alarms);
- cqa->alarms = NULL;
-
- g_free (cqa);
-}
-
-/* Callback used when an alarm triggers */
-static void
-alarm_trigger_cb (gpointer alarm_id, time_t trigger, gpointer data)
-{
- CompQueuedAlarms *cqa;
- CalComponent *comp;
- QueuedAlarm *qa;
- CalComponentAlarm *alarm;
- CalAlarmAction action;
-
- cqa = data;
- comp = cqa->alarms->comp;
-
- save_notification_time (trigger);
-
- qa = lookup_queued_alarm (cqa, alarm_id);
- if (!qa)
- return;
-
- /* Decide what to do based on the alarm action. We use the trigger that
- * is passed to us instead of the one from the instance structure
- * because this may be a snoozed alarm instead of an original
- * occurrence.
- */
-
- alarm = cal_component_get_alarm (comp, qa->instance->auid);
- g_assert (alarm != NULL);
-
- cal_component_alarm_get_action (alarm, &action);
- cal_component_alarm_free (alarm);
-
- switch (action) {
- case CAL_ALARM_AUDIO:
- audio_notification (trigger, cqa, alarm_id);
- break;
-
- case CAL_ALARM_DISPLAY:
- display_notification (trigger, cqa, alarm_id, TRUE);
- break;
-
- case CAL_ALARM_EMAIL:
- mail_notification (trigger, cqa, alarm_id);
- break;
-
- case CAL_ALARM_PROCEDURE:
- procedure_notification (trigger, cqa, alarm_id);
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
-}
-
-/* Adds the alarms in a CalComponentAlarms structure to the alarms queued for a
- * particular client. Also puts the triggers in the alarm timer queue.
- */
-static void
-add_component_alarms (ClientAlarms *ca, CalComponentAlarms *alarms)
-{
- const char *uid;
- CompQueuedAlarms *cqa;
- GSList *l;
-
- /* No alarms? */
- if (alarms->alarms == NULL) {
- cal_component_alarms_free (alarms);
- return;
- }
-
- cqa = g_new (CompQueuedAlarms, 1);
- cqa->parent_client = ca;
- cqa->alarms = alarms;
-
- cqa->queued_alarms = NULL;
-
- for (l = alarms->alarms; l; l = l->next) {
- CalAlarmInstance *instance;
- gpointer alarm_id;
- QueuedAlarm *qa;
-
- instance = l->data;
-
- alarm_id = alarm_add (instance->trigger, alarm_trigger_cb, cqa, NULL);
- if (!alarm_id) {
- g_message ("add_component_alarms(): Could not schedule a trigger for "
- "%ld, discarding...", (long) instance->trigger);
- continue;
- }
-
- qa = g_new (QueuedAlarm, 1);
- qa->alarm_id = alarm_id;
- qa->instance = instance;
- qa->snooze = FALSE;
-
- cqa->queued_alarms = g_slist_prepend (cqa->queued_alarms, qa);
- }
-
- cal_component_get_uid (alarms->comp, &uid);
-
- /* If we failed to add all the alarms, then we should get rid of the cqa */
- if (cqa->queued_alarms == NULL) {
- g_message ("add_component_alarms(): Could not add any of the alarms "
- "for the component `%s'; discarding it...", uid);
-
- cal_component_alarms_free (cqa->alarms);
- cqa->alarms = NULL;
-
- g_free (cqa);
- return;
- }
-
- cqa->queued_alarms = g_slist_reverse (cqa->queued_alarms);
- g_hash_table_insert (ca->uid_alarms_hash, (char *) uid, cqa);
-}
-
-/* Loads the alarms of a client for a given range of time */
-static void
-load_alarms (ClientAlarms *ca, time_t start, time_t end)
-{
- GSList *comp_alarms;
- GSList *l;
-
- comp_alarms = cal_client_get_alarms_in_range (ca->client, start, end);
-
- for (l = comp_alarms; l; l = l->next) {
- CalComponentAlarms *alarms;
-
- alarms = l->data;
- add_component_alarms (ca, alarms);
- }
-
- g_slist_free (comp_alarms);
-}
-
-/* Loads today's remaining alarms for a client */
-static void
-load_alarms_for_today (ClientAlarms *ca)
-{
- time_t now, day_end;
- icaltimezone *zone;
-
- now = time (NULL);
-
- zone = config_data_get_timezone ();
-
- day_end = time_day_end_with_zone (now, zone);
- load_alarms (ca, now, day_end);
-}
-
-/* Adds any alarms that should have occurred while the alarm daemon was not
- * running.
- */
-static void
-load_missed_alarms (ClientAlarms *ca)
-{
- time_t now;
-
- now = time (NULL);
-
- g_assert (saved_notification_time != -1);
-
- /* We add 1 to the saved_notification_time to make the time ranges
- * half-open; we do not want to display the "last" displayed alarm
- * twice, once when it occurs and once when the alarm daemon restarts.
- */
- load_alarms (ca, saved_notification_time + 1, now);
-}
-
-/* Called when a calendar client finished loading; we load its alarms */
-static void
-cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
-{
- ClientAlarms *ca;
-
- ca = data;
-
- if (status != CAL_CLIENT_OPEN_SUCCESS)
- return;
-
- load_alarms_for_today (ca);
- load_missed_alarms (ca);
-}
-
-/* Looks up a component's queued alarm structure in a client alarms structure */
-static CompQueuedAlarms *
-lookup_comp_queued_alarms (ClientAlarms *ca, const char *uid)
-{
- return g_hash_table_lookup (ca->uid_alarms_hash, uid);
-}
-
-/* Removes a component an its alarms */
-static void
-remove_comp (ClientAlarms *ca, const char *uid)
-{
- CompQueuedAlarms *cqa;
- GSList *l;
-
- cqa = lookup_comp_queued_alarms (ca, uid);
- if (!cqa)
- return;
-
- /* If a component is present, then it means we must have alarms queued
- * for it.
- */
- g_assert (cqa->queued_alarms != NULL);
-
- for (l = cqa->queued_alarms; l;) {
- QueuedAlarm *qa;
-
- qa = l->data;
-
- /* Get the next element here because the list element will go
- * away in remove_queued_alarm(). The qa will be freed there as
- * well.
- */
- l = l->next;
-
- alarm_remove (qa->alarm_id);
- remove_queued_alarm (cqa, qa->alarm_id);
- }
-
- /* The list should be empty now, and thus the queued component alarms
- * structure should have been freed and removed from the hash table.
- */
- g_assert (lookup_comp_queued_alarms (ca, uid) == NULL);
-}
-
-/* Called when a calendar component changes; we must reload its corresponding
- * alarms.
- */
-static void
-obj_updated_cb (CalClient *client, const char *uid, gpointer data)
-{
- ClientAlarms *ca;
- time_t now, day_end;
- CalComponentAlarms *alarms;
- gboolean found;
- icaltimezone *zone;
-
- ca = data;
-
- remove_comp (ca, uid);
-
- now = time (NULL);
-
- zone = config_data_get_timezone ();
-
- day_end = time_day_end_with_zone (now, zone);
-
- found = cal_client_get_alarms_for_object (ca->client, uid, now, day_end, &alarms);
-
- if (!found)
- return;
-
- add_component_alarms (ca, alarms);
-}
-
-/* Called when a calendar component is removed; we must delete its corresponding
- * alarms.
- */
-static void
-obj_removed_cb (CalClient *client, const char *uid, gpointer data)
-{
- ClientAlarms *ca;
-
- ca = data;
-
- remove_comp (ca, uid);
-}
-
-
-
-/* Notification functions */
-
-/* Creates a snooze alarm based on an existing one. The snooze offset is
- * compued with respect to the current time.
- */
-static void
-create_snooze (CompQueuedAlarms *cqa, gpointer alarm_id, int snooze_mins)
-{
- QueuedAlarm *orig_qa, *qa;
- CalAlarmInstance *instance;
- time_t t;
- gpointer new_id;
-
- orig_qa = lookup_queued_alarm (cqa, alarm_id);
- if (!orig_qa)
- return;
-
- t = time (NULL);
- t += snooze_mins * 60;
-
- new_id = alarm_add (t, alarm_trigger_cb, cqa, NULL);
- if (!new_id) {
- g_message ("create_snooze(): Could not schedule a trigger for "
- "%ld, discarding...", (long) t);
- return;
- }
-
- instance = g_new (CalAlarmInstance, 1);
- instance->auid = orig_qa->instance->auid;
- instance->trigger = t;
- instance->occur_start = orig_qa->instance->occur_start;
- instance->occur_end = orig_qa->instance->occur_end;
-
- cqa->alarms->alarms = g_slist_prepend (cqa->alarms->alarms, instance);
-
- qa = g_new (QueuedAlarm, 1);
- qa->alarm_id = new_id;
- qa->instance = instance;
- qa->snooze = TRUE;
-
- cqa->queued_alarms = g_slist_prepend (cqa->queued_alarms, qa);
-}
-
-/* Launches a component editor for a component */
-static void
-edit_component (CompQueuedAlarms *cqa)
-{
- CalComponent *comp;
- const char *uid;
- const char *uri;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_CompEditorFactory factory;
-
- comp = cqa->alarms->comp;
- cal_component_get_uid (comp, &uid);
-
- uri = cal_client_get_uri (cqa->parent_client->client);
-
- /* Get the factory */
-
- CORBA_exception_init (&ev);
- factory = oaf_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_CompEditorFactory",
- 0, NULL, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- g_message ("edit_component(): Could not activate the component editor factory");
- CORBA_exception_free (&ev);
- return;
- }
- CORBA_exception_free (&ev);
-
- /* Edit the component */
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_CompEditorFactory_editExisting (factory, uri, (char *) uid, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("edit_component(): Exception while editing the component");
-
- CORBA_exception_free (&ev);
-
- /* Get rid of the factory */
-
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (factory, &ev);
- if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("edit_component(): Could not unref the calendar component factory");
-
- CORBA_exception_free (&ev);
-}
-
-struct notify_dialog_closure {
- CompQueuedAlarms *cqa;
- gpointer alarm_id;
-};
-
-/* Callback used from the alarm notify dialog */
-static void
-notify_dialog_cb (AlarmNotifyResult result, int snooze_mins, gpointer data)
-{
- struct notify_dialog_closure *c;
-
- c = data;
-
- switch (result) {
- case ALARM_NOTIFY_SNOOZE:
- create_snooze (c->cqa, c->alarm_id, snooze_mins);
- break;
-
- case ALARM_NOTIFY_EDIT:
- edit_component (c->cqa);
- break;
-
- case ALARM_NOTIFY_CLOSE:
- /* Do nothing */
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- remove_queued_alarm (c->cqa, c->alarm_id);
- g_free (c);
-}
-
-/* Performs notification of a display alarm */
-static void
-display_notification (time_t trigger, CompQueuedAlarms *cqa,
- gpointer alarm_id, gboolean use_description)
-{
- CalComponent *comp;
- CalComponentVType vtype;
- CalComponentText text;
- QueuedAlarm *qa;
- const char *message;
- struct notify_dialog_closure *c;
- gboolean use_summary;
-
- comp = cqa->alarms->comp;
- qa = lookup_queued_alarm (cqa, alarm_id);
- if (!qa)
- return;
-
- vtype = cal_component_get_vtype (comp);
-
- /* Pick a sensible notification message. First we try the DESCRIPTION
- * from the alarm, then the SUMMARY of the component.
- */
-
- use_summary = TRUE;
- message = NULL;
-
- if (use_description) {
- CalComponentAlarm *alarm;
-
- alarm = cal_component_get_alarm (comp, qa->instance->auid);
- g_assert (alarm != NULL);
-
- cal_component_alarm_get_description (alarm, &text);
- cal_component_alarm_free (alarm);
-
- if (text.value) {
- message = text.value;
- use_summary = FALSE;
- }
- }
-
- if (use_summary) {
- cal_component_get_summary (comp, &text);
- if (text.value)
- message = text.value;
- else
- message = _("No description available.");
- }
-
- c = g_new (struct notify_dialog_closure, 1);
- c->cqa = cqa;
- c->alarm_id = alarm_id;
-
- if (!alarm_notify_dialog (trigger,
- qa->instance->occur_start, qa->instance->occur_end,
- vtype, message,
- notify_dialog_cb, c))
- g_message ("display_notification(): Could not create the alarm notify dialog");
-}
-
-/* Performs notification of an audio alarm */
-static void
-audio_notification (time_t trigger, CompQueuedAlarms *cqa,
- gpointer alarm_id)
-{
- QueuedAlarm *qa;
- CalComponent *comp;
- CalComponentAlarm *alarm;
- icalattach *attach;
-
- comp = cqa->alarms->comp;
- qa = lookup_queued_alarm (cqa, alarm_id);
- if (!qa)
- return;
-
- alarm = cal_component_get_alarm (comp, qa->instance->auid);
- g_assert (alarm != NULL);
-
- cal_component_alarm_get_attach (alarm, &attach);
- cal_component_alarm_free (alarm);
-
- if (attach && icalattach_get_is_url (attach)) {
- const char *url;
-
- url = icalattach_get_url (attach);
- g_assert (url != NULL);
-
- gnome_sound_play (url); /* this sucks */
- }
-
- if (attach)
- icalattach_unref (attach);
-
- /* We present a notification message in addition to playing the sound */
- display_notification (trigger, cqa, alarm_id, FALSE);
-}
-
-/* Performs notification of a mail alarm */
-static void
-mail_notification (time_t trigger, CompQueuedAlarms *cqa, gpointer alarm_id)
-{
- GtkWidget *dialog;
-
- /* FIXME */
-
- display_notification (trigger, cqa, alarm_id, FALSE);
-
- dialog = gnome_warning_dialog (_("Evolution does not support calendar reminders with\n"
- "email notifications yet, but this reminder was\n"
- "configured to send an email. Evolution will display\n"
- "a normal reminder dialog box instead."));
- gnome_dialog_run (GNOME_DIALOG (dialog));
-}
-
-/* Performs notification of a procedure alarm */
-static gboolean
-procedure_notification_dialog (const char *cmd, const char *url)
-{
- GtkWidget *dialog, *label, *checkbox;
- char *str;
- int btn;
-
- if (is_blessed_program (url))
- return TRUE;
-
- dialog = gnome_dialog_new (_("Warning"),
- GNOME_STOCK_BUTTON_YES,
- GNOME_STOCK_BUTTON_NO,
- NULL);
-
- str = g_strdup_printf (_("An Evolution Calendar reminder is about to trigger. "
- "This reminder is configured to run the following program:\n\n"
- " %s\n\n"
- "Are you sure you want to run this program?"),
- cmd);
- label = gtk_label_new (str);
- gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
- gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
- gtk_widget_show (label);
- gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox),
- label, TRUE, TRUE, 4);
- g_free (str);
-
- checkbox = gtk_check_button_new_with_label
- (_("Do not ask me about this program again."));
- gtk_widget_show (checkbox);
- gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox),
- checkbox, TRUE, TRUE, 4);
-
- /* Run the dialog */
- btn = gnome_dialog_run (GNOME_DIALOG (dialog));
- if (btn == GNOME_YES && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox)))
- save_blessed_program (url);
- gnome_dialog_close (GNOME_DIALOG (dialog));
-
- return (btn == GNOME_YES);
-}
-
-static void
-procedure_notification (time_t trigger, CompQueuedAlarms *cqa, gpointer alarm_id)
-{
- QueuedAlarm *qa;
- CalComponent *comp;
- CalComponentAlarm *alarm;
- CalComponentText description;
- icalattach *attach;
- const char *url;
- char *cmd;
- int result;
-
- comp = cqa->alarms->comp;
- qa = lookup_queued_alarm (cqa, alarm_id);
- if (!qa)
- return;
-
- alarm = cal_component_get_alarm (comp, qa->instance->auid);
- g_assert (alarm != NULL);
-
- cal_component_alarm_get_attach (alarm, &attach);
- cal_component_alarm_get_description (alarm, &description);
- cal_component_alarm_free (alarm);
-
- /* If the alarm has no attachment, simply display a notification dialog. */
- if (!attach)
- goto fallback;
-
- if (!icalattach_get_is_url (attach)) {
- icalattach_unref (attach);
- goto fallback;
- }
-
- url = icalattach_get_url (attach);
- g_assert (url != NULL);
-
- /* Ask for confirmation before executing the stuff */
- if (description.value)
- cmd = g_strconcat (url, " ", description.value, NULL);
- else
- cmd = (char *) url;
-
- result = 0;
- if (procedure_notification_dialog (cmd, url))
- result = gnome_execute_shell (NULL, cmd);
-
- if (cmd != (char *) url)
- g_free (cmd);
-
- icalattach_unref (attach);
-
- /* Fall back to display notification if we got an error */
- if (result < 0)
- goto fallback;
-
- remove_queued_alarm (cqa, alarm_id);
- return;
-
- fallback:
-
- display_notification (trigger, cqa, alarm_id, FALSE);
-}
-
-
-
-/**
- * alarm_queue_init:
- *
- * Initializes the alarm queueing system. This should be called near the
- * beginning of the program.
- **/
-void
-alarm_queue_init (void)
-{
- g_return_if_fail (alarm_queue_inited == FALSE);
-
- client_alarms_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
- queue_midnight_refresh ();
-
- saved_notification_time = get_saved_notification_time ();
- if (saved_notification_time == -1) {
- saved_notification_time = time (NULL);
- save_notification_time (saved_notification_time);
- }
-
- alarm_queue_inited = TRUE;
-}
-
-/**
- * alarm_queue_done:
- *
- * Shuts down the alarm queueing system. This should be called near the end
- * of the program. All the monitored calendar clients should already have been
- * unregistered with alarm_queue_remove_client().
- **/
-void
-alarm_queue_done (void)
-{
- g_return_if_fail (alarm_queue_inited);
-
- /* All clients must be unregistered by now */
- g_return_if_fail (g_hash_table_size (client_alarms_hash) == 0);
-
- g_hash_table_destroy (client_alarms_hash);
- client_alarms_hash = NULL;
-
- g_assert (midnight_refresh_id != NULL);
- alarm_remove (midnight_refresh_id);
- midnight_refresh_id = NULL;
-
- alarm_queue_inited = FALSE;
-}
-
-/**
- * alarm_queue_add_client:
- * @client: A calendar client.
- *
- * Adds a calendar client to the alarm queueing system. Alarm trigger
- * notifications will be presented at the appropriate times. The client should
- * be removed with alarm_queue_remove_client() when receiving notifications
- * from it is no longer desired.
- *
- * A client can be added any number of times to the alarm queueing system,
- * but any single alarm trigger will only be presented once for a particular
- * client. The client must still be removed the same number of times from the
- * queueing system when it is no longer wanted.
- **/
-void
-alarm_queue_add_client (CalClient *client)
-{
- ClientAlarms *ca;
-
- g_return_if_fail (alarm_queue_inited);
- g_return_if_fail (client != NULL);
- g_return_if_fail (IS_CAL_CLIENT (client));
-
- ca = lookup_client (client);
- if (ca) {
- ca->refcount++;
- return;
- }
-
- ca = g_new (ClientAlarms, 1);
-
- ca->client = client;
- gtk_object_ref (GTK_OBJECT (ca->client));
-
- ca->refcount = 1;
- g_hash_table_insert (client_alarms_hash, client, ca);
-
- ca->uid_alarms_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- if (cal_client_get_load_state (client) != CAL_CLIENT_LOAD_LOADED)
- gtk_signal_connect (GTK_OBJECT (client), "cal_opened",
- GTK_SIGNAL_FUNC (cal_opened_cb), ca);
-
- gtk_signal_connect (GTK_OBJECT (client), "obj_updated",
- GTK_SIGNAL_FUNC (obj_updated_cb), ca);
- gtk_signal_connect (GTK_OBJECT (client), "obj_removed",
- GTK_SIGNAL_FUNC (obj_removed_cb), ca);
-
- if (cal_client_get_load_state (client) == CAL_CLIENT_LOAD_LOADED) {
- load_alarms_for_today (ca);
- load_missed_alarms (ca);
- }
-}
-
-/* Called from g_hash_table_foreach(); adds a component UID to a list */
-static void
-add_uid_cb (gpointer key, gpointer value, gpointer data)
-{
- GSList **uids;
- const char *uid;
-
- uids = data;
- uid = key;
-
- *uids = g_slist_prepend (*uids, (char *) uid);
-}
-
-/* Removes all the alarms queued for a particular calendar client */
-static void
-remove_client_alarms (ClientAlarms *ca)
-{
- GSList *uids;
- GSList *l;
-
- /* First we build a list of UIDs so that we can remove them one by one */
-
- uids = NULL;
- g_hash_table_foreach (ca->uid_alarms_hash, add_uid_cb, &uids);
-
- for (l = uids; l; l = l->next) {
- const char *uid;
-
- uid = l->data;
-
- remove_comp (ca, uid);
- }
-
- g_slist_free (uids);
-
- /* The hash table should be empty now */
-
- g_assert (g_hash_table_size (ca->uid_alarms_hash) == 0);
-}
-
-/**
- * alarm_queue_remove_client:
- * @client: A calendar client.
- *
- * Removes a calendar client from the alarm queueing system.
- **/
-void
-alarm_queue_remove_client (CalClient *client)
-{
- ClientAlarms *ca;
-
- g_return_if_fail (alarm_queue_inited);
- g_return_if_fail (client != NULL);
- g_return_if_fail (IS_CAL_CLIENT (client));
-
- ca = lookup_client (client);
- g_return_if_fail (ca != NULL);
-
- g_assert (ca->refcount > 0);
- ca->refcount--;
-
- if (ca->refcount > 0)
- return;
-
- remove_client_alarms (ca);
-
- /* Clean up */
-
- gtk_signal_disconnect_by_data (GTK_OBJECT (ca->client), ca);
-
- gtk_object_unref (GTK_OBJECT (ca->client));
- ca->client = NULL;
-
- g_hash_table_destroy (ca->uid_alarms_hash);
- ca->uid_alarms_hash = NULL;
-
- g_free (ca);
-
- g_hash_table_remove (client_alarms_hash, client);
-}
diff --git a/calendar/gui/alarm-notify/alarm-queue.h b/calendar/gui/alarm-notify/alarm-queue.h
deleted file mode 100644
index a37119145f..0000000000
--- a/calendar/gui/alarm-notify/alarm-queue.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Evolution calendar - Alarm queueing engine
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@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 ALARM_QUEUE_H
-#define ALARM_QUEUE_H
-
-#include <cal-client/cal-client.h>
-
-
-void alarm_queue_init (void);
-void alarm_queue_done (void);
-
-void alarm_queue_add_client (CalClient *client);
-void alarm_queue_remove_client (CalClient *client);
-
-
-#endif
diff --git a/calendar/gui/alarm-notify/alarm.c b/calendar/gui/alarm-notify/alarm.c
deleted file mode 100644
index 8c6c4c59cd..0000000000
--- a/calendar/gui/alarm-notify/alarm.c
+++ /dev/null
@@ -1,305 +0,0 @@
-/* Evolution calendar - Low-level alarm timer mechanism
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Miguel de Icaza <miguel@ximian.com>
- * Federico Mena-Quintero <federico@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 <unistd.h>
-#include <time.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <gdk/gdk.h>
-#include "alarm.h"
-
-
-
-/* Our glib timeout */
-static guint timeout_id;
-
-/* The list of pending alarms */
-static GList *alarms = NULL;
-
-/* A queued alarm structure */
-typedef struct {
- time_t trigger;
- AlarmFunction alarm_fn;
- gpointer data;
- AlarmDestroyNotify destroy_notify_fn;
-} AlarmRecord;
-
-static void setup_timeout (time_t now);
-
-
-
-/* Removes the head alarm from the queue. Does not touch the timeout_id. */
-static void
-pop_alarm (void)
-{
- AlarmRecord *ar;
- GList *l;
-
- g_assert (alarms != NULL);
-
- ar = alarms->data;
-
- l = alarms;
- alarms = g_list_remove_link (alarms, l);
- g_list_free_1 (l);
-
- g_free (ar);
-}
-
-/* Callback from the alarm timeout */
-static gboolean
-alarm_ready_cb (gpointer data)
-{
- time_t now;
-
- g_assert (alarms != NULL);
- timeout_id = 0;
-
- now = time (NULL);
-
- while (alarms) {
- AlarmRecord *notify_id, *ar;
- AlarmRecord ar_copy;
-
- ar = alarms->data;
-
- if (ar->trigger > now)
- break;
-
- notify_id = ar;
-
- ar_copy = *ar;
- ar = &ar_copy;
-
- pop_alarm (); /* This will free the original AlarmRecord; that's why we copy it */
-
- (* ar->alarm_fn) (notify_id, ar->trigger, ar->data);
-
- if (ar->destroy_notify_fn)
- (* ar->destroy_notify_fn) (notify_id, ar->data);
- }
-
- if (alarms) {
- /* We need this check because one of the alarm_fn above may have
- * re-entered and added an alarm of its own, so the timer will
- * already be set up.
- */
- if (timeout_id == 0)
- setup_timeout (now);
- } else
- g_assert (timeout_id == 0);
-
- return FALSE;
-}
-
-/* Sets up a timeout for the next minute. We do not need to be concerned with
- * timezones here, as this is just a periodic check on the alarm queue.
- */
-static void
-setup_timeout (time_t now)
-{
- time_t next, diff;
- struct tm tm;
-
- g_assert (timeout_id == 0);
- g_assert (alarms != NULL);
-
- tm = *localtime (&now);
- tm.tm_sec = 0;
- tm.tm_min++; /* next minute */
-
- next = mktime (&tm);
- g_assert (next != -1);
-
- diff = next - now;
-
- g_assert (diff >= 0);
- timeout_id = g_timeout_add (diff * 1000, alarm_ready_cb, NULL);
-}
-
-/* Used from g_list_insert_sorted(); compares the trigger times of two AlarmRecord structures. */
-static int
-compare_alarm_by_time (gconstpointer a, gconstpointer b)
-{
- const AlarmRecord *ara = a;
- const AlarmRecord *arb = b;
- time_t diff;
-
- diff = ara->trigger - arb->trigger;
- return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
-}
-
-/* Adds an alarm to the queue and sets up the timer */
-static void
-queue_alarm (AlarmRecord *ar)
-{
- time_t now;
- AlarmRecord *old_head;
-
- if (alarms) {
- g_assert (timeout_id != 0);
-
- old_head = alarms->data;
- } else {
- g_assert (timeout_id == 0);
-
- old_head = NULL;
- }
-
- alarms = g_list_insert_sorted (alarms, ar, compare_alarm_by_time);
-
- if (old_head == alarms->data)
- return;
-
- /* Set the timer for removal upon activation */
-
- if (!old_head) {
- now = time (NULL);
- setup_timeout (now);
- }
-}
-
-
-
-/**
- * alarm_add:
- * @trigger: Time at which alarm will trigger.
- * @alarm_fn: Callback for trigger.
- * @data: Closure data for callback.
- *
- * Adds an alarm to trigger at the specified time. The @alarm_fn will be called
- * with the provided data and the alarm will be removed from the trigger list.
- *
- * Return value: An identifier for this alarm; it can be used to remove the
- * alarm later with alarm_remove(). If the trigger time occurs in the past, then
- * the alarm will not be queued and the function will return NULL.
- **/
-gpointer
-alarm_add (time_t trigger, AlarmFunction alarm_fn, gpointer data,
- AlarmDestroyNotify destroy_notify_fn)
-{
- AlarmRecord *ar;
-
- g_return_val_if_fail (trigger != -1, NULL);
- g_return_val_if_fail (alarm_fn != NULL, NULL);
-
- ar = g_new (AlarmRecord, 1);
- ar->trigger = trigger;
- ar->alarm_fn = alarm_fn;
- ar->data = data;
- ar->destroy_notify_fn = destroy_notify_fn;
-
- queue_alarm (ar);
-
- return ar;
-}
-
-/**
- * alarm_remove:
- * @alarm: A queued alarm identifier.
- *
- * Removes an alarm from the alarm queue.
- **/
-void
-alarm_remove (gpointer alarm)
-{
- AlarmRecord *notify_id, *ar;
- AlarmRecord ar_copy;
- AlarmRecord *old_head;
- GList *l;
-
- g_return_if_fail (alarm != NULL);
-
- ar = alarm;
-
- l = g_list_find (alarms, ar);
- if (!l) {
- g_message ("alarm_remove(): Requested removal of nonexistent alarm!");
- return;
- }
-
- old_head = alarms->data;
-
- notify_id = ar;
-
- if (old_head == ar) {
- ar_copy = *ar;
- ar = &ar_copy;
- pop_alarm (); /* This will free the original AlarmRecord; that's why we copy it */
- } else {
- alarms = g_list_remove_link (alarms, l);
- g_list_free_1 (l);
- }
-
- /* Reset the timeout */
-
- g_assert (timeout_id != 0);
-
- if (!alarms) {
- g_source_remove (timeout_id);
- timeout_id = 0;
- }
-
- /* Notify about destructiono of the alarm */
-
- if (ar->destroy_notify_fn)
- (* ar->destroy_notify_fn) (notify_id, ar->data);
-
-}
-
-/**
- * alarm_done:
- *
- * Terminates the alarm timer mechanism. This should be called at the end of
- * the program.
- **/
-void
-alarm_done (void)
-{
- GList *l;
-
- if (timeout_id == 0) {
- g_assert (alarms == NULL);
- return;
- }
-
- g_assert (alarms != NULL);
-
- g_source_remove (timeout_id);
- timeout_id = 0;
-
- for (l = alarms; l; l = l->next) {
- AlarmRecord *ar;
-
- ar = l->data;
-
- if (ar->destroy_notify_fn)
- (* ar->destroy_notify_fn) (ar, ar->data);
-
- g_free (ar);
- }
-
- g_list_free (alarms);
- alarms = NULL;
-}
diff --git a/calendar/gui/alarm-notify/alarm.h b/calendar/gui/alarm-notify/alarm.h
deleted file mode 100644
index 23fde886c9..0000000000
--- a/calendar/gui/alarm-notify/alarm.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Evolution calendar - Low-level alarm timer mechanism
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Miguel de Icaza <miguel@ximian.com>
- * Federico Mena-Quintero <federico@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 ALARM_H
-#define ALARM_H
-
-#include <time.h>
-#include <glib.h>
-
-
-
-typedef void (* AlarmFunction) (gpointer alarm_id, time_t trigger, gpointer data);
-typedef void (* AlarmDestroyNotify) (gpointer alarm_id, gpointer data);
-
-void alarm_done (void);
-
-gpointer alarm_add (time_t trigger, AlarmFunction alarm_fn, gpointer data,
- AlarmDestroyNotify destroy_notify_fn);
-void alarm_remove (gpointer alarm);
-
-
-
-#endif
diff --git a/calendar/gui/alarm-notify/config-data.c b/calendar/gui/alarm-notify/config-data.c
deleted file mode 100644
index 0e2846308f..0000000000
--- a/calendar/gui/alarm-notify/config-data.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Evolution calendar - Configuration values for the alarm notification daemon
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "config-data.h"
-#include "save.h"
-
-
-
-/* Whether we have initied ourselves by reading the data from the configuration engine */
-static gboolean inited = FALSE;
-static EConfigListener *config;
-
-
-
-/* Copied from ../calendar-config.c; returns whether the locale has 'am' and
- * 'pm' strings defined.
- */
-static gboolean
-locale_supports_12_hour_format (void)
-{
- char s[16];
- time_t t = 0;
-
- strftime (s, sizeof s, "%p", gmtime (&t));
- return s[0] != '\0';
-}
-
-static void
-do_cleanup (void)
-{
- gtk_object_unref (GTK_OBJECT (config));
- config = NULL;
- inited = FALSE;
-}
-
-/* Ensures that the configuration values have been read */
-static void
-ensure_inited (void)
-{
- if (inited)
- return;
-
- inited = TRUE;
-
- config = e_config_listener_new ();
- if (!E_IS_CONFIG_LISTENER (config)) {
- inited = FALSE;
- return;
- }
-
- g_atexit ((GVoidFunc) do_cleanup);
-}
-
-EConfigListener *
-config_data_get_listener (void)
-{
- ensure_inited ();
- return config;
-}
-
-icaltimezone *
-config_data_get_timezone (void)
-{
- char *location;
- icaltimezone *local_timezone;
-
- ensure_inited ();
-
- location = e_config_listener_get_string_with_default (config,
- "/Calendar/Display/Timezone",
- "UTC", NULL);
- if (location && location[0]) {
- local_timezone = icaltimezone_get_builtin_timezone (location);
- } else {
- local_timezone = icaltimezone_get_utc_timezone ();
- }
-
- g_free (location);
-
- return local_timezone;
-}
-
-gboolean
-config_data_get_24_hour_format (void)
-{
- ensure_inited ();
-
- if (locale_supports_12_hour_format ()) {
- return e_config_listener_get_boolean_with_default (
- config,
- "/Calendar/Display/Use24HourFormat", FALSE, NULL);
- }
-
- return TRUE;
-}
diff --git a/calendar/gui/alarm-notify/config-data.h b/calendar/gui/alarm-notify/config-data.h
deleted file mode 100644
index c7041be111..0000000000
--- a/calendar/gui/alarm-notify/config-data.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Evolution calendar - Configuration values for the alarm notification daemon
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@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 CONFIG_DATA_H
-#define CONFIG_DATA_H
-
-#include <glib.h>
-#include <ical.h>
-#include <e-util/e-config-listener.h>
-
-EConfigListener *config_data_get_listener (void);
-
-icaltimezone *config_data_get_timezone (void);
-gboolean config_data_get_24_hour_format (void);
-
-#endif
diff --git a/calendar/gui/alarm-notify/notify-main.c b/calendar/gui/alarm-notify/notify-main.c
deleted file mode 100644
index c0af3ea51a..0000000000
--- a/calendar/gui/alarm-notify/notify-main.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* Evolution calendar - Alarm notification service main file
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-init.h>
-#include <libgnomevfs/gnome-vfs-init.h>
-#include <glade/glade.h>
-#include <bonobo/bonobo-main.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <liboaf/liboaf.h>
-#include "alarm.h"
-#include "alarm-queue.h"
-#include "alarm-notify.h"
-#include "save.h"
-
-
-
-static GnomeClient *master_client = NULL;
-
-static BonoboGenericFactory *factory;
-
-static AlarmNotify *alarm_notify_service = NULL;
-
-
-/* Callback for the master client's "die" signal. We must terminate the daemon
- * since the session is ending.
- */
-static void
-client_die_cb (GnomeClient *client)
-{
- gtk_main_quit ();
-}
-
-/* Sees if a session manager is present. If so, it tells the SM how to restart
- * the daemon when the session starts. It also sets the die callback so that
- * the daemon can terminate properly when the session ends.
- */
-static void
-set_session_parameters (char **argv)
-{
- int flags;
- char *args[2];
-
- master_client = gnome_master_client ();
- flags = gnome_client_get_flags (master_client);
-
- if (!(flags & GNOME_CLIENT_IS_CONNECTED))
- return;
-
- /* The daemon should always be started up by the session manager when
- * the session starts. The daemon will take care of loading whatever
- * calendars it was told to load.
- */
- gnome_client_set_restart_style (master_client, GNOME_RESTART_ANYWAY);
-
- args[0] = argv[0];
- args[1] = NULL;
-
- gnome_client_set_restart_command (master_client, 1, args);
-
- gtk_signal_connect (GTK_OBJECT (master_client), "die",
- GTK_SIGNAL_FUNC (client_die_cb), NULL);
-}
-
-/* Factory function for the alarm notify service; just creates and references a
- * singleton service object.
- */
-static BonoboObject *
-alarm_notify_factory_fn (BonoboGenericFactory *factory, void *data)
-{
- if (!alarm_notify_service) {
- alarm_notify_service = alarm_notify_new ();
- g_assert (alarm_notify_service != NULL);
- }
-
- bonobo_object_ref (BONOBO_OBJECT (alarm_notify_service));
- return BONOBO_OBJECT (alarm_notify_service);
-}
-
-/* Loads the calendars that the alarm daemon has been told to load in the past */
-static gboolean
-load_calendars (gpointer user_data)
-{
- GPtrArray *uris;
- int i;
-
- alarm_queue_init ();
-
- /* create the alarm notification service */
- if (!alarm_notify_service) {
- alarm_notify_service = alarm_notify_new ();
- g_assert (alarm_notify_service != NULL);
- }
-
- uris = get_calendars_to_load ();
- if (!uris) {
- g_message ("load_calendars(): Could not get the list of calendars to load");
- return TRUE; /* should we continue retrying? */;
- }
-
- for (i = 0; i < uris->len; i++) {
- char *uri;
- CORBA_Environment ev;
-
- uri = uris->pdata[i];
-
- CORBA_exception_init (&ev);
- alarm_notify_add_calendar (alarm_notify_service, uri, FALSE, &ev);
-
- if (ev._major == CORBA_USER_EXCEPTION) {
- char *ex_id;
-
- ex_id = CORBA_exception_id (&ev);
- if (strcmp (ex_id, ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI) == 0)
- g_message ("load_calendars(): Invalid URI `%s'; will not load "
- "that calendar.", uri);
- else if (strcmp (ex_id,
- ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError)
- == 0)
- g_message ("load_calendars(): Could not contact the backend "
- "while trying to load `%s'", uri);
- } else if (ev._major != CORBA_NO_EXCEPTION)
- g_message ("load_calendars(): Exception while loading calendar `%s'", uri);
-
- CORBA_exception_free (&ev);
-
- g_free (uri);
- }
-
- g_ptr_array_free (uris, TRUE);
-
- return FALSE;
-}
-
-int
-main (int argc, char **argv)
-{
- free (malloc (8));
-
- bindtextdomain (PACKAGE, EVOLUTION_LOCALEDIR);
- textdomain (PACKAGE);
-
- if (gnome_init_with_popt_table ("evolution-alarm-notify", VERSION, argc, argv,
- oaf_popt_options, 0, NULL) != 0)
- g_error (_("Could not initialize GNOME"));
-
- oaf_init (argc, argv);
-
- if (bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL) == FALSE)
- g_error (_("Could not initialize Bonobo"));
-
- if (!gnome_vfs_init ())
- g_error (_("Could not initialize gnome-vfs"));
-
- glade_gnome_init ();
-
- factory = bonobo_generic_factory_new ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify_Factory",
- alarm_notify_factory_fn, NULL);
- if (!factory)
- g_error (_("Could not create the alarm notify service factory"));
-
- set_session_parameters (argv);
-
- g_idle_add ((GSourceFunc) load_calendars, NULL);
-
- bonobo_main ();
-
- bonobo_object_unref (BONOBO_OBJECT (factory));
- factory = NULL;
-
- /* FIXME: free the alarm_notify_service */
-
- alarm_queue_done ();
- alarm_done ();
-
- gnome_vfs_shutdown ();
-
- return 0;
-}
diff --git a/calendar/gui/alarm-notify/save.c b/calendar/gui/alarm-notify/save.c
deleted file mode 100644
index dc78686250..0000000000
--- a/calendar/gui/alarm-notify/save.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/* Evolution calendar - Functions to save alarm notification times
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <bonobo/bonobo-arg.h>
-#include <bonobo/bonobo-exception.h>
-#include <bonobo/bonobo-moniker-util.h>
-#include "evolution-calendar.h"
-#include "config-data.h"
-#include "save.h"
-
-
-
-/* Key names for the configuration values */
-
-#define KEY_LAST_NOTIFICATION_TIME "/Calendar/AlarmNotify/LastNotificationTime"
-#define KEY_NUM_CALENDARS_TO_LOAD "/Calendar/AlarmNotify/NumCalendarsToLoad"
-#define BASE_KEY_CALENDAR_TO_LOAD "/Calendar/AlarmNotify/CalendarToLoad"
-#define KEY_NUM_BLESSED_PROGRAMS "/Calendar/AlarmNotify/NumBlessedPrograms"
-#define BASE_KEY_BLESSED_PROGRAM "/Calendar/AlarmNotify/BlessedProgram"
-
-
-
-/**
- * save_notification_time:
- * @t: A time value.
- *
- * Saves the last notification time so that it can be fetched the next time the
- * alarm daemon is run. This way the daemon can show alarms that should have
- * triggered while it was not running.
- **/
-void
-save_notification_time (time_t t)
-{
- EConfigListener *cl;
- time_t current_t;
-
- g_return_if_fail (t != -1);
-
- if (!(cl = config_data_get_listener ()))
- return;
-
- /* we only store the new notification time if it is bigger
- than the already stored one */
- current_t = e_config_listener_get_long_with_default (cl, KEY_LAST_NOTIFICATION_TIME,
- -1, NULL);
- if (t > current_t)
- e_config_listener_set_long (cl, KEY_LAST_NOTIFICATION_TIME, (long) t);
-}
-
-/**
- * get_saved_notification_time:
- *
- * Queries the last saved value for alarm notification times.
- *
- * Return value: The last saved value, or -1 if no value had been saved before.
- **/
-time_t
-get_saved_notification_time (void)
-{
- EConfigListener *cl;
- long t;
-
- if (!(cl = config_data_get_listener ()))
- return -1;
-
- t = e_config_listener_get_long_with_default (cl, KEY_LAST_NOTIFICATION_TIME, -1, NULL);
-
- return (time_t) t;
-}
-
-/**
- * save_calendars_to_load:
- * @uris: A list of URIs of calendars.
- *
- * Saves the list of calendars that should be loaded the next time the alarm
- * daemon starts up.
- **/
-void
-save_calendars_to_load (GPtrArray *uris)
-{
- EConfigListener *cl;
- int len, i;
-
- g_return_if_fail (uris != NULL);
-
- if (!(cl = config_data_get_listener ()))
- return;
-
- len = uris->len;
-
- e_config_listener_set_long (cl, KEY_NUM_CALENDARS_TO_LOAD, len);
-
- for (i = 0; i < len; i++) {
- const char *uri;
- char *key;
-
- uri = uris->pdata[i];
-
- key = g_strdup_printf ("%s%d", BASE_KEY_CALENDAR_TO_LOAD, i);
- e_config_listener_set_string (cl, key, uri);
- g_free (key);
- }
-}
-
-/**
- * get_calendars_to_load:
- *
- * Gets the list of calendars that should be loaded when the alarm daemon starts
- * up.
- *
- * Return value: A list of URIs, or NULL if the value could not be retrieved.
- **/
-GPtrArray *
-get_calendars_to_load (void)
-{
- EConfigListener *cl;
- GPtrArray *uris;
- int len, i;
-
- if (!(cl = config_data_get_listener ()))
- return NULL;
-
- /* Getting the default value below is not necessarily an error, as we
- * may not have saved the list of calendar yet.
- */
-
- len = e_config_listener_get_long_with_default (cl, KEY_NUM_CALENDARS_TO_LOAD, 0, NULL);
-
- uris = g_ptr_array_new ();
- g_ptr_array_set_size (uris, len);
-
- for (i = 0; i < len; i++) {
- char *key;
- gboolean used_default;
-
- key = g_strdup_printf ("%s%d", BASE_KEY_CALENDAR_TO_LOAD, i);
- uris->pdata[i] = e_config_listener_get_string_with_default (cl, key, "", &used_default);
- if (used_default)
- g_message ("get_calendars_to_load(): Could not read calendar name %d", i);
-
- g_free (key);
- }
-
- return uris;
-}
-
-/**
- * save_blessed_program:
- * @program: a program name
- *
- * Saves a program name as "blessed"
- **/
-void
-save_blessed_program (const char *program)
-{
- EConfigListener *cl;
- char *key;
- int len;
-
- g_return_if_fail (program != NULL);
-
- if (!(cl = config_data_get_listener ()))
- return;
-
- /* Up the number saved */
- len = e_config_listener_get_long_with_default (cl, KEY_NUM_BLESSED_PROGRAMS, 0, NULL);
- len++;
-
- e_config_listener_set_long (cl, KEY_NUM_BLESSED_PROGRAMS, len);
-
- /* Save the program name */
- key = g_strdup_printf ("%s%d", BASE_KEY_BLESSED_PROGRAM, len - 1);
- e_config_listener_set_string (cl, key, program);
- g_free (key);
-}
-
-/**
- * is_blessed_program:
- * @program: a program name
- *
- * Checks to see if a program is blessed
- *
- * Return value: TRUE if program is blessed, FALSE otherwise
- **/
-gboolean
-is_blessed_program (const char *program)
-{
- EConfigListener *cl;
- int len, i;
-
- g_return_val_if_fail (program != NULL, FALSE);
-
- if (!(cl = config_data_get_listener ()))
- return FALSE;
-
- /* Getting the default value below is not necessarily an error, as we
- * may not have saved the list of calendar yet.
- */
-
- len = e_config_listener_get_long_with_default (cl, KEY_NUM_BLESSED_PROGRAMS, 0, NULL);
-
- for (i = 0; i < len; i++) {
- char *key, *value;
- gboolean used_default;
-
- key = g_strdup_printf ("%s%d", BASE_KEY_BLESSED_PROGRAM, i);
- value = e_config_listener_get_string_with_default (cl, key, "", &used_default);
- if (used_default)
- g_message ("get_calendars_to_load(): Could not read calendar name %d", i);
-
- if (value != NULL && !strcmp (value, program)) {
- g_free (key);
- g_free (value);
- return TRUE;
- }
-
- g_free (key);
- g_free (value);
- }
-
- return FALSE;
-}
diff --git a/calendar/gui/alarm-notify/save.h b/calendar/gui/alarm-notify/save.h
deleted file mode 100644
index 50371e0a5b..0000000000
--- a/calendar/gui/alarm-notify/save.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Evolution calendar - Functions to save alarm notification times
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@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 SAVE_H
-#define SAVE_H
-
-#include <time.h>
-#include <bonobo-conf/bonobo-config-database.h>
-
-Bonobo_ConfigDatabase get_config_db (void);
-void discard_config_db (Bonobo_ConfigDatabase db);
-
-void save_notification_time (time_t t);
-time_t get_saved_notification_time (void);
-
-void save_calendars_to_load (GPtrArray *uris);
-GPtrArray *get_calendars_to_load (void);
-
-void save_blessed_program (const char *program);
-gboolean is_blessed_program (const char *program);
-
-#endif
diff --git a/calendar/gui/cal-search-bar.c b/calendar/gui/cal-search-bar.c
deleted file mode 100644
index 2483b2b126..0000000000
--- a/calendar/gui/cal-search-bar.c
+++ /dev/null
@@ -1,544 +0,0 @@
-/* Evolution calendar - Search bar widget for calendar views
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-#include <gtk/gtkmenu.h>
-#include <gtk/gtkmenuitem.h>
-#include <gtk/gtkoptionmenu.h>
-#include <gtk/gtksignal.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <gal/widgets/e-unicode.h>
-#include "cal-search-bar.h"
-
-
-
-/* IDs and option items for the ESearchBar */
-enum {
- SEARCH_ANY_FIELD_CONTAINS,
- SEARCH_SUMMARY_CONTAINS,
- SEARCH_DESCRIPTION_CONTAINS,
- SEARCH_COMMENT_CONTAINS,
- SEARCH_CATEGORY_IS,
-};
-
-static ESearchBarItem search_option_items[] = {
- { N_("Any field contains"), SEARCH_ANY_FIELD_CONTAINS, NULL },
- { N_("Summary contains"), SEARCH_SUMMARY_CONTAINS, NULL },
- { N_("Description contains"), SEARCH_DESCRIPTION_CONTAINS, NULL },
- { N_("Comment contains"), SEARCH_COMMENT_CONTAINS, NULL },
- { N_("Category is"), SEARCH_CATEGORY_IS, NULL },
- { NULL, -1, NULL }
-};
-
-/* IDs for the categories suboptions */
-#define CATEGORIES_ALL 0
-#define CATEGORIES_UNMATCHED 1
-#define CATEGORIES_OFFSET 3
-
-/* Private part of the CalSearchBar structure */
-struct CalSearchBarPrivate {
- /* Array of categories */
- GPtrArray *categories;
-};
-
-
-
-static void cal_search_bar_class_init (CalSearchBarClass *class);
-static void cal_search_bar_init (CalSearchBar *cal_search);
-static void cal_search_bar_destroy (GtkObject *object);
-
-static void cal_search_bar_search_activated (ESearchBar *search);
-
-static ESearchBarClass *parent_class = NULL;
-
-/* Signal IDs */
-enum {
- SEXP_CHANGED,
- CATEGORY_CHANGED,
- LAST_SIGNAL
-};
-
-static guint cal_search_bar_signals[LAST_SIGNAL] = { 0 };
-
-
-
-/**
- * cal_search_bar_get_type:
- *
- * Registers the #CalSearchBar class if necessary and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the #CalSearchBar class.
- **/
-GtkType
-cal_search_bar_get_type (void)
-{
- static GtkType cal_search_bar_type = 0;
-
- if (!cal_search_bar_type) {
- static const GtkTypeInfo cal_search_bar_info = {
- "CalSearchBar",
- sizeof (CalSearchBar),
- sizeof (CalSearchBarClass),
- (GtkClassInitFunc) cal_search_bar_class_init,
- (GtkObjectInitFunc) cal_search_bar_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- cal_search_bar_type = gtk_type_unique (E_SEARCH_BAR_TYPE, &cal_search_bar_info);
- }
-
- return cal_search_bar_type;
-}
-
-/* Class initialization function for the calendar search bar */
-static void
-cal_search_bar_class_init (CalSearchBarClass *class)
-{
- ESearchBarClass *e_search_bar_class;
- GtkObjectClass *object_class;
-
- e_search_bar_class = (ESearchBarClass *) class;
- object_class = (GtkObjectClass *) class;
-
- parent_class = gtk_type_class (E_SEARCH_BAR_TYPE);
-
- cal_search_bar_signals[SEXP_CHANGED] =
- gtk_signal_new ("sexp_changed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalSearchBarClass, sexp_changed),
- gtk_marshal_NONE__STRING,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_STRING);
-
- cal_search_bar_signals[CATEGORY_CHANGED] =
- gtk_signal_new ("category_changed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CalSearchBarClass, category_changed),
- gtk_marshal_NONE__STRING,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_STRING);
-
- gtk_object_class_add_signals (object_class, cal_search_bar_signals, LAST_SIGNAL);
-
- class->sexp_changed = NULL;
- class->category_changed = NULL;
-
- e_search_bar_class->search_activated = cal_search_bar_search_activated;
-
- object_class->destroy = cal_search_bar_destroy;
-}
-
-/* Object initialization function for the calendar search bar */
-static void
-cal_search_bar_init (CalSearchBar *cal_search)
-{
- CalSearchBarPrivate *priv;
-
- priv = g_new (CalSearchBarPrivate, 1);
- cal_search->priv = priv;
-
- priv->categories = g_ptr_array_new ();
- g_ptr_array_set_size (priv->categories, 0);
-}
-
-/* Frees an array of categories */
-static void
-free_categories (GPtrArray *categories)
-{
- int i;
-
- for (i = 0; i < categories->len; i++) {
- g_assert (categories->pdata[i] != NULL);
- g_free (categories->pdata[i]);
- }
-
- g_ptr_array_free (categories, TRUE);
-}
-
-/* Destroy handler for the calendar search bar */
-static void
-cal_search_bar_destroy (GtkObject *object)
-{
- CalSearchBar *cal_search;
- CalSearchBarPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CAL_SEARCH_BAR (object));
-
- cal_search = CAL_SEARCH_BAR (object);
- priv = cal_search->priv;
-
- if (priv->categories) {
- free_categories (priv->categories);
- priv->categories = NULL;
- }
-
- g_free (priv);
- cal_search->priv = NULL;
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-
-
-/* Emits the "sexp_changed" signal for the calendar search bar */
-static void
-notify_sexp_changed (CalSearchBar *cal_search, const char *sexp)
-{
- gtk_signal_emit (GTK_OBJECT (cal_search), cal_search_bar_signals[SEXP_CHANGED],
- sexp);
-}
-
-/* Returns the string of the currently selected category, NULL for "Unmatched",
- * or (const char *) 1 for "All".
- */
-static const char *
-get_current_category (CalSearchBar *cal_search)
-{
- CalSearchBarPrivate *priv;
- int id, subid;
-
- priv = cal_search->priv;
-
- g_assert (priv->categories != NULL);
-
- id = e_search_bar_get_item_id (E_SEARCH_BAR (cal_search));
- if (id != SEARCH_CATEGORY_IS)
- return NULL;
-
- subid = e_search_bar_get_subitem_id (E_SEARCH_BAR (cal_search));
- if (subid == CATEGORIES_ALL)
- return (const char *) 1;
- else if (subid == CATEGORIES_UNMATCHED)
- return NULL;
- else {
- int i;
-
- i = subid - CATEGORIES_OFFSET;
- g_assert (i >= 0 && i < priv->categories->len);
-
- return priv->categories->pdata[i];
- }
-}
-
-/* Sets the query string to be (contains? "field" "text") */
-static void
-notify_query_contains (CalSearchBar *cal_search, const char *field)
-{
- char *text;
- char *sexp;
-
- text = e_search_bar_get_text (E_SEARCH_BAR (cal_search));
- if (!text)
- return; /* This is an error in the UTF8 conversion, not an empty string! */
-
- sexp = g_strdup_printf ("(contains? \"%s\" \"%s\")", field, text);
- g_free (text);
-
- notify_sexp_changed (cal_search, sexp);
- g_free (sexp);
-}
-
-/* Returns a sexp for the selected category in the drop-down menu. The "All"
- * option is returned as (const char *) 1, and the "Unfiled" option is returned
- * as NULL.
- */
-static char *
-get_category_sexp (CalSearchBar *cal_search)
-{
- const char *category;
-
- category = get_current_category (cal_search);
-
- if (category == NULL)
- return g_strdup ("(has-categories? #f)"); /* Unfiled items */
- else if (category == (const char *) 1)
- return NULL; /* All items */
- else
- return g_strdup_printf ("(has-categories? \"%s\")", category); /* Specific category */
-}
-
-/* Sets the query string to the appropriate match for categories */
-static void
-notify_category_is (CalSearchBar *cal_search)
-{
- char *sexp;
-
- sexp = get_category_sexp (cal_search);
- if (!sexp)
- notify_sexp_changed (cal_search, "#t"); /* Match all */
- else
- notify_sexp_changed (cal_search, sexp);
-
- if (sexp)
- g_free (sexp);
-}
-
-/* Creates a new query from the values in the widgets and notifies upstream */
-static void
-regen_query (CalSearchBar *cal_search)
-{
- CalSearchBarPrivate *priv;
- int id;
- const char *category;
-
- priv = cal_search->priv;
-
- /* Fetch the data from the ESearchBar's entry widgets */
-
- id = e_search_bar_get_item_id (E_SEARCH_BAR (cal_search));
-
- /* Generate the different types of queries */
-
- switch (id) {
- case SEARCH_ANY_FIELD_CONTAINS:
- notify_query_contains (cal_search, "any");
- break;
-
- case SEARCH_SUMMARY_CONTAINS:
- notify_query_contains (cal_search, "summary");
- break;
-
- case SEARCH_DESCRIPTION_CONTAINS:
- notify_query_contains (cal_search, "description");
- break;
-
- case SEARCH_COMMENT_CONTAINS:
- notify_query_contains (cal_search, "comment");
- break;
-
- case SEARCH_CATEGORY_IS:
- notify_category_is (cal_search);
-
- category = cal_search_bar_get_category (cal_search);
- gtk_signal_emit (GTK_OBJECT (cal_search), cal_search_bar_signals[CATEGORY_CHANGED],
- category);
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-/* search_activated handler for the calendar search bar */
-static void
-cal_search_bar_search_activated (ESearchBar *search)
-{
- CalSearchBar *cal_search;
-
- cal_search = CAL_SEARCH_BAR (search);
- regen_query (cal_search);
-}
-
-
-
-/* Creates the suboptions menu for the ESearchBar with the list of categories */
-static void
-make_suboptions (CalSearchBar *cal_search)
-{
- CalSearchBarPrivate *priv;
- ESearchBarSubitem *subitems;
- int i;
-
- priv = cal_search->priv;
-
- g_assert (priv->categories != NULL);
-
- /* Categories plus "all", "unmatched", separator, terminator */
- subitems = g_new (ESearchBarSubitem, priv->categories->len + 3 + 1);
-
- /* All, unmatched, separator */
-
- subitems[0].text = _("Any Category");
- subitems[0].id = CATEGORIES_ALL;
- subitems[0].translate = FALSE;
-
- subitems[1].text = _("Unmatched");
- subitems[1].id = CATEGORIES_UNMATCHED;
- subitems[1].translate = FALSE;
-
- /* All the other items */
-
- if (priv->categories->len > 0) {
- subitems[2].text = NULL; /* separator */
- subitems[2].id = 0;
-
- for (i = 0; i < priv->categories->len; i++) {
- const char *category;
- char *str;
-
- category = priv->categories->pdata[i];
- str = e_utf8_to_gtk_string (GTK_WIDGET (cal_search), category);
- if (!str)
- str = g_strdup ("");
-
- subitems[i + CATEGORIES_OFFSET].text = str;
- subitems[i + CATEGORIES_OFFSET].id = i + CATEGORIES_OFFSET;
- subitems[i + CATEGORIES_OFFSET].translate = FALSE;
- }
-
- subitems[i + CATEGORIES_OFFSET].id = -1; /* terminator */
- } else
- subitems[2].id = -1; /* terminator */
-
- e_search_bar_set_suboption (E_SEARCH_BAR (cal_search), SEARCH_CATEGORY_IS, subitems);
-
- /* Free the strings */
- for (i = 0; i < priv->categories->len; i++)
- g_free (subitems[i + CATEGORIES_OFFSET].text);
-
- g_free (subitems);
-}
-
-/**
- * cal_search_bar_construct:
- * @cal_search: A calendar search bar.
- *
- * Constructs a calendar search bar by binding its menu and option items.
- *
- * Return value: The same value as @cal_search.
- **/
-CalSearchBar *
-cal_search_bar_construct (CalSearchBar *cal_search)
-{
- g_return_val_if_fail (cal_search != NULL, NULL);
- g_return_val_if_fail (IS_CAL_SEARCH_BAR (cal_search), NULL);
-
- e_search_bar_construct (E_SEARCH_BAR (cal_search), NULL, search_option_items);
- make_suboptions (cal_search);
-
- e_search_bar_set_ids (E_SEARCH_BAR (cal_search), SEARCH_CATEGORY_IS, CATEGORIES_ALL);
-
- return cal_search;
-}
-
-/**
- * cal_search_bar_new:
- *
- * Creates a new calendar search bar.
- *
- * Return value: A newly-created calendar search bar. You should connect to the
- * "sexp_changed" signal to monitor changes in the generated sexps.
- **/
-GtkWidget *
-cal_search_bar_new (void)
-{
- CalSearchBar *cal_search;
-
- cal_search = gtk_type_new (TYPE_CAL_SEARCH_BAR);
- return GTK_WIDGET (cal_search_bar_construct (cal_search));
-}
-
-/* Used from qsort() */
-static int
-compare_categories_cb (const void *a, const void *b)
-{
- const char **ca, **cb;
-
- ca = (const char **) a;
- cb = (const char **) b;
-
- /* FIXME: should use some utf8 strcoll() thingy */
- return strcmp (*ca, *cb);
-}
-
-/* Creates a sorted array of categories based on the original one; copies the
- * string values.
- */
-static GPtrArray *
-sort_categories (GPtrArray *categories)
-{
- GPtrArray *c;
- int i;
-
- c = g_ptr_array_new ();
- g_ptr_array_set_size (c, categories->len);
-
- for (i = 0; i < categories->len; i++)
- c->pdata[i] = g_strdup (categories->pdata[i]);
-
- qsort (c->pdata, c->len, sizeof (gpointer), compare_categories_cb);
-
- return c;
-}
-
-/**
- * cal_search_bar_set_categories:
- * @cal_search: A calendar search bar.
- * @categories: Array of pointers to strings for the category names.
- *
- * Sets the list of categories that are to be shown in the drop-down list
- * of a calendar search bar. The search bar will automatically add an item
- * for "unfiled" components, that is, those that have no categories assigned
- * to them.
- **/
-void
-cal_search_bar_set_categories (CalSearchBar *cal_search, GPtrArray *categories)
-{
- CalSearchBarPrivate *priv;
-
- g_return_if_fail (cal_search != NULL);
- g_return_if_fail (IS_CAL_SEARCH_BAR (cal_search));
- g_return_if_fail (categories != NULL);
-
- priv = cal_search->priv;
-
- g_assert (priv->categories != NULL);
- free_categories (priv->categories);
-
- priv->categories = sort_categories (categories);
- make_suboptions (cal_search);
-}
-
-/**
- * cal_search_bar_get_category:
- * @cal_search: A calendar search bar.
- *
- * Queries the currently selected category name in a calendar search bar.
- * If "All" or "Unfiled" are selected, this function will return NULL.
- *
- * Return value: Name of the selected category, or NULL if there is no
- * selected category.
- **/
-const char *
-cal_search_bar_get_category (CalSearchBar *cal_search)
-{
- const char *category;
-
- category = get_current_category (cal_search);
-
- if (!category || category == (const char *) 1)
- return NULL;
- else
- return category;
-}
diff --git a/calendar/gui/cal-search-bar.h b/calendar/gui/cal-search-bar.h
deleted file mode 100644
index 5cfb29fa76..0000000000
--- a/calendar/gui/cal-search-bar.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Evolution calendar - Search bar widget for calendar views
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 CAL_SEARCH_BAR_H
-#define CAL_SEARCH_BAR_H
-
-#include <libgnome/gnome-defs.h>
-#include "widgets/misc/e-search-bar.h"
-#include "widgets/misc/e-filter-bar.h"
-
-BEGIN_GNOME_DECLS
-
-
-
-#define TYPE_CAL_SEARCH_BAR (cal_search_bar_get_type ())
-#define CAL_SEARCH_BAR(obj) (GTK_CHECK_CAST ((obj), TYPE_CAL_SEARCH_BAR, CalSearchBar))
-#define CAL_SEARCH_BAR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_CAL_SEARCH_BAR, \
- CalSearchBarClass))
-#define IS_CAL_SEARCH_BAR(obj) (GTK_CHECK_TYPE ((obj), TYPE_CAL_SEARCH_BAR))
-#define IS_CAL_SEARCH_BAR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_CAL_SEARCH_BAR))
-
-typedef struct CalSearchBarPrivate CalSearchBarPrivate;
-
-typedef struct {
- ESearchBar search_bar;
-
- /* Private data */
- CalSearchBarPrivate *priv;
-} CalSearchBar;
-
-typedef struct {
- ESearchBarClass parent_class;
-
- /* Notification signals */
-
- void (* sexp_changed) (CalSearchBar *cal_search, const char *sexp);
- void (* category_changed) (CalSearchBar *cal_search, const char *category);
-} CalSearchBarClass;
-
-GtkType cal_search_bar_get_type (void);
-
-CalSearchBar *cal_search_bar_construct (CalSearchBar *cal_search);
-
-GtkWidget *cal_search_bar_new (void);
-
-void cal_search_bar_set_categories (CalSearchBar *cal_search, GPtrArray *categories);
-
-const char *cal_search_bar_get_category (CalSearchBar *cal_search);
-
-
-
-END_GNOME_DECLS
-
-#endif
diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c
deleted file mode 100644
index d288b8e77c..0000000000
--- a/calendar/gui/calendar-commands.c
+++ /dev/null
@@ -1,810 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Evolution calendar - Commands for the calendar GUI control
- *
- * Copyright (C) 1998 The Free Software Foundation
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Miguel de Icaza <miguel@ximian.com>
- * Federico Mena-Quintero <federico@ximian.com>
- * Seth Alves <alves@hungry.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 <pwd.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gtk/gtkfilesel.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtksignal.h>
-
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-util.h>
-#include <libgnomeui/gnome-dialog-util.h>
-#include <libgnomeui/gnome-messagebox.h>
-#include <libgnomeui/gnome-stock.h>
-#include <libgnome/gnome-util.h>
-#include <libgnome/gnome-i18n.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <bonobo/bonobo-exception.h>
-#include <cal-util/timeutil.h>
-#include "shell/Evolution.h"
-#include "calendar-commands.h"
-#include "calendar-config.h"
-#include "gnome-cal.h"
-#include "goto.h"
-#include "print.h"
-#include "dialogs/cal-prefs-dialog.h"
-#include "itip-utils.h"
-#include "evolution-shell-component-utils.h"
-
-/* A list of all of the calendars started */
-static GList *all_calendars = NULL;
-
-/* Focusing information for the calendar view. We have to keep track of this
- * ourselves because with Bonobo controls, we may get unpaired focus_out events.
- */
-typedef struct {
- guint calendar_focused : 1;
- guint taskpad_focused : 1;
-} FocusData;
-
-/* Prints the calendar at its current view and time range */
-static void
-print (GnomeCalendar *gcal, gboolean preview)
-{
- time_t start;
- GnomeCalendarViewType view_type;
- PrintView print_view;
-
- gnome_calendar_get_current_time_range (gcal, &start, NULL);
- view_type = gnome_calendar_get_view (gcal);
-
- switch (view_type) {
- case GNOME_CAL_DAY_VIEW:
- print_view = PRINT_VIEW_DAY;
- break;
-
- case GNOME_CAL_WORK_WEEK_VIEW:
- case GNOME_CAL_WEEK_VIEW:
- print_view = PRINT_VIEW_WEEK;
- break;
-
- case GNOME_CAL_MONTH_VIEW:
- print_view = PRINT_VIEW_MONTH;
- break;
-
- default:
- g_assert_not_reached ();
- return;
- }
-
- print_calendar (gcal, preview, start, print_view);
-}
-
-/* File/Print callback */
-static void
-file_print_cb (BonoboUIComponent *uic, gpointer data, const char *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
- print (gcal, FALSE);
-}
-
-static void
-file_print_preview_cb (BonoboUIComponent *uic, gpointer data, const char *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
- print (gcal, TRUE);
-}
-
-/* This iterates over each calendar telling them to update their config
- settings. */
-void
-update_all_config_settings (void)
-{
- GList *l;
-
- for (l = all_calendars; l; l = l->next)
- gnome_calendar_update_config_settings (GNOME_CALENDAR (l->data), FALSE);
-}
-
-
-/* Sets a clock cursor for the specified calendar window */
-static void
-set_clock_cursor (GnomeCalendar *gcal)
-{
- GdkCursor *cursor;
-
- cursor = gdk_cursor_new (GDK_WATCH);
- gdk_window_set_cursor (GTK_WIDGET (gcal)->window, cursor);
- gdk_cursor_destroy (cursor);
- gdk_flush ();
-}
-
-/* Resets the normal cursor for the specified calendar window */
-static void
-set_normal_cursor (GnomeCalendar *gcal)
-{
- gdk_window_set_cursor (GTK_WIDGET (gcal)->window, NULL);
- gdk_flush ();
-}
-
-static void
-previous_clicked (BonoboUIComponent *uic, gpointer data, const char *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- set_clock_cursor (gcal);
- gnome_calendar_previous (gcal);
- set_normal_cursor (gcal);
-}
-
-static void
-next_clicked (BonoboUIComponent *uic, gpointer data, const char *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- set_clock_cursor (gcal);
- gnome_calendar_next (gcal);
- set_normal_cursor (gcal);
-}
-
-void
-calendar_goto_today (GnomeCalendar *gcal)
-{
- set_clock_cursor (gcal);
- gnome_calendar_goto_today (gcal);
- set_normal_cursor (gcal);
-}
-
-static void
-today_clicked (BonoboUIComponent *uic, gpointer data, const char *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- calendar_goto_today (gcal);
-}
-
-static void
-goto_clicked (BonoboUIComponent *uic, gpointer data, const char *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- goto_dialog (gcal);
-}
-
-static void
-show_day_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- gnome_calendar_set_view (gcal, GNOME_CAL_DAY_VIEW, FALSE, TRUE);
-}
-
-static void
-show_work_week_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- gnome_calendar_set_view (gcal, GNOME_CAL_WORK_WEEK_VIEW, FALSE, TRUE);
-}
-
-static void
-show_week_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- gnome_calendar_set_view (gcal, GNOME_CAL_WEEK_VIEW, FALSE, TRUE);
-}
-
-static void
-show_month_view_clicked (BonoboUIComponent *uic, gpointer data, const char *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- gnome_calendar_set_view (gcal, GNOME_CAL_MONTH_VIEW, FALSE, TRUE);
-}
-
-
-
-static void
-cut_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
- set_clock_cursor (gcal);
- gnome_calendar_cut_clipboard (gcal);
- set_normal_cursor (gcal);
-}
-
-static void
-copy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- set_clock_cursor (gcal);
- gnome_calendar_copy_clipboard (gcal);
- set_normal_cursor (gcal);
-}
-
-static void
-paste_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- set_clock_cursor (gcal);
- gnome_calendar_paste_clipboard (gcal);
- set_normal_cursor (gcal);
-}
-
-static void
-delete_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- set_clock_cursor (gcal);
- gnome_calendar_delete_selection (gcal);
- set_normal_cursor (gcal);
-}
-
-static void
-publish_freebusy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path)
-{
- GnomeCalendar *gcal;
- CalClient *client;
- GList *comp_list;
- icaltimezone *utc;
- time_t start = time (NULL), end;
-
- gcal = GNOME_CALENDAR (data);
-
- utc = icaltimezone_get_utc_timezone ();
- start = time_day_begin_with_zone (start, utc);
- end = time_add_week_with_zone (start, 6, utc);
-
- client = gnome_calendar_get_cal_client (gcal);
- comp_list = cal_client_get_free_busy (client, NULL, start, end);
- if (comp_list) {
- GList *l;
-
- for (l = comp_list; l; l = l->next) {
- CalComponent *comp = CAL_COMPONENT (l->data);
- itip_send_comp (CAL_COMPONENT_METHOD_PUBLISH, comp, client, NULL);
-
- gtk_object_unref (GTK_OBJECT (comp));
- }
-
- g_list_free (comp_list);
- }
-}
-
-/* Does a queryInterface on the control's parent control frame for the ShellView interface */
-static GNOME_Evolution_ShellView
-get_shell_view_interface (BonoboControl *control)
-{
- Bonobo_ControlFrame control_frame;
- GNOME_Evolution_ShellView shell_view;
- CORBA_Environment ev;
-
- control_frame = bonobo_control_get_control_frame (control);
-
- g_assert (control_frame != CORBA_OBJECT_NIL);
-
- CORBA_exception_init (&ev);
- shell_view = Bonobo_Unknown_queryInterface (control_frame,
- "IDL:GNOME/Evolution/ShellView:1.0",
- &ev);
- if (BONOBO_EX (&ev)) {
- g_message ("get_shell_view_interface(): "
- "Could not queryInterface() on the control frame");
- shell_view = CORBA_OBJECT_NIL;
- goto out;
- }
-
- CORBA_exception_free (&ev);
-
- out:
-
- return shell_view;
-}
-
-/* Displays the currently displayed time range in the folder bar label on the
- shell view, according to which view we are showing. */
-void
-calendar_set_folder_bar_label (GnomeCalendar *gcal, BonoboControl *control)
-{
- icaltimezone *zone;
- struct icaltimetype start_tt, end_tt;
- time_t start_time, end_time;
- struct tm start_tm, end_tm;
- char buffer[512], end_buffer[256];
- GnomeCalendarViewType view;
-
- gnome_calendar_get_visible_time_range (gcal, &start_time, &end_time);
- zone = gnome_calendar_get_timezone (gcal);
-
- start_tt = icaltime_from_timet_with_zone (start_time, FALSE, zone);
- start_tm.tm_year = start_tt.year - 1900;
- start_tm.tm_mon = start_tt.month - 1;
- start_tm.tm_mday = start_tt.day;
- start_tm.tm_hour = start_tt.hour;
- start_tm.tm_min = start_tt.minute;
- start_tm.tm_sec = start_tt.second;
- start_tm.tm_isdst = -1;
- start_tm.tm_wday = time_day_of_week (start_tt.day, start_tt.month - 1,
- start_tt.year);
-
- /* Take one off end_time so we don't get an extra day. */
- end_tt = icaltime_from_timet_with_zone (end_time - 1, FALSE, zone);
- end_tm.tm_year = end_tt.year - 1900;
- end_tm.tm_mon = end_tt.month - 1;
- end_tm.tm_mday = end_tt.day;
- end_tm.tm_hour = end_tt.hour;
- end_tm.tm_min = end_tt.minute;
- end_tm.tm_sec = end_tt.second;
- end_tm.tm_isdst = -1;
- end_tm.tm_wday = time_day_of_week (end_tt.day, end_tt.month - 1,
- end_tt.year);
-
- view = gnome_calendar_get_view (gcal);
-
- switch (view) {
- case GNOME_CAL_DAY_VIEW:
- case GNOME_CAL_WORK_WEEK_VIEW:
- case GNOME_CAL_WEEK_VIEW:
- if (start_tm.tm_year == end_tm.tm_year
- && start_tm.tm_mon == end_tm.tm_mon
- && start_tm.tm_mday == end_tm.tm_mday) {
- strftime (buffer, sizeof (buffer),
- _("%A %d %B %Y"), &start_tm);
- } else if (start_tm.tm_year == end_tm.tm_year) {
- strftime (buffer, sizeof (buffer),
- _("%a %d %b"), &start_tm);
- strftime (end_buffer, sizeof (end_buffer),
- _("%a %d %b %Y"), &end_tm);
- strcat (buffer, " - ");
- strcat (buffer, end_buffer);
- } else {
- strftime (buffer, sizeof (buffer),
- _("%a %d %b %Y"), &start_tm);
- strftime (end_buffer, sizeof (end_buffer),
- _("%a %d %b %Y"), &end_tm);
- strcat (buffer, " - ");
- strcat (buffer, end_buffer);
- }
- break;
- case GNOME_CAL_MONTH_VIEW:
- if (start_tm.tm_year == end_tm.tm_year) {
- if (start_tm.tm_mon == end_tm.tm_mon) {
- strftime (buffer, sizeof (buffer),
- "%d", &start_tm);
- strftime (end_buffer, sizeof (end_buffer),
- _("%d %B %Y"), &end_tm);
- strcat (buffer, " - ");
- strcat (buffer, end_buffer);
- } else {
- strftime (buffer, sizeof (buffer),
- _("%d %B"), &start_tm);
- strftime (end_buffer, sizeof (end_buffer),
- _("%d %B %Y"), &end_tm);
- strcat (buffer, " - ");
- strcat (buffer, end_buffer);
- }
- } else {
- strftime (buffer, sizeof (buffer),
- _("%d %B %Y"), &start_tm);
- strftime (end_buffer, sizeof (end_buffer),
- _("%d %B %Y"), &end_tm);
- strcat (buffer, " - ");
- strcat (buffer, end_buffer);
- }
- break;
- default:
- g_assert_not_reached ();
- }
-
- control_util_set_folder_bar_label (control, buffer);
-}
-
-void
-control_util_set_folder_bar_label (BonoboControl *control, char *label)
-{
- GNOME_Evolution_ShellView shell_view;
- CORBA_Environment ev;
-
- shell_view = get_shell_view_interface (control);
- if (shell_view == CORBA_OBJECT_NIL)
- return;
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_ShellView_setFolderBarLabel (shell_view, label, &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("control_util_set_folder_bar_label(): Could not set the folder bar label");
-
- CORBA_exception_free (&ev);
-}
-
-void
-control_util_show_settings (GnomeCalendar *gcal)
-{
- BonoboControl *control;
- GNOME_Evolution_ShellView shell_view;
- CORBA_Environment ev;
-
- control = gtk_object_get_data (GTK_OBJECT (gcal), "control");
- if (control == NULL)
- return;
-
- shell_view = get_shell_view_interface (control);
- if (shell_view == CORBA_OBJECT_NIL)
- return;
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_ShellView_showSettings (shell_view, &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("control_util_show_settings(): Could not show settings");
-
- CORBA_exception_free (&ev);
-}
-
-/* Sensitizes the UI Component menu/toolbar calendar commands based on the
- * number of selected events. (This will always be 0 or 1 currently.) If enable
- * 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)
-{
- BonoboUIComponent *uic;
- int n_selected;
- gboolean read_only;
-
- 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 (gnome_calendar_get_cal_client (gcal));
-
- bonobo_ui_component_set_prop (uic, "/commands/Cut", "sensitive",
- n_selected == 0 || read_only ? "0" : "1",
- NULL);
- bonobo_ui_component_set_prop (uic, "/commands/Copy", "sensitive",
- n_selected == 0 ? "0" : "1",
- NULL);
- bonobo_ui_component_set_prop (uic, "/commands/Paste", "sensitive",
- enable && !read_only ? "1" : "0",
- NULL);
- bonobo_ui_component_set_prop (uic, "/commands/Delete", "sensitive",
- n_selected == 0 || read_only ? "0" : "1",
- NULL);
-}
-
-/* Sensitizes the UI Component menu/toolbar tasks commands based on the number
- * of selected tasks. If enable is FALSE, all will be disabled. Otherwise, the
- * currently-selected number of tasks will be used.
- */
-static void
-sensitize_taskpad_commands (GnomeCalendar *gcal, BonoboControl *control, gboolean enable)
-{
- BonoboUIComponent *uic;
- int n_selected;
- gboolean read_only;
-
- 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));
-
- bonobo_ui_component_set_prop (uic, "/commands/Cut", "sensitive",
- n_selected == 0 || read_only ? "0" : "1",
- NULL);
- bonobo_ui_component_set_prop (uic, "/commands/Copy", "sensitive",
- n_selected == 0 ? "0" : "1",
- NULL);
- bonobo_ui_component_set_prop (uic, "/commands/Paste", "sensitive",
- enable && !read_only ? "1" : "0",
- NULL);
- bonobo_ui_component_set_prop (uic, "/commands/Delete", "sensitive",
- n_selected == 0 || read_only ? "0" : "1",
- NULL);
-}
-
-/* Callback used when the dates shown by the GnomeCalendar are changed.
- We want to update the dates in the folder bar. */
-static void
-gcal_calendar_dates_change_cb (GnomeCalendar *gcal, gpointer data)
-{
- BonoboControl *control;
-
- control = BONOBO_CONTROL (data);
-
- calendar_set_folder_bar_label (gcal, control);
-}
-
-/* Callback used when the selection in the calendar views changes */
-static void
-gcal_calendar_selection_changed_cb (GnomeCalendar *gcal, gpointer data)
-{
- BonoboControl *control;
-
- control = BONOBO_CONTROL (data);
-
- sensitize_calendar_commands (gcal, control, TRUE);
-}
-
-/* Callback used when the selection in the taskpad changes */
-static void
-gcal_taskpad_selection_changed_cb (GnomeCalendar *gcal, gpointer data)
-{
- BonoboControl *control;
-
- control = BONOBO_CONTROL (data);
-
- sensitize_taskpad_commands (gcal, control, TRUE);
-}
-
-/* Callback used when the focus changes for a calendar view */
-static void
-gcal_calendar_focus_change_cb (GnomeCalendar *gcal, gboolean in, gpointer data)
-{
- BonoboControl *control;
- FocusData *focus;
-
- control = BONOBO_CONTROL (data);
-
- focus = gtk_object_get_data (GTK_OBJECT (control), "focus_data");
- g_assert (focus != NULL);
-
- if (in) {
- gtk_signal_connect (GTK_OBJECT (gcal), "calendar_selection_changed",
- GTK_SIGNAL_FUNC (gcal_calendar_selection_changed_cb), control);
- sensitize_calendar_commands (gcal, control, TRUE);
- focus->calendar_focused = TRUE;
- } else if (focus->calendar_focused) {
- gtk_signal_disconnect_by_func (GTK_OBJECT (gcal),
- GTK_SIGNAL_FUNC (gcal_calendar_selection_changed_cb),
- control);
- sensitize_calendar_commands (gcal, control, FALSE);
- focus->calendar_focused = FALSE;
- }
-}
-
-/* Callback used when the taskpad focus changes */
-static void
-gcal_taskpad_focus_change_cb (GnomeCalendar *gcal, gboolean in, gpointer data)
-{
- BonoboControl *control;
- FocusData *focus;
-
- control = BONOBO_CONTROL (data);
-
- focus = gtk_object_get_data (GTK_OBJECT (control), "focus_data");
- g_assert (focus != NULL);
-
- if (in) {
- gtk_signal_connect (GTK_OBJECT (gcal), "taskpad_selection_changed",
- GTK_SIGNAL_FUNC (gcal_taskpad_selection_changed_cb), control);
- sensitize_taskpad_commands (gcal, control, TRUE);
- focus->taskpad_focused = TRUE;
- } else if (focus->taskpad_focused) {
- /* With Bonobo controls, we may get unpaired focus_out events.
- * That is why we have to keep track of this ourselves instead
- * of blindly assumming that we are getting this event because
- * the taskpad was in fact focused.
- */
- gtk_signal_disconnect_by_func (GTK_OBJECT (gcal),
- GTK_SIGNAL_FUNC (gcal_taskpad_selection_changed_cb),
- control);
- sensitize_taskpad_commands (gcal, control, FALSE);
- focus->taskpad_focused = FALSE;
- }
-
-}
-
-
-static BonoboUIVerb verbs [] = {
- BONOBO_UI_VERB ("CalendarPrint", file_print_cb),
- BONOBO_UI_VERB ("CalendarPrintPreview", file_print_preview_cb),
-
- BONOBO_UI_VERB ("Cut", cut_cmd),
- BONOBO_UI_VERB ("Copy", copy_cmd),
- BONOBO_UI_VERB ("Paste", paste_cmd),
- BONOBO_UI_VERB ("Delete", delete_cmd),
-
- BONOBO_UI_VERB ("CalendarPrev", previous_clicked),
- BONOBO_UI_VERB ("CalendarToday", today_clicked),
- BONOBO_UI_VERB ("CalendarNext", next_clicked),
- BONOBO_UI_VERB ("CalendarGoto", goto_clicked),
-
- BONOBO_UI_VERB ("ShowDayView", show_day_view_clicked),
- BONOBO_UI_VERB ("ShowWorkWeekView", show_work_week_view_clicked),
- BONOBO_UI_VERB ("ShowWeekView", show_week_view_clicked),
- BONOBO_UI_VERB ("ShowMonthView", show_month_view_clicked),
-
- BONOBO_UI_VERB ("PublishFreeBusy", publish_freebusy_cmd),
-
- BONOBO_UI_VERB_END
-};
-
-static EPixmap pixmaps [] =
-{
- E_PIXMAP ("/menu/EditPlaceholder/Edit/Cut", "16_cut.png"),
- E_PIXMAP ("/menu/EditPlaceholder/Edit/Copy", "16_copy.png"),
- E_PIXMAP ("/menu/EditPlaceholder/Edit/Paste", "16_paste.png"),
- E_PIXMAP ("/menu/EditPlaceholder/Edit/Delete", "evolution-trash-mini.png"),
- E_PIXMAP ("/menu/File/Print/Print", "print.xpm"),
- E_PIXMAP ("/menu/File/Print/PrintPreview", "print-preview.xpm"),
- E_PIXMAP ("/menu/View/ViewBegin/Goto", "goto-16.png"),
-
- E_PIXMAP ("/Toolbar/Print", "buttons/print.png"),
- E_PIXMAP ("/Toolbar/Delete", "buttons/delete-message.png"),
- E_PIXMAP ("/Toolbar/Prev", "buttons/arrow-left-24.png"),
- E_PIXMAP ("/Toolbar/Next", "buttons/arrow-right-24.png"),
- E_PIXMAP ("/Toolbar/Goto", "buttons/goto-24.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_END
-};
-
-void
-calendar_control_activate (BonoboControl *control,
- GnomeCalendar *gcal)
-{
- Bonobo_UIContainer remote_uih;
- BonoboUIComponent *uic;
- FocusData *focus;
-
- uic = bonobo_control_get_ui_component (control);
- g_assert (uic != NULL);
-
- remote_uih = bonobo_control_get_remote_ui_container (control);
- bonobo_ui_component_set_container (uic, remote_uih);
- bonobo_object_release_unref (remote_uih, NULL);
-
- gnome_calendar_set_ui_component (gcal, uic);
-
- bonobo_ui_component_add_verb_list_with_data (uic, verbs, gcal);
-
- bonobo_ui_component_freeze (uic, NULL);
-
- bonobo_ui_util_set_ui (uic, EVOLUTION_DATADIR,
- "evolution-calendar.xml",
- "evolution-calendar");
-
- e_pixmaps_update (uic, pixmaps);
-
- gnome_calendar_setup_view_menus (gcal, uic);
-
- gtk_signal_connect (GTK_OBJECT (gcal), "dates_shown_changed",
- GTK_SIGNAL_FUNC (gcal_calendar_dates_change_cb),
- control);
- gtk_signal_connect (GTK_OBJECT (gcal), "calendar_focus_change",
- GTK_SIGNAL_FUNC (gcal_calendar_focus_change_cb), control);
- gtk_signal_connect (GTK_OBJECT (gcal), "taskpad_focus_change",
- GTK_SIGNAL_FUNC (gcal_taskpad_focus_change_cb), control);
-
- sensitize_calendar_commands (gcal, control, FALSE);
- sensitize_taskpad_commands (gcal, control, FALSE);
-
- bonobo_ui_component_thaw (uic, NULL);
-
- /* Show the dialog for setting the timezone if the user hasn't chosen
- a default timezone already. This is done in the startup wizard now,
- so we don't do it here. */
-#if 0
- calendar_config_check_timezone_set ();
-#endif
-
- calendar_set_folder_bar_label (gcal, control);
-
- focus = g_new (FocusData, 1);
- focus->calendar_focused = FALSE;
- focus->taskpad_focused = FALSE;
-
- gtk_object_set_data (GTK_OBJECT (control), "focus_data", focus);
-}
-
-void
-calendar_control_deactivate (BonoboControl *control, GnomeCalendar *gcal)
-{
- FocusData *focus;
- BonoboUIComponent *uic;
-
- uic = bonobo_control_get_ui_component (control);
- g_assert (uic != NULL);
-
- gnome_calendar_set_ui_component (gcal, uic);
-
- focus = gtk_object_get_data (GTK_OBJECT (control), "focus_data");
- g_assert (focus != NULL);
-
- gtk_object_remove_data (GTK_OBJECT (control), "focus_data");
- g_free (focus);
-
- gnome_calendar_discard_view_menus (gcal);
-
- gtk_signal_disconnect_by_data (GTK_OBJECT (gcal), control);
-
- bonobo_ui_component_rm (uic, "/", NULL);
- bonobo_ui_component_unset_container (uic);
-}
-
-/* Removes a calendar from our list of all calendars when it is destroyed. */
-static void
-on_calendar_destroyed (GnomeCalendar *gcal)
-{
- all_calendars = g_list_remove (all_calendars, gcal);
-}
-
-GnomeCalendar *
-new_calendar (void)
-{
- GtkWidget *gcal;
-
- gcal = gnome_calendar_new ();
- if (!gcal) {
- gnome_warning_dialog (_("Could not create the calendar view. Please check your "
- "ORBit and OAF setup."));
- return NULL;
- }
-
- gtk_signal_connect (GTK_OBJECT (gcal), "destroy",
- GTK_SIGNAL_FUNC (on_calendar_destroyed), NULL);
-
- all_calendars = g_list_prepend (all_calendars, gcal);
-
- return GNOME_CALENDAR (gcal);
-}
diff --git a/calendar/gui/calendar-commands.h b/calendar/gui/calendar-commands.h
deleted file mode 100644
index 9ebac6eef4..0000000000
--- a/calendar/gui/calendar-commands.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Evolution calendar - Commands for the calendar GUI control
- *
- * Copyright (C) 1998 The Free Software Foundation
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Miguel de Icaza <miguel@ximian.com>
- * Federico Mena-Quintero <federico@ximian.com>
- * Seth Alves <alves@hungry.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 CALENDAR_COMMANDS_H
-#define CALENDAR_COMMANDS_H
-
-#include "gnome-cal.h"
-
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-ui-component.h>
-
-/* This tells all the calendars to reload the config settings. */
-void update_all_config_settings (void);
-
-GnomeCalendar *new_calendar (void);
-
-void calendar_control_activate (BonoboControl *control, GnomeCalendar *gcal);
-void calendar_control_deactivate (BonoboControl *control, GnomeCalendar *gcal);
-
-void calendar_goto_today (GnomeCalendar *gcal);
-
-void calendar_set_folder_bar_label (GnomeCalendar *gcal, BonoboControl *control);
-
-/* Used by calendar and tasks control to set the folder title bar label. */
-void control_util_set_folder_bar_label (BonoboControl *control, char *label);
-
-/* Used by calendar views and tasks to show the settings dialog */
-void control_util_show_settings (GnomeCalendar *gcal);
-
-#endif /* CALENDAR_COMMANDS_H */
diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c
deleted file mode 100644
index 82dfc8b575..0000000000
--- a/calendar/gui/calendar-component.c
+++ /dev/null
@@ -1,773 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* component-factory.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- * 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.
- *
- * Author: Ettore Perazzoli <ettore@ximian.com>
- */
-
-#include <config.h>
-
-#include <errno.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 "component-factory.h"
-#include "tasks-control-factory.h"
-#include "config-control-factory.h"
-#include "control-factory.h"
-#include "calendar-config.h"
-#include "tasks-control.h"
-#include "tasks-migrate.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;
-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 }
-};
-
-
-
-static inline gboolean
-type_is_calendar (const char *type)
-{
- return !strcmp (type, FOLDER_CALENDAR) ||
- !strcmp (type, FOLDER_PUBLIC_CALENDAR);
-}
-
-static inline gboolean
-type_is_tasks (const char *type)
-{
- return !strcmp (type, FOLDER_TASKS) ||
- !strcmp (type, FOLDER_PUBLIC_TASKS);
-}
-
-/* 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;
-
- 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, "folder_uri", physical_uri, NULL);
- if (type_is_calendar (type) && *view_info)
- bonobo_control_set_property (control, "view", view_info, NULL);
-
- *control_return = control;
-
- return EVOLUTION_SHELL_COMPONENT_OK;
-}
-
-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;
-
- 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;
- }
-
- 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);
- }
-
- CORBA_exception_free (&ev);
-}
-
-/* Asks the alarm daemon to stop monitoring the specified URI */
-static void
-stop_alarms (GnomeVFSURI *uri)
-{
- char *str_uri;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_AlarmNotify an;
-
- /* Activate the alarm notification service */
-
- CORBA_exception_init (&ev);
- an = oaf_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");
- }
-
- 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);
-}
-
-static void
-remove_folder (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- const GNOME_Evolution_ShellComponentListener listener,
- void *closure)
-{
- 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");
-
- CORBA_exception_free (&ev);
- return;
- }
-
- /* 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);
- 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 ();
- 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);
-}
-
-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;
- }
-
- /* 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;
- }
-
- 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 (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);
- }
-
- 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;
-}
-
-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)
-{
- 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);
-
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
-
- CORBA_exception_free (&ev);
-}
-
-static gboolean
-request_quit (EvolutionShellComponent *shell_component, void *closure)
-{
- return e_comp_editor_registry_close_all (comp_editor_registry);
-}
-
-static GList *shells = NULL;
-
-static void
-owner_set_cb (EvolutionShellComponent *shell_component,
- EvolutionShellClient *shell_client,
- const char *evolution_homedir,
- gpointer user_data)
-{
- static gboolean migrated = FALSE;
-
- evolution_dir = g_strdup (evolution_homedir);
-
- if (!migrated) {
- tasks_migrate ();
- migrated = TRUE;
- }
-
- shells = g_list_append (shells, shell_component);
-
- global_shell_client = shell_client;
-
- config_control_factory_register (bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)));
-}
-
-static void
-owner_unset_cb (EvolutionShellComponent *shell_component,
- gpointer user_data)
-{
- shells = g_list_remove (shells, shell_component);
-
- if (g_list_length (shells) == 0)
- gtk_main_quit ();
-}
-
-/* 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 g_concat_dir_and_file (uri, "calendar.ics");
- else if (vtype == CAL_COMPONENT_TODO)
- return g_concat_dir_and_file (uri, "tasks.ics");
- 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 ();
- }
-
- return NULL;
-}
-
-/* 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;
- }
-
- real_uri = get_data_uri (uri, vtype);
-
- /* Get the factory */
-
- CORBA_exception_init (&ev);
- factory = oaf_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_CompEditorFactory",
- 0, NULL, &ev);
-
- 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);
-
- /* Create the item */
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_CompEditorFactory_editNew (factory, real_uri, type, &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("create_component(): Exception while creating the component");
-
- CORBA_exception_free (&ev);
- g_free (real_uri);
-
- /* Get rid of the factory */
-
- 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");
-
- CORBA_exception_free (&ev);
-}
-
-/* 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)
-{
- 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
- create_component (NULL,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT);
- } 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
- create_component (NULL,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT);
- } 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
- create_component (NULL,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING);
- } 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
- create_component (NULL,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO);
- } 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_ICONSDIR, icon_name);
- icon = gdk_pixbuf_new_from_file (icon_path);
- }
-
- 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);
-}
-
-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));
-
- gtk_signal_connect (GTK_OBJECT (shell_component), "owner_set",
- GTK_SIGNAL_FUNC (owner_set_cb), NULL);
- gtk_signal_connect (GTK_OBJECT (shell_component), "owner_unset",
- GTK_SIGNAL_FUNC (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");
-
- add_creatable_item (shell_component, CREATE_MEETING_ID,
- _("New meeting"), _("_Meeting"),
- _("Create a new meeting request"),
- FOLDER_CALENDAR, 's', "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");
-
- 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");
-
- gtk_signal_connect (GTK_OBJECT (shell_component), "user_create_new_item",
- GTK_SIGNAL_FUNC (sc_user_create_new_item_cb), NULL);
-
- return BONOBO_OBJECT (shell_component);
-}
-
-
-void
-component_factory_init (void)
-{
- BonoboObject *object;
- int result;
-
- object = create_object ();
-
- result = oaf_active_server_register (COMPONENT_ID, bonobo_object_corba_objref (object));
-
- if (result == OAF_REG_ERROR)
- g_error ("Cannot initialize Evolution's calendar component.");
-}
diff --git a/calendar/gui/calendar-component.h b/calendar/gui/calendar-component.h
deleted file mode 100644
index 576255cb6d..0000000000
--- a/calendar/gui/calendar-component.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* component-factory.h
- *
- * Copyright (C) 2000 Ximian, Inc.
- * 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.
- *
- * Author: Ettore Perazzoli <ettore@ximian.com>
- */
-
-#ifndef _COMPONENT_FACTORY_H_
-#define _COMPONENT_FACTORY_H_
-
-extern char *evolution_dir;
-
-void component_factory_init (void);
-
-#endif /* _COMPONENT_FACTORY_H_ */
diff --git a/calendar/gui/calendar-config-keys.h b/calendar/gui/calendar-config-keys.h
new file mode 100644
index 0000000000..09c53478fb
--- /dev/null
+++ b/calendar/gui/calendar-config-keys.h
@@ -0,0 +1,79 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * JP Rosevear <jpr@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef _CALENDAR_CONFIG_KEYS_H_
+#define _CALENDAR_CONFIG_KEYS_H_
+
+G_BEGIN_DECLS
+
+#define CALENDAR_CONFIG_PREFIX "/apps/evolution/calendar"
+
+/* Display settings */
+#define CALENDAR_CONFIG_TIMEZONE CALENDAR_CONFIG_PREFIX "/display/timezone"
+#define CALENDAR_CONFIG_SELECTED_CALENDARS CALENDAR_CONFIG_PREFIX "/display/selected_calendars"
+#define CALENDAR_CONFIG_24HOUR CALENDAR_CONFIG_PREFIX "/display/use_24hour_format"
+#define CALENDAR_CONFIG_DAY_START_HOUR CALENDAR_CONFIG_PREFIX "/display/day_start_hour"
+#define CALENDAR_CONFIG_DAY_START_MINUTE CALENDAR_CONFIG_PREFIX "/display/day_start_minute"
+#define CALENDAR_CONFIG_DAY_END_HOUR CALENDAR_CONFIG_PREFIX "/display/day_end_hour"
+#define CALENDAR_CONFIG_DAY_END_MINUTE CALENDAR_CONFIG_PREFIX "/display/day_end_minute"
+#define CALENDAR_CONFIG_TIME_DIVISIONS CALENDAR_CONFIG_PREFIX "/display/time_divisions"
+#define CALENDAR_CONFIG_MONTH_SCROLL_BY_WEEK CALENDAR_CONFIG_PREFIX "/display/month_scroll_by_week"
+#define CALENDAR_CONFIG_COMPRESS_WEEKEND CALENDAR_CONFIG_PREFIX "/display/compress_weekend"
+#define CALENDAR_CONFIG_WORKING_DAYS CALENDAR_CONFIG_PREFIX "/display/working_days"
+#define CALENDAR_CONFIG_DAY_SECOND_ZONE CALENDAR_CONFIG_PREFIX "/display/day_second_zone"
+#define CALENDAR_CONFIG_DAY_SECOND_ZONES_LIST CALENDAR_CONFIG_PREFIX "/display/day_second_zones"
+#define CALENDAR_CONFIG_DAY_SECOND_ZONES_MAX CALENDAR_CONFIG_PREFIX "/display/day_second_zones_max"
+
+/* Task display settings */
+#define CALENDAR_CONFIG_TASKS_SELECTED_TASKS CALENDAR_CONFIG_PREFIX "/tasks/selected_tasks"
+#define CALENDAR_CONFIG_TASKS_HIDE_COMPLETED CALENDAR_CONFIG_PREFIX "/tasks/hide_completed"
+#define CALENDAR_CONFIG_TASKS_HIDE_COMPLETED_UNITS CALENDAR_CONFIG_PREFIX "/tasks/hide_completed_units"
+#define CALENDAR_CONFIG_TASKS_HIDE_COMPLETED_VALUE CALENDAR_CONFIG_PREFIX "/tasks/hide_completed_value"
+
+/* Memo display settings */
+#define CALENDAR_CONFIG_MEMOS_SELECTED_MEMOS CALENDAR_CONFIG_PREFIX "/memos/selected_memos"
+
+/* Prompt settings */
+#define CALENDAR_CONFIG_PROMPT_DELETE CALENDAR_CONFIG_PREFIX "/prompts/confirm_delete"
+
+/* Default reminder */
+#define CALENDAR_CONFIG_DEFAULT_REMINDER CALENDAR_CONFIG_PREFIX "/other/use_default_reminder"
+#define CALENDAR_CONFIG_DEFAULT_REMINDER_INTERVAL CALENDAR_CONFIG_PREFIX "/other/default_reminder_interval"
+#define CALENDAR_CONFIG_DEFAULT_REMINDER_UNITS CALENDAR_CONFIG_PREFIX "/other/default_reminder_units"
+
+/* Free/Busy settings */
+#define CALENDAR_CONFIG_TEMPLATE CALENDAR_CONFIG_PREFIX"/publish/template"
+
+#define CALENDAR_CONFIG_SAVE_DIR CALENDAR_CONFIG_PREFIX"/audio_dir"
+
+/* Birthday & Anniversary reminder */
+#define CALENDAR_CONFIG_BA_REMINDER CALENDAR_CONFIG_PREFIX "/other/use_ba_reminder"
+#define CALENDAR_CONFIG_BA_REMINDER_INTERVAL CALENDAR_CONFIG_PREFIX "/other/ba_reminder_interval"
+#define CALENDAR_CONFIG_BA_REMINDER_UNITS CALENDAR_CONFIG_PREFIX "/other/ba_reminder_units"
+
+/* drawing of events */
+#define CALENDAR_CONFIG_DISPLAY_EVENTS_GRADIENT CALENDAR_CONFIG_PREFIX "/display/events_gradient"
+#define CALENDAR_CONFIG_DISPLAY_EVENTS_ALPHA CALENDAR_CONFIG_PREFIX "/display/events_transparency"
+
+G_END_DECLS
+
+#endif
diff --git a/calendar/gui/calendar-config.c b/calendar/gui/calendar-config.c
index 8ae43ba2c6..04ca534ca4 100644
--- a/calendar/gui/calendar-config.c
+++ b/calendar/gui/calendar-config.c
@@ -1,955 +1,458 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
/*
- * Authors :
- * Damon Chaplin <damon@ximian.com>
- * Rodrigo Moya <rodrigo@ximian.com>
- *
- * Copyright 2000, Ximian, Inc.
- * Copyright 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Damon Chaplin <damon@ximian.com>
+ * Rodrigo Moya <rodrigo@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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
*/
/*
* calendar-config.c - functions to load/save/get/set user settings.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
+
#include <time.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-config.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <widgets/e-timezone-dialog/e-timezone-dialog.h>
-#include <cal-util/timeutil.h>
-#include "component-factory.h"
-#include "calendar-commands.h"
-#include "e-tasks.h"
-#include "e-cell-date-edit-text.h"
-#include "calendar-config.h"
-#include "e-util/e-config-listener.h"
+#include <string.h>
+#include <gio/gio.h>
+#include <shell/e-shell.h>
-static EConfigListener *config = NULL;
+#include "calendar-config-keys.h"
+#include "calendar-config.h"
-static void on_timezone_set (GnomeDialog *dialog,
- int button,
- ETimezoneDialog *etd);
-static gboolean on_timezone_dialog_delete_event (GnomeDialog *dialog,
- GdkEvent *event,
- ETimezoneDialog *etd);
+static GSettings *config = NULL;
static void
do_cleanup (void)
{
- gtk_object_unref (GTK_OBJECT (config));
+ g_object_unref (config);
config = NULL;
}
-void
-calendar_config_init (void)
+static void
+calendar_config_init (void)
{
if (config)
return;
- config = e_config_listener_new ();
- g_atexit ((GVoidFunc) do_cleanup);
+ config = g_settings_new ("org.gnome.evolution.calendar");
+
+ /* will be freed together with EShell */
+ g_object_set_data_full (
+ G_OBJECT (e_shell_get_default ()),
+ "calendar-config-config-cleanup", (gpointer) "1",
+ (GDestroyNotify) do_cleanup);
}
-/* Returns TRUE if the locale has 'am' and 'pm' strings defined, in which
- case the user can choose between 12 and 24-hour time formats. */
-gboolean
-calendar_config_locale_supports_12_hour_format (void)
+void
+calendar_config_remove_notification (CalendarConfigChangedFunc func,
+ gpointer data)
{
- char s[16];
- time_t t = 0;
+ calendar_config_init ();
- strftime (s, sizeof s, "%p", gmtime (&t));
- return s[0] != '\0';
+ g_signal_handlers_disconnect_by_func (config, G_CALLBACK (func), data);
}
-/* Returns the string representation of a units value */
-static const char *
-units_to_string (CalUnits units)
+/* Returns TRUE if the locale has 'am' and 'pm' strings defined, in which
+ * case the user can choose between 12 and 24-hour time formats. */
+gboolean
+calendar_config_locale_supports_12_hour_format (void)
{
- switch (units) {
- case CAL_DAYS:
- return "days";
-
- case CAL_HOURS:
- return "hours";
+ gchar s[16];
+ time_t t = 0;
- case CAL_MINUTES:
- return "minutes";
+ calendar_config_init ();
- default:
- g_assert_not_reached ();
- return NULL;
- }
+ e_utf8_strftime (s, sizeof s, "%p", gmtime (&t));
+ return s[0] != '\0';
}
/*
* Calendar Settings.
*/
-/* The current timezone, e.g. "Europe/London". It may be NULL, in which case
- you should assume UTC (though Evolution will show the timezone-setting
- dialog the next time a calendar or task folder is selected). */
-gchar*
-calendar_config_get_timezone (void)
-{
- static char *timezone = NULL;
-
- if (timezone)
- g_free (timezone);
-
- timezone = e_config_listener_get_string_with_default (config, "/Calendar/Display/Timezone",
- "UTC", NULL);
- if (!timezone)
- timezone = g_strdup ("UTC");
-
- return timezone;
-}
-
-
-/* Sets the timezone. If set to NULL it defaults to UTC.
- FIXME: Should check it is being set to a valid timezone. */
-void
-calendar_config_set_timezone (gchar *timezone)
-{
- if (timezone && timezone[0])
- e_config_listener_set_string (config, "/Calendar/Display/Timezone", timezone);
- else
- e_config_listener_set_string (config, "/Calendar/Display/Timezone", "UTC");
-}
-
-
-/* Whether we use 24-hour format or 12-hour format (AM/PM). */
-gboolean
-calendar_config_get_24_hour_format (void)
-{
- /* If the locale defines 'am' and 'pm' strings then the user has the
- choice of 12-hour or 24-hour time format, with 12-hour as the
- default. If the locale doesn't have 'am' and 'pm' strings we have
- to use 24-hour format, or strftime()/strptime() won't work. */
- if (calendar_config_locale_supports_12_hour_format ()) {
- return e_config_listener_get_boolean_with_default (
- config, "/Calendar/Display/Use24HourFormat", FALSE, NULL);
- }
-
- return TRUE;
-}
-
-
-void
-calendar_config_set_24_hour_format (gboolean use_24_hour)
+static gchar *
+calendar_config_get_timezone_stored (void)
{
- e_config_listener_set_boolean (config, "/Calendar/Display/Use24HourFormat", use_24_hour);
-}
-
+ calendar_config_init ();
-/* The start day of the week (0 = Sun to 6 = Mon). */
-gint
-calendar_config_get_week_start_day (void)
-{
- return e_config_listener_get_long_with_default (config, "/Calendar/Display/WeekStartDay", 1, NULL);
+ return g_settings_get_string (config, "timezone");
}
-
-void
-calendar_config_set_week_start_day (gint week_start_day)
+static gchar *
+calendar_config_get_timezone (void)
{
- e_config_listener_set_long (config, "/Calendar/Display/WeekStartDay", week_start_day);
-}
+ GSettings *settings;
+ gboolean use_system_timezone;
+ settings = g_settings_new ("org.gnome.evolution.calendar");
-/* The start and end times of the work-day. */
-gint
-calendar_config_get_day_start_hour (void)
-{
- return e_config_listener_get_long_with_default (config, "/Calendar/Display/DayStartHour", 9, NULL);
-}
+ use_system_timezone =
+ g_settings_get_boolean (settings, "use-system-timezone");
+ g_object_unref (settings);
-void
-calendar_config_set_day_start_hour (gint day_start_hour)
-{
- e_config_listener_set_long (config, "/Calendar/Display/DayStartHour", day_start_hour);
-}
+ if (use_system_timezone)
+ return e_cal_util_get_system_timezone_location ();
-
-gint
-calendar_config_get_day_start_minute (void)
-{
- return e_config_listener_get_long_with_default (config, "/Calendar/Display/DayStartMinute", 0, NULL);
-}
-
-
-void
-calendar_config_set_day_start_minute (gint day_start_min)
-{
- e_config_listener_set_long (config, "/Calendar/Display/DayStartMinute", day_start_min);
+ return calendar_config_get_timezone_stored ();
}
-
-gint
-calendar_config_get_day_end_hour (void)
+icaltimezone *
+calendar_config_get_icaltimezone (void)
{
- return e_config_listener_get_long_with_default (config, "/Calendar/Display/DayEndHour", 17, NULL);
-}
+ gchar *location;
+ icaltimezone *zone = NULL;
+ calendar_config_init ();
-void
-calendar_config_set_day_end_hour (gint day_end_hour)
-{
- e_config_listener_set_long (config, "/Calendar/Display/DayEndHour", day_end_hour);
-}
-
-
-gint
-calendar_config_get_day_end_minute (void)
-{
- return e_config_listener_get_long_with_default (config, "/Calendar/Display/DayEndMinute", 0, NULL);
-}
-
-
-void
-calendar_config_set_day_end_minute (gint day_end_min)
-{
- e_config_listener_set_long (config, "/Calendar/Display/DayEndMinute", day_end_min);
-}
-
-
-/* The time divisions in the Day/Work-Week view in minutes (5/10/15/30/60). */
-gint
-calendar_config_get_time_divisions (void)
-{
- return e_config_listener_get_long_with_default (config, "/Calendar/Display/TimeDivisions", 30, NULL);
-}
-
+ location = calendar_config_get_timezone ();
+ if (location) {
+ zone = icaltimezone_get_builtin_timezone (location);
-void
-calendar_config_set_time_divisions (gint divisions)
-{
- e_config_listener_set_long (config, "/Calendar/Display/TimeDivisions", divisions);
+ g_free (location);
+ }
+ return zone;
}
-
-/* Whether we show week numbers in the Date Navigator. */
+/* Whether we use 24-hour format or 12-hour format (AM/PM). */
gboolean
-calendar_config_get_dnav_show_week_no (void)
-{
- return e_config_listener_get_boolean_with_default (config, "/Calendar/DateNavigator/ShowWeekNumbers", FALSE, NULL);
-}
-
-
-void
-calendar_config_set_dnav_show_week_no (gboolean show_week_no)
+calendar_config_get_24_hour_format (void)
{
- e_config_listener_set_boolean (config, "/Calendar/DateNavigator/ShowWeekNumbers", show_week_no);
-}
-
-
-/* The view to show on start-up, 0 = Day, 1 = WorkWeek, 2 = Week, 3 = Month. */
-gint
-calendar_config_get_default_view (void)
-{
- return e_config_listener_get_long_with_default (config, "/Calendar/Display/View", 0, NULL);
-}
-
-
-void
-calendar_config_set_default_view (gint view)
-{
- e_config_listener_set_long (config, "/Calendar/Display/View", view);
-}
-
-
-/* The positions of the panes in the normal and month views. */
-gfloat
-calendar_config_get_hpane_pos (void)
-{
- return e_config_listener_get_float_with_default (config, "/Calendar/Display/HPanePosition", 1.0, NULL);
-}
-
-
-void
-calendar_config_set_hpane_pos (gfloat hpane_pos)
-{
- e_config_listener_set_float (config, "/Calendar/Display/HPanePosition", hpane_pos);
-}
-
-
-gfloat
-calendar_config_get_vpane_pos (void)
-{
- return e_config_listener_get_float_with_default (config, "/Calendar/Display/VPanePosition", 1.0, NULL);
-}
-
-
-void
-calendar_config_set_vpane_pos (gfloat vpane_pos)
-{
- e_config_listener_set_float (config, "/Calendar/Display/VPanePosition", vpane_pos);
-}
-
-
-gfloat
-calendar_config_get_month_hpane_pos (void)
-{
- return e_config_listener_get_float_with_default (config, "/Calendar/Display/MonthHPanePosition", 0.0, NULL);
-}
-
-
-void
-calendar_config_set_month_hpane_pos (gfloat hpane_pos)
-{
- e_config_listener_set_float (config, "/Calendar/Display/MonthHPanePosition", hpane_pos);
-}
-
-
-gfloat
-calendar_config_get_month_vpane_pos (void)
-{
- return e_config_listener_get_float_with_default (config, "/Calendar/Display/MonthVPanePosition", 1.0, NULL);
-}
+ calendar_config_init ();
+ /* If the locale defines 'am' and 'pm' strings then the user has the
+ * choice of 12-hour or 24-hour time format, with 12-hour as the
+ * default. If the locale doesn't have 'am' and 'pm' strings we have
+ * to use 24-hour format, or strftime ()/strptime () won't work. */
+ if (calendar_config_locale_supports_12_hour_format ())
+ return g_settings_get_boolean (config, "use-24hour-format");
-void
-calendar_config_set_month_vpane_pos (gfloat vpane_pos)
-{
- e_config_listener_set_float (config, "/Calendar/Display/MonthVPanePosition", vpane_pos);
+ return TRUE;
}
-
-/* Whether we compress the weekend in the week/month views. */
+/* Scroll in a month view by a week, not by a month */
gboolean
-calendar_config_get_compress_weekend (void)
-{
- return e_config_listener_get_boolean_with_default (config, "/Calendar/Display/CompressWeekend", TRUE, NULL);
-}
-
-
-void
-calendar_config_set_compress_weekend (gboolean compress)
+calendar_config_get_month_scroll_by_week (void)
{
- e_config_listener_set_boolean (config, "/Calendar/Display/CompressWeekend", compress);
-}
+ calendar_config_init ();
-
-/* Whether we show event end times. */
-gboolean
-calendar_config_get_show_event_end (void)
-{
- return e_config_listener_get_boolean_with_default (config, "/Calendar/Display/ShowEventEndTime", TRUE, NULL);
+ return g_settings_get_boolean (config, "month-scroll-by-week");
}
-
void
-calendar_config_set_show_event_end (gboolean show_end)
+calendar_config_add_notification_month_scroll_by_week (CalendarConfigChangedFunc func,
+ gpointer data)
{
- e_config_listener_set_boolean (config, "/Calendar/Display/ShowEventEndTime", show_end);
-}
-
+ calendar_config_init ();
-/* The working days of the week, a bit-wise combination of flags. */
-CalWeekdays
-calendar_config_get_working_days (void)
-{
- return e_config_listener_get_long_with_default (config,
- "/Calendar/Display/WorkingDays", CAL_MONDAY | CAL_TUESDAY |
- CAL_WEDNESDAY | CAL_THURSDAY | CAL_FRIDAY, NULL);
-}
-
-
-void
-calendar_config_set_working_days (CalWeekdays days)
-{
- e_config_listener_set_long (config, "/Calendar/Display/WorkingDays", days);
+ g_signal_connect (
+ config, "changed::month-scroll-by-week",
+ G_CALLBACK (func), data);
}
+/***************************************/
/* Settings to hide completed tasks. */
gboolean
-calendar_config_get_hide_completed_tasks (void)
+calendar_config_get_hide_completed_tasks (void)
{
- return e_config_listener_get_boolean_with_default (config, "/Calendar/Tasks/HideCompletedTasks", FALSE, NULL);
-}
-
+ calendar_config_init ();
-void
-calendar_config_set_hide_completed_tasks (gboolean hide)
-{
- e_config_listener_set_boolean (config, "/Calendar/Tasks/HideCompletedTasks", hide);
+ return g_settings_get_boolean (config, "hide-completed-tasks");
}
-
-CalUnits
-calendar_config_get_hide_completed_tasks_units (void)
+static EDurationType
+calendar_config_get_hide_completed_tasks_units (void)
{
- char *units;
- CalUnits cu;
+ gchar *units;
+ EDurationType cu;
+
+ calendar_config_init ();
- units = e_config_listener_get_string_with_default (config, "/Calendar/Tasks/HideCompletedTasksUnits", "days", NULL);
+ units = g_settings_get_string (config, "hide-completed-tasks-units");
- if (!strcmp (units, "minutes"))
- cu = CAL_MINUTES;
- else if (!strcmp (units, "hours"))
- cu = CAL_HOURS;
+ if (units && !strcmp (units, "minutes"))
+ cu = E_DURATION_MINUTES;
+ else if (units && !strcmp (units, "hours"))
+ cu = E_DURATION_HOURS;
else
- cu = CAL_DAYS;
+ cu = E_DURATION_DAYS;
g_free (units);
return cu;
}
-
-void
-calendar_config_set_hide_completed_tasks_units (CalUnits cu)
-{
- char *units;
-
- switch (cu) {
- case CAL_MINUTES :
- units = g_strdup ("minutes");
- break;
- case CAL_HOURS :
- units = g_strdup ("hours");
- break;
- default :
- units = g_strdup ("days");
- }
-
- e_config_listener_set_string (config, "/Calendar/Tasks/HideCompletedTasksUnits", units);
-
- g_free (units);
-}
-
-
-gint
-calendar_config_get_hide_completed_tasks_value (void)
-{
- return e_config_listener_get_long_with_default (config, "/Calendar/Tasks/HideCompletedTasksValue", 1, NULL);
-}
-
-
-void
-calendar_config_set_hide_completed_tasks_value (gint value)
-{
- e_config_listener_set_long (config, "/Calendar/Tasks/HideCompletedTasksValue", value);
-}
-
-/**
- * calendar_config_get_confirm_delete:
- *
- * Queries the configuration value for whether a confirmation dialog is
- * presented when deleting calendar/tasks items.
- *
- * Return value: Whether confirmation is required when deleting items.
- **/
-gboolean
-calendar_config_get_confirm_delete (void)
-{
- return e_config_listener_get_boolean_with_default (config, "/Calendar/Other/ConfirmDelete", TRUE, NULL);
-}
-
/**
- * calendar_config_set_confirm_delete:
- * @confirm: Whether confirmation is required when deleting items.
+ * calendar_config_get_hide_completed_tasks_sexp:
*
- * Sets the configuration value for whether a confirmation dialog is presented
- * when deleting calendar/tasks items.
+ * @get_completed: Whether to form subexpression that
+ * gets completed or not completed tasks.
+ * Returns the subexpression to use to filter out completed tasks according
+ * to the config settings. The returned sexp should be freed.
**/
-void
-calendar_config_set_confirm_delete (gboolean confirm)
+gchar *
+calendar_config_get_hide_completed_tasks_sexp (gboolean get_completed)
{
- e_config_listener_set_boolean (config, "/Calendar/Other/ConfirmDelete", confirm);
-}
+ gchar *sexp = NULL;
-/**
- * calendar_config_get_confirm_expunge:
- *
- * Queries the configuration value for whether a confirmation dialog is
- * presented when expunging calendar/tasks items.
- *
- * Return value: Whether confirmation is required when expunging items.
- **/
-gboolean
-calendar_config_get_confirm_expunge (void)
-{
- return e_config_listener_get_boolean_with_default (config, "/Calendar/Other/ConfirmExpunge", TRUE, NULL);
-}
+ if (calendar_config_get_hide_completed_tasks ()) {
+ EDurationType units;
+ gint value;
-/**
- * calendar_config_set_confirm_expunge:
- * @confirm: Whether confirmation is required when expunging items.
- *
- * Sets the configuration value for whether a confirmation dialog is presented
- * when expunging calendar/tasks items.
- **/
-void
-calendar_config_set_confirm_expunge (gboolean confirm)
-{
- e_config_listener_set_boolean (config, "/Calendar/Other/ConfirmExpunge", confirm);
-}
+ units = calendar_config_get_hide_completed_tasks_units ();
+ value = g_settings_get_int (config, "hide-completed-tasks-value");
-/* This sets all the common config settings for an ECalendar widget.
- These are the week start day, and whether we show week numbers. */
-void
-calendar_config_configure_e_calendar (ECalendar *cal)
-{
- gboolean dnav_show_week_no;
- gint week_start_day;
+ if (value == 0) {
+ /* If the value is 0, we want to hide completed tasks
+ * immediately, so we filter out all complete/incomplete tasks.*/
+ if (!get_completed)
+ sexp = g_strdup ("(not is-completed?)");
+ else
+ sexp = g_strdup ("(is-completed?)");
+ } else {
+ gchar *isodate;
+ icaltimezone *zone;
+ struct icaltimetype tt;
+ time_t t;
- g_return_if_fail (E_IS_CALENDAR (cal));
+ /* Get the current time, and subtract the appropriate
+ * number of days/hours/minutes. */
+ zone = calendar_config_get_icaltimezone ();
+ tt = icaltime_current_time_with_zone (zone);
- dnav_show_week_no = calendar_config_get_dnav_show_week_no ();
+ switch (units) {
+ case E_DURATION_DAYS:
+ icaltime_adjust (&tt, -value, 0, 0, 0);
+ break;
+ case E_DURATION_HOURS:
+ icaltime_adjust (&tt, 0, -value, 0, 0);
+ break;
+ case E_DURATION_MINUTES:
+ icaltime_adjust (&tt, 0, 0, -value, 0);
+ break;
+ default:
+ g_return_val_if_reached (NULL);
+ }
- /* Note that this is 0 (Sun) to 6 (Sat). */
- week_start_day = calendar_config_get_week_start_day ();
+ t = icaltime_as_timet_with_zone (tt, zone);
- /* Convert it to 0 (Mon) to 6 (Sun), which is what we use. */
- week_start_day = (week_start_day + 6) % 7;
+ /* Convert the time to an ISO date string, and build
+ * the query sub-expression. */
+ isodate = isodate_from_time_t (t);
+ if (!get_completed)
+ sexp = g_strdup_printf (
+ "(not (completed-before? "
+ "(make-time \"%s\")))", isodate);
+ else
+ sexp = g_strdup_printf (
+ "(completed-before? "
+ "(make-time \"%s\"))", isodate);
+ g_free (isodate);
+ }
+ }
- gnome_canvas_item_set (GNOME_CANVAS_ITEM (cal->calitem),
- "show_week_numbers", dnav_show_week_no,
- "week_start_day", week_start_day,
- NULL);
+ return sexp;
}
-
-/* This sets all the common config settings for an EDateEdit widget.
- These are the week start day, whether we show week numbers, and whether we
- use 24 hour format. */
void
-calendar_config_configure_e_date_edit (EDateEdit *dedit)
+calendar_config_set_dir_path (const gchar *path)
{
- gboolean dnav_show_week_no, use_24_hour;
- gint week_start_day;
-
- g_return_if_fail (E_IS_DATE_EDIT (dedit));
-
- dnav_show_week_no = calendar_config_get_dnav_show_week_no ();
-
- /* Note that this is 0 (Sun) to 6 (Sat). */
- week_start_day = calendar_config_get_week_start_day ();
+ calendar_config_init ();
- /* Convert it to 0 (Mon) to 6 (Sun), which is what we use. */
- week_start_day = (week_start_day + 6) % 7;
-
- use_24_hour = calendar_config_get_24_hour_format ();
-
- e_date_edit_set_week_start_day (dedit, week_start_day);
- e_date_edit_set_show_week_numbers (dedit, dnav_show_week_no);
- e_date_edit_set_use_24_hour_format (dedit, use_24_hour);
+ g_settings_set_string (config, "audio-dir", path);
}
-
-/* This sets all the common config settings for an ECellDateEdit ETable item.
- These are the settings for the ECalendar popup and the time list (if we use
- 24 hour format, and the hours of the working day). */
-void
-calendar_config_configure_e_cell_date_edit (ECellDateEdit *ecde)
+gchar *
+calendar_config_get_dir_path (void)
{
- gboolean use_24_hour;
- gint start_hour, end_hour;
- ECellPopup *ecp;
- ECellDateEditText *ecd;
- char *location;
- icaltimezone *zone;
+ gchar *path;
- g_return_if_fail (E_IS_CELL_DATE_EDIT (ecde));
+ calendar_config_init ();
- ecp = E_CELL_POPUP (ecde);
- ecd = E_CELL_DATE_EDIT_TEXT (ecp->child);
+ path = g_settings_get_string (config, "audio-dir");
- location = calendar_config_get_timezone ();
- zone = icaltimezone_get_builtin_timezone (location);
-
- calendar_config_configure_e_calendar (E_CALENDAR (ecde->calendar));
+ return path;
+}
- use_24_hour = calendar_config_get_24_hour_format ();
+/* contains list of strings, locations, recently used as the second timezone
+ * in a day view. Free with calendar_config_free_day_second_zones. */
+GSList *
+calendar_config_get_day_second_zones (void)
+{
+ GSList *res = NULL;
+ gchar **strv;
+ gint i;
- start_hour = calendar_config_get_day_start_hour ();
- end_hour = calendar_config_get_day_end_hour ();
+ calendar_config_init ();
- /* Round up the end hour. */
- if (calendar_config_get_day_end_minute () != 0)
- end_hour++;
+ strv = g_settings_get_strv (config, "day-second-zones");
+ for (i = 0; i < g_strv_length (strv); i++) {
+ if (strv[i] != NULL)
+ res = g_slist_append (res, g_strdup (strv[i]));
+ }
- e_cell_date_edit_freeze (ecde);
- gtk_object_set (GTK_OBJECT (ecde),
- "use_24_hour_format", use_24_hour,
-#if 0
- /* We use the default 0 - 24 now. */
- "lower_hour", start_hour,
- "upper_hour", end_hour,
-#endif
- NULL);
- e_cell_date_edit_thaw (ecde);
+ g_strfreev (strv);
- e_cell_date_edit_text_set_timezone (ecd, zone);
- e_cell_date_edit_text_set_use_24_hour_format (ecd, use_24_hour);
+ return res;
}
-
-/* This sets all the common config settings for an ECalendarTable widget.
- These are the settings for the ECalendar popup and the time list (if we use
- 24 hour format, and the hours of the working day). */
+/* frees list from calendar_config_get_day_second_zones */
void
-calendar_config_configure_e_calendar_table (ECalendarTable *cal_table)
+calendar_config_free_day_second_zones (GSList *zones)
{
- CalendarModel *model;
- gboolean use_24_hour;
- char *location;
- icaltimezone *zone;
-
- g_return_if_fail (E_IS_CALENDAR_TABLE (cal_table));
-
- use_24_hour = calendar_config_get_24_hour_format ();
-
- model = e_calendar_table_get_model (cal_table);
- calendar_model_set_use_24_hour_format (model, use_24_hour);
-
- location = calendar_config_get_timezone ();
- zone = icaltimezone_get_builtin_timezone (location);
- calendar_model_set_timezone (model, zone);
-
- calendar_config_configure_e_cell_date_edit (cal_table->dates_cell);
-
- /* Reload the event/tasks, since the 'Hide Completed Tasks' option
- may have been changed, so the query needs to be updated. */
- calendar_model_refresh (model);
+ if (zones) {
+ g_slist_foreach (zones, (GFunc) g_free, NULL);
+ g_slist_free (zones);
+ }
}
-
-
+/* keeps max 'day_second_zones_max' zones, if 'location'
+ * is already in a list, then it'll became first there */
void
-calendar_config_check_timezone_set ()
+calendar_config_set_day_second_zone (const gchar *location)
{
- ETimezoneDialog *timezone_dialog;
- GtkWidget *dialog;
- GList *elem;
- char *zone;
+ calendar_config_init ();
- zone = calendar_config_get_timezone ();
- if (zone && zone[0])
- return;
-
- /* Show timezone dialog. */
- timezone_dialog = e_timezone_dialog_new ();
- dialog = e_timezone_dialog_get_toplevel (timezone_dialog);
+ if (location && *location) {
+ GSList *lst, *l;
+ gint max_zones;
+ GPtrArray *array;
+ gint i;
- /* Hide the cancel button, which is the 2nd button. */
- elem = g_list_nth (GNOME_DIALOG (dialog)->buttons, 1);
- gtk_widget_hide (elem->data);
+ /* configurable max number of timezones to remember */
+ max_zones = g_settings_get_int (config, "day-second-zones-max");
- gtk_signal_connect (GTK_OBJECT (dialog), "clicked",
- GTK_SIGNAL_FUNC (on_timezone_set),
- timezone_dialog);
- gtk_signal_connect (GTK_OBJECT (dialog), "delete-event",
- GTK_SIGNAL_FUNC (on_timezone_dialog_delete_event),
- timezone_dialog);
+ if (max_zones <= 0)
+ max_zones = 5;
- gtk_widget_show (dialog);
-}
+ lst = calendar_config_get_day_second_zones ();
+ for (l = lst; l; l = l->next) {
+ if (l->data && g_str_equal (l->data, location)) {
+ if (l != lst) {
+ /* isn't first in the list */
+ gchar *val = l->data;
+ lst = g_slist_remove (lst, val);
+ lst = g_slist_prepend (lst, val);
+ }
+ break;
+ }
+ }
-static void
-on_timezone_set (GnomeDialog *dialog,
- int button,
- ETimezoneDialog *etd)
-{
- char *display_name;
- icaltimezone *zone;
+ if (!l) {
+ /* not in the list yet */
+ lst = g_slist_prepend (lst, g_strdup (location));
+ }
- e_timezone_dialog_get_timezone (etd, &display_name);
+ array = g_ptr_array_new ();
+ for (i = 0, l = lst; i < max_zones && l != NULL; i++, l = l->next)
+ g_ptr_array_add (array, l->data);
+ g_ptr_array_add (array, NULL);
- /* We know it can only be a builtin timezone, since there is no way
- to set it to anything else. */
- zone = e_timezone_dialog_get_builtin_timezone (display_name);
- if (zone) {
- calendar_config_set_timezone (icaltimezone_get_location (zone));
+ g_settings_set_strv (
+ config, "day-second-zones",
+ (const gchar * const *) array->pdata);
- update_all_config_settings ();
- e_tasks_update_all_config_settings ();
+ calendar_config_free_day_second_zones (lst);
+ g_ptr_array_free (array, FALSE);
}
- gtk_object_unref (GTK_OBJECT (etd));
+ g_settings_set_string (
+ config, "day-second-zone",
+ (location != NULL) ? location : "");
}
-
-static gboolean
-on_timezone_dialog_delete_event (GnomeDialog *dialog,
- GdkEvent *event,
- ETimezoneDialog *etd)
-{
- gtk_object_unref (GTK_OBJECT (etd));
- return TRUE;
-}
-
-
-/**
- * calendar_config_get_tasks_due_today_color:
- *
- * Queries the color to be used to display tasks that are due today.
- *
- * Return value: An X color specification.
- **/
-const char *
-calendar_config_get_tasks_due_today_color (void)
+/* location of the second time zone user has selected. Free with g_free. */
+gchar *
+calendar_config_get_day_second_zone (void)
{
- static char *color = NULL;
-
- if (color)
- g_free (color);
+ calendar_config_init ();
- color = e_config_listener_get_string_with_default (config, "/Calendar/Tasks/Colors/TasksDueToday", "blue", NULL);
- return color;
+ return g_settings_get_string (config, "day-second-zone");
}
-/**
- * calendar_config_set_tasks_due_today_color:
- * @color: X color specification
- *
- * Sets the color to be used to display tasks that are due today.
- **/
void
-calendar_config_set_tasks_due_today_color (const char *color)
+calendar_config_select_day_second_zone (void)
{
- g_return_if_fail (color != NULL);
-
- e_config_listener_set_string (config, "/Calendar/Tasks/Colors/TasksDueToday", color);
-}
+ icaltimezone *zone = NULL;
+ ETimezoneDialog *tzdlg;
+ GtkWidget *dialog;
+ gchar *second_location;
-/**
- * calendar_config_get_tasks_overdue_color:
- *
- * Queries the color to be used to display overdue tasks.
- *
- * Return value: An X color specification.
- **/
-const char *
-calendar_config_get_tasks_overdue_color (void)
-{
- static char *color = NULL;
+ second_location = calendar_config_get_day_second_zone ();
+ if (second_location && *second_location)
+ zone = icaltimezone_get_builtin_timezone (second_location);
+ g_free (second_location);
- if (color)
- g_free (color);
+ if (!zone)
+ zone = calendar_config_get_icaltimezone ();
- color = e_config_listener_get_string_with_default (config, "/Calendar/Tasks/Colors/TasksOverdue", "red", NULL);
- return color;
-}
+ tzdlg = e_timezone_dialog_new ();
+ e_timezone_dialog_set_timezone (tzdlg, zone);
-/**
- * calendar_config_set_tasks_overdue_color:
- * @color: X color specification
- *
- * Sets the color to be used to display overdue tasks.
- **/
-void
-calendar_config_set_tasks_overdue_color (const char *color)
-{
- g_return_if_fail (color != NULL);
+ dialog = e_timezone_dialog_get_toplevel (tzdlg);
- e_config_listener_set_string (config, "/Calendar/Tasks/Colors/TasksOverdue", color);
-}
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
+ const gchar *location = NULL;
-/**
- * calendar_config_get_use_default_reminder:
- *
- * Queries whether new appointments should be created with a default reminder.
- *
- * Return value: Boolean value indicating whether new appointments should be
- * created with a default reminder from the values of
- * calendar_config_get_default_reminder_interval() and
- * calendar_config_get_default_reminder_units().
- **/
-gboolean
-calendar_config_get_use_default_reminder (void)
-{
- return e_config_listener_get_boolean_with_default (config, "/Calendar/Other/UseDefaultReminder", FALSE, NULL);
-}
+ zone = e_timezone_dialog_get_timezone (tzdlg);
+ if (zone == icaltimezone_get_utc_timezone ()) {
+ location = "UTC";
+ } else if (zone) {
+ location = icaltimezone_get_location (zone);
+ }
-/**
- * calendar_config_set_use_default_reminder:
- * @value: Whether to create new appointments with a default reminder.
- *
- * Sets whether newly-created appointments should get a default reminder set
- * them.
- **/
-void
-calendar_config_set_use_default_reminder (gboolean value)
-{
- e_config_listener_set_boolean (config, "/Calendar/Other/UseDefaultReminder", value);
-}
+ calendar_config_set_day_second_zone (location);
+ }
-/**
- * calendar_config_get_default_reminder_interval:
- *
- * Queries the interval for the default reminder of newly-created
- * appointments, i.e. 5 in "5 minutes".
- *
- * Return value: Interval for default reminders.
- **/
-int
-calendar_config_get_default_reminder_interval (void)
-{
- return e_config_listener_get_long_with_default (config, "/Calendar/Other/DefaultReminderInterval", 15, NULL);
+ g_object_unref (tzdlg);
}
-/**
- * calendar_config_set_default_reminder_interval:
- * @interval: Interval value, e.g. 5 for "5 minutes".
- *
- * Sets the interval that should be used for the default reminder in new
- * appointments.
- **/
void
-calendar_config_set_default_reminder_interval (int interval)
-{
- e_config_listener_set_long (config, "/Calendar/Other/DefaultReminderInterval", interval);
-}
-
-/**
- * calendar_config_get_default_reminder_units:
- *
- * Queries the units of time in which default reminders should be created for
- * new appointments, e.g. CAL_MINUTES for "5 minutes".
- *
- * Return value: Time units for default reminders.
- **/
-CalUnits
-calendar_config_get_default_reminder_units (void)
+calendar_config_add_notification_day_second_zone (CalendarConfigChangedFunc func,
+ gpointer data)
{
- char *units;
- CalUnits cu;
-
- units = e_config_listener_get_string_with_default (config, "/Calendar/Other/DefaultReminderUnits", "minutes", NULL);
-
- if (!strcmp (units, "days"))
- cu = CAL_DAYS;
- else if (!strcmp (units, "hours"))
- cu = CAL_HOURS;
- else
- cu = CAL_MINUTES; /* changed from above because
- * if bonobo-config fucks up
- * we want minutes, not days!
- */
- g_free (units);
-
- return cu;
-}
+ calendar_config_init ();
-/**
- * calendar_config_set_default_reminder_units:
- * @units: Time units, e.g. CAL_MINUTES for "5 minutes".
- *
- * Sets the units to be used for default reminders in new appointments.
- **/
-void
-calendar_config_set_default_reminder_units (CalUnits units)
-{
- switch (units) {
- case CAL_DAYS :
- e_config_listener_set_string (config, "/Calendar/Other/DefaultReminderUnits", "days");
- break;
- case CAL_HOURS :
- e_config_listener_set_string (config, "/Calendar/Other/DefaultReminderUnits", "hours");
- break;
- default :
- e_config_listener_set_string (config, "/Calendar/Other/DefaultReminderUnits", "minutes");
- }
+ g_signal_connect (
+ config, "changed::day-second-zone",
+ G_CALLBACK (func), data);
}
-/**
- * calendar_config_get_hide_completed_tasks_sexp:
- *
- * Returns the subexpression to use to filter out completed tasks according
- * to the config settings. The returned sexp should be freed.
- **/
-char*
-calendar_config_get_hide_completed_tasks_sexp (void)
+gboolean
+calendar_config_get_prefer_meeting (void)
{
- char *sexp = NULL;
+ GSettings *settings;
+ gchar *prefer_new_item;
+ gboolean prefer_meeting;
- if (calendar_config_get_hide_completed_tasks ()) {
- CalUnits units;
- gint value;
-
- units = calendar_config_get_hide_completed_tasks_units ();
- value = calendar_config_get_hide_completed_tasks_value ();
+ settings = g_settings_new ("org.gnome.evolution.calendar");
- if (value == 0) {
- /* If the value is 0, we want to hide completed tasks
- immediately, so we filter out all completed tasks.*/
- sexp = g_strdup ("(not is-completed?)");
- } else {
- char *location, *isodate;
- icaltimezone *zone;
- struct icaltimetype tt;
- time_t t;
+ prefer_new_item = g_settings_get_string (settings, "prefer-new-item");
+ prefer_meeting = g_strcmp0 (prefer_new_item, "event-meeting-new") == 0;
+ g_free (prefer_new_item);
- /* Get the current time, and subtract the appropriate
- number of days/hours/minutes. */
- location = calendar_config_get_timezone ();
- zone = icaltimezone_get_builtin_timezone (location);
- tt = icaltime_current_time_with_zone (zone);
+ g_object_unref (settings);
- switch (units) {
- case CAL_DAYS:
- icaltime_adjust (&tt, -value, 0, 0, 0);
- break;
- case CAL_HOURS:
- icaltime_adjust (&tt, 0, -value, 0, 0);
- break;
- case CAL_MINUTES:
- icaltime_adjust (&tt, 0, 0, -value, 0);
- break;
- default:
- g_assert_not_reached ();
- }
-
- t = icaltime_as_timet_with_zone (tt, zone);
-
- /* Convert the time to an ISO date string, and build
- the query sub-expression. */
- isodate = isodate_from_time_t (t);
- sexp = g_strdup_printf ("(not (completed-before? (make-time \"%s\")))", isodate);
- }
- }
-
- return sexp;
-}
-
-char *
-calendar_config_default_calendar_folder (void)
-{
- char *uri;
-
- uri = e_config_listener_get_string_with_default (config, "/DefaultFolders/calendar_uri", NULL, NULL);
- return uri;
-}
-
-char *
-calendar_config_default_tasks_folder (void)
-{
- char *uri;
-
- uri = e_config_listener_get_string_with_default (config, "/DefaultFolders/tasks_uri", NULL, NULL);
- return uri;
+ return prefer_meeting;
}
-
diff --git a/calendar/gui/calendar-config.h b/calendar/gui/calendar-config.h
index 6f0a9ee0fd..d868851026 100644
--- a/calendar/gui/calendar-config.h
+++ b/calendar/gui/calendar-config.h
@@ -1,26 +1,24 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
/*
- * Authors :
- * Damon Chaplin <damon@ximian.com>
- * Rodrigo Moya <rodrigo@ximian.com>
- *
- * Copyright 2000, Ximian, Inc.
- * Copyright 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Damon Chaplin <damon@ximian.com>
+ * Rodrigo Moya <rodrigo@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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
*/
/*
@@ -30,160 +28,52 @@
#ifndef _CALENDAR_CONFIG_H_
#define _CALENDAR_CONFIG_H_
-#include <widgets/misc/e-calendar.h>
-#include <widgets/misc/e-dateedit.h>
-#include <widgets/misc/e-cell-date-edit.h>
-#include "e-calendar-table.h"
-
-
-/* These are used to get/set the working days in the week. The bit-flags are
- combined together. The bits must be from 0 (Sun) to 6 (Sat) to match the
- day values used by localtime etc. */
-typedef enum
-{
- CAL_SUNDAY = 1 << 0,
- CAL_MONDAY = 1 << 1,
- CAL_TUESDAY = 1 << 2,
- CAL_WEDNESDAY = 1 << 3,
- CAL_THURSDAY = 1 << 4,
- CAL_FRIDAY = 1 << 5,
- CAL_SATURDAY = 1 << 6
-} CalWeekdays;
+#include <gio/gio.h>
+#include <gdk/gdk.h>
+#include <libecal/libecal.h>
+#include <e-util/e-util.h>
-/* Units for settings. */
-typedef enum
-{
- CAL_DAYS,
- CAL_HOURS,
- CAL_MINUTES
-} CalUnits;
-
-
-void calendar_config_init (void);
-void calendar_config_write (void);
-void calendar_config_write_on_exit (void);
+typedef void (* CalendarConfigChangedFunc) (GSettings *settings,
+ const gchar *key,
+ gpointer user_data);
+void calendar_config_remove_notification (CalendarConfigChangedFunc func, gpointer data);
/*
* Calendar Settings.
*/
/* The current timezone, e.g. "Europe/London". */
-gchar* calendar_config_get_timezone (void);
-void calendar_config_set_timezone (gchar *timezone);
-
-/* The working days of the week, a bit-wise combination of flags. */
-CalWeekdays calendar_config_get_working_days (void);
-void calendar_config_set_working_days (CalWeekdays days);
-
-/* The start day of the week (0 = Sun to 6 = Sat). */
-gint calendar_config_get_week_start_day (void);
-void calendar_config_set_week_start_day (gint week_start_day);
-
-/* The start and end times of the work-day. */
-gint calendar_config_get_day_start_hour (void);
-void calendar_config_set_day_start_hour (gint day_start_hour);
-
-gint calendar_config_get_day_start_minute (void);
-void calendar_config_set_day_start_minute (gint day_start_min);
-
-gint calendar_config_get_day_end_hour (void);
-void calendar_config_set_day_end_hour (gint day_end_hour);
-
-gint calendar_config_get_day_end_minute (void);
-void calendar_config_set_day_end_minute (gint day_end_min);
+icaltimezone *calendar_config_get_icaltimezone (void);
/* Whether we use 24-hour format or 12-hour format (AM/PM). */
gboolean calendar_config_get_24_hour_format (void);
-void calendar_config_set_24_hour_format (gboolean use_24_hour);
-
-/* The time divisions in the Day/Work-Week view in minutes (5/10/15/30/60). */
-gint calendar_config_get_time_divisions (void);
-void calendar_config_set_time_divisions (gint divisions);
-
-/* Whether we show event end times. */
-gboolean calendar_config_get_show_event_end (void);
-void calendar_config_set_show_event_end (gboolean show_end);
-
-/* Whether we compress the weekend in the week/month views. */
-gboolean calendar_config_get_compress_weekend (void);
-void calendar_config_set_compress_weekend (gboolean compress);
-
-/* Whether we show week numbers in the Date Navigator. */
-gboolean calendar_config_get_dnav_show_week_no (void);
-void calendar_config_set_dnav_show_week_no (gboolean show_week_no);
-
-/* The view to show on start-up, 0 = Day, 1 = WorkWeek, 2 = Week, 3 = Month. */
-gint calendar_config_get_default_view (void);
-void calendar_config_set_default_view (gint view);
-
-/* The positions of the panes in the normal and month views. */
-gfloat calendar_config_get_hpane_pos (void);
-void calendar_config_set_hpane_pos (gfloat hpane_pos);
-
-gfloat calendar_config_get_vpane_pos (void);
-void calendar_config_set_vpane_pos (gfloat vpane_pos);
-
-gfloat calendar_config_get_month_hpane_pos (void);
-void calendar_config_set_month_hpane_pos (gfloat hpane_pos);
-
-gfloat calendar_config_get_month_vpane_pos (void);
-void calendar_config_set_month_vpane_pos (gfloat vpane_pos);
-
-/* Colors for the task list */
-const char *calendar_config_get_tasks_due_today_color (void);
-void calendar_config_set_tasks_due_today_color (const char *color);
-
-const char *calendar_config_get_tasks_overdue_color (void);
-void calendar_config_set_tasks_overdue_color (const char *color);
/* Settings to hide completed tasks. */
gboolean calendar_config_get_hide_completed_tasks (void);
-void calendar_config_set_hide_completed_tasks (gboolean hide);
-
-CalUnits calendar_config_get_hide_completed_tasks_units(void);
-void calendar_config_set_hide_completed_tasks_units(CalUnits units);
-
-gint calendar_config_get_hide_completed_tasks_value(void);
-void calendar_config_set_hide_completed_tasks_value(gint value);
-
-char* calendar_config_get_hide_completed_tasks_sexp (void);
-
-/* Confirmation options */
-gboolean calendar_config_get_confirm_delete (void);
-void calendar_config_set_confirm_delete (gboolean confirm);
-gboolean calendar_config_get_confirm_expunge (void);
-void calendar_config_set_confirm_expunge (gboolean confirm);
+gchar * calendar_config_get_hide_completed_tasks_sexp (gboolean get_completed);
-/* Default reminder options */
-gboolean calendar_config_get_use_default_reminder (void);
-void calendar_config_set_use_default_reminder (gboolean value);
-
-int calendar_config_get_default_reminder_interval (void);
-void calendar_config_set_default_reminder_interval (int interval);
-
-CalUnits calendar_config_get_default_reminder_units (void);
-void calendar_config_set_default_reminder_units (CalUnits units);
+/* Returns TRUE if the locale has 'am' and 'pm' strings defined, i.e. it
+ * supports 12-hour time format. */
+gboolean calendar_config_locale_supports_12_hour_format (void);
+void calendar_config_set_dir_path (const gchar *);
+gchar * calendar_config_get_dir_path (void);
-/* Convenience functions to configure common properties of ECalendar,
- EDateEdit & ECalendarTable widgets, and the ECellDateEdit ETable cell. */
-void calendar_config_configure_e_calendar (ECalendar *cal);
-void calendar_config_configure_e_date_edit (EDateEdit *dedit);
-void calendar_config_configure_e_calendar_table (ECalendarTable *cal_table);
-void calendar_config_configure_e_cell_date_edit (ECellDateEdit *ecde);
+GSList *calendar_config_get_day_second_zones (void);
+void calendar_config_free_day_second_zones (GSList *zones);
+void calendar_config_set_day_second_zone (const gchar *location);
+gchar * calendar_config_get_day_second_zone (void);
+void calendar_config_select_day_second_zone (void);
-/* Shows the timezone dialog if the user hasn't set a default timezone. */
-void calendar_config_check_timezone_set (void);
+void calendar_config_add_notification_day_second_zone (CalendarConfigChangedFunc func, gpointer data);
-/* Returns TRUE if the locale has 'am' and 'pm' strings defined, i.e. it
- supports 12-hour time format. */
-gboolean calendar_config_locale_supports_12_hour_format(void);
+/* Scroll in a month view by a week, not by a month */
+gboolean calendar_config_get_month_scroll_by_week (void);
+void calendar_config_add_notification_month_scroll_by_week (CalendarConfigChangedFunc func, gpointer data);
-/* Default folders, read-only */
-char *calendar_config_default_calendar_folder (void);
-char *calendar_config_default_tasks_folder (void);
+gboolean calendar_config_get_prefer_meeting (void);
#endif /* _CALENDAR_CONFIG_H_ */
diff --git a/calendar/gui/calendar-model.c b/calendar/gui/calendar-model.c
deleted file mode 100644
index cef066c1b1..0000000000
--- a/calendar/gui/calendar-model.c
+++ /dev/null
@@ -1,2469 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/* Evolution calendar - Data model for ETable
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@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 <math.h>
-#include <sys/types.h>
-
-#include <ctype.h>
-
-#include <libgnomeui/gnome-messagebox.h>
-#include <libgnomeui/gnome-stock.h>
-#include <libgnome/gnome-i18n.h>
-#include <gal/widgets/e-unicode.h>
-#include <e-util/e-time-utils.h>
-#include <cal-util/timeutil.h>
-#include "calendar-commands.h"
-#include "calendar-config.h"
-#include "comp-util.h"
-#include "itip-utils.h"
-#include "calendar-model.h"
-#include "evolution-activity-client.h"
-#include "e-cell-date-edit-text.h"
-#include "misc.h"
-
-/* This specifies how often we refresh the list, so that completed tasks are
- hidden according to the config setting, and overdue tasks change color etc.
- It is in milliseconds, so this is 10 minutes.
- Note that if the user is editing an item in the list, they will probably
- lose their edit, so this isn't ideal. */
-#define CALENDAR_MODEL_REFRESH_TIMEOUT 1000 * 60 * 10
-
-/* These hold the date values of the objects, so we can free the values when
- we no longer need them. */
-typedef struct _CalendarModelObjectData CalendarModelObjectData;
-struct _CalendarModelObjectData {
- ECellDateEditValue *dtstart;
- ECellDateEditValue *dtend;
- ECellDateEditValue *due;
- ECellDateEditValue *completed;
-};
-
-/* We use a pointer to this value to indicate that the property is not set. */
-static ECellDateEditValue unset_date_edit_value;
-
-/* Private part of the ECalendarModel structure */
-struct _CalendarModelPrivate {
- /* Calendar client we are using */
- CalClient *client;
-
- /* Types of objects we are dealing with */
- CalObjType type;
-
- /* S-expression for query and the query object */
- char *sexp;
- CalQuery *query;
-
- /* Array of pointers to calendar objects */
- GArray *objects;
-
- /* Array of CalendarModelObjectData* holding data for each of the
- objects in the objects array above. */
- GArray *objects_data;
-
- /* UID -> array index hash */
- GHashTable *uid_index_hash;
-
- /* Type of components to create when using click-to-add in the table */
- CalComponentVType new_comp_vtype;
-
- /* Whether we display dates in 24-hour format. */
- gboolean use_24_hour_format;
-
- /* The default category to use when creating new tasks, e.g. when the
- filter is set to a certain category we use that category when
- creating a new task. */
- gchar *default_category;
-
- /* Addresses for determining icons */
- GList *addresses;
-
- /* The current timezone. */
- icaltimezone *zone;
-
- /* The id of our timeout function for refreshing the list. */
- gint timeout_id;
-
- /* The activity client used to show messages on the status bar. */
- EvolutionActivityClient *activity;
-};
-
-
-
-static void calendar_model_class_init (CalendarModelClass *class);
-static void calendar_model_init (CalendarModel *model);
-static void calendar_model_destroy (GtkObject *object);
-
-static int calendar_model_column_count (ETableModel *etm);
-static int calendar_model_row_count (ETableModel *etm);
-static void *calendar_model_value_at (ETableModel *etm, int col, int row);
-static void calendar_model_set_value_at (ETableModel *etm, int col, int row, const void *value);
-static gboolean calendar_model_is_cell_editable (ETableModel *etm, int col, int row);
-static void calendar_model_append_row (ETableModel *etm, ETableModel *source, gint row);
-static void *calendar_model_duplicate_value (ETableModel *etm, int col, const void *value);
-static void calendar_model_free_value (ETableModel *etm, int col, void *value);
-static void *calendar_model_initialize_value (ETableModel *etm, int col);
-static gboolean calendar_model_value_is_empty (ETableModel *etm, int col, const void *value);
-static char * calendar_model_value_to_string (ETableModel *etm, int col, const void *value);
-static int remove_object (CalendarModel *model, const char *uid);
-static void ensure_task_complete (CalComponent *comp,
- time_t completed_date);
-static void ensure_task_not_complete (CalComponent *comp);
-
-static ETableModelClass *parent_class;
-
-
-
-/**
- * calendar_model_get_type:
- * @void:
- *
- * Registers the #CalendarModel class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the #CalendarModel class.
- **/
-GtkType
-calendar_model_get_type (void)
-{
- static GtkType calendar_model_type = 0;
-
- if (!calendar_model_type) {
- static GtkTypeInfo calendar_model_info = {
- "CalendarModel",
- sizeof (CalendarModel),
- sizeof (CalendarModelClass),
- (GtkClassInitFunc) calendar_model_class_init,
- (GtkObjectInitFunc) calendar_model_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- calendar_model_type = gtk_type_unique (E_TABLE_MODEL_TYPE, &calendar_model_info);
- }
-
- return calendar_model_type;
-}
-
-/* Class initialization function for the calendar table model */
-static void
-calendar_model_class_init (CalendarModelClass *class)
-{
- GtkObjectClass *object_class;
- ETableModelClass *etm_class;
-
- object_class = (GtkObjectClass *) class;
- etm_class = (ETableModelClass *) class;
-
- parent_class = gtk_type_class (E_TABLE_MODEL_TYPE);
-
- object_class->destroy = calendar_model_destroy;
-
- etm_class->column_count = calendar_model_column_count;
- etm_class->row_count = calendar_model_row_count;
- etm_class->value_at = calendar_model_value_at;
- etm_class->set_value_at = calendar_model_set_value_at;
- etm_class->is_cell_editable = calendar_model_is_cell_editable;
- etm_class->append_row = calendar_model_append_row;
- etm_class->duplicate_value = calendar_model_duplicate_value;
- etm_class->free_value = calendar_model_free_value;
- etm_class->initialize_value = calendar_model_initialize_value;
- etm_class->value_is_empty = calendar_model_value_is_empty;
- etm_class->value_to_string = calendar_model_value_to_string;
-}
-
-
-static gboolean
-calendar_model_timeout_cb (gpointer data)
-{
- CalendarModel *model;
-
- g_return_val_if_fail (IS_CALENDAR_MODEL (data), FALSE);
-
- model = CALENDAR_MODEL (data);
-
- GDK_THREADS_ENTER ();
-
- calendar_model_refresh (model);
-
- GDK_THREADS_LEAVE ();
- return TRUE;
-}
-
-
-/* Object initialization function for the calendar table model */
-static void
-calendar_model_init (CalendarModel *model)
-{
- CalendarModelPrivate *priv;
-
- priv = g_new0 (CalendarModelPrivate, 1);
- model->priv = priv;
-
- priv->sexp = g_strdup ("#t"); /* match all by default */
- priv->query = NULL;
-
- priv->objects = g_array_new (FALSE, TRUE, sizeof (CalComponent *));
- priv->objects_data = g_array_new (FALSE, FALSE, sizeof (CalendarModelObjectData));
- priv->uid_index_hash = g_hash_table_new (g_str_hash, g_str_equal);
- priv->new_comp_vtype = CAL_COMPONENT_EVENT;
- priv->use_24_hour_format = TRUE;
-
- priv->timeout_id = g_timeout_add (CALENDAR_MODEL_REFRESH_TIMEOUT,
- calendar_model_timeout_cb, model);
-
- priv->addresses = itip_addresses_get ();
-
- priv->zone = NULL;
-
- priv->activity = NULL;
-}
-
-static void
-calendar_model_free_object_data (CalendarModel *model,
- CalendarModelObjectData *object_data)
-{
- if (object_data->dtstart != &unset_date_edit_value)
- g_free (object_data->dtstart);
-
- if (object_data->dtend != &unset_date_edit_value)
- g_free (object_data->dtend);
-
- if (object_data->due != &unset_date_edit_value)
- g_free (object_data->due);
-
- if (object_data->completed != &unset_date_edit_value)
- g_free (object_data->completed);
-}
-
-/* Called from g_hash_table_foreach_remove(), frees a stored UID->index
- * mapping.
- */
-static gboolean
-free_uid_index (gpointer key, gpointer value, gpointer data)
-{
- int *idx;
-
- idx = value;
- g_free (idx);
-
- return TRUE;
-}
-
-/* Frees the objects stored in the calendar model */
-static void
-free_objects (CalendarModel *model)
-{
- CalendarModelPrivate *priv;
- int i;
-
- priv = model->priv;
-
- g_hash_table_foreach_remove (priv->uid_index_hash, free_uid_index, NULL);
-
- for (i = 0; i < priv->objects->len; i++) {
- CalComponent *comp;
- CalendarModelObjectData *object_data;
-
- comp = g_array_index (priv->objects, CalComponent *, i);
- g_assert (comp != NULL);
- gtk_object_unref (GTK_OBJECT (comp));
-
- object_data = &g_array_index (priv->objects_data,
- CalendarModelObjectData, i);
- calendar_model_free_object_data (model, object_data);
- }
-
- g_array_set_size (priv->objects, 0);
- g_array_set_size (priv->objects_data, 0);
-}
-
-/* Destroy handler for the calendar table model */
-static void
-calendar_model_destroy (GtkObject *object)
-{
- CalendarModel *model;
- CalendarModelPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CALENDAR_MODEL (object));
-
- model = CALENDAR_MODEL (object);
- priv = model->priv;
-
- if (priv->timeout_id) {
- g_source_remove (priv->timeout_id);
- priv->timeout_id = 0;
- }
-
- /* Free the calendar client interface object */
-
- if (priv->client) {
- gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), model);
- gtk_object_unref (GTK_OBJECT (priv->client));
- priv->client = NULL;
- }
-
- if (priv->sexp) {
- g_free (priv->sexp);
- priv->sexp = NULL;
- }
-
- if (priv->query) {
- gtk_signal_disconnect_by_data (GTK_OBJECT (priv->query), model);
- gtk_object_unref (GTK_OBJECT (priv->query));
- priv->query = NULL;
- }
-
- /* Free the uid->index hash data and the array of UIDs */
-
- free_objects (model);
-
- g_hash_table_destroy (priv->uid_index_hash);
- priv->uid_index_hash = NULL;
-
- g_array_free (priv->objects, TRUE);
- priv->objects = NULL;
-
- g_array_free (priv->objects_data, TRUE);
- priv->objects_data = NULL;
-
- g_free (priv->default_category);
-
- itip_addresses_free (priv->addresses);
-
- if (priv->activity) {
- gtk_object_unref (GTK_OBJECT (priv->activity));
- priv->activity = NULL;
- }
-
- /* Free the private structure */
-
- g_free (priv);
- model->priv = NULL;
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-
-
-/* ETableModel methods */
-
-/* column_count handler for the calendar table model */
-static int
-calendar_model_column_count (ETableModel *etm)
-{
- return CAL_COMPONENT_FIELD_NUM_FIELDS;
-}
-
-/* row_count handler for the calendar table model */
-static int
-calendar_model_row_count (ETableModel *etm)
-{
- CalendarModel *model;
- CalendarModelPrivate *priv;
-
- model = CALENDAR_MODEL (etm);
- priv = model->priv;
-
- return priv->objects->len;
-}
-
-/* Builds a string based on the list of CATEGORIES properties of a calendar
- * component.
- */
-static char *
-get_categories (CalComponent *comp)
-{
- const char *categories;
-
- cal_component_get_categories (comp, &categories);
-
- return categories ? (char*) categories : "";
-}
-
-/* Returns a string based on the CLASSIFICATION property of a calendar component */
-static char *
-get_classification (CalComponent *comp)
-{
- CalComponentClassification classif;
-
- cal_component_get_classification (comp, &classif);
-
- switch (classif) {
- case CAL_COMPONENT_CLASS_PRIVATE:
- return _("Private");
-
- case CAL_COMPONENT_CLASS_CONFIDENTIAL:
- return _("Confidential");
-
- default:
- return _("Public");
- }
-}
-
-/* Returns an ECellDateEditValue* for a COMPLETED property of a
- calendar component. Note that we cache these in the objects_data array so
- we can free them eventually. */
-static ECellDateEditValue*
-get_completed (CalendarModel *model,
- CalComponent *comp,
- int row)
-{
- CalendarModelPrivate *priv;
- CalendarModelObjectData *object_data;
- struct icaltimetype *completed;
-
- priv = model->priv;
-
- object_data = &g_array_index (priv->objects_data,
- CalendarModelObjectData, row);
-
- if (!object_data->completed) {
- cal_component_get_completed (comp, &completed);
-
- if (completed) {
- object_data->completed = g_new (ECellDateEditValue, 1);
- object_data->completed->tt = *completed;
- object_data->completed->zone = icaltimezone_get_utc_timezone ();
- cal_component_free_icaltimetype (completed);
- } else {
- object_data->completed = &unset_date_edit_value;
- }
- }
-
- return (object_data->completed == &unset_date_edit_value)
- ? NULL : object_data->completed;
-}
-
-/* Returns an ECellDateEditValue* for a DTSTART, DTEND or DUE property of a
- calendar component. Note that we cache these in the objects_data array so
- we can free them eventually. */
-static ECellDateEditValue*
-get_date_edit_value (CalendarModel *model, CalComponent *comp,
- int col, int row)
-{
- CalendarModelPrivate *priv;
- CalComponentDateTime dt;
- CalendarModelObjectData *object_data;
- ECellDateEditValue **value;
-
- priv = model->priv;
-
- object_data = &g_array_index (priv->objects_data,
- CalendarModelObjectData, row);
-
- if (col == CAL_COMPONENT_FIELD_DTSTART)
- value = &object_data->dtstart;
- else if (col == CAL_COMPONENT_FIELD_DTEND)
- value = &object_data->dtend;
- else
- value = &object_data->due;
-
- if (!(*value)) {
- if (col == CAL_COMPONENT_FIELD_DTSTART)
- cal_component_get_dtstart (comp, &dt);
- else if (col == CAL_COMPONENT_FIELD_DTEND)
- cal_component_get_dtend (comp, &dt);
- else
- cal_component_get_due (comp, &dt);
-
- if (dt.value) {
- CalClientGetStatus status;
- icaltimezone *zone;
-
- /* For a DTEND with a DATE value, we subtract 1 from
- the day to display it. */
- if (col == CAL_COMPONENT_FIELD_DTEND
- && dt.value->is_date) {
- icaltime_adjust (dt.value, -1, 0, 0, 0);
- }
-
- *value = g_new (ECellDateEditValue, 1);
- (*value)->tt = *dt.value;
-
- /* FIXME: TIMEZONES: Handle error. */
- status = cal_client_get_timezone (model->priv->client,
- dt.tzid, &zone);
- (*value)->zone = zone;
- } else {
- *value = &unset_date_edit_value;
- }
-
- cal_component_free_datetime (&dt);
- }
-
- return (*value == &unset_date_edit_value) ? NULL : *value;
-}
-
-/* Builds a string for the GEO property of a calendar component */
-static char*
-get_geo (CalComponent *comp)
-{
- struct icalgeotype *geo;
- static gchar buf[32];
-
- cal_component_get_geo (comp, &geo);
-
- if (!geo)
- buf[0] = '\0';
- else {
- g_snprintf (buf, sizeof (buf), "%g %s, %g %s",
- fabs (geo->lat),
- geo->lat >= 0.0 ? _("N") : _("S"),
- fabs (geo->lon),
- geo->lon >= 0.0 ? _("E") : _("W"));
- cal_component_free_geo (geo);
- }
-
- return buf;
-}
-
-/* Builds a string for the PERCENT property of a calendar component */
-static int
-get_percent (CalComponent *comp)
-{
- int *percent, retval;
-
- cal_component_get_percent (comp, &percent);
-
- if (percent) {
- retval = *percent;
- cal_component_free_percent (percent);
- } else {
- retval = -1;
- }
-
- return retval;
-}
-
-/* Builds a string for the PRIORITY property of a calendar component */
-static char *
-get_priority (CalComponent *comp)
-{
- int *priority;
- char *retval = "";
-
- cal_component_get_priority (comp, &priority);
-
- if (priority) {
- retval = cal_util_priority_to_string (*priority);
- cal_component_free_priority (priority);
- }
-
- return retval;
-}
-
-/* Builds a string for the SUMMARY property of a calendar component */
-static char *
-get_summary (CalComponent *comp)
-{
- CalComponentText summary;
-
- cal_component_get_summary (comp, &summary);
-
- if (summary.value)
- return (char *) summary.value;
- else
- return "";
-}
-
-/* Builds a string for the TRANSPARENCY property of a calendar component */
-static char *
-get_transparency (CalComponent *comp)
-{
- CalComponentTransparency transp;
-
- cal_component_get_transparency (comp, &transp);
-
- if (transp == CAL_COMPONENT_TRANSP_TRANSPARENT)
- return _("Free");
- else
- return _("Busy");
-}
-
-/* Builds a string for the URL property of a calendar component */
-static char *
-get_url (CalComponent *comp)
-{
- const char *url;
-
- cal_component_get_url (comp, &url);
-
- if (url)
- return (char *) url;
- else
- return "";
-}
-
-/* Returns whether the completion date has been set on a component */
-static gboolean
-is_complete (CalComponent *comp)
-{
- struct icaltimetype *t;
- gboolean retval;
-
- cal_component_get_completed (comp, &t);
- retval = (t != NULL);
-
- if (retval)
- cal_component_free_icaltimetype (t);
-
- return retval;
-}
-
-typedef enum {
- CALENDAR_MODEL_DUE_NEVER,
- CALENDAR_MODEL_DUE_FUTURE,
- CALENDAR_MODEL_DUE_TODAY,
- CALENDAR_MODEL_DUE_OVERDUE,
- CALENDAR_MODEL_DUE_COMPLETE
-} CalendarModelDueStatus;
-
-
-static CalendarModelDueStatus
-get_due_status (CalendarModel *model, CalComponent *comp)
-{
- CalComponentDateTime dt;
- CalendarModelDueStatus retval;
-
- cal_component_get_due (comp, &dt);
-
- /* First, do we have a due date? */
-
- if (!dt.value)
- retval = CALENDAR_MODEL_DUE_NEVER;
- else {
- struct icaltimetype now_tt;
- CalClientGetStatus status;
- icaltimezone *zone;
-
- /* Second, is it already completed? */
-
- if (is_complete (comp)) {
- retval = CALENDAR_MODEL_DUE_COMPLETE;
- goto out;
- }
-
- /* Third, are we overdue as of right now? */
-
- if (dt.value->is_date) {
- int cmp;
-
- now_tt = icaltime_today ();
- cmp = icaltime_compare_date_only (*dt.value, now_tt);
-
- if (cmp < 0)
- retval = CALENDAR_MODEL_DUE_OVERDUE;
- else if (cmp == 0)
- retval = CALENDAR_MODEL_DUE_TODAY;
- else
- retval = CALENDAR_MODEL_DUE_FUTURE;
- } else {
- /* Get the current time in the same timezone as the DUE date.*/
- /* FIXME: TIMEZONES: Handle error. */
- status = cal_client_get_timezone (model->priv->client, dt.tzid,
- &zone);
- now_tt = icaltime_current_time_with_zone (zone);
-
- if (icaltime_compare (*dt.value, now_tt) <= 0)
- retval = CALENDAR_MODEL_DUE_OVERDUE;
- else
- if (icaltime_compare_date_only (*dt.value, now_tt) == 0)
- retval = CALENDAR_MODEL_DUE_TODAY;
- else
- retval = CALENDAR_MODEL_DUE_FUTURE;
- }
- }
-
- out:
-
- cal_component_free_datetime (&dt);
-
- return retval;
-}
-
-/* Returns whether a component is overdue. */
-static gboolean
-is_overdue (CalendarModel *model, CalComponent *comp)
-{
- switch (get_due_status (model, comp)) {
- case CALENDAR_MODEL_DUE_NEVER:
- case CALENDAR_MODEL_DUE_FUTURE:
- case CALENDAR_MODEL_DUE_COMPLETE:
- return FALSE;
- case CALENDAR_MODEL_DUE_TODAY:
- case CALENDAR_MODEL_DUE_OVERDUE:
- return TRUE;
- }
-
- return FALSE;
-}
-
-/* Computes the color to be used to display a component */
-static const char *
-get_color (CalendarModel *model, CalComponent *comp)
-{
- switch (get_due_status (model, comp)) {
- case CALENDAR_MODEL_DUE_NEVER:
- case CALENDAR_MODEL_DUE_FUTURE:
- case CALENDAR_MODEL_DUE_COMPLETE:
- return NULL;
- case CALENDAR_MODEL_DUE_TODAY:
- return calendar_config_get_tasks_due_today_color ();
- case CALENDAR_MODEL_DUE_OVERDUE:
- return calendar_config_get_tasks_overdue_color ();
- }
-
- return NULL;
-}
-
-static void *
-get_status (CalComponent *comp)
-{
- icalproperty_status status;
-
- cal_component_get_status (comp, &status);
-
- switch (status) {
- case ICAL_STATUS_NONE:
- return "";
-
- case ICAL_STATUS_NEEDSACTION:
- return _("Not Started");
-
- case ICAL_STATUS_INPROCESS:
- return _("In Progress");
-
- case ICAL_STATUS_COMPLETED:
- return _("Completed");
-
- case ICAL_STATUS_CANCELLED:
- return _("Cancelled");
-
- default:
- g_assert_not_reached ();
- return NULL;
- }
-}
-
-#if 0
-static void *
-get_location (CalComponent *comp)
-{
- const char *location;
-
- cal_component_get_location (comp, &location);
- return (void*) location;
-}
-#endif
-
-/* value_at handler for the calendar table model */
-static void *
-calendar_model_value_at (ETableModel *etm, int col, int row)
-{
- CalendarModel *model;
- CalendarModelPrivate *priv;
- CalComponent *comp;
-
- model = CALENDAR_MODEL (etm);
- priv = model->priv;
-
- g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, NULL);
- g_return_val_if_fail (row >= 0 && row < priv->objects->len, NULL);
-
- comp = g_array_index (priv->objects, CalComponent *, row);
- g_assert (comp != NULL);
-
-#if 0
- g_print ("In calendar_model_value_at: %i\n", col);
-#endif
-
- switch (col) {
- case CAL_COMPONENT_FIELD_CATEGORIES:
- return get_categories (comp);
-
- case CAL_COMPONENT_FIELD_CLASSIFICATION:
- return get_classification (comp);
-
- case CAL_COMPONENT_FIELD_COMPLETED:
- return get_completed (model, comp, row);
-
- case CAL_COMPONENT_FIELD_DTEND:
- case CAL_COMPONENT_FIELD_DTSTART:
- case CAL_COMPONENT_FIELD_DUE:
- return get_date_edit_value (model, comp, col, row);
-
- case CAL_COMPONENT_FIELD_GEO:
- return get_geo (comp);
-
- case CAL_COMPONENT_FIELD_PERCENT:
- return GINT_TO_POINTER (get_percent (comp));
-
- case CAL_COMPONENT_FIELD_PRIORITY:
- return get_priority (comp);
-
- case CAL_COMPONENT_FIELD_SUMMARY:
- return get_summary (comp);
-
- case CAL_COMPONENT_FIELD_TRANSPARENCY:
- return get_transparency (comp);
-
- case CAL_COMPONENT_FIELD_URL:
- return get_url (comp);
-
- case CAL_COMPONENT_FIELD_HAS_ALARMS:
- return GINT_TO_POINTER (cal_component_has_alarms (comp));
-
- case CAL_COMPONENT_FIELD_ICON:
- {
- ItipAddress *ia;
- GSList *attendees = NULL, *sl;
- gint retval = 0;
-
- if (cal_component_has_recurrences (comp))
- return GINT_TO_POINTER (1);
-
- if (itip_organizer_is_user (comp))
- return GINT_TO_POINTER (3);
-
- cal_component_get_attendee_list (comp, &attendees);
- for (sl = attendees; sl != NULL; sl = sl->next) {
- CalComponentAttendee *ca = sl->data;
- const char *text;
- GList *l;
-
- text = itip_strip_mailto (ca->value);
- for (l = priv->addresses; l != NULL; l = l->next) {
- ia = l->data;
-
- if (!strcmp (text, ia->address)) {
- if (ca->delto != NULL)
- retval = 3;
- else
- retval = 2;
- goto cleanup;
- }
- }
- }
-
- cleanup:
- cal_component_free_attendee_list (attendees);
- return GINT_TO_POINTER (retval);
- break;
- }
- case CAL_COMPONENT_FIELD_COMPLETE:
- return GINT_TO_POINTER (is_complete (comp));
-
- case CAL_COMPONENT_FIELD_RECURRING:
- return GINT_TO_POINTER (cal_component_has_recurrences (comp));
-
- case CAL_COMPONENT_FIELD_OVERDUE:
- return GINT_TO_POINTER (is_overdue (model, comp));
-
- case CAL_COMPONENT_FIELD_COLOR:
- return (void *) get_color (model, comp);
-
- case CAL_COMPONENT_FIELD_STATUS:
- return get_status (comp);
-
- case CAL_COMPONENT_FIELD_COMPONENT:
- return comp;
-
-#if 0
- case CAL_COMPONENT_FIELD_LOCATION :
- return get_location (comp);
-#endif
-
- default:
- g_message ("calendar_model_value_at(): Requested invalid column %d", col);
- g_assert_not_reached ();
- return NULL;
- }
-}
-
-/* Builds a list of categories from a comma-delimited string */
-static GSList *
-categories_from_string (const char *value)
-{
- GSList *list;
- const char *categ_start;
- const char *categ_end;
- const char *p;
-
- if (!value)
- return NULL;
-
- list = NULL;
-
- categ_start = categ_end = NULL;
-
- for (p = value; *p; p++) {
- if (categ_start) {
- if (*p == ',') {
- char *c;
-
- c = g_strndup (categ_start, categ_end - categ_start + 1);
- list = g_slist_prepend (list, c);
-
- categ_start = categ_end = NULL;
- } else if (!isspace (*p))
- categ_end = p;
- } else if (!isspace (*p) && *p != ',')
- categ_start = categ_end = p;
- }
-
- if (categ_start) {
- char *c;
-
- c = g_strndup (categ_start, categ_end - categ_start + 1);
- list = g_slist_prepend (list, c);
- }
-
- return g_slist_reverse (list);
-}
-
-/* Sets the list of categories from a comma-delimited string */
-static void
-set_categories (CalComponent *comp, const char *value)
-{
- GSList *list;
- GSList *l;
-
- list = categories_from_string (value);
-
- cal_component_set_categories_list (comp, list);
-
- for (l = list; l; l = l->next) {
- char *s;
-
- s = l->data;
- g_free (s);
- }
-
- g_slist_free (list);
-}
-
-
-static void
-set_classification (CalComponent *comp,
- const char *value)
-{
- CalComponentClassification classif;
-
- if (!g_strcasecmp (value, _("Private")))
- classif = CAL_COMPONENT_CLASS_PRIVATE;
- else if (!g_strcasecmp (value, _("Confidential")))
- classif = CAL_COMPONENT_CLASS_CONFIDENTIAL;
- else
- classif = CAL_COMPONENT_CLASS_PUBLIC;
-
- cal_component_set_classification (comp, classif);
-}
-
-
-/* Called to set the "Date Completed" field. We also need to update the
- Status and Percent fields to make sure they match. */
-static void
-set_completed (CalendarModel *model, CalComponent *comp, const void *value)
-{
- CalendarModelPrivate *priv = model->priv;
- ECellDateEditValue *dv = (ECellDateEditValue*) value;
-
- if (!dv) {
- ensure_task_not_complete (comp);
- } else {
- time_t t;
-
- if (dv->tt.is_date) {
- /* If its a date, it will be floating,
- but completed needs a date time value */
- dv->tt.is_date = FALSE;
- t = icaltime_as_timet_with_zone (dv->tt, priv->zone);
- } else {
- /* We assume that COMPLETED is entered in the current timezone,
- even though it gets stored in UTC. */
- t = icaltime_as_timet_with_zone (dv->tt, dv->zone);
- }
-
- ensure_task_complete (comp, t);
- }
-}
-
-/* Sets a CalComponentDateTime value */
-static void
-set_datetime (CalendarModel *model, CalComponent *comp, const void *value,
- void (* set_func) (CalComponent *comp, CalComponentDateTime *dt),
- gboolean is_dtend)
-{
- ECellDateEditValue *dv = (ECellDateEditValue*) value;
-
- if (!dv) {
- (* set_func) (comp, NULL);
- } else {
- CalComponentDateTime dt;
-
- dt.value = &dv->tt;
- dt.tzid = icaltimezone_get_tzid (dv->zone);
-
- /* For a DTEND with a DATE value, we add 1 day to it. */
- if (is_dtend && dt.value->is_date) {
- icaltime_adjust (dt.value, 1, 0, 0, 0);
- }
-
- (* set_func) (comp, &dt);
- }
-}
-
-/* FIXME: We need to set the "transient_for" property for the dialog, but the
- * model doesn't know anything about the windows.
- */
-static void
-show_geo_warning (void)
-{
- GtkWidget *dialog;
-
- dialog = gnome_message_box_new (_("The geographical position must be entered "
- "in the format: \n\n45.436845,125.862501"),
- GNOME_MESSAGE_BOX_ERROR,
- GNOME_STOCK_BUTTON_OK, NULL);
- gtk_widget_show (dialog);
-}
-
-/* Sets the geographical position value of a component */
-static void
-set_geo (CalComponent *comp, const char *value)
-{
- double latitude, longitude;
- int matched;
- struct icalgeotype geo;
-
- if (string_is_empty (value)) {
- cal_component_set_geo (comp, NULL);
- return;
- }
-
- matched = sscanf (value, "%lg , %lg", &latitude, &longitude);
-
- if (matched != 2) {
- show_geo_warning ();
- return;
- }
-
- geo.lat = latitude;
- geo.lon = longitude;
- cal_component_set_geo (comp, &geo);
-}
-
-/* Sets the percent value of a calendar component */
-static void
-set_percent (CalComponent *comp, const void *value)
-{
- gint percent = GPOINTER_TO_INT (value);
-
- g_return_if_fail (percent >= -1);
- g_return_if_fail (percent <= 100);
-
- /* A value of -1 means it isn't set. */
- if (percent == -1) {
- cal_component_set_percent (comp, NULL);
- ensure_task_not_complete (comp);
- } else {
- cal_component_set_percent (comp, &percent);
-
- if (percent == 100)
- ensure_task_complete (comp, -1);
- else {
- ensure_task_not_complete (comp);
- if (percent > 0)
- cal_component_set_status (comp, ICAL_STATUS_INPROCESS);
- }
- }
-}
-
-/* Sets the priority of a calendar component */
-static void
-set_priority (CalComponent *comp, const char *value)
-{
- int priority;
-
- priority = cal_util_priority_from_string (value);
- /* If the priority is invalid (which should never happen) output a
- warning and set it to undefined. */
- if (priority == -1) {
- g_warning ("Invalid priority");
- priority = 0;
- }
-
- cal_component_set_priority (comp, &priority);
-}
-
-/* Sets the summary of a calendar component */
-static void
-set_summary (CalComponent *comp, const char *value)
-{
- CalComponentText text;
-
- if (string_is_empty (value)) {
- cal_component_set_summary (comp, NULL);
- return;
- }
-
- text.value = value;
- text.altrep = NULL; /* FIXME: should we preserve the old ALTREP? */
-
- cal_component_set_summary (comp, &text);
-}
-
-/* Sets the transparency of a calendar component */
-static void
-set_transparency (CalComponent *comp, const char *value)
-{
- CalComponentTransparency transp;
-
- if (!g_strcasecmp (value, _("Free")))
- transp = CAL_COMPONENT_TRANSP_TRANSPARENT;
- else
- transp = CAL_COMPONENT_TRANSP_OPAQUE;
-
- cal_component_set_transparency (comp, transp);
-}
-
-/* Sets the URI of a calendar component */
-static void
-set_url (CalComponent *comp, const char *value)
-{
- if (string_is_empty (value)) {
- cal_component_set_url (comp, NULL);
- return;
- }
-
- cal_component_set_url (comp, value);
-}
-
-/* Called to set the checkbutton field which indicates whether a task is
- complete. */
-static void
-set_complete (CalComponent *comp, const void *value)
-{
- gint state = GPOINTER_TO_INT (value);
-
- if (state) {
- ensure_task_complete (comp, -1);
- } else {
- ensure_task_not_complete (comp);
- }
-}
-
-/* Sets the status of a calendar component. */
-static void
-set_status (CalComponent *comp, const char *value)
-{
- icalproperty_status status;
- int percent;
-
- /* An empty string is the same as 'None'. */
- if (!value[0] || !g_strcasecmp (value, _("None")))
- status = ICAL_STATUS_NONE;
- else if (!g_strcasecmp (value, _("Not Started")))
- status = ICAL_STATUS_NEEDSACTION;
- else if (!g_strcasecmp (value, _("In Progress")))
- status = ICAL_STATUS_INPROCESS;
- else if (!g_strcasecmp (value, _("Completed")))
- status = ICAL_STATUS_COMPLETED;
- else if (!g_strcasecmp (value, _("Cancelled")))
- status = ICAL_STATUS_CANCELLED;
- else {
- g_warning ("Invalid status: %s\n", value);
- return;
- }
-
- cal_component_set_status (comp, status);
-
- if (status == ICAL_STATUS_NEEDSACTION) {
- percent = 0;
- cal_component_set_percent (comp, &percent);
- cal_component_set_completed (comp, NULL);
- } else if (status == ICAL_STATUS_INPROCESS) {
- ensure_task_not_complete (comp);
- percent = 50;
- cal_component_set_percent (comp, &percent);
- } else if (status == ICAL_STATUS_COMPLETED) {
- ensure_task_complete (comp, -1);
- }
-}
-
-#if 0
-static void
-set_location (CalComponent *comp, const char *value)
-{
- if (string_is_empty (value)) {
- cal_component_set_location (comp, NULL);
- return;
- }
-
- cal_component_set_location (comp, value);
-}
-#endif
-
-/* set_value_at handler for the calendar table model */
-static void
-calendar_model_set_value_at (ETableModel *etm, int col, int row, const void *value)
-{
- CalendarModel *model;
- CalendarModelPrivate *priv;
- CalComponent *comp;
-
- model = CALENDAR_MODEL (etm);
- priv = model->priv;
-
- g_return_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS);
- g_return_if_fail (row >= 0 && row < priv->objects->len);
-
- comp = g_array_index (priv->objects, CalComponent *, row);
- g_assert (comp != NULL);
-
-#if 0
- g_print ("In calendar_model_set_value_at: %i\n", col);
-#endif
-
- switch (col) {
- case CAL_COMPONENT_FIELD_CATEGORIES:
- set_categories (comp, value);
- break;
-
- case CAL_COMPONENT_FIELD_CLASSIFICATION:
- set_classification (comp, value);
- break;
-
- case CAL_COMPONENT_FIELD_COMPLETED:
- set_completed (model, comp, value);
- break;
-
- case CAL_COMPONENT_FIELD_DTEND:
- /* FIXME: Need to reset dtstart if dtend happens before it */
- set_datetime (model, comp, value, cal_component_set_dtend,
- TRUE);
- break;
-
- case CAL_COMPONENT_FIELD_DTSTART:
- /* FIXME: Need to reset dtend if dtstart happens after it */
- set_datetime (model, comp, value, cal_component_set_dtstart,
- FALSE);
- break;
-
- case CAL_COMPONENT_FIELD_DUE:
- set_datetime (model, comp, value, cal_component_set_due,
- FALSE);
- break;
-
- case CAL_COMPONENT_FIELD_GEO:
- set_geo (comp, value);
- break;
-
- case CAL_COMPONENT_FIELD_PERCENT:
- set_percent (comp, value);
- break;
-
- case CAL_COMPONENT_FIELD_PRIORITY:
- set_priority (comp, value);
- break;
-
- case CAL_COMPONENT_FIELD_SUMMARY:
- set_summary (comp, value);
- break;
-
- case CAL_COMPONENT_FIELD_TRANSPARENCY:
- set_transparency (comp, value);
- break;
-
- case CAL_COMPONENT_FIELD_URL:
- set_url (comp, value);
- break;
-
- case CAL_COMPONENT_FIELD_COMPLETE:
- set_complete (comp, value);
- break;
-
- case CAL_COMPONENT_FIELD_STATUS:
- set_status (comp, value);
- break;
-
-#if 0
- case CAL_COMPONENT_FIELD_LOCATION :
- set_location (comp, value);
- break;
-#endif
-
- default:
- g_message ("calendar_model_set_value_at(): Requested invalid column %d", col);
- g_assert_not_reached ();
- return;
- }
-
- if (cal_client_update_object (priv->client, comp) != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("calendar_model_set_value_at(): Could not update the object!");
-}
-
-/* is_cell_editable handler for the calendar table model */
-static gboolean
-calendar_model_is_cell_editable (ETableModel *etm, int col, int row)
-{
- CalendarModel *model;
- CalendarModelPrivate *priv;
-
- model = CALENDAR_MODEL (etm);
- priv = model->priv;
-
- g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, FALSE);
-
- /* FIXME: We can't check this as 'click-to-add' passes row 0. */
- /*g_return_val_if_fail (row >= 0 && row < priv->objects->len, FALSE);*/
-
- switch (col) {
- case CAL_COMPONENT_FIELD_CATEGORIES:
- case CAL_COMPONENT_FIELD_CLASSIFICATION:
- case CAL_COMPONENT_FIELD_COMPLETED:
- case CAL_COMPONENT_FIELD_DTEND:
- case CAL_COMPONENT_FIELD_DTSTART:
- case CAL_COMPONENT_FIELD_DUE:
- case CAL_COMPONENT_FIELD_GEO:
- case CAL_COMPONENT_FIELD_PERCENT:
- case CAL_COMPONENT_FIELD_PRIORITY:
- case CAL_COMPONENT_FIELD_SUMMARY:
- case CAL_COMPONENT_FIELD_TRANSPARENCY:
- case CAL_COMPONENT_FIELD_URL:
- case CAL_COMPONENT_FIELD_COMPLETE:
- case CAL_COMPONENT_FIELD_STATUS:
- return TRUE;
-
- default:
- return FALSE;
- }
-}
-
-/* append_row handler for the calendar model */
-static void
-calendar_model_append_row (ETableModel *etm, ETableModel *source, gint row)
-{
- CalendarModel *model;
- CalendarModelPrivate *priv;
- CalComponent *comp;
-
- model = CALENDAR_MODEL (etm);
- priv = model->priv;
-
- /* FIXME: This should support other types of components, but for now it
- * is only used for the task list.
- */
- if (priv->new_comp_vtype == CAL_COMPONENT_EVENT)
- comp = cal_comp_event_new_with_defaults ();
- else {
- comp = cal_component_new ();
- cal_component_set_new_vtype (comp, priv->new_comp_vtype);
- }
-
- set_categories (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_CATEGORIES, row));
- set_classification (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_CLASSIFICATION, row));
- set_completed (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_COMPLETED, row));
- /* FIXME: Need to reset dtstart if dtend happens before it */
- set_datetime (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_DTEND, row), cal_component_set_dtend, TRUE);
- /* FIXME: Need to reset dtend if dtstart happens after it */
- set_datetime (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_DTSTART, row), cal_component_set_dtstart, FALSE);
- set_datetime (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_DUE, row), cal_component_set_due, FALSE);
- set_geo (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_GEO, row));
- set_percent (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_PERCENT, row));
- set_priority (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_PRIORITY, row));
- set_summary (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_SUMMARY, row));
- set_transparency (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_TRANSPARENCY, row));
- set_url (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_URL, row));
- set_complete (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_COMPLETE, row));
- set_status (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_STATUS, row));
-
- if (cal_client_update_object (priv->client, comp) != CAL_CLIENT_RESULT_SUCCESS) {
- /* FIXME: Show error dialog. */
- g_message ("calendar_model_append_row(): Could not add new object!");
- }
-
- gtk_object_unref (GTK_OBJECT (comp));
-}
-
-/* Duplicates a string value */
-static char *
-dup_string (const char *value)
-{
- return g_strdup (value);
-}
-
-static void*
-dup_date_edit_value (const void *value)
-{
- ECellDateEditValue *dv, *orig_dv;
-
- if (value == NULL)
- return NULL;
-
- orig_dv = (ECellDateEditValue*) value;
-
- dv = g_new (ECellDateEditValue, 1);
- *dv = *orig_dv;
-
- return dv;
-}
-
-/* duplicate_value handler for the calendar table model */
-static void *
-calendar_model_duplicate_value (ETableModel *etm, int col, const void *value)
-{
- g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, NULL);
-
- /* They are almost all dup_string()s for now, but we'll have real fields
- * later.
- */
-
- switch (col) {
- case CAL_COMPONENT_FIELD_CATEGORIES:
- case CAL_COMPONENT_FIELD_CLASSIFICATION:
- case CAL_COMPONENT_FIELD_GEO:
- case CAL_COMPONENT_FIELD_PRIORITY:
- case CAL_COMPONENT_FIELD_SUMMARY:
- case CAL_COMPONENT_FIELD_TRANSPARENCY:
- case CAL_COMPONENT_FIELD_URL:
- case CAL_COMPONENT_FIELD_STATUS:
- return dup_string (value);
-
- case CAL_COMPONENT_FIELD_COMPLETED:
- case CAL_COMPONENT_FIELD_DTEND:
- case CAL_COMPONENT_FIELD_DTSTART:
- case CAL_COMPONENT_FIELD_DUE:
- return dup_date_edit_value (value);
-
- case CAL_COMPONENT_FIELD_HAS_ALARMS:
- case CAL_COMPONENT_FIELD_ICON:
- case CAL_COMPONENT_FIELD_COMPLETE:
- case CAL_COMPONENT_FIELD_PERCENT:
- case CAL_COMPONENT_FIELD_RECURRING:
- case CAL_COMPONENT_FIELD_OVERDUE:
- case CAL_COMPONENT_FIELD_COLOR:
- return (void *) value;
-
- case CAL_COMPONENT_FIELD_COMPONENT: {
- CalComponent *comp;
-
- comp = CAL_COMPONENT (value);
- gtk_object_ref (GTK_OBJECT (comp));
- return comp;
- }
-
- default:
- g_message ("calendar_model_duplicate_value(): Requested invalid column %d", col);
- return NULL;
- }
-}
-
-/* free_value handler for the calendar table model */
-static void
-calendar_model_free_value (ETableModel *etm, int col, void *value)
-{
- g_return_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS);
-
- switch (col) {
- case CAL_COMPONENT_FIELD_CATEGORIES:
- if (value)
- g_free (value);
- break;
-
- case CAL_COMPONENT_FIELD_CLASSIFICATION:
- break;
-
- case CAL_COMPONENT_FIELD_COMPLETED:
- case CAL_COMPONENT_FIELD_DTEND:
- case CAL_COMPONENT_FIELD_DTSTART:
- case CAL_COMPONENT_FIELD_DUE:
- case CAL_COMPONENT_FIELD_GEO:
- case CAL_COMPONENT_FIELD_PRIORITY:
- case CAL_COMPONENT_FIELD_SUMMARY:
- case CAL_COMPONENT_FIELD_STATUS:
- if (value)
- g_free (value);
- break;
-
- case CAL_COMPONENT_FIELD_TRANSPARENCY:
- break;
-
- case CAL_COMPONENT_FIELD_URL:
- if (value)
- g_free (value);
- break;
-
- case CAL_COMPONENT_FIELD_PERCENT:
- case CAL_COMPONENT_FIELD_HAS_ALARMS:
- case CAL_COMPONENT_FIELD_ICON:
- case CAL_COMPONENT_FIELD_COMPLETE:
- case CAL_COMPONENT_FIELD_RECURRING:
- case CAL_COMPONENT_FIELD_OVERDUE:
- case CAL_COMPONENT_FIELD_COLOR:
- break;
-
- case CAL_COMPONENT_FIELD_COMPONENT:
- if (value)
- gtk_object_unref (GTK_OBJECT (value));
- break;
-
- default:
- g_message ("calendar_model_free_value(): Requested invalid column %d", col);
- }
-}
-
-/* Initializes a string value */
-static char *
-init_string (void)
-{
- return g_strdup ("");
-}
-
-/* initialize_value handler for the calendar table model */
-static void *
-calendar_model_initialize_value (ETableModel *etm, int col)
-{
- CalendarModel *model;
-
- g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, NULL);
-
- model = CALENDAR_MODEL (etm);
-
- switch (col) {
- case CAL_COMPONENT_FIELD_CATEGORIES:
- return g_strdup (model->priv->default_category ? model->priv->default_category : "");
-
- case CAL_COMPONENT_FIELD_CLASSIFICATION:
- case CAL_COMPONENT_FIELD_GEO:
- case CAL_COMPONENT_FIELD_PRIORITY:
- case CAL_COMPONENT_FIELD_SUMMARY:
- case CAL_COMPONENT_FIELD_TRANSPARENCY:
- case CAL_COMPONENT_FIELD_URL:
- case CAL_COMPONENT_FIELD_STATUS:
- return init_string ();
-
- case CAL_COMPONENT_FIELD_COMPLETED:
- case CAL_COMPONENT_FIELD_DTEND:
- case CAL_COMPONENT_FIELD_DTSTART:
- case CAL_COMPONENT_FIELD_DUE:
- case CAL_COMPONENT_FIELD_HAS_ALARMS:
- case CAL_COMPONENT_FIELD_ICON:
- case CAL_COMPONENT_FIELD_COMPLETE:
- case CAL_COMPONENT_FIELD_RECURRING:
- case CAL_COMPONENT_FIELD_OVERDUE:
- case CAL_COMPONENT_FIELD_COLOR:
- case CAL_COMPONENT_FIELD_COMPONENT:
- return NULL;
-
- case CAL_COMPONENT_FIELD_PERCENT:
- return GINT_TO_POINTER (-1);
-
- default:
- g_message ("calendar_model_initialize_value(): Requested invalid column %d", col);
- return NULL;
- }
-}
-
-/* value_is_empty handler for the calendar model. This should return TRUE
- unless a significant value has been set. The 'click-to-add' feature
- checks all fields to see if any are not empty and if so it adds a new
- row, so we only want to return FALSE if we have a useful object. */
-static gboolean
-calendar_model_value_is_empty (ETableModel *etm, int col, const void *value)
-{
- CalendarModel *model;
- CalendarModelPrivate *priv;
-
- g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, TRUE);
-
- model = CALENDAR_MODEL (etm);
- priv = model->priv;
-
- switch (col) {
- case CAL_COMPONENT_FIELD_CATEGORIES:
- /* This could be a hack or not. If the categories field only
- * contains the default category, then it possibly means that
- * the user has not entered anything at all in the click-to-add;
- * the category is in the value because we put it there in
- * calendar_model_initialize_value().
- */
- if (priv->default_category && value && strcmp (priv->default_category, value) == 0)
- return TRUE;
- else
- return string_is_empty (value);
-
- case CAL_COMPONENT_FIELD_CLASSIFICATION: /* actually goes here, not by itself */
- case CAL_COMPONENT_FIELD_GEO:
- case CAL_COMPONENT_FIELD_PRIORITY:
- case CAL_COMPONENT_FIELD_SUMMARY:
- case CAL_COMPONENT_FIELD_TRANSPARENCY:
- case CAL_COMPONENT_FIELD_URL:
- case CAL_COMPONENT_FIELD_STATUS:
- return string_is_empty (value);
-
- case CAL_COMPONENT_FIELD_COMPLETED:
- case CAL_COMPONENT_FIELD_DTEND:
- case CAL_COMPONENT_FIELD_DTSTART:
- case CAL_COMPONENT_FIELD_DUE:
- return value ? FALSE : TRUE;
-
- case CAL_COMPONENT_FIELD_PERCENT:
- return (GPOINTER_TO_INT (value) < 0) ? TRUE : FALSE;
-
- case CAL_COMPONENT_FIELD_HAS_ALARMS:
- case CAL_COMPONENT_FIELD_ICON:
- case CAL_COMPONENT_FIELD_COMPLETE:
- case CAL_COMPONENT_FIELD_RECURRING:
- case CAL_COMPONENT_FIELD_OVERDUE:
- case CAL_COMPONENT_FIELD_COLOR:
- case CAL_COMPONENT_FIELD_COMPONENT:
- return TRUE;
-
- default:
- g_message ("calendar_model_value_is_empty(): Requested invalid column %d", col);
- return TRUE;
- }
-}
-
-static char*
-date_value_to_string (ETableModel *etm, const void *value)
-{
- CalendarModel *model;
- CalendarModelPrivate *priv;
- ECellDateEditValue *dv = (ECellDateEditValue *) value;
- struct icaltimetype tt;
- struct tm tmp_tm;
- char buffer[64];
-
- model = CALENDAR_MODEL (etm);
- priv = model->priv;
-
- if (!dv)
- return g_strdup ("");
-
- /* We currently convert all the dates to the current timezone. */
- tt = dv->tt;
- icaltimezone_convert_time (&tt, dv->zone, priv->zone);
-
- tmp_tm.tm_year = tt.year - 1900;
- tmp_tm.tm_mon = tt.month - 1;
- tmp_tm.tm_mday = tt.day;
- tmp_tm.tm_hour = tt.hour;
- tmp_tm.tm_min = tt.minute;
- tmp_tm.tm_sec = tt.second;
- tmp_tm.tm_isdst = -1;
-
- tmp_tm.tm_wday = time_day_of_week (tt.day, tt.month - 1, tt.year);
-
- e_time_format_date_and_time (&tmp_tm, priv->use_24_hour_format,
- TRUE, FALSE,
- buffer, sizeof (buffer));
- return e_utf8_from_locale_string (buffer);
-}
-
-
-static char *
-calendar_model_value_to_string (ETableModel *etm, int col, const void *value)
-{
- g_return_val_if_fail (col >= 0 && col < CAL_COMPONENT_FIELD_NUM_FIELDS, NULL);
-
- switch (col) {
- case CAL_COMPONENT_FIELD_CATEGORIES:
- case CAL_COMPONENT_FIELD_CLASSIFICATION:
- case CAL_COMPONENT_FIELD_GEO:
- case CAL_COMPONENT_FIELD_PRIORITY:
- case CAL_COMPONENT_FIELD_SUMMARY:
- case CAL_COMPONENT_FIELD_TRANSPARENCY:
- case CAL_COMPONENT_FIELD_URL:
- case CAL_COMPONENT_FIELD_STATUS:
- return g_strdup (value);
-
- case CAL_COMPONENT_FIELD_COMPLETED:
- case CAL_COMPONENT_FIELD_DTEND:
- case CAL_COMPONENT_FIELD_DTSTART:
- case CAL_COMPONENT_FIELD_DUE:
- return date_value_to_string (etm, value);
-
- case CAL_COMPONENT_FIELD_ICON:
- if (GPOINTER_TO_INT (value) == 0)
- return e_utf8_from_locale_string (_("Normal"));
- else if (GPOINTER_TO_INT (value) == 1)
- return e_utf8_from_locale_string (_("Recurring"));
- else
- return e_utf8_from_locale_string (_("Assigned"));
-
- case CAL_COMPONENT_FIELD_HAS_ALARMS:
- case CAL_COMPONENT_FIELD_COMPLETE:
- case CAL_COMPONENT_FIELD_RECURRING:
- case CAL_COMPONENT_FIELD_OVERDUE:
- return e_utf8_from_locale_string (value ? _("Yes") : _("No"));
-
- case CAL_COMPONENT_FIELD_COLOR:
- return NULL;
-
- case CAL_COMPONENT_FIELD_COMPONENT:
- return NULL;
-
- case CAL_COMPONENT_FIELD_PERCENT:
- if (GPOINTER_TO_INT (value) < 0)
- return NULL;
- else
- return g_strdup_printf ("%i%%", GPOINTER_TO_INT (value));
-
- default:
- g_message ("calendar_model_value_as_string(): Requested invalid column %d", col);
- return NULL;
- }
-}
-
-
-
-/**
- * calendar_model_new:
- *
- * Creates a new calendar model. It must be told about the calendar client
- * interface object it will monitor with calendar_model_set_cal_client().
- *
- * Return value: A newly-created calendar model.
- **/
-CalendarModel *
-calendar_model_new (void)
-{
- return CALENDAR_MODEL (gtk_type_new (TYPE_CALENDAR_MODEL));
-}
-
-
-/* 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)
-{
- CalendarModel *model;
- CalendarModelPrivate *priv;
- int orig_idx;
- CalComponent *new_comp;
- const char *new_comp_uid;
- int *new_idx;
- CalClientGetStatus status;
- CalendarModelObjectData new_object_data = { NULL, NULL, NULL, NULL };
-
- model = CALENDAR_MODEL (data);
- priv = model->priv;
-
- e_table_model_pre_change (E_TABLE_MODEL (model));
-
- orig_idx = remove_object (model, uid);
-
- status = cal_client_get_object (priv->client, uid, &new_comp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- /* Insert the object into the model */
-
- cal_component_get_uid (new_comp, &new_comp_uid);
-
- if (orig_idx == -1) {
- /* The object not in the model originally, so we just append it */
-
- g_array_append_val (priv->objects, new_comp);
- g_array_append_val (priv->objects_data, new_object_data);
-
- new_idx = g_new (int, 1);
- *new_idx = priv->objects->len - 1;
-
- g_hash_table_insert (priv->uid_index_hash, (char *) new_comp_uid, new_idx);
- e_table_model_row_inserted (E_TABLE_MODEL (model), *new_idx);
- } else {
- int i;
-
- /* Insert the new version of the object in its old position */
-
- g_array_insert_val (priv->objects, orig_idx, new_comp);
- g_array_insert_val (priv->objects_data, orig_idx,
- new_object_data);
-
- new_idx = g_new (int, 1);
- *new_idx = orig_idx;
- g_hash_table_insert (priv->uid_index_hash, (char *) new_comp_uid, new_idx);
-
- /* Increase the indices of all subsequent objects */
-
- for (i = orig_idx + 1; i < priv->objects->len; i++) {
- CalComponent *comp;
- int *comp_idx;
- const char *comp_uid;
-
- comp = g_array_index (priv->objects, CalComponent *, i);
- g_assert (comp != NULL);
-
- cal_component_get_uid (comp, &comp_uid);
-
- comp_idx = g_hash_table_lookup (priv->uid_index_hash, comp_uid);
- g_assert (comp_idx != NULL);
-
- (*comp_idx)++;
- }
-
- e_table_model_row_changed (E_TABLE_MODEL (model), *new_idx);
- }
-
- break;
-
- case CAL_CLIENT_GET_NOT_FOUND:
- /* Nothing; the object may have been removed from the server. We just
- * notify that the old object was deleted.
- */
- if (orig_idx != -1)
- e_table_model_row_deleted (E_TABLE_MODEL (model), orig_idx);
- else
- e_table_model_no_change (E_TABLE_MODEL (model));
-
- break;
-
- case CAL_CLIENT_GET_SYNTAX_ERROR:
- g_message ("obj_updated_cb(): Syntax error when getting object `%s'", uid);
-
- /* Same notification as above */
- if (orig_idx != -1)
- e_table_model_row_deleted (E_TABLE_MODEL (model), orig_idx);
- else
- e_table_model_no_change (E_TABLE_MODEL (model));
-
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-/* Callback used when a component is removed from the live query */
-static void
-query_obj_removed_cb (CalQuery *query, const char *uid, gpointer data)
-{
- CalendarModel *model;
- int idx;
-
- model = CALENDAR_MODEL (data);
-
- e_table_model_pre_change (E_TABLE_MODEL (model));
-
- idx = remove_object (model, uid);
-
- if (idx != -1)
- e_table_model_row_deleted (E_TABLE_MODEL (model), idx);
- else
- e_table_model_no_change (E_TABLE_MODEL (model));
-}
-
-/* Callback used when a query ends */
-static void
-query_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer data)
-{
- CalendarModel *model;
-
- model = CALENDAR_MODEL (data);
-
- /* FIXME */
-
- calendar_model_set_status_message (model, NULL);
-
- if (status != CAL_QUERY_DONE_SUCCESS)
- g_warning ("query done: %s\n", error_str);
-}
-
-/* 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)
-{
- CalendarModel *model;
-
- model = CALENDAR_MODEL (data);
-
- /* FIXME */
-
- calendar_model_set_status_message (model, NULL);
-
- g_warning ("eval error: %s\n", error_str);
-}
-
-/* Builds a complete query sexp for the calendar model by adding the predicates
- * to filter only for the type of objects that the model supports, and
- * whether we want completed tasks.
- */
-static char *
-adjust_query_sexp (CalendarModel *model, const char *sexp)
-{
- CalendarModelPrivate *priv;
- CalObjType type;
- char *type_sexp;
- char *completed_sexp;
- char *new_sexp;
-
- priv = model->priv;
-
- type = priv->type;
-
- if (!(type & CALOBJ_TYPE_ANY))
- type_sexp = g_strdup ("#t");
- else
- type_sexp = g_strdup_printf (
- "(or %s %s %s)",
- (type & CALOBJ_TYPE_EVENT) ? "(= (get-vtype) \"VEVENT\")" : "",
- (type & CALOBJ_TYPE_TODO) ? "(= (get-vtype) \"VTODO\")" : "",
- (type & CALOBJ_TYPE_JOURNAL) ? "(= (get-vtype) \"VJOURNAL\")" : "");
-
- /* Create a sub-expression for filtering out completed tasks, based on
- the config settings. */
- completed_sexp = calendar_config_get_hide_completed_tasks_sexp ();
-
- new_sexp = g_strdup_printf ("(and %s %s %s)", type_sexp,
- completed_sexp ? completed_sexp : "",
- sexp);
- g_free (type_sexp);
- g_free (completed_sexp);
-
-#if 0
- g_print ("Calendar model sexp:\n%s\n", new_sexp);
-#endif
-
- return new_sexp;
-}
-
-/* Restarts a query */
-static void
-update_query (CalendarModel *model)
-{
- CalendarModelPrivate *priv;
- CalQuery *old_query;
- char *real_sexp;
-
- priv = model->priv;
-
- e_table_model_pre_change (E_TABLE_MODEL (model));
- free_objects (model);
- e_table_model_changed (E_TABLE_MODEL (model));
-
- if (!(priv->client
- && cal_client_get_load_state (priv->client) == CAL_CLIENT_LOAD_LOADED))
- return;
-
- old_query = priv->query;
- priv->query = NULL;
-
- if (old_query) {
- gtk_signal_disconnect_by_data (GTK_OBJECT (old_query), model);
- gtk_object_unref (GTK_OBJECT (old_query));
- }
-
- g_assert (priv->sexp != NULL);
- real_sexp = adjust_query_sexp (model, priv->sexp);
-
- calendar_model_set_status_message (model, _("Searching"));
- priv->query = cal_client_get_query (priv->client, real_sexp);
- g_free (real_sexp);
-
- if (!priv->query) {
- g_message ("update_query(): Could not create the query");
- calendar_model_set_status_message (model, NULL);
- return;
- }
-
- gtk_signal_connect (GTK_OBJECT (priv->query), "obj_updated",
- GTK_SIGNAL_FUNC (query_obj_updated_cb), model);
- gtk_signal_connect (GTK_OBJECT (priv->query), "obj_removed",
- GTK_SIGNAL_FUNC (query_obj_removed_cb), model);
- gtk_signal_connect (GTK_OBJECT (priv->query), "query_done",
- GTK_SIGNAL_FUNC (query_query_done_cb), model);
- gtk_signal_connect (GTK_OBJECT (priv->query), "eval_error",
- GTK_SIGNAL_FUNC (query_eval_error_cb), model);
-}
-
-/* Callback used when a calendar is opened into the server */
-static void
-cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
-{
- CalendarModel *model;
-
- model = CALENDAR_MODEL (data);
-
- if (status != CAL_CLIENT_OPEN_SUCCESS)
- return;
-
- update_query (model);
-}
-
-
-/* Removes an object from the model and updates all the indices that follow.
- * Returns the index of the object that was removed, or -1 if no object with
- * such UID was found.
- */
-static int
-remove_object (CalendarModel *model, const char *uid)
-{
- CalendarModelPrivate *priv;
- int *idx;
- CalComponent *orig_comp;
- int i;
- int n;
- CalendarModelObjectData *object_data;
-
- priv = model->priv;
-
- /* Find the index of the object to be removed */
-
- idx = g_hash_table_lookup (priv->uid_index_hash, uid);
- if (!idx)
- return -1;
-
- orig_comp = g_array_index (priv->objects, CalComponent *, *idx);
- g_assert (orig_comp != NULL);
-
- /* Decrease the indices of all the objects that follow in the array */
-
- for (i = *idx + 1; i < priv->objects->len; i++) {
- CalComponent *comp;
- int *comp_idx;
- const char *comp_uid;
-
- comp = g_array_index (priv->objects, CalComponent *, i);
- g_assert (comp != NULL);
-
- cal_component_get_uid (comp, &comp_uid);
-
- comp_idx = g_hash_table_lookup (priv->uid_index_hash, comp_uid);
- g_assert (comp_idx != NULL);
-
- (*comp_idx)--;
- g_assert (*comp_idx >= 0);
- }
-
- /* Remove this object from the array and hash */
-
- g_hash_table_remove (priv->uid_index_hash, uid);
- g_array_remove_index (priv->objects, *idx);
-
- object_data = &g_array_index (priv->objects_data,
- CalendarModelObjectData, *idx);
- calendar_model_free_object_data (model, object_data);
- g_array_remove_index (priv->objects_data, *idx);
-
- gtk_object_unref (GTK_OBJECT (orig_comp));
-
- n = *idx;
- g_free (idx);
-
- return n;
-}
-
-/* Displays messages on the status bar */
-#define EVOLUTION_TASKS_PROGRESS_IMAGE "evolution-tasks-mini.png"
-static GdkPixbuf *progress_icon[2] = { NULL, NULL };
-
-void
-calendar_model_set_status_message (CalendarModel *model, const char *message)
-{
- extern EvolutionShellClient *global_shell_client; /* ugly */
- CalendarModelPrivate *priv;
-
- g_return_if_fail (IS_CALENDAR_MODEL (model));
-
- priv = model->priv;
-
- if (!message || !*message) {
- if (priv->activity) {
- gtk_object_unref (GTK_OBJECT (priv->activity));
- priv->activity = NULL;
- }
- }
- else if (!priv->activity) {
- int display;
- char *client_id = g_strdup_printf ("%p", model);
-
- if (progress_icon[0] == NULL)
- progress_icon[0] = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" EVOLUTION_TASKS_PROGRESS_IMAGE);
- priv->activity = evolution_activity_client_new (
- global_shell_client, client_id,
- progress_icon, message, TRUE, &display);
-
- g_free (client_id);
- }
- else
- evolution_activity_client_update (priv->activity, message, -1.0);
-}
-
-/**
- * calendar_model_get_cal_client:
- * @model: A calendar model.
- *
- * Queries the calendar client interface object that a calendar model is using.
- *
- * Return value: A calendar client interface object.
- **/
-CalClient *
-calendar_model_get_cal_client (CalendarModel *model)
-{
- CalendarModelPrivate *priv;
-
- g_return_val_if_fail (model != NULL, NULL);
- g_return_val_if_fail (IS_CALENDAR_MODEL (model), NULL);
-
- priv = model->priv;
-
- return priv->client;
-}
-
-
-/**
- * calendar_model_set_cal_client:
- * @model: A calendar model.
- * @client: A calendar client interface object.
- * @type: Type of objects to present.
- *
- * Sets the calendar client interface object that a calendar model will monitor.
- * It also sets the types of objects this model will present to an #ETable.
- **/
-void
-calendar_model_set_cal_client (CalendarModel *model, CalClient *client, CalObjType type)
-{
- CalendarModelPrivate *priv;
-
- g_return_if_fail (model != NULL);
- g_return_if_fail (IS_CALENDAR_MODEL (model));
-
- if (client)
- g_return_if_fail (IS_CAL_CLIENT (client));
-
- priv = model->priv;
-
- if (priv->client == client && priv->type == type)
- return;
-
- if (client)
- gtk_object_ref (GTK_OBJECT (client));
-
- if (priv->client) {
- gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), model);
- gtk_object_unref (GTK_OBJECT (priv->client));
- }
-
- priv->client = client;
- priv->type = type;
-
- if (priv->client) {
- if (cal_client_get_load_state (priv->client) == CAL_CLIENT_LOAD_LOADED)
- update_query (model);
- else
- gtk_signal_connect (GTK_OBJECT (priv->client), "cal_opened",
- GTK_SIGNAL_FUNC (cal_opened_cb), model);
- }
-}
-
-/**
- * calendar_model_set_query:
- * @model: A calendar model.
- * @sexp: Sexp that defines the query.
- *
- * Sets the query sexp that a calendar model will use to filter its contents.
- **/
-void
-calendar_model_set_query (CalendarModel *model, const char *sexp)
-{
- CalendarModelPrivate *priv;
-
- g_return_if_fail (model != NULL);
- g_return_if_fail (IS_CALENDAR_MODEL (model));
- g_return_if_fail (sexp != NULL);
-
- priv = model->priv;
-
- if (priv->sexp)
- g_free (priv->sexp);
-
- priv->sexp = g_strdup (sexp);
-
- update_query (model);
-}
-
-
-/**
- * calendar_model_set_new_comp_vtype:
- * @model: A calendar model.
- * @vtype: Type of calendar components to create.
- *
- * Sets the type of calendar components that will be created by a calendar table
- * model when the click-to-add functionality of the table is used.
- **/
-void
-calendar_model_set_new_comp_vtype (CalendarModel *model, CalComponentVType vtype)
-{
- CalendarModelPrivate *priv;
-
- g_return_if_fail (model != NULL);
- g_return_if_fail (IS_CALENDAR_MODEL (model));
- g_return_if_fail (vtype != CAL_COMPONENT_NO_TYPE);
-
- priv = model->priv;
- priv->new_comp_vtype = vtype;
-}
-
-/**
- * calendar_model_get_new_comp_vtype:
- * @model: A calendar model.
- *
- * Queries the type of calendar components that are created by a calendar table
- * model when using the click-to-add functionality in a table.
- *
- * Return value: Type of components that are created.
- **/
-CalComponentVType
-calendar_model_get_new_comp_vtype (CalendarModel *model)
-{
- CalendarModelPrivate *priv;
-
- g_return_val_if_fail (model != NULL, CAL_COMPONENT_NO_TYPE);
- g_return_val_if_fail (IS_CALENDAR_MODEL (model), CAL_COMPONENT_NO_TYPE);
-
- priv = model->priv;
- return priv->new_comp_vtype;
-}
-
-
-void
-calendar_model_mark_task_complete (CalendarModel *model,
- gint row)
-{
- CalendarModelPrivate *priv;
- CalComponent *comp;
-
- g_return_if_fail (model != NULL);
- g_return_if_fail (IS_CALENDAR_MODEL (model));
-
- priv = model->priv;
-
- g_return_if_fail (row >= 0 && row < priv->objects->len);
-
- comp = g_array_index (priv->objects, CalComponent *, row);
- g_assert (comp != NULL);
-
- ensure_task_complete (comp, -1);
-
- if (cal_client_update_object (priv->client, comp) != CAL_CLIENT_RESULT_SUCCESS)
- g_message ("calendar_model_mark_task_complete(): Could not update the object!");
-}
-
-
-/**
- * calendar_model_get_component:
- * @model: A calendar model.
- * @row: Row number of sought calendar component.
- *
- * Queries a calendar component from a calendar model based on its row number.
- *
- * Return value: The sought calendar component.
- **/
-CalComponent *
-calendar_model_get_component (CalendarModel *model,
- gint row)
-{
- CalendarModelPrivate *priv;
-
- g_return_val_if_fail (model != NULL, NULL);
- g_return_val_if_fail (IS_CALENDAR_MODEL (model), NULL);
-
- priv = model->priv;
-
- g_return_val_if_fail (row >= 0 && row < priv->objects->len, NULL);
-
- return g_array_index (priv->objects, CalComponent *, row);
-}
-
-
-/* This makes sure a task is marked as complete.
- It makes sure the "Date Completed" property is set. If the completed_date
- is not -1, then that is used, otherwise if the "Date Completed" property
- is not already set it is set to the current time.
- It makes sure the percent is set to 100, and that the status is "Completed".
- Note that this doesn't update the component on the server. */
-static void
-ensure_task_complete (CalComponent *comp,
- time_t completed_date)
-{
- struct icaltimetype *old_completed = NULL;
- int *old_percent, new_percent;
- icalproperty_status status;
- gboolean set_completed = TRUE;
-
- /* Date Completed. */
- if (completed_date == -1) {
- cal_component_get_completed (comp, &old_completed);
-
- if (old_completed) {
- cal_component_free_icaltimetype (old_completed);
- set_completed = FALSE;
- } else {
- completed_date = time (NULL);
- }
- }
-
- if (set_completed) {
- icaltimezone *utc_zone;
- struct icaltimetype new_completed;
-
- /* COMPLETED is stored in UTC. */
- utc_zone = icaltimezone_get_utc_timezone ();
- new_completed = icaltime_from_timet_with_zone (completed_date,
- FALSE,
- utc_zone);
- cal_component_set_completed (comp, &new_completed);
- }
-
- /* Percent. */
- cal_component_get_percent (comp, &old_percent);
- if (!old_percent || *old_percent != 100) {
- new_percent = 100;
- cal_component_set_percent (comp, &new_percent);
- }
- if (old_percent)
- cal_component_free_percent (old_percent);
-
- /* Status. */
- cal_component_get_status (comp, &status);
- if (status != ICAL_STATUS_COMPLETED) {
- cal_component_set_status (comp, ICAL_STATUS_COMPLETED);
- }
-}
-
-
-/* This makes sure a task is marked as incomplete. It clears the
- "Date Completed" property. If the percent is set to 100 it removes it,
- and if the status is "Completed" it sets it to "Needs Action".
- Note that this doesn't update the component on the client. */
-static void
-ensure_task_not_complete (CalComponent *comp)
-{
- icalproperty_status old_status;
- int *old_percent;
-
- /* Date Completed. */
- cal_component_set_completed (comp, NULL);
-
- /* Percent. */
- cal_component_get_percent (comp, &old_percent);
- if (old_percent && *old_percent == 100)
- cal_component_set_percent (comp, NULL);
- if (old_percent)
- cal_component_free_percent (old_percent);
-
- /* Status. */
- cal_component_get_status (comp, &old_status);
- if (old_status == ICAL_STATUS_COMPLETED)
- cal_component_set_status (comp, ICAL_STATUS_NEEDSACTION);
-}
-
-
-/* Whether we use 24 hour format to display the times. */
-gboolean
-calendar_model_get_use_24_hour_format (CalendarModel *model)
-{
- g_return_val_if_fail (IS_CALENDAR_MODEL (model), TRUE);
-
- return model->priv->use_24_hour_format;
-}
-
-
-void
-calendar_model_set_use_24_hour_format (CalendarModel *model,
- gboolean use_24_hour_format)
-{
- g_return_if_fail (IS_CALENDAR_MODEL (model));
-
- if (model->priv->use_24_hour_format != use_24_hour_format) {
- e_table_model_pre_change (E_TABLE_MODEL (model));
- model->priv->use_24_hour_format = use_24_hour_format;
- /* Get the views to redraw themselves. */
- e_table_model_changed (E_TABLE_MODEL (model));
- }
-}
-
-
-void
-calendar_model_set_default_category (CalendarModel *model,
- const char *default_category)
-{
- g_return_if_fail (IS_CALENDAR_MODEL (model));
-
- g_free (model->priv->default_category);
- model->priv->default_category = g_strdup (default_category);
-}
-
-
-
-/* The current timezone. */
-icaltimezone*
-calendar_model_get_timezone (CalendarModel *model)
-{
- g_return_val_if_fail (IS_CALENDAR_MODEL (model), NULL);
-
- return model->priv->zone;
-}
-
-
-void
-calendar_model_set_timezone (CalendarModel *model,
- icaltimezone *zone)
-{
- g_return_if_fail (IS_CALENDAR_MODEL (model));
-
- if (model->priv->zone != zone) {
- e_table_model_pre_change (E_TABLE_MODEL (model));
- model->priv->zone = zone;
-
- /* The timezone affects the times shown for COMPLETED and
- maybe other fields, so we need to redisplay everything. */
- e_table_model_changed (E_TABLE_MODEL (model));
- }
-}
-
-
-/**
- * calendar_model_refresh:
- * @model: A calendar model.
- *
- * Refreshes the calendar model, reloading the events/tasks from the server.
- * Be careful about doing this when the user is editing an event/task.
- **/
-void
-calendar_model_refresh (CalendarModel *model)
-{
- g_return_if_fail (model != NULL);
- g_return_if_fail (IS_CALENDAR_MODEL (model));
-
- update_query (model);
-}
diff --git a/calendar/gui/calendar-model.h b/calendar/gui/calendar-model.h
deleted file mode 100644
index 6ac175034c..0000000000
--- a/calendar/gui/calendar-model.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Evolution calendar - Data model for ETable
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@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 CALENDAR_MODEL_H
-#define CALENDAR_MODEL_H
-
-#include <libgnome/gnome-defs.h>
-#include <gal/e-table/e-table-model.h>
-#include <cal-client/cal-client.h>
-
-BEGIN_GNOME_DECLS
-
-
-
-#define TYPE_CALENDAR_MODEL (calendar_model_get_type ())
-#define CALENDAR_MODEL(obj) (GTK_CHECK_CAST ((obj), TYPE_CALENDAR_MODEL, CalendarModel))
-#define CALENDAR_MODEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_CALENDAR_MODEL, \
- CalendarModelClass))
-#define IS_CALENDAR_MODEL(obj) (GTK_CHECK_TYPE ((obj), TYPE_CALENDAR_MODEL))
-#define IS_CALENDAR_MODEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_CALENDAR_MODEL))
-
-typedef struct _CalendarModel CalendarModel;
-typedef struct _CalendarModelClass CalendarModelClass;
-
-typedef struct _CalendarModelPrivate CalendarModelPrivate;
-
-struct _CalendarModel {
- ETableModel model;
-
- /* Private data */
- CalendarModelPrivate *priv;
-};
-
-struct _CalendarModelClass {
- ETableModelClass parent_class;
-};
-
-GtkType calendar_model_get_type (void);
-
-CalendarModel* calendar_model_new (void);
-
-CalClient* calendar_model_get_cal_client (CalendarModel *model);
-void calendar_model_set_cal_client (CalendarModel *model,
- CalClient *client,
- CalObjType type);
-
-void calendar_model_set_query (CalendarModel *model,
- const char *sexp);
-
-void calendar_model_refresh (CalendarModel *model);
-
-void calendar_model_set_new_comp_vtype (CalendarModel *model,
- CalComponentVType vtype);
-CalComponentVType calendar_model_get_new_comp_vtype (CalendarModel *model);
-
-void calendar_model_mark_task_complete (CalendarModel *model,
- gint row);
-
-CalComponent* calendar_model_get_component (CalendarModel *model,
- gint row);
-
-/* Whether we use 24 hour format to display the times. */
-gboolean calendar_model_get_use_24_hour_format (CalendarModel *model);
-void calendar_model_set_use_24_hour_format (CalendarModel *model,
- gboolean use_24_hour_format);
-
-/* The current timezone. */
-icaltimezone* calendar_model_get_timezone (CalendarModel *model);
-void calendar_model_set_timezone (CalendarModel *model,
- icaltimezone *zone);
-
-void calendar_model_set_default_category (CalendarModel *model,
- const char *default_category);
-
-void calendar_model_set_status_message (CalendarModel *model,
- const char *message);
-
-
-
-END_GNOME_DECLS
-
-#endif
diff --git a/calendar/gui/calendar-offline-handler.c b/calendar/gui/calendar-offline-handler.c
deleted file mode 100644
index a01d3fa160..0000000000
--- a/calendar/gui/calendar-offline-handler.c
+++ /dev/null
@@ -1,282 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* calendar-offline-handler.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.
- *
- * Authors:
- * Ettore Perazzoli <ettore@ximian.com>
- * Dan Winship <danw@ximian.com>
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gtk/gtkmain.h>
-#include <gtk/gtksignal.h>
-#include <bonobo/bonobo-exception.h>
-#include <gal/util/e-util.h>
-#include "e-util/e-url.h"
-#include <cal-client/cal-client.h>
-#include "calendar-offline-handler.h"
-
-#define PARENT_TYPE bonobo_x_object_get_type ()
-static BonoboXObjectClass *parent_class = NULL;
-
-struct _CalendarOfflineHandlerPrivate {
- CalClient *client;
-
- GNOME_Evolution_OfflineProgressListener listener_interface;
-
- gboolean is_offline;
-};
-
-static void
-add_connection (gpointer data, gpointer user_data)
-{
- EUri *uri = e_uri_new (data);
- GNOME_Evolution_ConnectionList *list = user_data;
-
- g_return_if_fail (uri != NULL);
-
- if (uri->host != NULL)
- list->_buffer[list->_length].hostName = CORBA_string_dup (uri->host);
- else
- list->_buffer[list->_length].hostName = CORBA_string_dup ("Unknown");
- if (uri->protocol != NULL)
- list->_buffer[list->_length].type = CORBA_string_dup (uri->protocol);
- else
- list->_buffer[list->_length].type = CORBA_string_dup ("Unknown");
- list->_length++;
-
- e_uri_free (uri);
-}
-
-static GNOME_Evolution_ConnectionList *
-create_connection_list (CalendarOfflineHandler *offline_handler)
-{
- CalendarOfflineHandlerPrivate *priv;
- GNOME_Evolution_ConnectionList *list;
- GList *uris;
-
- priv = offline_handler->priv;
-
- uris = cal_client_uri_list (priv->client, CAL_MODE_REMOTE);
-
- list = GNOME_Evolution_ConnectionList__alloc ();
- list->_length = 0;
- list->_maximum = g_list_length (uris);
- list->_buffer = CORBA_sequence_GNOME_Evolution_Connection_allocbuf (list->_maximum);
-
- g_list_foreach (uris, add_connection, list);
-
- return list;
-}
-
-/* GNOME::Evolution::Offline methods. */
-static CORBA_boolean
-impl__get_isOffline (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- CalendarOfflineHandler *offline_handler;
- CalendarOfflineHandlerPrivate *priv;
-
- offline_handler = CALENDAR_OFFLINE_HANDLER (bonobo_object_from_servant (servant));
- priv = offline_handler->priv;
-
- return priv->is_offline;
-}
-
-static void
-impl_prepareForOffline (PortableServer_Servant servant,
- GNOME_Evolution_ConnectionList **active_connection_list,
- CORBA_Environment *ev)
-{
- CalendarOfflineHandler *offline_handler;
- CalendarOfflineHandlerPrivate *priv;
-
- offline_handler = CALENDAR_OFFLINE_HANDLER (bonobo_object_from_servant (servant));
- priv = offline_handler->priv;
-
- *active_connection_list = create_connection_list (offline_handler);
-}
-
-static void
-update_offline (CalendarOfflineHandler *offline_handler)
-{
- CalendarOfflineHandlerPrivate *priv;
- GNOME_Evolution_ConnectionList *connection_list;
- CORBA_Environment ev;
-
- priv = offline_handler->priv;
-
- connection_list = create_connection_list (offline_handler);
-
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_OfflineProgressListener_updateProgress (priv->listener_interface,
- connection_list, &ev);
-
- if (BONOBO_EX (&ev))
- g_warning ("Error updating offline progress");
-
- CORBA_exception_free (&ev);
-}
-
-static void
-backend_cal_set_mode (CalClient *client, CalClientSetModeStatus status, CalMode mode, gpointer data)
-{
- CalendarOfflineHandler *offline_handler = data;
-
- update_offline (offline_handler);
-}
-
-static void
-backend_cal_opened (CalClient *client, CalClientOpenStatus status, gpointer data)
-{
- CalendarOfflineHandler *offline_handler = data;
-
- if (status != CAL_CLIENT_OPEN_SUCCESS) {
- update_offline (offline_handler);
- gtk_object_unref (GTK_OBJECT (client));
- return;
- }
-
- gtk_signal_connect (GTK_OBJECT (client), "cal_set_mode",
- backend_cal_set_mode, offline_handler);
- cal_client_set_mode (client, CAL_MODE_LOCAL);
-}
-
-static void
-backend_go_offline (gpointer data, gpointer user_data)
-{
- CalendarOfflineHandler *offline_handler = user_data;
- char *uri = data;
- CalClient *client;
- gboolean success;
-
- client = cal_client_new ();
- gtk_signal_connect (GTK_OBJECT (client), "cal_opened",
- backend_cal_opened, offline_handler);
- success = cal_client_open_calendar (client, uri, TRUE);
- if (!success) {
- update_offline (offline_handler);
- gtk_object_unref (GTK_OBJECT (client));
- return;
- }
-}
-
-static void
-impl_goOffline (PortableServer_Servant servant,
- const GNOME_Evolution_OfflineProgressListener progress_listener,
- CORBA_Environment *ev)
-{
- CalendarOfflineHandler *offline_handler;
- CalendarOfflineHandlerPrivate *priv;
- GList *uris;
-
- offline_handler = CALENDAR_OFFLINE_HANDLER (bonobo_object_from_servant (servant));
- priv = offline_handler->priv;
-
- /* To update the status */
- priv->listener_interface = CORBA_Object_duplicate (progress_listener, ev);
-
- uris = cal_client_uri_list (priv->client, CAL_MODE_REMOTE);
-
- g_list_foreach (uris, backend_go_offline, offline_handler);
-}
-
-static void
-impl_goOnline (PortableServer_Servant servant,
- CORBA_Environment *ev)
-{
- CalendarOfflineHandler *offline_handler;
- CalendarOfflineHandlerPrivate *priv;
-
- offline_handler = CALENDAR_OFFLINE_HANDLER (bonobo_object_from_servant (servant));
- priv = offline_handler->priv;
-}
-
-/* GtkObject methods. */
-
-static void
-impl_destroy (GtkObject *object)
-{
- CalendarOfflineHandler *offline_handler;
- CalendarOfflineHandlerPrivate *priv;
-
- offline_handler = CALENDAR_OFFLINE_HANDLER (object);
- priv = offline_handler->priv;
-
- if (priv->listener_interface != CORBA_OBJECT_NIL) {
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- CORBA_Object_release (priv->listener_interface, &ev);
- CORBA_exception_free (&ev);
- }
-
- g_free (priv);
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy != NULL)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-/* GTK+ type initialization. */
-
-static void
-calendar_offline_handler_class_init (CalendarOfflineHandlerClass *klass)
-{
- GtkObjectClass *object_class;
- POA_GNOME_Evolution_Offline__epv *epv;
-
- object_class = GTK_OBJECT_CLASS (klass);
- object_class->destroy = impl_destroy;
-
- epv = & klass->epv;
- epv->_get_isOffline = impl__get_isOffline;
- epv->prepareForOffline = impl_prepareForOffline;
- epv->goOffline = impl_goOffline;
- epv->goOnline = impl_goOnline;
-
- parent_class = gtk_type_class (PARENT_TYPE);
-}
-
-static void
-calendar_offline_handler_init (CalendarOfflineHandler *offline_handler)
-{
- CalendarOfflineHandlerPrivate *priv;
-
- priv = g_new (CalendarOfflineHandlerPrivate, 1);
- offline_handler->priv = priv;
-
- priv->client = cal_client_new ();
- priv->listener_interface = CORBA_OBJECT_NIL;
- priv->is_offline = FALSE;
-}
-
-CalendarOfflineHandler *
-calendar_offline_handler_new (void)
-{
- CalendarOfflineHandler *new;
-
- new = gtk_type_new (calendar_offline_handler_get_type ());
-
- return new;
-}
-
-BONOBO_X_TYPE_FUNC_FULL (CalendarOfflineHandler, GNOME_Evolution_Offline, PARENT_TYPE, calendar_offline_handler);
diff --git a/calendar/gui/calendar-offline-handler.h b/calendar/gui/calendar-offline-handler.h
deleted file mode 100644
index 4b87fd659f..0000000000
--- a/calendar/gui/calendar-offline-handler.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* calendar-offline-handler.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: Ettore Perazzoli <ettore@ximian.com>
- */
-
-#ifndef _CALENDAR_OFFLINE_HANDLER_H_
-#define _CALENDAR_OFFLINE_HANDLER_H_
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <bonobo/bonobo-xobject.h>
-#include "Evolution.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-#define CALENDAR_TYPE_OFFLINE_HANDLER (calendar_offline_handler_get_type ())
-#define CALENDAR_OFFLINE_HANDLER(obj) (GTK_CHECK_CAST ((obj), CALENDAR_TYPE_OFFLINE_HANDLER, CalendarOfflineHandler))
-#define CALENDAR_OFFLINE_HANDLER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CALENDAR_TYPE_OFFLINE_HANDLER, CalendarOfflineHandlerClass))
-#define CALENDAR_IS_OFFLINE_HANDLER(obj) (GTK_CHECK_TYPE ((obj), CALENDAR_TYPE_OFFLINE_HANDLER))
-#define CALENDAR_IS_OFFLINE_HANDLER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), CALENDAR_TYPE_OFFLINE_HANDLER))
-
-
-typedef struct _CalendarOfflineHandler CalendarOfflineHandler;
-typedef struct _CalendarOfflineHandlerPrivate CalendarOfflineHandlerPrivate;
-typedef struct _CalendarOfflineHandlerClass CalendarOfflineHandlerClass;
-
-struct _CalendarOfflineHandler {
- BonoboXObject parent;
-
- CalendarOfflineHandlerPrivate *priv;
-};
-
-struct _CalendarOfflineHandlerClass {
- BonoboXObjectClass parent_class;
-
- POA_GNOME_Evolution_Offline__epv epv;
-};
-
-
-GtkType calendar_offline_handler_get_type (void);
-CalendarOfflineHandler *calendar_offline_handler_new (void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _CALENDAR_OFFLINE_HANDLER_H_ */
diff --git a/calendar/gui/calendar-view-factory.c b/calendar/gui/calendar-view-factory.c
deleted file mode 100644
index 0c3f0562f9..0000000000
--- a/calendar/gui/calendar-view-factory.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/* Evolution calendar - Generic view factory for calendar views
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include "calendar-view-factory.h"
-#include "calendar-view.h"
-
-
-
-/* Private part of the CalendarViewFactory structure */
-struct _CalendarViewFactoryPrivate {
- /* Type of views created by this factory */
- GnomeCalendarViewType view_type;
-};
-
-
-
-static void calendar_view_factory_class_init (CalendarViewFactoryClass *class);
-static void calendar_view_factory_init (CalendarViewFactory *cal_view_factory);
-static void calendar_view_factory_destroy (GtkObject *object);
-
-static const char *calendar_view_factory_get_title (GalViewFactory *factory);
-static const char *calendar_view_factory_get_type_code (GalViewFactory *factory);
-static GalView *calendar_view_factory_new_view (GalViewFactory *factory, const char *name);
-
-static GalViewFactoryClass *parent_class = NULL;
-
-
-
-/**
- * calendar_view_factory_get_type:
- *
- * Registers the #CalendarViewFactory class if necessary, and returns the type
- * ID associated to it.
- *
- * Return value: The type ID of the #CalendarViewFactory class.
- **/
-GtkType
-calendar_view_factory_get_type (void)
-{
- static GtkType calendar_view_factory_type;
-
- if (!calendar_view_factory_type) {
- static const GtkTypeInfo calendar_view_factory_info = {
- "CalendarViewFactory",
- sizeof (CalendarViewFactory),
- sizeof (CalendarViewFactoryClass),
- (GtkClassInitFunc) calendar_view_factory_class_init,
- (GtkObjectInitFunc) calendar_view_factory_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- calendar_view_factory_type = gtk_type_unique (GAL_VIEW_FACTORY_TYPE,
- &calendar_view_factory_info);
- }
-
- return calendar_view_factory_type;
-}
-
-/* Class initialization function for the calendar view factory */
-static void
-calendar_view_factory_class_init (CalendarViewFactoryClass *class)
-{
- GalViewFactoryClass *gal_view_factory_class;
- GtkObjectClass *object_class;
-
- parent_class = gtk_type_class (GAL_VIEW_FACTORY_TYPE);
-
- gal_view_factory_class = (GalViewFactoryClass *) class;
- object_class = (GtkObjectClass *) class;
-
- gal_view_factory_class->get_title = calendar_view_factory_get_title;
- gal_view_factory_class->get_type_code = calendar_view_factory_get_type_code;
- gal_view_factory_class->new_view = calendar_view_factory_new_view;
-
- object_class->destroy = calendar_view_factory_destroy;
-}
-
-/* Object initialization class for the calendar view factory */
-static void
-calendar_view_factory_init (CalendarViewFactory *cal_view_factory)
-{
- CalendarViewFactoryPrivate *priv;
-
- priv = g_new0 (CalendarViewFactoryPrivate, 1);
- cal_view_factory->priv = priv;
-}
-
-/* Destroy method for the calendar view factory */
-static void
-calendar_view_factory_destroy (GtkObject *object)
-{
- CalendarViewFactory *cal_view_factory;
- CalendarViewFactoryPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CALENDAR_VIEW_FACTORY (object));
-
- cal_view_factory = CALENDAR_VIEW_FACTORY (object);
- priv = cal_view_factory->priv;
-
- g_free (priv);
- cal_view_factory->priv = NULL;
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-
-
-/* get_title method for the calendar view factory */
-static const char *
-calendar_view_factory_get_title (GalViewFactory *factory)
-{
- CalendarViewFactory *cal_view_factory;
- CalendarViewFactoryPrivate *priv;
-
- cal_view_factory = CALENDAR_VIEW_FACTORY (factory);
- priv = cal_view_factory->priv;
-
- switch (priv->view_type) {
- case GNOME_CAL_DAY_VIEW:
- return _("Day View");
-
- case GNOME_CAL_WORK_WEEK_VIEW:
- return _("Work Week View");
-
- case GNOME_CAL_WEEK_VIEW:
- return _("Week View");
-
- case GNOME_CAL_MONTH_VIEW:
- return _("Month View");
-
- default:
- g_assert_not_reached ();
- return NULL;
- }
-}
-
-/* get_type_code method for the calendar view factory */
-static const char *
-calendar_view_factory_get_type_code (GalViewFactory *factory)
-{
- CalendarViewFactory *cal_view_factory;
- CalendarViewFactoryPrivate *priv;
-
- cal_view_factory = CALENDAR_VIEW_FACTORY (factory);
- priv = cal_view_factory->priv;
-
- switch (priv->view_type) {
- case GNOME_CAL_DAY_VIEW:
- return "day_view";
-
- case GNOME_CAL_WORK_WEEK_VIEW:
- return "work_week_view";
-
- case GNOME_CAL_WEEK_VIEW:
- return "week_view";
-
- case GNOME_CAL_MONTH_VIEW:
- return "month_view";
-
- default:
- g_assert_not_reached ();
- return NULL;
- }
-}
-
-/* new_view method for the calendar view factory */
-static GalView *
-calendar_view_factory_new_view (GalViewFactory *factory, const char *name)
-{
- CalendarViewFactory *cal_view_factory;
- CalendarViewFactoryPrivate *priv;
- CalendarView *cal_view;
-
- cal_view_factory = CALENDAR_VIEW_FACTORY (factory);
- priv = cal_view_factory->priv;
-
- cal_view = calendar_view_new (priv->view_type, name);
- return GAL_VIEW (cal_view);
-}
-
-
-
-/**
- * calendar_view_factory_construct:
- * @cal_view_factory: A calendar view factory.
- * @view_type: Type of calendar views that the factory will create.
- *
- * Constructs a calendar view factory by setting the type of views it will
- * create.
- *
- * Return value: The same value as @cal_view_factory.
- **/
-CalendarViewFactory *
-calendar_view_factory_construct (CalendarViewFactory *cal_view_factory,
- GnomeCalendarViewType view_type)
-{
- CalendarViewFactoryPrivate *priv;
-
- g_return_val_if_fail (cal_view_factory != NULL, NULL);
- g_return_val_if_fail (IS_CALENDAR_VIEW_FACTORY (cal_view_factory), NULL);
-
- priv = cal_view_factory->priv;
-
- priv->view_type = view_type;
-
- return cal_view_factory;
-}
-
-/**
- * calendar_view_factory_new:
- * @view_type: Type of calendar views that the factory will create.
- *
- * Creates a new factory for calendar views.
- *
- * Return value: A newly-created calendar view factory.
- **/
-CalendarViewFactory *
-calendar_view_factory_new (GnomeCalendarViewType view_type)
-{
- CalendarViewFactory *cal_view_factory;
-
- cal_view_factory = gtk_type_new (TYPE_CALENDAR_VIEW_FACTORY);
- return calendar_view_factory_construct (cal_view_factory, view_type);
-}
diff --git a/calendar/gui/calendar-view-factory.h b/calendar/gui/calendar-view-factory.h
deleted file mode 100644
index 6b3409afeb..0000000000
--- a/calendar/gui/calendar-view-factory.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Evolution calendar - Generic view factory for calendar views
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@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 CALENDAR_VIEW_FACTORY_H
-#define CALENDAR_VIEW_FACTORY_H
-
-#include <libgnome/gnome-defs.h>
-#include <gal/menus/gal-view-factory.h>
-#include "gnome-cal.h"
-
-BEGIN_GNOME_DECLS
-
-
-
-#define TYPE_CALENDAR_VIEW_FACTORY (calendar_view_factory_get_type ())
-#define CALENDAR_VIEW_FACTORY(obj) (GTK_CHECK_CAST ((obj), TYPE_CALENDAR_VIEW_FACTORY, \
- CalendarViewFactory))
-#define CALENDAR_VIEW_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \
- TYPE_CALENDAR_VIEW_FACTORY, CalendarViewClass))
-#define IS_CALENDAR_VIEW_FACTORY(obj) (GTK_CHECK_TYPE ((obj), TYPE_CALENDAR_VIEW_FACTORY))
-#define IS_CALENDAR_VIEW_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), \
- TYPE_CALENDAR_VIEW_FACTORY))
-
-typedef struct _CalendarViewFactoryPrivate CalendarViewFactoryPrivate;
-
-typedef struct {
- GalViewFactory factory;
-
- /* Private data */
- CalendarViewFactoryPrivate *priv;
-} CalendarViewFactory;
-
-typedef struct {
- GalViewFactoryClass parent_class;
-} CalendarViewFactoryClass;
-
-GtkType calendar_view_factory_get_type (void);
-
-CalendarViewFactory *calendar_view_factory_construct (CalendarViewFactory *cal_view_factory,
- GnomeCalendarViewType view_type);
-
-CalendarViewFactory *calendar_view_factory_new (GnomeCalendarViewType view_type);
-
-
-
-END_GNOME_DECLS
-
-#endif
diff --git a/calendar/gui/calendar-view.c b/calendar/gui/calendar-view.c
index 7ab5e9f13c..88cdd3cb82 100644
--- a/calendar/gui/calendar-view.c
+++ b/calendar/gui/calendar-view.c
@@ -1,316 +1,84 @@
-/* Evolution calendar - Generic view object for calendar views
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@ximian.com>
+/*
+ * calendar-view.c
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
*
- * 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.
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include "calendar-view.h"
-
-
-/* Private part of the CalendarView structure */
-struct _CalendarViewPrivate {
- /* Type of the view */
- GnomeCalendarViewType view_type;
-
- /* Title of the view */
- char *title;
-};
-
-
-
-static void calendar_view_class_init (CalendarViewClass *class);
-static void calendar_view_init (CalendarView *cview);
-static void calendar_view_destroy (GtkObject *object);
+G_DEFINE_TYPE (
+ GalViewCalendarDay,
+ gal_view_calendar_day,
+ GAL_TYPE_VIEW)
-static void calendar_view_edit (GalView *view);
-static void calendar_view_load (GalView *view, const char *filename);
-static void calendar_view_save (GalView *view, const char *filename);
-static const char *calendar_view_get_title (GalView *view);
-static void calendar_view_set_title (GalView *view, const char *title);
-static const char *calendar_view_get_type_code (GalView *view);
-static GalView *calendar_view_clone (GalView *view);
+G_DEFINE_TYPE (
+ GalViewCalendarWorkWeek,
+ gal_view_calendar_work_week,
+ GAL_TYPE_VIEW)
-static GalViewClass *parent_class = NULL;
+G_DEFINE_TYPE (
+ GalViewCalendarWeek,
+ gal_view_calendar_week,
+ GAL_TYPE_VIEW)
-
+G_DEFINE_TYPE (
+ GalViewCalendarMonth,
+ gal_view_calendar_month,
+ GAL_TYPE_VIEW)
-/**
- * calendar_view_get_type:
- *
- * Registers the #CalendarView class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the #CalendarView class.
- **/
-GtkType
-calendar_view_get_type (void)
-{
- static GtkType calendar_view_type;
-
- if (!calendar_view_type) {
- static const GtkTypeInfo calendar_view_info = {
- "CalendarView",
- sizeof (CalendarView),
- sizeof (CalendarViewClass),
- (GtkClassInitFunc) calendar_view_class_init,
- (GtkObjectInitFunc) calendar_view_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- calendar_view_type = gtk_type_unique (GAL_VIEW_TYPE, &calendar_view_info);
- }
-
- return calendar_view_type;
-}
-
-/* Class initialization function for the calendar view */
static void
-calendar_view_class_init (CalendarViewClass *class)
+gal_view_calendar_day_class_init (GalViewClass *class)
{
- GalViewClass *gal_view_class;
- GtkObjectClass *object_class;
-
- parent_class = gtk_type_class (GAL_VIEW_TYPE);
-
- gal_view_class = (GalViewClass *) class;
- object_class = (GtkObjectClass *) class;
-
- gal_view_class->edit = calendar_view_edit;
- gal_view_class->load = calendar_view_load;
- gal_view_class->save = calendar_view_save;
- gal_view_class->get_title = calendar_view_get_title;
- gal_view_class->set_title = calendar_view_set_title;
- gal_view_class->get_type_code = calendar_view_get_type_code;
- gal_view_class->clone = calendar_view_clone;
-
- object_class->destroy = calendar_view_destroy;
+ class->type_code = "day_view";
}
-/* Object initialization function for the calendar view */
static void
-calendar_view_init (CalendarView *cal_view)
+gal_view_calendar_day_init (GalView *view)
{
- CalendarViewPrivate *priv;
-
- priv = g_new0 (CalendarViewPrivate, 1);
- cal_view->priv = priv;
-
- priv->title = NULL;
}
-/* Destroy method for the calendar view */
static void
-calendar_view_destroy (GtkObject *object)
+gal_view_calendar_work_week_class_init (GalViewClass *class)
{
- CalendarView *cal_view;
- CalendarViewPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_CALENDAR_VIEW (object));
-
- cal_view = CALENDAR_VIEW (object);
- priv = cal_view->priv;
-
- if (priv->title) {
- g_free (priv->title);
- priv->title = NULL;
- }
-
- g_free (priv);
- cal_view->priv = NULL;
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+ class->type_code = "work_week_view";
}
-
-
-/* edit method of the calendar view */
static void
-calendar_view_edit (GalView *view)
+gal_view_calendar_work_week_init (GalView *view)
{
- /* nothing */
}
-/* load method of the calendar view */
static void
-calendar_view_load (GalView *view, const char *filename)
+gal_view_calendar_week_class_init (GalViewClass *class)
{
- /* nothing */
+ class->type_code = "week_view";
}
-/* save method of the calendar view */
static void
-calendar_view_save (GalView *view, const char *filename)
-{
- /* nothing */
-}
-
-/* get_title method of the calendar view */
-static const char *
-calendar_view_get_title (GalView *view)
+gal_view_calendar_week_init (GalView *view)
{
- CalendarView *cal_view;
- CalendarViewPrivate *priv;
-
- cal_view = CALENDAR_VIEW (view);
- priv = cal_view->priv;
-
- return priv->title;
}
-/* set_title method of the calendar view */
static void
-calendar_view_set_title (GalView *view, const char *title)
-{
- CalendarView *cal_view;
- CalendarViewPrivate *priv;
-
- cal_view = CALENDAR_VIEW (view);
- priv = cal_view->priv;
-
- if (priv->title)
- g_free (priv->title);
-
- priv->title = g_strdup (title);
-}
-
-/* get_type_code method for the calendar view */
-static const char *
-calendar_view_get_type_code (GalView *view)
-{
- CalendarView *cal_view;
- CalendarViewPrivate *priv;
-
- cal_view = CALENDAR_VIEW (view);
- priv = cal_view->priv;
-
- switch (priv->view_type) {
- case GNOME_CAL_DAY_VIEW:
- return "day_view";
-
- case GNOME_CAL_WORK_WEEK_VIEW:
- return "work_week_view";
-
- case GNOME_CAL_WEEK_VIEW:
- return "week_view";
-
- case GNOME_CAL_MONTH_VIEW:
- return "month_view";
-
- default:
- g_assert_not_reached ();
- return NULL;
- }
-}
-
-/* clone method for the calendar view */
-static GalView *
-calendar_view_clone (GalView *view)
-{
- CalendarView *cal_view;
- CalendarViewPrivate *priv;
- CalendarView *new_view;
- CalendarViewPrivate *new_priv;
-
- cal_view = CALENDAR_VIEW (view);
- priv = cal_view->priv;
-
- new_view = gtk_type_new (TYPE_CALENDAR_VIEW);
- new_priv = new_view->priv;
-
- new_priv->view_type = priv->view_type;
- new_priv->title = g_strdup (priv->title);
-
- return GAL_VIEW (new_view);
-}
-
-
-
-/**
- * calendar_view_construct:
- * @cal_view: A calendar view.
- * @view_type: The type of calendar view that this object will represent.
- * @title: Title for the view.
- *
- * Constructs a calendar view by setting its view type and title.
- *
- * Return value: The same value as @cal_view.
- **/
-CalendarView *
-calendar_view_construct (CalendarView *cal_view,
- GnomeCalendarViewType view_type,
- const char *title)
+gal_view_calendar_month_class_init (GalViewClass *class)
{
- CalendarViewPrivate *priv;
-
- g_return_val_if_fail (cal_view != NULL, NULL);
- g_return_val_if_fail (IS_CALENDAR_VIEW (cal_view), NULL);
- g_return_val_if_fail (title != NULL, NULL);
-
- priv = cal_view->priv;
-
- priv->view_type = view_type;
- priv->title = g_strdup (title);
-
- return cal_view;
+ class->type_code = "month_view";
}
-/**
- * calendar_view_new:
- * @view_type: The type of calendar view that this object will represent.
- * @title: Title for the view.
- *
- * Creates a new calendar view object.
- *
- * Return value: A newly-created calendar view.
- **/
-CalendarView *
-calendar_view_new (GnomeCalendarViewType view_type, const char *title)
+static void
+gal_view_calendar_month_init (GalView *view)
{
- CalendarView *cal_view;
-
- cal_view = gtk_type_new (TYPE_CALENDAR_VIEW);
- return calendar_view_construct (cal_view, view_type, title);
}
-/**
- * calendar_view_get_view_type:
- * @cal_view: A calendar view.
- *
- * Queries the calendar view type of a calendar view.
- *
- * Return value: Type of calendar view.
- **/
-GnomeCalendarViewType
-calendar_view_get_view_type (CalendarView *cal_view)
-{
- CalendarViewPrivate *priv;
-
- g_return_val_if_fail (cal_view != NULL, GNOME_CAL_DAY_VIEW);
- g_return_val_if_fail (IS_CALENDAR_VIEW (cal_view), GNOME_CAL_DAY_VIEW);
-
- priv = cal_view->priv;
- return priv->view_type;
-}
diff --git a/calendar/gui/calendar-view.h b/calendar/gui/calendar-view.h
index 515038d874..60b41ea0ea 100644
--- a/calendar/gui/calendar-view.h
+++ b/calendar/gui/calendar-view.h
@@ -1,67 +1,55 @@
-/* Evolution calendar - Generic view object for calendar views
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@ximian.com>
+/*
+ * calendar-view.h
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
*
- * 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 CALENDAR_VIEW_H
#define CALENDAR_VIEW_H
-#include <libgnome/gnome-defs.h>
-#include <gal/menus/gal-view.h>
-#include "gnome-cal.h"
-
-BEGIN_GNOME_DECLS
-
-
-
-#define TYPE_CALENDAR_VIEW (calendar_view_get_type ())
-#define CALENDAR_VIEW(obj) (GTK_CHECK_CAST ((obj), TYPE_CALENDAR_VIEW, CalendarView))
-#define CALENDAR_VIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_CALENDAR_VIEW, \
- CalendarViewClass))
-#define IS_CALENDAR_VIEW(obj) (GTK_CHECK_TYPE ((obj), TYPE_CALENDAR_VIEW))
-#define IS_CALENDAR_VIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_CALENDAR_VIEW))
-
-typedef struct _CalendarViewPrivate CalendarViewPrivate;
-
-typedef struct {
- GalView view;
+#include <e-util/e-util.h>
- /* Private data */
- CalendarViewPrivate *priv;
-} CalendarView;
+/* Standard GObject macros */
+#define GAL_TYPE_VIEW_CALENDAR_DAY \
+ (gal_view_calendar_day_get_type ())
+#define GAL_TYPE_VIEW_CALENDAR_WORK_WEEK \
+ (gal_view_calendar_work_week_get_type ())
+#define GAL_TYPE_VIEW_CALENDAR_WEEK \
+ (gal_view_calendar_week_get_type ())
+#define GAL_TYPE_VIEW_CALENDAR_MONTH \
+ (gal_view_calendar_month_get_type ())
-typedef struct {
- GalViewClass parent_class;
-} CalendarViewClass;
+G_BEGIN_DECLS
-GtkType calendar_view_get_type (void);
+typedef struct _GalView GalViewCalendarDay;
+typedef struct _GalViewClass GalViewCalendarDayClass;
-CalendarView *calendar_view_construct (CalendarView *cal_view,
- GnomeCalendarViewType view_type,
- const char *title);
+typedef struct _GalView GalViewCalendarWorkWeek;
+typedef struct _GalViewClass GalViewCalendarWorkWeekClass;
-CalendarView *calendar_view_new (GnomeCalendarViewType view_type,
- const char *title);
+typedef struct _GalView GalViewCalendarWeek;
+typedef struct _GalViewClass GalViewCalendarWeekClass;
-GnomeCalendarViewType calendar_view_get_view_type (CalendarView *cal_view);
+typedef struct _GalView GalViewCalendarMonth;
+typedef struct _GalViewClass GalViewCalendarMonthClass;
-
+GType gal_view_calendar_day_get_type (void) G_GNUC_CONST;
+GType gal_view_calendar_work_week_get_type (void) G_GNUC_CONST;
+GType gal_view_calendar_week_get_type (void) G_GNUC_CONST;
+GType gal_view_calendar_month_get_type (void) G_GNUC_CONST;
-END_GNOME_DECLS
+G_END_DECLS
-#endif
+#endif /* CALENDAR_VIEW_H */
diff --git a/calendar/gui/caltypes.xml b/calendar/gui/caltypes.xml
new file mode 100644
index 0000000000..964b623a3e
--- /dev/null
+++ b/calendar/gui/caltypes.xml
@@ -0,0 +1,229 @@
+<?xml version="1.0"?>
+<filterdescription>
+<partset>
+ <part name="summary">
+ <_title>Summary</_title>
+ <input type="optionlist" name="summary-type">
+ <option value="contains">
+ <_title>contains</_title>
+ <code>(contains? "summary" ${summary})</code>
+ </option>
+ <option value="not contains">
+ <_title>does not contain</_title>
+ <code>(not (contains? "summary" ${summary}))</code>
+ </option>
+ </input>
+ <input type="string" name="summary"/>
+ </part>
+
+ <part name="description">
+ <_title>Description</_title>
+ <input type="optionlist" name="description-type">
+ <option value="contains">
+ <_title>contains</_title>
+ <code>(contains? "description" ${description})</code>
+ </option>
+ <option value="not contains">
+ <_title>does not contain</_title>
+ <code>(not (contains? "description" ${description}))</code>
+ </option>
+ </input>
+ <input type="string" name="description"/>
+ </part>
+ <part name="anyfield">
+ <_title>Any Field</_title>
+ <input type="optionlist" name="anyfield-type">
+ <option value="contains">
+ <_title>contains</_title>
+ <code>(contains? "any" ${anyfield})</code>
+ </option>
+ <option value="not contains">
+ <_title>does not contain</_title>
+ <code>(not (contains? "any" ${anyfield}))</code>
+ </option>
+ </input>
+ <input type="string" name="anyfield"/>
+ </part>
+
+ <part name="name5">
+ <_title>Classification</_title>
+ <input type="optionlist" name="name-type">
+ <option value="is">
+ <_title>is</_title>
+ <code>(contains? "classification" ${classification})</code>
+ </option>
+ <option value="is not">
+ <_title>is not</_title>
+ <code>(not(contains? "classification" ${classification}))</code>
+ </option>
+ </input>
+ <input type="optionlist" name="classification">
+ <option value="Public">
+ <_title>Public</_title>
+ </option>
+ <option value="Private">
+ <_title>Private</_title>
+ </option>
+ <option value="Confidential">
+ <_title>Confidential</_title>
+ </option>
+ </input>
+ </part>
+
+
+ <part name="name2">
+ <_title>Organizer</_title>
+ <input type="optionlist" name="name-type">
+ <option value="contains">
+ <_title>contains</_title>
+ <code>(contains? "organizer" ${name})</code>
+ </option>
+ <option value="not contains">
+ <_title>does not contain</_title>
+ <code>(not (contains? "organizer" ${name}))</code>
+ </option>
+ </input>
+ <input type="string" name="name"/>
+ </part>
+
+ <part name="name3">
+ <_title>Attendee</_title>
+ <input type="optionlist" name="name-type">
+ <option value="contains">
+ <_title>contains</_title>
+ <code>(contains? "attendee" ${name})</code>
+ </option>
+ <option value="not contains">
+ <_title>does not contain</_title>
+ <code>(not (contains? "attendee" ${name}))</code>
+ </option>
+ </input>
+ <input type="string" name="name"/>
+ </part>
+
+ <part name="name4">
+ <_title>Location</_title>
+ <input type="optionlist" name="name-type">
+ <option value="contains">
+ <_title>contains</_title>
+ <code>(contains? "location" ${name})</code>
+ </option>
+ <option value="not contains">
+ <_title>does not contain</_title>
+ <code>(not (contains? "location" ${name}))</code>
+ </option>
+ </input>
+ <input type="string" name="name"/>
+ </part>
+
+ <part name="category">
+ <_title>Category</_title>
+ <input type="optionlist" name="category-type">
+ <option value="is">
+ <_title>is</_title>
+ <code>(has-categories? ${category})</code>
+ </option>
+ <option value="is not">
+ <_title>is not</_title>
+ <code>(not(has-categories? ${category}))</code>
+ </option>
+ </input>
+ <input type="optionlist" name="category">
+ <dynamic func="e_util_get_category_filter_options"/>
+ </input>
+ </part>
+
+ <part name="attachments">
+ <_title>Attachments</_title>
+ <input type="optionlist" name="match-type">
+ <option value="exist">
+ <_title>Exist</_title>
+ <code>
+ (has-attachments?)
+ </code>
+ </option>
+ <option value="not exist">
+ <_title>Do Not Exist</_title>
+ <code>
+ (not(has-attachments?))
+ </code>
+ </option>
+ </input>
+ </part>
+
+ <part name="recurrences">
+ <_title>Recurrence</_title>
+ <input type="optionlist" name="match-type">
+ <option value="exist">
+ <_title>Exist</_title>
+ <code>
+ (has-recurrences?)
+ </code>
+ </option>
+ <option value="not exist">
+ <_title>Do Not Exist</_title>
+ <code>
+ (not (has-recurrences?))
+ </code>
+ </option>
+ </input>
+ </part>
+
+ <part name="count-occurrences">
+ <_title>Occurs</_title>
+ <input type="optionlist" name="match-type">
+ <option value="less-than">
+ <_title>Less Than</_title>
+ <code>((or (= (occurrences-count?) (- 1)) (&lt; (occurrences-count?) ${count}))</code>
+ </option>
+ <option value="exactly">
+ <_title>Exactly</_title>
+ <code>((or (= (occurrences-count?) (- 1)) (= (occurrences-count?) ${count}))</code>
+ </option>
+ <option value="more-than">
+ <_title>More Than</_title>
+ <code>((or (= (occurrences-count?) (- 1)) (&gt; (occurrences-count?) ${count}))</code>
+ </option>
+ </input>
+ <input type="integer" name="count"/>
+ </part>
+ </partset>
+
+<ruleset>
+ <rule grouping="any" source="demand">
+ <_title>Summary Contains</_title>
+ <partset>
+ <part name="summary">
+ <value name="summary-type" type="option" value="contains"/>
+ <value name="summary" type="string"/>
+ </part>
+ </partset>
+
+ <sources/>
+ </rule>
+
+ <rule grouping="any" source="demand">
+ <_title>Description Contains</_title>
+ <partset>
+ <part name="description">
+ <value name="description-type" type="option" value="contains"/>
+ <value name="description" type="string"/>
+ </part>
+ </partset>
+ <sources/>
+ </rule>
+
+ <rule grouping="any" source="demand">
+ <_title>Any field contains</_title>
+ <partset>
+ <part name="anyfield">
+ <value name="anyfield-type" type="option" value="contains"/>
+ <value name="anyfield" type="string"/>
+ </part>
+ </partset>
+ <sources/>
+ </rule>
+
+ </ruleset>
+
+ </filterdescription>
diff --git a/calendar/gui/comp-editor-factory.c b/calendar/gui/comp-editor-factory.c
deleted file mode 100644
index 31746ae55b..0000000000
--- a/calendar/gui/comp-editor-factory.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/* Evolution calendar - Component editor factory object
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <bonobo/bonobo-exception.h>
-#include <evolution-calendar.h>
-#include <e-util/e-url.h>
-#include <cal-client/cal-client.h>
-#include "calendar-config.h"
-#include "e-comp-editor-registry.h"
-#include "comp-editor-factory.h"
-#include "comp-util.h"
-#include "dialogs/event-editor.h"
-#include "dialogs/task-editor.h"
-
-extern ECompEditorRegistry *comp_editor_registry;
-
-
-
-/* A pending request */
-
-typedef enum {
- REQUEST_EXISTING,
- REQUEST_NEW
-} RequestType;
-
-typedef struct {
- RequestType type;
-
- union {
- struct {
- char *uid;
- } existing;
-
- struct {
- GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type;
- } new;
- } u;
-} Request;
-
-/* A client we have open */
-typedef struct {
- /* Our parent CompEditorFactory */
- CompEditorFactory *factory;
-
- /* Uri of the calendar, used as key in the clients hash table */
- char *uri;
-
- /* Client of the calendar */
- CalClient *client;
-
- /* Count editors using this client */
- int editor_count;
-
- /* Pending requests; they are pending if the client is still being opened */
- GSList *pending;
-
- /* Whether this is open or still waiting */
- guint open : 1;
-} OpenClient;
-
-/* Private part of the CompEditorFactory structure */
-struct CompEditorFactoryPrivate {
- /* Hash table of URI->OpenClient */
- GHashTable *uri_client_hash;
-};
-
-
-
-static void comp_editor_factory_class_init (CompEditorFactoryClass *class);
-static void comp_editor_factory_init (CompEditorFactory *factory);
-static void comp_editor_factory_destroy (GtkObject *object);
-
-static void impl_editExisting (PortableServer_Servant servant,
- const CORBA_char *str_uri,
- const GNOME_Evolution_Calendar_CalObjUID uid,
- CORBA_Environment *ev);
-static void impl_editNew (PortableServer_Servant servant,
- const CORBA_char *str_uri,
- const GNOME_Evolution_Calendar_CalObjType type,
- CORBA_Environment *ev);
-
-static BonoboXObjectClass *parent_class = NULL;
-
-
-
-BONOBO_X_TYPE_FUNC_FULL (CompEditorFactory,
- GNOME_Evolution_Calendar_CompEditorFactory,
- BONOBO_X_OBJECT_TYPE,
- comp_editor_factory);
-
-/* Class initialization function for the component editor factory */
-static void
-comp_editor_factory_class_init (CompEditorFactoryClass *class)
-{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) class;
-
- parent_class = gtk_type_class (BONOBO_X_OBJECT_TYPE);
-
- class->epv.editExisting = impl_editExisting;
- class->epv.editNew = impl_editNew;
-
- object_class->destroy = comp_editor_factory_destroy;
-}
-
-/* Object initialization function for the component editor factory */
-static void
-comp_editor_factory_init (CompEditorFactory *factory)
-{
- CompEditorFactoryPrivate *priv;
-
- priv = g_new (CompEditorFactoryPrivate, 1);
- factory->priv = priv;
-
- priv->uri_client_hash = g_hash_table_new (g_str_hash, g_str_equal);
-}
-
-/* Frees a Request structure */
-static void
-free_request (Request *r)
-{
- if (r->type == REQUEST_EXISTING) {
- g_assert (r->u.existing.uid != NULL);
- g_free (r->u.existing.uid);
- }
-
- g_free (r);
-}
-
-/* Frees an OpenClient structure */
-static void
-free_client (OpenClient *oc)
-{
- GSList *l;
-
- g_free (oc->uri);
- oc->uri = NULL;
-
- gtk_object_unref (GTK_OBJECT (oc->client));
- oc->client = NULL;
-
- for (l = oc->pending; l; l = l->next) {
- Request *r;
-
- r = l->data;
- free_request (r);
- }
- g_slist_free (oc->pending);
- oc->pending = NULL;
-
- g_free (oc);
-}
-
-/* Used from g_hash_table_foreach(); frees a client structure */
-static void
-free_client_cb (gpointer key, gpointer value, gpointer data)
-{
- OpenClient *oc;
-
- oc = value;
- free_client (oc);
-}
-
-/* Destroy handler for the component editor factory */
-static void
-comp_editor_factory_destroy (GtkObject *object)
-{
- CompEditorFactory *factory;
- CompEditorFactoryPrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_COMP_EDITOR_FACTORY (object));
-
- factory = COMP_EDITOR_FACTORY (object);
- priv = factory->priv;
-
- g_hash_table_foreach (priv->uri_client_hash, free_client_cb, NULL);
- g_hash_table_destroy (priv->uri_client_hash);
- priv->uri_client_hash = NULL;
-
- g_free (priv);
- factory->priv = NULL;
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-
-
-/* Callback used when a component editor gets destroyed */
-static void
-editor_destroy_cb (GtkObject *object, gpointer data)
-{
- OpenClient *oc;
- CompEditorFactory *factory;
- CompEditorFactoryPrivate *priv;
-
- oc = data;
- factory = oc->factory;
- priv = factory->priv;
-
- oc->editor_count--;
-
- /* See if we need to free the client */
- g_assert (oc->pending == NULL);
-
- if (oc->editor_count != 0)
- return;
-
- g_hash_table_remove (priv->uri_client_hash, oc->uri);
- free_client (oc);
-}
-
-/* Starts editing an existing component on a client that is already open */
-static void
-edit_existing (OpenClient *oc, const char *uid)
-{
- CalComponent *comp;
- CalClientGetStatus status;
- CompEditor *editor;
- CalComponentVType vtype;
-
- g_assert (oc->open);
-
- /* Get the object */
-
- status = cal_client_get_object (oc->client, uid, &comp);
-
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- /* see below */
- 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 ();
- return;
- }
-
- /* Create the appropriate type of editor */
-
- vtype = cal_component_get_vtype (comp);
-
- switch (vtype) {
- case CAL_COMPONENT_EVENT:
- editor = COMP_EDITOR (event_editor_new (oc->client));
- break;
-
- case CAL_COMPONENT_TODO:
- editor = COMP_EDITOR (task_editor_new (oc->client));
- break;
-
- default:
- g_message ("edit_exiting(): Unsupported object type %d", (int) vtype);
- gtk_object_unref (GTK_OBJECT (comp));
- return;
- }
-
- /* Set the object on the editor */
- comp_editor_edit_comp (editor, comp);
- comp_editor_focus (editor);
-
- oc->editor_count++;
- gtk_signal_connect (GTK_OBJECT (editor), "destroy",
- GTK_SIGNAL_FUNC (editor_destroy_cb), oc);
-
- e_comp_editor_registry_add (comp_editor_registry, editor, TRUE);
-}
-
-/* Creates a component with the appropriate defaults for the specified component
- * type.
- */
-static CalComponent *
-get_default_event (gboolean all_day)
-{
- CalComponent *comp;
- struct icaltimetype itt;
- CalComponentDateTime dt;
- char *location;
- icaltimezone *zone;
-
- comp = cal_comp_event_new_with_defaults ();
-
- location = calendar_config_get_timezone ();
- zone = icaltimezone_get_builtin_timezone (location);
-
- if (all_day) {
- itt = icaltime_from_timet_with_zone (time (NULL), 1, zone);
-
- dt.value = &itt;
- dt.tzid = icaltimezone_get_tzid (zone);
-
- cal_component_set_dtstart (comp, &dt);
- cal_component_set_dtend (comp, &dt);
- } else {
- itt = icaltime_current_time_with_zone (zone);
- icaltime_adjust (&itt, 0, 1, -itt.minute, -itt.second);
-
- dt.value = &itt;
- dt.tzid = icaltimezone_get_tzid (zone);
-
- cal_component_set_dtstart (comp, &dt);
- icaltime_adjust (&itt, 0, 1, 0, 0);
- cal_component_set_dtend (comp, &dt);
- }
-
- cal_component_commit_sequence (comp);
-
- return comp;
-}
-
-static CalComponent *
-get_default_task (void)
-{
- CalComponent *comp;
-
- comp = cal_component_new ();
- cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO);
-
- return comp;
-}
-
-/* Edits a new object in the context of a client */
-static void
-edit_new (OpenClient *oc, const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type)
-{
- CalComponent *comp;
- CompEditor *editor;
-
- switch (type) {
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT:
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING:
- editor = COMP_EDITOR (event_editor_new (oc->client));
- comp = get_default_event (FALSE);
- break;
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT:
- editor = COMP_EDITOR (event_editor_new (oc->client));
- comp = get_default_event (TRUE);
- break;
- case GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO:
- editor = COMP_EDITOR (task_editor_new (oc->client));
- comp = get_default_task ();
- break;
- default:
- g_assert_not_reached ();
- return;
- }
-
- comp_editor_edit_comp (editor, comp);
- if (type == GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING)
- event_editor_show_meeting (EVENT_EDITOR (editor));
- comp_editor_focus (editor);
-
- oc->editor_count++;
- gtk_signal_connect (GTK_OBJECT (editor), "destroy",
- GTK_SIGNAL_FUNC (editor_destroy_cb), oc);
-
- e_comp_editor_registry_add (comp_editor_registry, editor, TRUE);
-}
-
-/* Resolves all the pending requests for a client */
-static void
-resolve_pending_requests (OpenClient *oc)
-{
- CompEditorFactory *factory;
- CompEditorFactoryPrivate *priv;
- GSList *l;
- char *location;
- icaltimezone *zone;
-
- factory = oc->factory;
- priv = factory->priv;
-
- g_assert (oc->pending != NULL);
-
- /* 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);
-
- for (l = oc->pending; l; l = l->next) {
- Request *request;
-
- request = l->data;
-
- switch (request->type) {
- case REQUEST_EXISTING:
- edit_existing (oc, request->u.existing.uid);
- break;
-
- case REQUEST_NEW:
- edit_new (oc, request->u.new.type);
- break;
- }
-
- free_request (request);
- }
-
- g_slist_free (oc->pending);
- oc->pending = NULL;
-}
-
-/* Callback used when a client is finished opening. We resolve all the pending
- * requests.
- */
-static void
-cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
-{
- OpenClient *oc;
- CompEditorFactory *factory;
- CompEditorFactoryPrivate *priv;
-
- oc = data;
- factory = oc->factory;
- priv = factory->priv;
-
- switch (status) {
- case CAL_CLIENT_OPEN_SUCCESS:
- oc->open = TRUE;
- resolve_pending_requests (oc);
- return;
-
- case CAL_CLIENT_OPEN_ERROR:
- g_message ("cal_opened_cb(): Error while opening the calendar");
- break;
-
- case CAL_CLIENT_OPEN_NOT_FOUND:
- /* bullshit; we specified only_if_exists = FALSE */
- g_assert_not_reached ();
- return;
-
- case CAL_CLIENT_OPEN_METHOD_NOT_SUPPORTED:
- g_message ("cal_opened_cb(): Method not supported when opening the calendar");
- break;
-
- default:
- g_assert_not_reached ();
- return;
- }
-
- g_hash_table_remove (priv->uri_client_hash, oc->uri);
- free_client (oc);
-}
-
-/* Creates a new OpenClient structure and queues the component editing/creation
- * process until the client is open. Returns NULL if it could not issue the
- * open request.
- */
-static OpenClient *
-open_client (CompEditorFactory *factory, const char *uristr)
-{
- CompEditorFactoryPrivate *priv;
- CalClient *client;
- OpenClient *oc;
-
- priv = factory->priv;
-
- client = cal_client_new ();
- if (!client)
- return NULL;
-
- oc = g_new (OpenClient, 1);
- oc->factory = factory;
-
- oc->uri = g_strdup (uristr);
-
- oc->client = client;
- oc->editor_count = 0;
- oc->pending = NULL;
- oc->open = FALSE;
-
- gtk_signal_connect (GTK_OBJECT (oc->client), "cal_opened",
- GTK_SIGNAL_FUNC (cal_opened_cb), oc);
-
- if (!cal_client_open_calendar (oc->client, uristr, FALSE)) {
- g_free (oc->uri);
- gtk_object_unref (GTK_OBJECT (oc->client));
- g_free (oc);
-
- return NULL;
- }
-
- g_hash_table_insert (priv->uri_client_hash, oc->uri, oc);
-
- return oc;
-}
-
-/* Looks up an open client or queues it for being opened. Returns the client or
- * NULL on failure; in the latter case it sets the ev exception.
- */
-static OpenClient *
-lookup_open_client (CompEditorFactory *factory, const char *str_uri, CORBA_Environment *ev)
-{
- CompEditorFactoryPrivate *priv;
- OpenClient *oc;
- EUri *uri;
-
- priv = factory->priv;
-
- /* Look up the client */
-
- uri = e_uri_new (str_uri);
- if (!uri) {
- bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_CompEditorFactory_InvalidURI);
- return NULL;
- }
- e_uri_free (uri);
-
- oc = g_hash_table_lookup (priv->uri_client_hash, str_uri);
- if (!oc) {
- oc = open_client (factory, str_uri);
- if (!oc) {
- bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_CompEditorFactory_BackendContactError);
- return NULL;
- }
- }
-
- return oc;
-}
-
-/* Queues a request for editing an existing object */
-static void
-queue_edit_existing (OpenClient *oc, const char *uid)
-{
- Request *request;
-
- g_assert (!oc->open);
-
- request = g_new (Request, 1);
- request->type = REQUEST_EXISTING;
- request->u.existing.uid = g_strdup (uid);
-
- oc->pending = g_slist_append (oc->pending, request);
-}
-
-/* ::editExisting() method implementation */
-static void
-impl_editExisting (PortableServer_Servant servant,
- const CORBA_char *str_uri,
- const GNOME_Evolution_Calendar_CalObjUID uid,
- CORBA_Environment *ev)
-{
- CompEditorFactory *factory;
- CompEditorFactoryPrivate *priv;
- OpenClient *oc;
- CompEditor *editor;
-
- factory = COMP_EDITOR_FACTORY (bonobo_object_from_servant (servant));
- priv = factory->priv;
-
- oc = lookup_open_client (factory, str_uri, ev);
- if (!oc)
- return;
-
- if (!oc->open) {
- queue_edit_existing (oc, uid);
- return;
- }
-
- /* Look up the component */
- editor = e_comp_editor_registry_find (comp_editor_registry, uid);
- if (editor == NULL) {
- edit_existing (oc, uid);
- } else {
- comp_editor_focus (editor);
- }
-}
-
-/* Queues a request for creating a new object */
-static void
-queue_edit_new (OpenClient *oc, const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode type)
-{
- Request *request;
-
- g_assert (!oc->open);
-
- request = g_new (Request, 1);
- request->type = REQUEST_NEW;
- request->u.new.type = type;
-
- oc->pending = g_slist_append (oc->pending, request);
-}
-
-/* ::editNew() method implementation */
-static void
-impl_editNew (PortableServer_Servant servant,
- const CORBA_char *str_uri,
- const GNOME_Evolution_Calendar_CompEditorFactory_CompEditorMode corba_type,
- CORBA_Environment *ev)
-{
- CompEditorFactory *factory;
- CompEditorFactoryPrivate *priv;
- OpenClient *oc;
-
- factory = COMP_EDITOR_FACTORY (bonobo_object_from_servant (servant));
- priv = factory->priv;
-
- oc = lookup_open_client (factory, str_uri, ev);
- if (!oc)
- return;
-
- if (!oc->open)
- queue_edit_new (oc, corba_type);
- else
- edit_new (oc, corba_type);
-}
-
-
-
-/**
- * comp_editor_factory_new:
- *
- * Creates a new calendar component editor factory.
- *
- * Return value: A newly-created component editor factory.
- **/
-CompEditorFactory *
-comp_editor_factory_new (void)
-{
- return gtk_type_new (TYPE_COMP_EDITOR_FACTORY);
-}
-
-
diff --git a/calendar/gui/comp-editor-factory.h b/calendar/gui/comp-editor-factory.h
deleted file mode 100644
index 21e27941fc..0000000000
--- a/calendar/gui/comp-editor-factory.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Evolution calendar - Component editor factory object
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@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 COMP_EDITOR_FACTORY_H
-#define COMP_EDITOR_FACTORY_H
-
-#include <bonobo/bonobo-xobject.h>
-#include "evolution-calendar.h"
-
-
-
-#define TYPE_COMP_EDITOR_FACTORY (comp_editor_factory_get_type ())
-#define COMP_EDITOR_FACTORY(obj) (GTK_CHECK_CAST ((obj), TYPE_COMP_EDITOR_FACTORY, \
- CompEditorFactory))
-#define COMP_EDITOR_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \
- TYPE_COMP_EDITOR_FACTORY, CompEditorFactoryClass))
-#define IS_COMP_EDITOR_FACTORY(obj) (GTK_CHECK_TYPE ((obj), TYPE_COMP_EDITOR_FACTORY))
-#define IS_COMP_EDITOR_FACTORY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_COMP_EDITOR_FACTORY))
-
-typedef struct CompEditorFactoryPrivate CompEditorFactoryPrivate;
-
-typedef struct {
- BonoboXObject xobject;
-
- /* Private data */
- CompEditorFactoryPrivate *priv;
-} CompEditorFactory;
-
-typedef struct {
- BonoboXObjectClass parent_class;
-
- POA_GNOME_Evolution_Calendar_CompEditorFactory__epv epv;
-} CompEditorFactoryClass;
-
-GtkType comp_editor_factory_get_type (void);
-
-CompEditorFactory *comp_editor_factory_new (void);
-
-
-
-#endif
diff --git a/calendar/gui/comp-util.c b/calendar/gui/comp-util.c
index 46331fa265..a271100167 100644
--- a/calendar/gui/comp-util.c
+++ b/calendar/gui/comp-util.c
@@ -1,68 +1,77 @@
-/* Evolution calendar - Utilities for manipulating CalComponent objects
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@ximian.com>
+/*
+ * Evolution calendar - Utilities for manipulating ECalComponent objects
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include <string.h>
+#include <time.h>
+
#include "calendar-config.h"
#include "comp-util.h"
#include "dialogs/delete-comp.h"
-
+#include "gnome-cal.h"
+#include "shell/e-shell-window.h"
+#include "shell/e-shell-view.h"
/**
* cal_comp_util_add_exdate:
* @comp: A calendar component object.
* @itt: Time for the exception.
- *
+ *
* Adds an exception date to the current list of EXDATE properties in a calendar
* component object.
**/
void
-cal_comp_util_add_exdate (CalComponent *comp, time_t t, icaltimezone *zone)
+cal_comp_util_add_exdate (ECalComponent *comp,
+ time_t t,
+ icaltimezone *zone)
{
GSList *list;
- CalComponentDateTime *cdt;
+ ECalComponentDateTime *cdt;
g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
+ g_return_if_fail (E_IS_CAL_COMPONENT (comp));
- cal_component_get_exdate_list (comp, &list);
+ e_cal_component_get_exdate_list (comp, &list);
- cdt = g_new (CalComponentDateTime, 1);
+ cdt = g_new (ECalComponentDateTime, 1);
cdt->value = g_new (struct icaltimetype, 1);
*cdt->value = icaltime_from_timet_with_zone (t, FALSE, zone);
cdt->tzid = g_strdup (icaltimezone_get_tzid (zone));
list = g_slist_append (list, cdt);
- cal_component_set_exdate_list (comp, list);
- cal_component_free_exdate_list (list);
+ e_cal_component_set_exdate_list (comp, list);
+ e_cal_component_free_exdate_list (list);
}
-
-
/* Returns TRUE if the TZIDs are equivalent, i.e. both NULL or the same. */
static gboolean
-cal_component_compare_tzid (const char *tzid1, const char *tzid2)
+e_cal_component_compare_tzid (const gchar *tzid1,
+ const gchar *tzid2)
{
gboolean retval = TRUE;
@@ -80,8 +89,8 @@ cal_component_compare_tzid (const char *tzid1, const char *tzid2)
/**
* cal_comp_util_compare_event_timezones:
* @comp: A calendar component object.
- * @client: A #CalClient.
- *
+ * @client: A #ECalClient.
+ *
* Checks if the component uses the given timezone for both the start and
* the end time, or if the UTC offsets of the start and end times are the same
* as in the given zone.
@@ -90,25 +99,24 @@ cal_component_compare_tzid (const char *tzid1, const char *tzid2)
* offset in the given timezone.
**/
gboolean
-cal_comp_util_compare_event_timezones (CalComponent *comp,
- CalClient *client,
- icaltimezone *zone)
+cal_comp_util_compare_event_timezones (ECalComponent *comp,
+ ECalClient *client,
+ icaltimezone *zone)
{
- CalClientGetStatus status;
- CalComponentDateTime start_datetime, end_datetime;
- const char *tzid;
+ ECalComponentDateTime start_datetime, end_datetime;
+ const gchar *tzid;
gboolean retval = FALSE;
icaltimezone *start_zone, *end_zone;
- int offset1, offset2;
+ gint offset1, offset2;
tzid = icaltimezone_get_tzid (zone);
- cal_component_get_dtstart (comp, &start_datetime);
- cal_component_get_dtend (comp, &end_datetime);
+ e_cal_component_get_dtstart (comp, &start_datetime);
+ e_cal_component_get_dtend (comp, &end_datetime);
/* If either the DTSTART or the DTEND is a DATE value, we return TRUE.
- Maybe if one was a DATE-TIME we should check that, but that should
- not happen often. */
+ * Maybe if one was a DATE-TIME we should check that, but that should
+ * not happen often. */
if ((start_datetime.value && start_datetime.value->is_date)
|| (end_datetime.value && end_datetime.value->is_date)) {
retval = TRUE;
@@ -116,8 +124,8 @@ cal_comp_util_compare_event_timezones (CalComponent *comp,
}
/* If the event uses UTC for DTSTART & DTEND, return TRUE. Outlook
- will send single events as UTC, so we don't want to mark all of
- these. */
+ * will send single events as UTC, so we don't want to mark all of
+ * these. */
if ((!start_datetime.value || start_datetime.value->is_utc)
&& (!end_datetime.value || end_datetime.value->is_utc)) {
retval = TRUE;
@@ -125,53 +133,53 @@ cal_comp_util_compare_event_timezones (CalComponent *comp,
}
/* If the event uses floating time for DTSTART & DTEND, return TRUE.
- Imported vCalendar files will use floating times, so we don't want
- to mark all of these. */
+ * Imported vCalendar files will use floating times, so we don't want
+ * to mark all of these. */
if (!start_datetime.tzid && !end_datetime.tzid) {
retval = TRUE;
goto out;
}
/* FIXME: DURATION may be used instead. */
- if (cal_component_compare_tzid (tzid, start_datetime.tzid)
- && cal_component_compare_tzid (tzid, end_datetime.tzid)) {
+ if (e_cal_component_compare_tzid (tzid, start_datetime.tzid)
+ && e_cal_component_compare_tzid (tzid, end_datetime.tzid)) {
/* If both TZIDs are the same as the given zone's TZID, then
- we know the timezones are the same so we return TRUE. */
+ * we know the timezones are the same so we return TRUE. */
retval = TRUE;
} else {
/* 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)
+ * of the start and end times, using their own timezones and
+ * the given timezone. */
+ if (!e_cal_client_get_timezone_sync (client, start_datetime.tzid,
+ &start_zone, NULL, NULL))
goto out;
if (start_datetime.value) {
- offset1 = icaltimezone_get_utc_offset (start_zone,
- start_datetime.value,
- NULL);
- offset2 = icaltimezone_get_utc_offset (zone,
- start_datetime.value,
- NULL);
+ offset1 = icaltimezone_get_utc_offset (
+ start_zone,
+ start_datetime.value,
+ NULL);
+ offset2 = icaltimezone_get_utc_offset (
+ zone,
+ start_datetime.value,
+ NULL);
if (offset1 != offset2)
goto out;
}
- status = cal_client_get_timezone (client,
- end_datetime.tzid,
- &end_zone);
- if (status != CAL_CLIENT_GET_SUCCESS)
+ if (!e_cal_client_get_timezone_sync (client, end_datetime.tzid,
+ &end_zone, NULL, NULL))
goto out;
if (end_datetime.value) {
- offset1 = icaltimezone_get_utc_offset (end_zone,
- end_datetime.value,
- NULL);
- offset2 = icaltimezone_get_utc_offset (zone,
- end_datetime.value,
- NULL);
+ offset1 = icaltimezone_get_utc_offset (
+ end_zone,
+ end_datetime.value,
+ NULL);
+ offset2 = icaltimezone_get_utc_offset (
+ zone,
+ end_datetime.value,
+ NULL);
if (offset1 != offset2)
goto out;
}
@@ -181,8 +189,8 @@ cal_comp_util_compare_event_timezones (CalComponent *comp,
out:
- cal_component_free_datetime (&start_datetime);
- cal_component_free_datetime (&end_datetime);
+ e_cal_component_free_datetime (&start_datetime);
+ e_cal_component_free_datetime (&end_datetime);
return retval;
}
@@ -192,30 +200,32 @@ cal_comp_util_compare_event_timezones (CalComponent *comp,
* @comp: A calendar component.
* @client: Calendar client where the component purportedly lives.
* @widget: Widget to be used as the basis for UTF8 conversion.
- *
+ *
* Assumming a calendar component with an empty SUMMARY property (as per
* string_is_empty()), asks whether the user wants to delete it based on
* whether the appointment is on the calendar server or not. If the
* component is on the server, this function will present a confirmation
* dialog and delete the component if the user tells it to. If the component
* is not on the server it will just return TRUE.
- *
+ *
* Return value: A result code indicating whether the component
* was not on the server and is to be deleted locally, whether it
* was on the server and the user deleted it, or whether the
* user cancelled the deletion.
**/
gboolean
-cal_comp_is_on_server (CalComponent *comp, CalClient *client)
+cal_comp_is_on_server (ECalComponent *comp,
+ ECalClient *client)
{
- const char *uid;
- CalClientGetStatus status;
- CalComponent *server_comp;
+ const gchar *uid;
+ gchar *rid = NULL;
+ icalcomponent *icalcomp;
+ GError *error = NULL;
g_return_val_if_fail (comp != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE);
+ g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
g_return_val_if_fail (client != NULL, FALSE);
- g_return_val_if_fail (IS_CAL_CLIENT (client), FALSE);
+ g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE);
/* See if the component is on the server. If it is not, then it likely
* means that the appointment is new, only in the day view, and we
@@ -223,100 +233,583 @@ cal_comp_is_on_server (CalComponent *comp, CalClient *client)
* confirm and we can just delete the event. Otherwise, we ask
* the user.
*/
- cal_component_get_uid (comp, &uid);
+ e_cal_component_get_uid (comp, &uid);
- status = cal_client_get_object (client, uid, &server_comp);
+ /* TODO We should not be checking for this here. But since
+ * e_cal_util_construct_instance does not create the instances
+ * of all day events, so we default to old behaviour. */
+ if (e_cal_client_check_recurrences_no_master (client)) {
+ rid = e_cal_component_get_recurid_as_string (comp);
+ }
- switch (status) {
- case CAL_CLIENT_GET_SUCCESS:
- gtk_object_unref (GTK_OBJECT (server_comp));
- return TRUE;
+ if (e_cal_client_get_object_sync (client, uid, rid, &icalcomp, NULL, &error)) {
+ icalcomponent_free (icalcomp);
+ g_free (rid);
- 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;
+ if (!g_error_matches (error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND))
+ g_warning (G_STRLOC ": %s", error->message);
+
+ g_clear_error (&error);
+ g_free (rid);
- default:
- g_assert_not_reached ();
- }
-
return FALSE;
}
/**
+ * is_icalcomp_on_the_server:
+ * same as @cal_comp_is_on_server, only the component parameter is
+ * icalcomponent, not the ECalComponent.
+ **/
+gboolean
+is_icalcomp_on_the_server (icalcomponent *icalcomp,
+ ECalClient *client)
+{
+ gboolean on_server;
+ ECalComponent *comp;
+
+ if (!icalcomp || !client || !icalcomponent_get_uid (icalcomp))
+ return FALSE;
+
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
+
+ on_server = cal_comp_is_on_server (comp, client);
+
+ g_object_unref (comp);
+
+ return on_server;
+}
+
+/**
* cal_comp_event_new_with_defaults:
- *
+ *
* Creates a new VEVENT component and adds any default alarms to it as set in
- * the program's configuration values.
- *
+ * the program's configuration values, but only if not the all_day event.
+ *
* Return value: A newly-created calendar component.
**/
-CalComponent *
-cal_comp_event_new_with_defaults (void)
+ECalComponent *
+cal_comp_event_new_with_defaults (ECalClient *client,
+ gboolean all_day,
+ gboolean use_default_reminder,
+ gint default_reminder_interval,
+ EDurationType default_reminder_units)
{
- CalComponent *comp;
- int interval;
- CalUnits units;
- CalComponentAlarm *alarm;
icalcomponent *icalcomp;
+ ECalComponent *comp;
+ ECalComponentAlarm *alarm;
icalproperty *icalprop;
- CalAlarmTrigger trigger;
+ ECalComponentAlarmTrigger trigger;
- comp = cal_component_new ();
+ if (!e_cal_client_get_default_object_sync (client, &icalcomp, NULL, NULL))
+ icalcomp = icalcomponent_new (ICAL_VEVENT_COMPONENT);
- cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT);
+ comp = e_cal_component_new ();
+ if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
- if (!calendar_config_get_use_default_reminder ())
- return comp;
+ e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_EVENT);
+ }
- interval = calendar_config_get_default_reminder_interval ();
- units = calendar_config_get_default_reminder_units ();
+ if (all_day || !use_default_reminder)
+ return comp;
- alarm = cal_component_alarm_new ();
+ alarm = e_cal_component_alarm_new ();
/* We don't set the description of the alarm; we'll copy it from the
* summary when it gets committed to the server. For that, we add a
* X-EVOLUTION-NEEDS-DESCRIPTION property to the alarm's component.
*/
- icalcomp = cal_component_alarm_get_icalcomponent (alarm);
+ icalcomp = e_cal_component_alarm_get_icalcomponent (alarm);
icalprop = icalproperty_new_x ("1");
icalproperty_set_x_name (icalprop, "X-EVOLUTION-NEEDS-DESCRIPTION");
icalcomponent_add_property (icalcomp, icalprop);
- cal_component_alarm_set_action (alarm, CAL_ALARM_DISPLAY);
+ e_cal_component_alarm_set_action (alarm, E_CAL_COMPONENT_ALARM_DISPLAY);
- trigger.type = CAL_ALARM_TRIGGER_RELATIVE_START;
+ trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START;
memset (&trigger.u.rel_duration, 0, sizeof (trigger.u.rel_duration));
trigger.u.rel_duration.is_neg = TRUE;
- switch (units) {
- case CAL_MINUTES:
- trigger.u.rel_duration.minutes = interval;
+ switch (default_reminder_units) {
+ case E_DURATION_MINUTES:
+ trigger.u.rel_duration.minutes = default_reminder_interval;
break;
- case CAL_HOURS:
- trigger.u.rel_duration.hours = interval;
+ case E_DURATION_HOURS:
+ trigger.u.rel_duration.hours = default_reminder_interval;
break;
- case CAL_DAYS:
- trigger.u.rel_duration.days = interval;
+ case E_DURATION_DAYS:
+ trigger.u.rel_duration.days = default_reminder_interval;
break;
default:
- g_assert_not_reached ();
+ g_warning ("wrong units %d\n", default_reminder_units);
+ }
+
+ e_cal_component_alarm_set_trigger (alarm, trigger);
+
+ e_cal_component_add_alarm (comp, alarm);
+ e_cal_component_alarm_free (alarm);
+
+ return comp;
+}
+
+ECalComponent *
+cal_comp_event_new_with_current_time (ECalClient *client,
+ gboolean all_day,
+ gboolean use_default_reminder,
+ gint default_reminder_interval,
+ EDurationType default_reminder_units)
+{
+ ECalComponent *comp;
+ struct icaltimetype itt;
+ ECalComponentDateTime dt;
+ icaltimezone *zone;
+
+ comp = cal_comp_event_new_with_defaults (
+ client, all_day, use_default_reminder,
+ default_reminder_interval, default_reminder_units);
+ g_return_val_if_fail (comp != NULL, NULL);
+
+ zone = e_cal_client_get_default_timezone (client);
+
+ if (all_day) {
+ itt = icaltime_from_timet_with_zone (time (NULL), 1, zone);
+
+ dt.value = &itt;
+ dt.tzid = icaltimezone_get_tzid (zone);
+
+ e_cal_component_set_dtstart (comp, &dt);
+ e_cal_component_set_dtend (comp, &dt);
+ } else {
+ itt = icaltime_current_time_with_zone (zone);
+ icaltime_adjust (&itt, 0, 1, -itt.minute, -itt.second);
+
+ dt.value = &itt;
+ dt.tzid = icaltimezone_get_tzid (zone);
+
+ e_cal_component_set_dtstart (comp, &dt);
+ icaltime_adjust (&itt, 0, 1, 0, 0);
+ e_cal_component_set_dtend (comp, &dt);
+ }
+
+ return comp;
+}
+
+ECalComponent *
+cal_comp_task_new_with_defaults (ECalClient *client)
+{
+ ECalComponent *comp;
+ icalcomponent *icalcomp;
+
+ if (!e_cal_client_get_default_object_sync (client, &icalcomp, NULL, NULL))
+ icalcomp = icalcomponent_new (ICAL_VTODO_COMPONENT);
+
+ comp = e_cal_component_new ();
+ if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
+
+ e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_TODO);
}
- cal_component_alarm_set_trigger (alarm, trigger);
+ return comp;
+}
+
+ECalComponent *
+cal_comp_memo_new_with_defaults (ECalClient *client)
+{
+ ECalComponent *comp;
+ icalcomponent *icalcomp;
+
+ if (!e_cal_client_get_default_object_sync (client, &icalcomp, NULL, NULL))
+ icalcomp = icalcomponent_new (ICAL_VJOURNAL_COMPONENT);
+
+ comp = e_cal_component_new ();
+ if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
- cal_component_add_alarm (comp, alarm);
- cal_component_alarm_free (alarm);
+ e_cal_component_set_new_vtype (comp, E_CAL_COMPONENT_JOURNAL);
+ }
return comp;
}
+
+void
+cal_comp_update_time_by_active_window (ECalComponent *comp,
+ EShell *shell)
+{
+ GtkWindow *window;
+
+ g_return_if_fail (comp != NULL);
+ g_return_if_fail (shell != NULL);
+
+ window = e_shell_get_active_window (shell);
+
+ if (E_IS_SHELL_WINDOW (window)) {
+ EShellWindow *shell_window;
+ const gchar *active_view;
+
+ shell_window = E_SHELL_WINDOW (window);
+ active_view = e_shell_window_get_active_view (shell_window);
+
+ if (g_strcmp0 (active_view, "calendar") == 0) {
+ EShellContent *shell_content;
+ EShellView *shell_view;
+ GnomeCalendar *gnome_cal;
+ time_t start = 0, end = 0;
+ icaltimezone *zone;
+ struct icaltimetype itt;
+ icalcomponent *icalcomp;
+ icalproperty *prop;
+
+ shell_view = e_shell_window_peek_shell_view (
+ shell_window, "calendar");
+ g_return_if_fail (shell_view != NULL);
+
+ gnome_cal = NULL;
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ g_object_get (shell_content, "calendar", &gnome_cal, NULL);
+ g_return_if_fail (gnome_cal != NULL);
+
+ gnome_calendar_get_current_time_range (gnome_cal, &start, &end);
+ g_return_if_fail (start != 0);
+
+ zone = e_cal_model_get_timezone (gnome_calendar_get_model (gnome_cal));
+ itt = icaltime_from_timet_with_zone (start, FALSE, zone);
+
+ icalcomp = e_cal_component_get_icalcomponent (comp);
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_DTSTART_PROPERTY);
+ if (prop) {
+ icalproperty_set_dtstart (prop, itt);
+ } else {
+ prop = icalproperty_new_dtstart (itt);
+ icalcomponent_add_property (icalcomp, prop);
+ }
+
+ e_cal_component_rescan (comp);
+ }
+ }
+}
+
+/**
+ * cal_comp_util_get_n_icons:
+ * @comp: A calendar component object.
+ * @pixbufs: List of pixbufs to use. Can be NULL.
+ *
+ * Get the number of icons owned by the component.
+ * Each member of pixmaps should be freed with g_object_unref
+ * and the list itself should be freed too.
+ *
+ * Returns: the number of icons owned by the component.
+ **/
+gint
+cal_comp_util_get_n_icons (ECalComponent *comp,
+ GSList **pixbufs)
+{
+ GSList *categories_list, *elem;
+ gint num_icons = 0;
+
+ g_return_val_if_fail (comp != NULL, 0);
+ g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), 0);
+
+ e_cal_component_get_categories_list (comp, &categories_list);
+ for (elem = categories_list; elem; elem = elem->next) {
+ const gchar *category;
+ GdkPixbuf *pixbuf = NULL;
+
+ category = elem->data;
+ if (e_categories_config_get_icon_for (category, &pixbuf)) {
+ if (!pixbuf)
+ continue;
+
+ num_icons++;
+
+ if (pixbufs) {
+ *pixbufs = g_slist_append (*pixbufs, pixbuf);
+ } else {
+ g_object_unref (pixbuf);
+ }
+ }
+ }
+ e_cal_component_free_categories_list (categories_list);
+
+ return num_icons;
+}
+
+/**
+ * cal_comp_selection_set_string_list
+ * @data: Selection data, where to put list of strings.
+ * @str_list: List of strings. (Each element is of type const gchar *.)
+ *
+ * Stores list of strings into selection target data. Use
+ * cal_comp_selection_get_string_list() to get this list from target data.
+ **/
+void
+cal_comp_selection_set_string_list (GtkSelectionData *data,
+ GSList *str_list)
+{
+ /* format is "str1\0str2\0...strN\0" */
+ GSList *p;
+ GByteArray *array;
+ GdkAtom target;
+
+ g_return_if_fail (data != NULL);
+
+ if (!str_list)
+ return;
+
+ array = g_byte_array_new ();
+ for (p = str_list; p; p = p->next) {
+ const guint8 *c = p->data;
+
+ if (c)
+ g_byte_array_append (array, c, strlen ((const gchar *) c) + 1);
+ }
+
+ target = gtk_selection_data_get_target (data);
+ gtk_selection_data_set (data, target, 8, array->data, array->len);
+ g_byte_array_free (array, TRUE);
+}
+
+/**
+ * cal_comp_selection_get_string_list
+ * @data: Selection data, where to put list of strings.
+ *
+ * Converts data from selection to list of strings. Data should be assigned
+ * to selection data with cal_comp_selection_set_string_list().
+ * Each string in newly created list should be freed by g_free().
+ * List itself should be freed by g_slist_free().
+ *
+ * Returns: Newly allocated #GSList of strings.
+ **/
+GSList *
+cal_comp_selection_get_string_list (GtkSelectionData *selection_data)
+{
+ /* format is "str1\0str2\0...strN\0" */
+ gchar *inptr, *inend;
+ GSList *list;
+ const guchar *data;
+ gint length;
+
+ g_return_val_if_fail (selection_data != NULL, NULL);
+
+ data = gtk_selection_data_get_data (selection_data);
+ length = gtk_selection_data_get_length (selection_data);
+
+ list = NULL;
+ inptr = (gchar *) data;
+ inend = (gchar *) (data + length);
+
+ while (inptr < inend) {
+ gchar *start = inptr;
+
+ while (inptr < inend && *inptr)
+ inptr++;
+
+ list = g_slist_prepend (list, g_strndup (start, inptr - start));
+
+ inptr++;
+ }
+
+ return list;
+}
+
+static void
+datetime_to_zone (ECalClient *client,
+ ECalComponentDateTime *date,
+ const gchar *tzid)
+{
+ icaltimezone *from, *to;
+
+ g_return_if_fail (date != NULL);
+
+ if (date->tzid == NULL || tzid == NULL ||
+ date->tzid == tzid || g_str_equal (date->tzid, tzid))
+ return;
+
+ from = icaltimezone_get_builtin_timezone_from_tzid (date->tzid);
+ if (!from) {
+ GError *error = NULL;
+
+ e_cal_client_get_timezone_sync (
+ client, date->tzid, &from, NULL, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Could not get timezone '%s' from server: %s",
+ G_STRFUNC, date->tzid ? date->tzid : "",
+ error->message);
+ g_error_free (error);
+ }
+ }
+
+ to = icaltimezone_get_builtin_timezone_from_tzid (tzid);
+ if (!to) {
+ /* do not check failure here, maybe the zone is not available there */
+ e_cal_client_get_timezone_sync (client, tzid, &to, NULL, NULL);
+ }
+
+ icaltimezone_convert_time (date->value, from, to);
+ date->tzid = tzid;
+}
+
+/**
+ * cal_comp_set_dtstart_with_oldzone:
+ * @client: ECalClient structure, to retrieve timezone from, when required.
+ * @comp: Component, where make the change.
+ * @pdate: Value, to change to.
+ *
+ * Changes 'dtstart' of the component, but converts time to the old timezone.
+ **/
+void
+cal_comp_set_dtstart_with_oldzone (ECalClient *client,
+ ECalComponent *comp,
+ const ECalComponentDateTime *pdate)
+{
+ ECalComponentDateTime olddate, date;
+
+ g_return_if_fail (comp != NULL);
+ g_return_if_fail (pdate != NULL);
+
+ e_cal_component_get_dtstart (comp, &olddate);
+
+ date = *pdate;
+
+ datetime_to_zone (client, &date, olddate.tzid);
+ e_cal_component_set_dtstart (comp, &date);
+
+ e_cal_component_free_datetime (&olddate);
+}
+
+/**
+ * cal_comp_set_dtend_with_oldzone:
+ * @client: ECalClient structure, to retrieve timezone from, when required.
+ * @comp: Component, where make the change.
+ * @pdate: Value, to change to.
+ *
+ * Changes 'dtend' of the component, but converts time to the old timezone.
+ **/
+void
+cal_comp_set_dtend_with_oldzone (ECalClient *client,
+ ECalComponent *comp,
+ const ECalComponentDateTime *pdate)
+{
+ ECalComponentDateTime olddate, date;
+
+ g_return_if_fail (comp != NULL);
+ g_return_if_fail (pdate != NULL);
+
+ e_cal_component_get_dtend (comp, &olddate);
+
+ date = *pdate;
+
+ datetime_to_zone (client, &date, olddate.tzid);
+ e_cal_component_set_dtend (comp, &date);
+
+ e_cal_component_free_datetime (&olddate);
+}
+
+void
+comp_util_sanitize_recurrence_master (ECalComponent *comp,
+ ECalClient *client)
+{
+ ECalComponent *master = NULL;
+ icalcomponent *icalcomp = NULL;
+ ECalComponentRange rid;
+ ECalComponentDateTime sdt;
+ const gchar *uid;
+ GError *error = NULL;
+
+ /* Get the master component */
+ e_cal_component_get_uid (comp, &uid);
+
+ e_cal_client_get_object_sync (
+ client, uid, NULL, &icalcomp, NULL, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "Unable to get the master component: %s",
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ master = e_cal_component_new ();
+ if (!e_cal_component_set_icalcomponent (master, icalcomp)) {
+ icalcomponent_free (icalcomp);
+ g_object_unref (master);
+ g_return_if_reached ();
+ return;
+ }
+
+ /* Compare recur id and start date */
+ e_cal_component_get_recurid (comp, &rid);
+ e_cal_component_get_dtstart (comp, &sdt);
+
+ if (rid.datetime.value && sdt.value &&
+ icaltime_compare_date_only (
+ *rid.datetime.value, *sdt.value) == 0) {
+ ECalComponentDateTime msdt, medt, edt;
+ gint *sequence;
+
+ e_cal_component_get_dtstart (master, &msdt);
+ e_cal_component_get_dtend (master, &medt);
+
+ e_cal_component_get_dtend (comp, &edt);
+
+ g_return_if_fail (msdt.value != NULL);
+ g_return_if_fail (medt.value != NULL);
+ g_return_if_fail (edt.value != NULL);
+
+ sdt.value->year = msdt.value->year;
+ sdt.value->month = msdt.value->month;
+ sdt.value->day = msdt.value->day;
+
+ edt.value->year = medt.value->year;
+ edt.value->month = medt.value->month;
+ edt.value->day = medt.value->day;
+
+ e_cal_component_set_dtstart (comp, &sdt);
+ e_cal_component_set_dtend (comp, &edt);
+
+ e_cal_component_get_sequence (master, &sequence);
+ e_cal_component_set_sequence (comp, sequence);
+
+ e_cal_component_free_datetime (&msdt);
+ e_cal_component_free_datetime (&medt);
+ e_cal_component_free_datetime (&edt);
+ }
+
+ e_cal_component_free_datetime (&sdt);
+ e_cal_component_free_range (&rid);
+ e_cal_component_set_recurid (comp, NULL);
+
+ g_object_unref (master);
+}
+
+gchar *
+icalcomp_suggest_filename (icalcomponent *icalcomp,
+ const gchar *default_name)
+{
+ icalproperty *prop;
+ const gchar *summary = NULL;
+
+ if (!icalcomp)
+ return g_strconcat (default_name, ".ics", NULL);
+
+ prop = icalcomponent_get_first_property (icalcomp, ICAL_SUMMARY_PROPERTY);
+ if (prop)
+ summary = icalproperty_get_summary (prop);
+
+ if (!summary || !*summary)
+ summary = default_name;
+
+ return g_strconcat (summary, ".ics", NULL);
+}
diff --git a/calendar/gui/comp-util.h b/calendar/gui/comp-util.h
index de5e9d5336..dcf5844c79 100644
--- a/calendar/gui/comp-util.h
+++ b/calendar/gui/comp-util.h
@@ -1,44 +1,78 @@
-/* Evolution calendar - Utilities for manipulating CalComponent objects
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@ximian.com>
+/*
+ * Evolution calendar - Utilities for manipulating ECalComponent objects
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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 COMP_UTIL_H
#define COMP_UTIL_H
-#include <gtk/gtkwidget.h>
-#include <cal-util/cal-component.h>
-#include <cal-client/cal-client.h>
+#include <gtk/gtk.h>
+#include <libecal/libecal.h>
+
+#include <e-util/e-util.h>
-void cal_comp_util_add_exdate (CalComponent *comp, time_t t, icaltimezone *zone);
+struct _EShell;
+void cal_comp_util_add_exdate (ECalComponent *comp, time_t t, icaltimezone *zone);
/* Returns TRUE if the component uses the given timezone for both DTSTART
- and DTEND, or if the UTC offsets of the start and end times are the same
- as in the given zone. */
-gboolean cal_comp_util_compare_event_timezones (CalComponent *comp,
- CalClient *client,
+ * and DTEND, or if the UTC offsets of the start and end times are the same
+ * as in the given zone. */
+gboolean cal_comp_util_compare_event_timezones (ECalComponent *comp,
+ ECalClient *client,
icaltimezone *zone);
-gboolean cal_comp_is_on_server (CalComponent *comp,
- CalClient *client);
+/* Returns the number of icons owned by the ECalComponent */
+gint cal_comp_util_get_n_icons (ECalComponent *comp, GSList **pixbufs);
+
+gboolean cal_comp_is_on_server (ECalComponent *comp,
+ ECalClient *client);
+gboolean is_icalcomp_on_the_server (icalcomponent *icalcomp, ECalClient *client);
+
+ECalComponent * cal_comp_event_new_with_defaults
+ (ECalClient *client,
+ gboolean all_day,
+ gboolean use_default_reminder,
+ gint default_reminder_interval,
+ EDurationType default_reminder_units);
+ECalComponent * cal_comp_event_new_with_current_time
+ (ECalClient *client,
+ gboolean all_day,
+ gboolean use_default_reminder,
+ gint default_reminder_interval,
+ EDurationType default_reminder_units);
+ECalComponent *cal_comp_task_new_with_defaults (ECalClient *client);
+ECalComponent *cal_comp_memo_new_with_defaults (ECalClient *client);
+
+void cal_comp_update_time_by_active_window (ECalComponent *comp, struct _EShell *shell);
+
+void cal_comp_selection_set_string_list (GtkSelectionData *data, GSList *str_list);
+GSList *cal_comp_selection_get_string_list (GtkSelectionData *data);
+
+void cal_comp_set_dtstart_with_oldzone (ECalClient *client, ECalComponent *comp, const ECalComponentDateTime *pdate);
+void cal_comp_set_dtend_with_oldzone (ECalClient *client, ECalComponent *comp, const ECalComponentDateTime *pdate);
+
+void comp_util_sanitize_recurrence_master (ECalComponent *comp, ECalClient *client);
-CalComponent *cal_comp_event_new_with_defaults (void);
+gchar *icalcomp_suggest_filename (icalcomponent *icalcomp, const gchar *default_name);
#endif
diff --git a/calendar/gui/component-factory.c b/calendar/gui/component-factory.c
deleted file mode 100644
index 82dfc8b575..0000000000
--- a/calendar/gui/component-factory.c
+++ /dev/null
@@ -1,773 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* component-factory.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- * 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.
- *
- * Author: Ettore Perazzoli <ettore@ximian.com>
- */
-
-#include <config.h>
-
-#include <errno.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 "component-factory.h"
-#include "tasks-control-factory.h"
-#include "config-control-factory.h"
-#include "control-factory.h"
-#include "calendar-config.h"
-#include "tasks-control.h"
-#include "tasks-migrate.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;
-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 }
-};
-
-
-
-static inline gboolean
-type_is_calendar (const char *type)
-{
- return !strcmp (type, FOLDER_CALENDAR) ||
- !strcmp (type, FOLDER_PUBLIC_CALENDAR);
-}
-
-static inline gboolean
-type_is_tasks (const char *type)
-{
- return !strcmp (type, FOLDER_TASKS) ||
- !strcmp (type, FOLDER_PUBLIC_TASKS);
-}
-
-/* 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;
-
- 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, "folder_uri", physical_uri, NULL);
- if (type_is_calendar (type) && *view_info)
- bonobo_control_set_property (control, "view", view_info, NULL);
-
- *control_return = control;
-
- return EVOLUTION_SHELL_COMPONENT_OK;
-}
-
-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;
-
- 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;
- }
-
- 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);
- }
-
- CORBA_exception_free (&ev);
-}
-
-/* Asks the alarm daemon to stop monitoring the specified URI */
-static void
-stop_alarms (GnomeVFSURI *uri)
-{
- char *str_uri;
- CORBA_Environment ev;
- GNOME_Evolution_Calendar_AlarmNotify an;
-
- /* Activate the alarm notification service */
-
- CORBA_exception_init (&ev);
- an = oaf_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");
- }
-
- 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);
-}
-
-static void
-remove_folder (EvolutionShellComponent *shell_component,
- const char *physical_uri,
- const char *type,
- const GNOME_Evolution_ShellComponentListener listener,
- void *closure)
-{
- 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");
-
- CORBA_exception_free (&ev);
- return;
- }
-
- /* 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);
- 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 ();
- 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);
-}
-
-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;
- }
-
- /* 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;
- }
-
- 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 (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);
- }
-
- 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;
-}
-
-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)
-{
- 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);
-
- gnome_vfs_uri_unref (src_uri);
- gnome_vfs_uri_unref (dest_uri);
-
- CORBA_exception_free (&ev);
-}
-
-static gboolean
-request_quit (EvolutionShellComponent *shell_component, void *closure)
-{
- return e_comp_editor_registry_close_all (comp_editor_registry);
-}
-
-static GList *shells = NULL;
-
-static void
-owner_set_cb (EvolutionShellComponent *shell_component,
- EvolutionShellClient *shell_client,
- const char *evolution_homedir,
- gpointer user_data)
-{
- static gboolean migrated = FALSE;
-
- evolution_dir = g_strdup (evolution_homedir);
-
- if (!migrated) {
- tasks_migrate ();
- migrated = TRUE;
- }
-
- shells = g_list_append (shells, shell_component);
-
- global_shell_client = shell_client;
-
- config_control_factory_register (bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)));
-}
-
-static void
-owner_unset_cb (EvolutionShellComponent *shell_component,
- gpointer user_data)
-{
- shells = g_list_remove (shells, shell_component);
-
- if (g_list_length (shells) == 0)
- gtk_main_quit ();
-}
-
-/* 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 g_concat_dir_and_file (uri, "calendar.ics");
- else if (vtype == CAL_COMPONENT_TODO)
- return g_concat_dir_and_file (uri, "tasks.ics");
- 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 ();
- }
-
- return NULL;
-}
-
-/* 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;
- }
-
- real_uri = get_data_uri (uri, vtype);
-
- /* Get the factory */
-
- CORBA_exception_init (&ev);
- factory = oaf_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_CompEditorFactory",
- 0, NULL, &ev);
-
- 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);
-
- /* Create the item */
-
- CORBA_exception_init (&ev);
- GNOME_Evolution_Calendar_CompEditorFactory_editNew (factory, real_uri, type, &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("create_component(): Exception while creating the component");
-
- CORBA_exception_free (&ev);
- g_free (real_uri);
-
- /* Get rid of the factory */
-
- 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");
-
- CORBA_exception_free (&ev);
-}
-
-/* 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)
-{
- 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
- create_component (NULL,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_EVENT);
- } 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
- create_component (NULL,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_ALLDAY_EVENT);
- } 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
- create_component (NULL,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_MEETING);
- } 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
- create_component (NULL,
- GNOME_Evolution_Calendar_CompEditorFactory_EDITOR_MODE_TODO);
- } 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_ICONSDIR, icon_name);
- icon = gdk_pixbuf_new_from_file (icon_path);
- }
-
- 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);
-}
-
-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));
-
- gtk_signal_connect (GTK_OBJECT (shell_component), "owner_set",
- GTK_SIGNAL_FUNC (owner_set_cb), NULL);
- gtk_signal_connect (GTK_OBJECT (shell_component), "owner_unset",
- GTK_SIGNAL_FUNC (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");
-
- add_creatable_item (shell_component, CREATE_MEETING_ID,
- _("New meeting"), _("_Meeting"),
- _("Create a new meeting request"),
- FOLDER_CALENDAR, 's', "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");
-
- 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");
-
- gtk_signal_connect (GTK_OBJECT (shell_component), "user_create_new_item",
- GTK_SIGNAL_FUNC (sc_user_create_new_item_cb), NULL);
-
- return BONOBO_OBJECT (shell_component);
-}
-
-
-void
-component_factory_init (void)
-{
- BonoboObject *object;
- int result;
-
- object = create_object ();
-
- result = oaf_active_server_register (COMPONENT_ID, bonobo_object_corba_objref (object));
-
- if (result == OAF_REG_ERROR)
- g_error ("Cannot initialize Evolution's calendar component.");
-}
diff --git a/calendar/gui/component-factory.h b/calendar/gui/component-factory.h
deleted file mode 100644
index 576255cb6d..0000000000
--- a/calendar/gui/component-factory.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* component-factory.h
- *
- * Copyright (C) 2000 Ximian, Inc.
- * 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.
- *
- * Author: Ettore Perazzoli <ettore@ximian.com>
- */
-
-#ifndef _COMPONENT_FACTORY_H_
-#define _COMPONENT_FACTORY_H_
-
-extern char *evolution_dir;
-
-void component_factory_init (void);
-
-#endif /* _COMPONENT_FACTORY_H_ */
diff --git a/calendar/gui/config-control-factory.c b/calendar/gui/config-control-factory.c
deleted file mode 100644
index f2a9b48383..0000000000
--- a/calendar/gui/config-control-factory.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* config-control-factory.c
- *
- * Copyright (C) 2002 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: Ettore Perazzoli
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "config-control-factory.h"
-
-#include "dialogs/cal-prefs-dialog.h"
-
-#include <bonobo/bonobo-generic-factory.h>
-
-
-#define CONFIG_CONTROL_FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_ConfigControlFactory"
-static BonoboGenericFactory *generic_factory = NULL;
-
-
-static BonoboObject *
-factory_fn (BonoboGenericFactory *generic_factory,
- void *data)
-{
- EvolutionConfigControl *config_control;
-
- config_control = cal_prefs_dialog_new ();
-
- return BONOBO_OBJECT (config_control);
-}
-
-gboolean
-config_control_factory_register (GNOME_Evolution_Shell shell)
-{
- generic_factory = bonobo_generic_factory_new (CONFIG_CONTROL_FACTORY_ID,
- factory_fn, shell);
-
- if (generic_factory == NULL) {
- g_warning ("Cannot register %s", CONFIG_CONTROL_FACTORY_ID);
- return FALSE;
- }
-
- return TRUE;
-}
diff --git a/calendar/gui/config-control-factory.h b/calendar/gui/config-control-factory.h
deleted file mode 100644
index b0ff927fa9..0000000000
--- a/calendar/gui/config-control-factory.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* config-control-factory.h
- *
- * Copyright (C) 2002 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: Ettore Perazzoli
- */
-
-#ifndef CONFIG_CONTROL_FACTORY_H
-#define CONFIG_CONTROL_FACTORY_H
-
-#include "Evolution.h"
-
-gboolean config_control_factory_register (GNOME_Evolution_Shell shell);
-
-#endif
diff --git a/calendar/gui/control-factory.c b/calendar/gui/control-factory.c
deleted file mode 100644
index a17790f197..0000000000
--- a/calendar/gui/control-factory.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* control-factory.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- * 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.
- *
- * Author: Ettore Perazzoli <ettore@ximian.com>
- */
-
-#include <config.h>
-#include <glade/glade.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-persist-file.h>
-#include <bonobo/bonobo-context.h>
-#include <glade/glade.h>
-
-#include <liboaf/liboaf.h>
-
-#include <cal-util/timeutil.h>
-#include <gui/gnome-cal.h>
-#include <gui/calendar-commands.h>
-
-#include "control-factory.h"
-
-#define PROPERTY_CALENDAR_URI "folder_uri"
-#define PROPERTY_CALENDAR_URI_IDX 1
-
-#define PROPERTY_CALENDAR_VIEW "view"
-#define PROPERTY_CALENDAR_VIEW_IDX 2
-
-#define CONTROL_FACTORY_ID "OAFIID:GNOME_Evolution_Calendar_ControlFactory"
-
-
-CORBA_Environment ev;
-CORBA_ORB orb;
-
-
-static void
-control_activate_cb (BonoboControl *control, gboolean activate, gpointer data)
-{
- GnomeCalendar *gcal;
-
- gcal = GNOME_CALENDAR (data);
-
- if (activate)
- calendar_control_activate (control, gcal);
- else
- calendar_control_deactivate (control, gcal);
-}
-
-static void
-get_prop (BonoboPropertyBag *bag,
- BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
-{
- GnomeCalendar *gcal = user_data;
- const char *uri;
-
- switch (arg_id) {
-
- case PROPERTY_CALENDAR_URI_IDX:
- uri = cal_client_get_uri (gnome_calendar_get_cal_client (gcal));
- BONOBO_ARG_SET_STRING (arg, uri);
- break;
-
- case PROPERTY_CALENDAR_VIEW_IDX:
- switch (gnome_calendar_get_view (gcal)) {
- case GNOME_CAL_DAY_VIEW:
- BONOBO_ARG_SET_STRING (arg, "day");
- break;
- case GNOME_CAL_WEEK_VIEW:
- BONOBO_ARG_SET_STRING (arg, "week");
- break;
- case GNOME_CAL_WORK_WEEK_VIEW:
- BONOBO_ARG_SET_STRING (arg, "workweek");
- break;
- case GNOME_CAL_MONTH_VIEW:
- BONOBO_ARG_SET_STRING (arg, "month");
- break;
- }
- break;
-
- default:
- g_warning ("Unhandled arg %d\n", arg_id);
- }
-}
-
-
-static void
-set_prop (BonoboPropertyBag *bag,
- const BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
-{
- GnomeCalendar *gcal = user_data;
- char *string;
- GnomeCalendarViewType view;
-
- switch (arg_id) {
- case PROPERTY_CALENDAR_URI_IDX:
- string = BONOBO_ARG_GET_STRING (arg);
- if (!gnome_calendar_open (gcal, string)) {
- char *msg;
-
- msg = g_strdup_printf (_("Could not open the folder in '%s'"), string);
- gnome_error_dialog_parented (
- msg,
- GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))));
- g_free (msg);
- }
- break;
-
- case PROPERTY_CALENDAR_VIEW_IDX:
- string = BONOBO_ARG_GET_STRING (arg);
- if (!g_strcasecmp (string, "week"))
- view = GNOME_CAL_WEEK_VIEW;
- else if (!g_strcasecmp (string, "workweek"))
- view = GNOME_CAL_WORK_WEEK_VIEW;
- else if (!g_strcasecmp (string, "month"))
- view = GNOME_CAL_MONTH_VIEW;
- else
- view = GNOME_CAL_DAY_VIEW;
-
- /* This doesn't actually work, because the GalView
- * comes along and resets the view. FIXME.
- */
- gnome_calendar_set_view (gcal, view, FALSE, TRUE);
- break;
-
- default:
- g_warning ("Unhandled arg %d\n", arg_id);
- break;
- }
-}
-
-
-static void
-calendar_properties_init (GnomeCalendar *gcal, BonoboControl *control)
-{
- BonoboPropertyBag *pbag;
-
- pbag = bonobo_property_bag_new (get_prop, set_prop, gcal);
-
- bonobo_property_bag_add (pbag,
- PROPERTY_CALENDAR_URI,
- PROPERTY_CALENDAR_URI_IDX,
- BONOBO_ARG_STRING,
- NULL,
- _("The URI that the calendar will display"),
- 0);
- bonobo_property_bag_add (pbag,
- PROPERTY_CALENDAR_VIEW,
- PROPERTY_CALENDAR_VIEW_IDX,
- BONOBO_ARG_STRING,
- NULL,
- _("The type of view to show"),
- 0);
-
- bonobo_control_set_properties (control, pbag);
- bonobo_object_unref (BONOBO_OBJECT (pbag));
-}
-
-/* Callback factory function for calendar controls */
-static BonoboObject *
-control_factory_fn (BonoboGenericFactory *Factory, void *data)
-{
- BonoboControl *control;
-
- control = control_factory_new_control ();
-
- if (control)
- return BONOBO_OBJECT (control);
- else
- return NULL;
-}
-
-
-void
-control_factory_init (void)
-{
- static BonoboGenericFactory *factory = NULL;
-
- if (factory != NULL)
- return;
-
- factory = bonobo_generic_factory_new (CONTROL_FACTORY_ID, control_factory_fn, NULL);
- bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory));
-
- if (factory == NULL)
- g_error ("I could not register a Calendar control factory.");
-}
-
-#if 0
-static int
-load_calendar (BonoboPersistFile *pf, const CORBA_char *filename, CORBA_Environment *ev, void *closure)
-{
- GnomeCalendar *gcal = closure;
-
- return gnome_calendar_open (gcal, filename);
-}
-
-static int
-save_calendar (BonoboPersistFile *pf, const CORBA_char *filename,
- CORBA_Environment *ev,
- void *closure)
-{
- /* Do not know how to save stuff yet */
- return -1;
-}
-
-static void
-calendar_persist_init (GnomeCalendar *gcal, BonoboControl *control)
-{
- BonoboPersistFile *f;
-
- f = bonobo_persist_file_new (load_calendar, save_calendar, gcal);
- bonobo_object_add_interface (BONOBO_OBJECT (control), BONOBO_OBJECT (f));
-}
-#endif
-
-BonoboControl *
-control_factory_new_control (void)
-{
- BonoboControl *control;
- GnomeCalendar *gcal;
-
- gcal = new_calendar ();
- if (!gcal)
- return NULL;
-
- gtk_widget_show (GTK_WIDGET (gcal));
-
- control = bonobo_control_new (GTK_WIDGET (gcal));
- if (!control) {
- g_message ("control_factory_fn(): could not create the control!");
- return NULL;
- }
- gtk_object_set_data (GTK_OBJECT (gcal), "control", control);
-
- calendar_properties_init (gcal, control);
-#if 0
- calendar_persist_init (gcal, control);
-#endif
-
- gtk_signal_connect (GTK_OBJECT (control), "activate",
- GTK_SIGNAL_FUNC (control_activate_cb), gcal);
-
- return control;
-}
diff --git a/calendar/gui/control-factory.h b/calendar/gui/control-factory.h
deleted file mode 100644
index 322b5a4a4e..0000000000
--- a/calendar/gui/control-factory.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* control-factory.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- * 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.
- *
- * Author: Ettore Perazzoli <ettore@ximian.com>
- */
-
-#ifndef _CONTROL_FACTORY_H_
-#define _CONTROL_FACTORY_H_
-
-void control_factory_init (void);
-BonoboControl *control_factory_new_control (void);
-
-#endif /* _CONTROL_FACTORY_H_ */
diff --git a/calendar/gui/dialogs/.cvsignore b/calendar/gui/dialogs/.cvsignore
deleted file mode 100644
index 64968755b7..0000000000
--- a/calendar/gui/dialogs/.cvsignore
+++ /dev/null
@@ -1,8 +0,0 @@
-.deps
-.pure
-Makefile
-Makefile.in
-Evolution-Addressbook-SelectNames.h
-Evolution-Addressbook-SelectNames-stubs.c
-Evolution-Addressbook-SelectNames-skels.c
-Evolution-Addressbook-SelectNames-common.c
diff --git a/calendar/gui/dialogs/Makefile.am b/calendar/gui/dialogs/Makefile.am
index 5108fc8b2c..42e6730103 100644
--- a/calendar/gui/dialogs/Makefile.am
+++ b/calendar/gui/dialogs/Makefile.am
@@ -1,99 +1,118 @@
-IDLS = $(top_srcdir)/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl
+noinst_LTLIBRARIES = libcal-dialogs.la
-IDL_GENERATED = \
- Evolution-Addressbook-SelectNames.h \
- Evolution-Addressbook-SelectNames-common.c \
- Evolution-Addressbook-SelectNames-skels.c \
- Evolution-Addressbook-SelectNames-stubs.c
-
-$(IDL_GENERATED): $(IDLS)
- $(ORBIT_IDL) -I $(srcdir) -I $(datadir)/idl `$(GNOME_CONFIG) --cflags idl` \
- $(top_srcdir)/addressbook/gui/component/select-names/Evolution-Addressbook-SelectNames.idl
-
-BUILT_SOURCES = $(IDL_GENERATED)
-
-INCLUDES = \
+libcal_dialogs_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
-DG_LOG_DOMAIN=\"calendar-gui\" \
-I$(top_srcdir) \
+ -I$(top_builddir) \
-I$(top_srcdir)/calendar \
- -I$(top_srcdir)/calendar/cal-client \
- -I$(top_builddir)/calendar/cal-client \
- -I$(top_srcdir)/libical/src/libical \
- -I$(top_builddir)/libical/src/libical \
-I$(top_builddir)/shell \
-I$(top_srcdir)/shell \
- -I$(top_srcdir)/addressbook/backend \
- -I$(top_builddir)/addressbook/backend \
- -I$(includedir) \
- -DEVOLUTION_DATADIR=\""$(datadir)"\" \
- -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
- -DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \
- -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
- -DGNOMELOCALEDIR=\""$(localedir)"\" \
- $(EVOLUTION_CALENDAR_CFLAGS)
+ -DEVOLUTION_UIDIR=\""$(uidir)"\" \
+ -DEVOLUTION_ICONDIR=\""$(icondir)"\" \
+ -DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \
+ -DPREFIX=\""$(prefix)"\" \
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS)
-noinst_LIBRARIES = libcal-dialogs.a
+ecalendarincludedir = $(privincludedir)/calendar/gui/dialogs
-libcal_dialogs_a_SOURCES = \
- $(IDL_GENERATED) \
- alarm-options.c \
- alarm-options.h \
- alarm-page.c \
- alarm-page.h \
- cal-prefs-dialog.c \
- cal-prefs-dialog.h \
- cancel-comp.c \
- cancel-comp.h \
- changed-comp.c \
- changed-comp.h \
- comp-editor.c \
- comp-editor.h \
- comp-editor-page.c \
- comp-editor-page.h \
- comp-editor-util.c \
- comp-editor-util.h \
- delete-comp.c \
- delete-comp.h \
- e-delegate-dialog.c \
- e-delegate-dialog.h \
- event-editor.c \
- event-editor.h \
- event-page.c \
- event-page.h \
- meeting-page.c \
- meeting-page.h \
- recurrence-page.c \
- recurrence-page.h \
- save-comp.c \
- save-comp.h \
- schedule-page.c \
- schedule-page.h \
- send-comp.c \
- send-comp.h \
- task-editor.c \
- task-editor.h \
- task-details-page.c \
- task-details-page.h \
- task-page.c \
+ecalendarinclude_HEADERS = \
+ comp-editor-page.h \
+ comp-editor.h \
+ alarm-dialog.h \
+ alarm-list-dialog.h \
+ cancel-comp.h \
+ changed-comp.h \
+ comp-editor-util.h \
+ copy-source-dialog.h \
+ delete-comp.h \
+ delete-error.h \
+ e-delegate-dialog.h \
+ e-send-options-utils.h \
+ event-editor.h \
+ event-page.h \
+ goto-dialog.h \
+ memo-editor.h \
+ memo-page.h \
+ recurrence-page.h \
+ recur-comp.h \
+ save-comp.h \
+ schedule-page.h \
+ select-source-dialog.h \
+ send-comp.h \
+ task-editor.h \
task-page.h
-iconsdir = $(datadir)/images/evolution
+libcal_dialogs_la_LIBADD = \
+ $(top_builddir)/addressbook/util/libeabutil.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_LIBS)
-gladedir = $(datadir)/evolution/glade
-glade_DATA = \
- alarm-options.glade \
- alarm-page.glade \
- cal-prefs-dialog.glade \
- e-delegate-dialog.glade \
- event-page.glade \
- meeting-page.glade \
- recurrence-page.glade \
- schedule-page.glade \
- task-details-page.glade \
- task-page.glade
+libcal_dialogs_la_SOURCES = \
+ alarm-dialog.c \
+ alarm-dialog.h \
+ alarm-list-dialog.c \
+ alarm-list-dialog.h \
+ cancel-comp.c \
+ cancel-comp.h \
+ changed-comp.c \
+ changed-comp.h \
+ comp-editor.c \
+ comp-editor.h \
+ comp-editor-page.c \
+ comp-editor-page.h \
+ comp-editor-util.c \
+ comp-editor-util.h \
+ copy-source-dialog.c \
+ copy-source-dialog.h \
+ delete-comp.c \
+ delete-comp.h \
+ delete-error.c \
+ delete-error.h \
+ e-delegate-dialog.c \
+ e-delegate-dialog.h \
+ e-send-options-utils.c \
+ e-send-options-utils.h \
+ event-editor.c \
+ event-editor.h \
+ event-page.c \
+ event-page.h \
+ goto-dialog.c \
+ goto-dialog.h \
+ memo-editor.c \
+ memo-editor.h \
+ memo-page.c \
+ memo-page.h \
+ recurrence-page.c \
+ recurrence-page.h \
+ recur-comp.c \
+ recur-comp.h \
+ save-comp.c \
+ save-comp.h \
+ schedule-page.c \
+ schedule-page.h \
+ select-source-dialog.c \
+ select-source-dialog.h \
+ send-comp.c \
+ send-comp.h \
+ task-editor.c \
+ task-editor.h \
+ task-page.c \
+ task-page.h
-etspecdir = $(datadir)/evolution/etspec/
-etspec_DATA = meeting-page.etspec
+ui_DATA = \
+ alarm-dialog.ui \
+ alarm-list-dialog.ui \
+ e-delegate-dialog.ui \
+ event-page.ui \
+ goto-dialog.ui \
+ memo-page.ui \
+ recurrence-page.ui \
+ schedule-page.ui \
+ task-page.ui
CLEANFILES = $(BUILT_SOURCES)
@@ -101,5 +120,6 @@ dist-hook:
cd $(distdir); rm -f $(BUILT_SOURCES)
EXTRA_DIST = \
- $(glade_DATA) \
- $(etspec_DATA)
+ $(ui_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/calendar/gui/dialogs/alarm-dialog.c b/calendar/gui/dialogs/alarm-dialog.c
new file mode 100644
index 0000000000..0f96d2091e
--- /dev/null
+++ b/calendar/gui/dialogs/alarm-dialog.c
@@ -0,0 +1,1344 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ * Miguel de Icaza <miguel@ximian.com>
+ * Seth Alves <alves@hungry.com>
+ * JP Rosevear <jpr@ximian.com>
+ * Hans Petter Jansson <hpj@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <libebook/libebook.h>
+
+#include <libical/icalattach.h>
+
+#include "../calendar-config.h"
+#include "comp-editor-util.h"
+#include "alarm-dialog.h"
+
+typedef struct {
+ GtkBuilder *builder;
+
+ /* The alarm */
+ ECalComponentAlarm *alarm;
+
+ /* The client */
+ ECalClient *cal_client;
+
+ EClientCache *client_cache;
+
+ /* Toplevel */
+ GtkWidget *toplevel;
+
+ GtkWidget *action_combo;
+ GtkWidget *interval_value;
+ GtkWidget *value_units_combo;
+ GtkWidget *relative_combo;
+ GtkWidget *time_combo;
+
+ /* Alarm repeat widgets */
+ GtkWidget *repeat_toggle;
+ GtkWidget *repeat_group;
+ GtkWidget *repeat_quantity;
+ GtkWidget *repeat_value;
+ GtkWidget *repeat_unit_combo;
+
+ GtkWidget *option_notebook;
+
+ /* Display alarm widgets */
+ GtkWidget *dalarm_group;
+ GtkWidget *dalarm_message;
+ GtkWidget *dalarm_description;
+
+ /* Audio alarm widgets */
+ GtkWidget *aalarm_group;
+ GtkWidget *aalarm_sound;
+ GtkWidget *aalarm_file_chooser;
+
+ /* Mail alarm widgets */
+ const gchar *email;
+ GtkWidget *malarm_group;
+ GtkWidget *malarm_address_group;
+ GtkWidget *malarm_addresses;
+ GtkWidget *malarm_addressbook;
+ GtkWidget *malarm_message;
+ GtkWidget *malarm_description;
+
+ /* Procedure alarm widgets */
+ GtkWidget *palarm_group;
+ GtkWidget *palarm_program;
+ GtkWidget *palarm_args;
+
+ /* Addressbook name selector */
+ ENameSelector *name_selector;
+} Dialog;
+
+static const gchar *section_name = "Send To";
+
+/* "relative" types */
+enum {
+ BEFORE,
+ AFTER
+};
+
+/* Time units */
+enum {
+ MINUTES,
+ HOURS,
+ DAYS
+};
+
+/* Combo box maps */
+static const gint action_map[] = {
+ E_CAL_COMPONENT_ALARM_DISPLAY,
+ E_CAL_COMPONENT_ALARM_AUDIO,
+ E_CAL_COMPONENT_ALARM_PROCEDURE,
+ E_CAL_COMPONENT_ALARM_EMAIL,
+ -1
+};
+
+static const gchar *action_map_cap[] = {
+ CAL_STATIC_CAPABILITY_NO_DISPLAY_ALARMS,
+ CAL_STATIC_CAPABILITY_NO_AUDIO_ALARMS,
+ CAL_STATIC_CAPABILITY_NO_PROCEDURE_ALARMS,
+ CAL_STATIC_CAPABILITY_NO_EMAIL_ALARMS
+};
+
+static const gint value_map[] = {
+ MINUTES,
+ HOURS,
+ DAYS,
+ -1
+};
+
+static const gint relative_map[] = {
+ BEFORE,
+ AFTER,
+ -1
+};
+
+static const gint time_map[] = {
+ E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START,
+ E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_END,
+ -1
+};
+
+enum duration_units {
+ DUR_MINUTES,
+ DUR_HOURS,
+ DUR_DAYS
+};
+
+static const gint duration_units_map[] = {
+ DUR_MINUTES,
+ DUR_HOURS,
+ DUR_DAYS,
+ -1
+};
+
+static void populate_widgets_from_alarm (Dialog *dialog);
+static void action_changed_cb (GtkWidget *action_combo, gpointer data);
+
+/* Fills the widgets with default values */
+static void
+clear_widgets (Dialog *dialog)
+{
+ /* Sane defaults */
+ e_dialog_combo_box_set (dialog->action_combo, E_CAL_COMPONENT_ALARM_DISPLAY, action_map);
+ gtk_spin_button_set_value (
+ GTK_SPIN_BUTTON (dialog->interval_value), 15);
+ e_dialog_combo_box_set (dialog->value_units_combo, MINUTES, value_map);
+ e_dialog_combo_box_set (dialog->relative_combo, BEFORE, relative_map);
+ e_dialog_combo_box_set (dialog->time_combo, E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START, time_map);
+
+ gtk_widget_set_sensitive (dialog->repeat_group, FALSE);
+ gtk_widget_set_sensitive (dialog->dalarm_group, FALSE);
+ gtk_widget_set_sensitive (dialog->aalarm_group, FALSE);
+ gtk_widget_set_sensitive (dialog->malarm_group, FALSE);
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (dialog->option_notebook), 0);
+}
+
+static void
+populate_relative_time_combobox_widget (GtkWidget *combobox,
+ ECalClient *cal_client,
+ const gint *map,
+ gint prop)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean valid;
+ gboolean alarm_after_start;
+ gint i;
+
+ alarm_after_start = !e_client_check_capability (
+ E_CLIENT (cal_client), CAL_STATIC_CAPABILITY_NO_ALARM_AFTER_START);
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (combobox));
+ valid = gtk_tree_model_get_iter_first (model, &iter);
+
+ for (i = 0; valid && map[i] != -1; i++) {
+ gtk_list_store_set (
+ GTK_LIST_STORE (model),
+ &iter,
+ 1,
+ alarm_after_start ? TRUE : (map[i] == prop ? FALSE : TRUE),
+ -1);
+ valid = gtk_tree_model_iter_next (model, &iter);
+ }
+}
+
+/* fill_widgets handler for the alarm page */
+static void
+alarm_to_dialog (Dialog *dialog)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean valid;
+ gboolean repeat;
+ ECalComponentAlarmAction action;
+ gchar *email;
+ gint i;
+
+ /* Clean the page */
+ clear_widgets (dialog);
+
+ /* Alarm types */
+ model = gtk_combo_box_get_model (GTK_COMBO_BOX (dialog->action_combo));
+ valid = gtk_tree_model_get_iter_first (model, &iter);
+ for (i = 0; valid && action_map[i] != -1; i++) {
+ gtk_list_store_set (
+ GTK_LIST_STORE (model), &iter,
+ 1, !e_client_check_capability (E_CLIENT (dialog->cal_client), action_map_cap[i]),
+ -1);
+ valid = gtk_tree_model_iter_next (model, &iter);
+ }
+
+ populate_relative_time_combobox_widget (dialog->relative_combo, dialog->cal_client, relative_map, AFTER);
+ populate_relative_time_combobox_widget (
+ dialog->time_combo, dialog->cal_client, time_map, E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_END);
+
+ /*
+ * If the client doesn't support set alarm description, disable the related widgets
+ */
+ if (!e_client_check_capability (E_CLIENT (dialog->cal_client), CAL_STATIC_CAPABILITY_ALARM_DESCRIPTION)) {
+ gtk_widget_hide (dialog->dalarm_group);
+ gtk_widget_hide (dialog->dalarm_message);
+ gtk_widget_hide (dialog->dalarm_description);
+ }
+
+ /* Set a default address if possible */
+ if (!e_client_check_capability (E_CLIENT (dialog->cal_client), CAL_STATIC_CAPABILITY_NO_EMAIL_ALARMS)
+ && !e_cal_component_alarm_has_attendees (dialog->alarm)
+ && e_client_get_backend_property_sync (E_CLIENT (dialog->cal_client), CAL_BACKEND_PROPERTY_ALARM_EMAIL_ADDRESS, &email, NULL, NULL)) {
+ ECalComponentAttendee *a;
+ GSList attendee_list;
+
+ a = g_new0 (ECalComponentAttendee, 1);
+ a->value = email;
+ a->cutype = ICAL_CUTYPE_INDIVIDUAL;
+ a->status = ICAL_PARTSTAT_NEEDSACTION;
+ a->role = ICAL_ROLE_REQPARTICIPANT;
+ attendee_list.data = a;
+ attendee_list.next = NULL;
+ e_cal_component_alarm_set_attendee_list (dialog->alarm, &attendee_list);
+ g_free (email);
+ g_free (a);
+ }
+
+ /* If we can repeat */
+ repeat = !e_client_check_capability (E_CLIENT (dialog->cal_client), CAL_STATIC_CAPABILITY_NO_ALARM_REPEAT);
+ gtk_widget_set_sensitive (dialog->repeat_toggle, repeat);
+
+ /* if we are editing a exiting alarm */
+ e_cal_component_alarm_get_action (dialog->alarm, &action);
+
+ if (action)
+ populate_widgets_from_alarm (dialog);
+}
+
+static void
+alarm_to_repeat_widgets (Dialog *dialog,
+ ECalComponentAlarm *alarm)
+{
+ ECalComponentAlarmRepeat repeat;
+
+ e_cal_component_alarm_get_repeat (dialog->alarm, &repeat);
+
+ if (repeat.repetitions) {
+ gtk_toggle_button_set_active (
+ GTK_TOGGLE_BUTTON (dialog->repeat_toggle), TRUE);
+ gtk_spin_button_set_value (
+ GTK_SPIN_BUTTON (dialog->repeat_quantity),
+ repeat.repetitions);
+ } else
+ return;
+
+ if (repeat.duration.minutes) {
+ e_dialog_combo_box_set (dialog->repeat_unit_combo, DUR_MINUTES, duration_units_map);
+ gtk_spin_button_set_value (
+ GTK_SPIN_BUTTON (dialog->repeat_value),
+ repeat.duration.minutes);
+ }
+
+ if (repeat.duration.hours) {
+ e_dialog_combo_box_set (dialog->repeat_unit_combo, DUR_HOURS, duration_units_map);
+ gtk_spin_button_set_value (
+ GTK_SPIN_BUTTON (dialog->repeat_value),
+ repeat.duration.hours);
+ }
+
+ if (repeat.duration.days) {
+ e_dialog_combo_box_set (dialog->repeat_unit_combo, DUR_DAYS, duration_units_map);
+ gtk_spin_button_set_value (
+ GTK_SPIN_BUTTON (dialog->repeat_value),
+ repeat.duration.days);
+ }
+}
+
+static void
+repeat_widgets_to_alarm (Dialog *dialog,
+ ECalComponentAlarm *alarm)
+{
+ ECalComponentAlarmRepeat repeat;
+
+ if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->repeat_toggle))) {
+ repeat.repetitions = 0;
+
+ e_cal_component_alarm_set_repeat (alarm, repeat);
+ return;
+ }
+
+ repeat.repetitions = gtk_spin_button_get_value_as_int (
+ GTK_SPIN_BUTTON (dialog->repeat_quantity));
+
+ memset (&repeat.duration, 0, sizeof (repeat.duration));
+ switch (e_dialog_combo_box_get (dialog->repeat_unit_combo, duration_units_map)) {
+ case DUR_MINUTES:
+ repeat.duration.minutes = gtk_spin_button_get_value_as_int (
+ GTK_SPIN_BUTTON (dialog->repeat_value));
+ break;
+
+ case DUR_HOURS:
+ repeat.duration.hours = gtk_spin_button_get_value_as_int (
+ GTK_SPIN_BUTTON (dialog->repeat_value));
+ break;
+
+ case DUR_DAYS:
+ repeat.duration.days = gtk_spin_button_get_value_as_int (
+ GTK_SPIN_BUTTON (dialog->repeat_value));
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+
+ e_cal_component_alarm_set_repeat (alarm, repeat);
+
+}
+
+/* Fills the audio alarm data with the values from the widgets */
+static void
+aalarm_widgets_to_alarm (Dialog *dialog,
+ ECalComponentAlarm *alarm)
+{
+ gchar *url;
+ icalattach *attach;
+
+ if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->aalarm_sound)))
+ return;
+
+ url = gtk_file_chooser_get_uri (
+ GTK_FILE_CHOOSER (dialog->aalarm_file_chooser));
+ attach = icalattach_new_from_url (url ? url : "");
+ g_free (url);
+
+ e_cal_component_alarm_set_attach (alarm, attach);
+ icalattach_unref (attach);
+}
+
+/* Fills the widgets with audio alarm data */
+static void
+alarm_to_aalarm_widgets (Dialog *dialog,
+ ECalComponentAlarm *alarm)
+{
+ const gchar *url;
+ icalattach *attach;
+
+ e_cal_component_alarm_get_attach (alarm, (&attach));
+ url = icalattach_get_url (attach);
+ icalattach_unref (attach);
+
+ if (!(url && *url))
+ return;
+
+ gtk_toggle_button_set_active (
+ GTK_TOGGLE_BUTTON (dialog->aalarm_sound), TRUE);
+ gtk_file_chooser_set_uri (
+ GTK_FILE_CHOOSER (dialog->aalarm_file_chooser), url);
+}
+
+/* Fills the widgets with display alarm data */
+static void
+alarm_to_dalarm_widgets (Dialog *dialog,
+ ECalComponentAlarm *alarm)
+{
+ ECalComponentText description;
+ GtkTextBuffer *text_buffer;
+
+ e_cal_component_alarm_get_description (alarm, &description);
+
+ if (description.value) {
+ gtk_toggle_button_set_active (
+ GTK_TOGGLE_BUTTON (dialog->dalarm_message), TRUE);
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->dalarm_description));
+ gtk_text_buffer_set_text (text_buffer, description.value, -1);
+ }
+}
+
+/* Fills the display alarm data with the values from the widgets */
+static void
+dalarm_widgets_to_alarm (Dialog *dialog,
+ ECalComponentAlarm *alarm)
+{
+ gchar *str;
+ ECalComponentText description;
+ GtkTextBuffer *text_buffer;
+ GtkTextIter text_iter_start, text_iter_end;
+ icalcomponent *icalcomp;
+ icalproperty *icalprop;
+
+ if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->dalarm_message)))
+ return;
+
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->dalarm_description));
+ gtk_text_buffer_get_start_iter (text_buffer, &text_iter_start);
+ gtk_text_buffer_get_end_iter (text_buffer, &text_iter_end);
+ str = gtk_text_buffer_get_text (text_buffer, &text_iter_start, &text_iter_end, FALSE);
+
+ description.value = str;
+ description.altrep = NULL;
+
+ e_cal_component_alarm_set_description (alarm, &description);
+ g_free (str);
+
+ /* remove the X-EVOLUTION-NEEDS-DESCRIPTION property, so that
+ * we don't re-set the alarm's description */
+ icalcomp = e_cal_component_alarm_get_icalcomponent (alarm);
+ icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
+ while (icalprop) {
+ const gchar *x_name;
+
+ x_name = icalproperty_get_x_name (icalprop);
+ if (!strcmp (x_name, "X-EVOLUTION-NEEDS-DESCRIPTION")) {
+ icalcomponent_remove_property (icalcomp, icalprop);
+ break;
+ }
+
+ icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
+ }
+}
+
+/* Fills the mail alarm data with the values from the widgets */
+static void
+malarm_widgets_to_alarm (Dialog *dialog,
+ ECalComponentAlarm *alarm)
+{
+ gchar *str;
+ ECalComponentText description;
+ GSList *attendee_list = NULL;
+ GtkTextBuffer *text_buffer;
+ GtkTextIter text_iter_start, text_iter_end;
+ ENameSelectorModel *name_selector_model;
+ EDestinationStore *destination_store;
+ GList *destinations;
+ icalcomponent *icalcomp;
+ icalproperty *icalprop;
+ GList *l;
+
+ /* Attendees */
+ name_selector_model = e_name_selector_peek_model (dialog->name_selector);
+ e_name_selector_model_peek_section (name_selector_model, section_name, NULL, &destination_store);
+ destinations = e_destination_store_list_destinations (destination_store);
+
+ for (l = destinations; l; l = g_list_next (l)) {
+ EDestination *dest;
+ ECalComponentAttendee *a;
+
+ dest = l->data;
+
+ a = g_new0 (ECalComponentAttendee, 1);
+ a->value = e_destination_get_email (dest);
+ a->cn = e_destination_get_name (dest);
+ a->cutype = ICAL_CUTYPE_INDIVIDUAL;
+ a->status = ICAL_PARTSTAT_NEEDSACTION;
+ a->role = ICAL_ROLE_REQPARTICIPANT;
+
+ attendee_list = g_slist_append (attendee_list, a);
+ }
+
+ e_cal_component_alarm_set_attendee_list (alarm, attendee_list);
+
+ e_cal_component_free_attendee_list (attendee_list);
+ g_list_free (destinations);
+
+ if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->malarm_message)))
+ return;
+
+ /* Description */
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->malarm_description));
+ gtk_text_buffer_get_start_iter (text_buffer, &text_iter_start);
+ gtk_text_buffer_get_end_iter (text_buffer, &text_iter_end);
+ str = gtk_text_buffer_get_text (text_buffer, &text_iter_start, &text_iter_end, FALSE);
+
+ description.value = str;
+ description.altrep = NULL;
+
+ e_cal_component_alarm_set_description (alarm, &description);
+ g_free (str);
+
+ /* remove the X-EVOLUTION-NEEDS-DESCRIPTION property, so that
+ * we don't re-set the alarm's description */
+ icalcomp = e_cal_component_alarm_get_icalcomponent (alarm);
+ icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
+ while (icalprop) {
+ const gchar *x_name;
+
+ x_name = icalproperty_get_x_name (icalprop);
+ if (!strcmp (x_name, "X-EVOLUTION-NEEDS-DESCRIPTION")) {
+ icalcomponent_remove_property (icalcomp, icalprop);
+ break;
+ }
+
+ icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
+ }
+}
+
+/* Fills the widgets from mail alarm data */
+static void
+alarm_to_malarm_widgets (Dialog *dialog,
+ ECalComponentAlarm *alarm)
+{
+ ENameSelectorModel *name_selector_model;
+ EDestinationStore *destination_store;
+ ECalComponentText description;
+ GtkTextBuffer *text_buffer;
+ GSList *attendee_list, *l;
+ gint len;
+
+ /* Attendees */
+ name_selector_model = e_name_selector_peek_model (dialog->name_selector);
+ e_name_selector_model_peek_section (name_selector_model, section_name, NULL, &destination_store);
+
+ e_cal_component_alarm_get_attendee_list (alarm, &attendee_list);
+ len = g_slist_length (attendee_list);
+ if (len > 0) {
+ for (l = attendee_list; l; l = g_slist_next (l)) {
+ ECalComponentAttendee *a = l->data;
+ EDestination *dest;
+
+ dest = e_destination_new ();
+ if (a->cn != NULL && *a->cn)
+ e_destination_set_name (dest, a->cn);
+ if (a->value != NULL && *a->value) {
+ if (!strncasecmp (a->value, "MAILTO:", 7))
+ e_destination_set_email (dest, a->value + 7);
+ else
+ e_destination_set_email (dest, a->value);
+ }
+ e_destination_store_append_destination (destination_store, dest);
+ g_object_unref (dest);
+ }
+ e_cal_component_free_attendee_list (attendee_list);
+ }
+
+ /* Description */
+ e_cal_component_alarm_get_description (alarm, &description);
+ if (description.value) {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->malarm_message), TRUE);
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->malarm_description));
+ gtk_text_buffer_set_text (text_buffer, description.value, -1);
+ }
+}
+
+/* Fills the widgets from procedure alarm data */
+static void
+alarm_to_palarm_widgets (Dialog *dialog,
+ ECalComponentAlarm *alarm)
+{
+ ECalComponentText description;
+ GtkEntry *entry;
+ const gchar *url;
+ icalattach *attach;
+
+ e_cal_component_alarm_get_attach (alarm, (&attach));
+ url = icalattach_get_url (attach);
+ icalattach_unref (attach);
+
+ if (!(url && *url))
+ return;
+
+ entry = GTK_ENTRY (dialog->palarm_program);
+ gtk_entry_set_text (entry, url);
+
+ entry = GTK_ENTRY (dialog->palarm_args);
+ e_cal_component_alarm_get_description (alarm, &description);
+ gtk_entry_set_text (entry, description.value);
+}
+
+/* Fills the procedure alarm data with the values from the widgets */
+static void
+palarm_widgets_to_alarm (Dialog *dialog,
+ ECalComponentAlarm *alarm)
+{
+ icalattach *attach;
+ ECalComponentText description;
+ icalcomponent *icalcomp;
+ icalproperty *icalprop;
+ const gchar *text;
+
+ text = gtk_entry_get_text (GTK_ENTRY (dialog->palarm_program));
+ attach = icalattach_new_from_url ((text != NULL) ? text : "");
+
+ e_cal_component_alarm_set_attach (alarm, attach);
+ icalattach_unref (attach);
+
+ text = gtk_entry_get_text (GTK_ENTRY (dialog->palarm_args));
+
+ description.value = text;
+ description.altrep = NULL;
+
+ e_cal_component_alarm_set_description (alarm, &description);
+
+ /* remove the X-EVOLUTION-NEEDS-DESCRIPTION property, so that
+ * we don't re-set the alarm's description */
+ icalcomp = e_cal_component_alarm_get_icalcomponent (alarm);
+ icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
+ while (icalprop) {
+ const gchar *x_name;
+
+ x_name = icalproperty_get_x_name (icalprop);
+ if (!strcmp (x_name, "X-EVOLUTION-NEEDS-DESCRIPTION")) {
+ icalcomponent_remove_property (icalcomp, icalprop);
+ break;
+ }
+
+ icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
+ }
+}
+
+static void
+populate_widgets_from_alarm (Dialog *dialog)
+{
+ ECalComponentAlarmTrigger *trigger;
+ ECalComponentAlarmAction *action;
+
+ action = g_new0 (ECalComponentAlarmAction, 1);
+ e_cal_component_alarm_get_action (dialog->alarm, action);
+ g_return_if_fail (action != NULL);
+
+ trigger = g_new0 (ECalComponentAlarmTrigger, 1);
+ e_cal_component_alarm_get_trigger (dialog->alarm, trigger);
+ g_return_if_fail (trigger != NULL);
+
+ if (*action == E_CAL_COMPONENT_ALARM_NONE)
+ return;
+
+ gtk_window_set_title (GTK_WINDOW (dialog->toplevel),_("Edit Reminder"));
+
+ /* Alarm Types */
+ switch (trigger->type) {
+ case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START:
+ e_dialog_combo_box_set (dialog->time_combo, E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START, time_map);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_END:
+ e_dialog_combo_box_set (dialog->time_combo, E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_END, time_map);
+ break;
+ default:
+ g_warning ("%s: Unexpected alarm type (%d)", G_STRLOC, trigger->type);
+ }
+
+ switch (trigger->u.rel_duration.is_neg) {
+ case 1:
+ e_dialog_combo_box_set (dialog->relative_combo, BEFORE, relative_map);
+ break;
+
+ case 0:
+ e_dialog_combo_box_set (dialog->relative_combo, AFTER, relative_map);
+ break;
+ }
+
+ if (trigger->u.rel_duration.days) {
+ e_dialog_combo_box_set (dialog->value_units_combo, DAYS, value_map);
+ gtk_spin_button_set_value (
+ GTK_SPIN_BUTTON (dialog->interval_value),
+ trigger->u.rel_duration.days);
+ } else if (trigger->u.rel_duration.hours) {
+ e_dialog_combo_box_set (dialog->value_units_combo, HOURS, value_map);
+ gtk_spin_button_set_value (
+ GTK_SPIN_BUTTON (dialog->interval_value),
+ trigger->u.rel_duration.hours);
+ } else if (trigger->u.rel_duration.minutes) {
+ e_dialog_combo_box_set (dialog->value_units_combo, MINUTES, value_map);
+ gtk_spin_button_set_value (
+ GTK_SPIN_BUTTON (dialog->interval_value),
+ trigger->u.rel_duration.minutes);
+ } else {
+ e_dialog_combo_box_set (dialog->value_units_combo, MINUTES, value_map);
+ gtk_spin_button_set_value (
+ GTK_SPIN_BUTTON (dialog->interval_value), 0);
+ }
+
+ /* Repeat options */
+ alarm_to_repeat_widgets (dialog, dialog->alarm);
+
+ /* Alarm options */
+ e_dialog_combo_box_set (dialog->action_combo, *action, action_map);
+ action_changed_cb (dialog->action_combo, dialog);
+
+ switch (*action) {
+ case E_CAL_COMPONENT_ALARM_AUDIO:
+ alarm_to_aalarm_widgets (dialog, dialog->alarm);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_DISPLAY:
+ alarm_to_dalarm_widgets (dialog, dialog->alarm);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_EMAIL:
+ alarm_to_malarm_widgets (dialog, dialog->alarm);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_PROCEDURE:
+ alarm_to_palarm_widgets (dialog, dialog->alarm);
+ break;
+ default:
+ g_warning ("%s: Unexpected alarm action (%d)", G_STRLOC, *action);
+ }
+}
+
+/* fill_component handler for the alarm page */
+static void
+dialog_to_alarm (Dialog *dialog)
+{
+ ECalComponentAlarmTrigger trigger;
+ ECalComponentAlarmAction action;
+
+ /* Fill out the alarm */
+ memset (&trigger, 0, sizeof (ECalComponentAlarmTrigger));
+ trigger.type = e_dialog_combo_box_get (dialog->time_combo, time_map);
+ if (e_dialog_combo_box_get (dialog->relative_combo, relative_map) == BEFORE)
+ trigger.u.rel_duration.is_neg = 1;
+ else
+ trigger.u.rel_duration.is_neg = 0;
+
+ switch (e_dialog_combo_box_get (dialog->value_units_combo, value_map)) {
+ case MINUTES:
+ trigger.u.rel_duration.minutes =
+ gtk_spin_button_get_value_as_int (
+ GTK_SPIN_BUTTON (dialog->interval_value));
+ break;
+
+ case HOURS:
+ trigger.u.rel_duration.hours =
+ gtk_spin_button_get_value_as_int (
+ GTK_SPIN_BUTTON (dialog->interval_value));
+ break;
+
+ case DAYS:
+ trigger.u.rel_duration.days =
+ gtk_spin_button_get_value_as_int (
+ GTK_SPIN_BUTTON (dialog->interval_value));
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+ e_cal_component_alarm_set_trigger (dialog->alarm, trigger);
+
+ action = e_dialog_combo_box_get (dialog->action_combo, action_map);
+ e_cal_component_alarm_set_action (dialog->alarm, action);
+
+ /* Repeat stuff */
+ repeat_widgets_to_alarm (dialog, dialog->alarm);
+
+ /* Options */
+ switch (action) {
+ case E_CAL_COMPONENT_ALARM_NONE:
+ g_return_if_reached ();
+ break;
+
+ case E_CAL_COMPONENT_ALARM_AUDIO:
+ aalarm_widgets_to_alarm (dialog, dialog->alarm);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_DISPLAY:
+ dalarm_widgets_to_alarm (dialog, dialog->alarm);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_EMAIL:
+ malarm_widgets_to_alarm (dialog, dialog->alarm);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_PROCEDURE:
+ palarm_widgets_to_alarm (dialog, dialog->alarm);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_UNKNOWN:
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+}
+
+static void
+build_combobox_widget (GtkWidget *combobox,
+ const gchar *actions[])
+{
+ GtkComboBox *combo = GTK_COMBO_BOX (combobox);
+ GtkCellRenderer *cell;
+ GtkListStore *store;
+ gint i;
+
+ g_return_if_fail (GTK_IS_COMBO_BOX (combo));
+
+ store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
+ gtk_combo_box_set_model (combo, GTK_TREE_MODEL (store));
+ g_object_unref (store);
+
+ gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
+
+ cell = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
+ gtk_cell_layout_set_attributes (
+ GTK_CELL_LAYOUT (combo), cell,
+ "text", 0,
+ "sensitive", 1,
+ NULL);
+
+ for (i = 0; actions[i] != NULL; i++) {
+ GtkTreeIter iter;
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (
+ store, &iter,
+ 0, _(actions[i]),
+ 1, TRUE,
+ -1);
+ }
+}
+
+/* Gets the widgets from the XML file and returns TRUE if they are all available. */
+static gboolean
+get_widgets (Dialog *dialog)
+{
+ dialog->toplevel = e_builder_get_widget (dialog->builder, "alarm-dialog");
+ if (!dialog->toplevel)
+ return FALSE;
+
+ dialog->action_combo = e_builder_get_widget (dialog->builder, "action-combobox");
+ dialog->interval_value = e_builder_get_widget (dialog->builder, "interval-value");
+ dialog->value_units_combo = e_builder_get_widget (dialog->builder, "value-units-combobox");
+ dialog->relative_combo = e_builder_get_widget (dialog->builder, "relative-combobox");
+ dialog->time_combo = e_builder_get_widget (dialog->builder, "time-combobox");
+
+ dialog->repeat_toggle = e_builder_get_widget (dialog->builder, "repeat-toggle");
+ dialog->repeat_group = e_builder_get_widget (dialog->builder, "repeat-group");
+ dialog->repeat_quantity = e_builder_get_widget (dialog->builder, "repeat-quantity");
+ dialog->repeat_value = e_builder_get_widget (dialog->builder, "repeat-value");
+ dialog->repeat_unit_combo = e_builder_get_widget (dialog->builder, "repeat-unit-combobox");
+
+ dialog->option_notebook = e_builder_get_widget (dialog->builder, "option-notebook");
+
+ dialog->dalarm_group = e_builder_get_widget (dialog->builder, "dalarm-group");
+ dialog->dalarm_message = e_builder_get_widget (dialog->builder, "dalarm-message");
+ dialog->dalarm_description = e_builder_get_widget (dialog->builder, "dalarm-description");
+
+ dialog->aalarm_group = e_builder_get_widget (dialog->builder, "aalarm-group");
+ dialog->aalarm_sound = e_builder_get_widget (dialog->builder, "aalarm-sound");
+ dialog->aalarm_file_chooser = e_builder_get_widget (dialog->builder, "aalarm-file-chooser");
+
+ dialog->malarm_group = e_builder_get_widget (dialog->builder, "malarm-group");
+ dialog->malarm_address_group = e_builder_get_widget (dialog->builder, "malarm-address-group");
+ dialog->malarm_addressbook = e_builder_get_widget (dialog->builder, "malarm-addressbook");
+ dialog->malarm_message = e_builder_get_widget (dialog->builder, "malarm-message");
+ dialog->malarm_description = e_builder_get_widget (dialog->builder, "malarm-description");
+
+ dialog->palarm_group = e_builder_get_widget (dialog->builder, "palarm-group");
+ dialog->palarm_program = e_builder_get_widget (dialog->builder, "palarm-program");
+ dialog->palarm_args = e_builder_get_widget (dialog->builder, "palarm-args");
+
+ if (dialog->action_combo) {
+ const gchar *actions[] = {
+ N_("Pop up an alert"),
+ N_("Play a sound"),
+ N_("Run a program"),
+ N_("Send an email"),
+ NULL
+ };
+
+ build_combobox_widget (dialog->action_combo, actions);
+ }
+
+ if (dialog->relative_combo) {
+ const gchar *actions[] = {
+ N_("before"),
+ N_("after"),
+ NULL
+ };
+
+ build_combobox_widget (dialog->relative_combo, actions);
+ }
+
+ if (dialog->time_combo) {
+ const gchar *actions[] = {
+ N_("start of appointment"),
+ N_("end of appointment"),
+ NULL
+ };
+
+ build_combobox_widget (dialog->time_combo, actions);
+ }
+
+ return (dialog->action_combo
+ && dialog->interval_value
+ && dialog->value_units_combo
+ && dialog->relative_combo
+ && dialog->time_combo
+ && dialog->repeat_toggle
+ && dialog->repeat_group
+ && dialog->repeat_quantity
+ && dialog->repeat_value
+ && dialog->repeat_unit_combo
+ && dialog->option_notebook
+ && dialog->dalarm_group
+ && dialog->dalarm_message
+ && dialog->dalarm_description
+ && dialog->aalarm_group
+ && dialog->aalarm_sound
+ && dialog->aalarm_file_chooser
+ && dialog->malarm_group
+ && dialog->malarm_address_group
+ && dialog->malarm_addressbook
+ && dialog->malarm_message
+ && dialog->malarm_description
+ && dialog->palarm_group
+ && dialog->palarm_program
+ && dialog->palarm_args);
+}
+
+static void
+addressbook_clicked_cb (GtkWidget *widget,
+ Dialog *dialog)
+{
+ e_name_selector_show_dialog (dialog->name_selector, dialog->toplevel);
+}
+
+static void
+addressbook_response_cb (GtkWidget *widget,
+ gint response,
+ gpointer data)
+{
+ Dialog *dialog = data;
+ ENameSelectorDialog *name_selector_dialog;
+
+ name_selector_dialog = e_name_selector_peek_dialog (dialog->name_selector);
+ gtk_widget_hide (GTK_WIDGET (name_selector_dialog));
+}
+
+static gboolean
+setup_select_names (Dialog *dialog)
+{
+ ENameSelectorModel *name_selector_model;
+ ENameSelectorDialog *name_selector_dialog;
+
+ dialog->name_selector = e_name_selector_new (dialog->client_cache);
+ e_name_selector_load_books (dialog->name_selector);
+ name_selector_model = e_name_selector_peek_model (dialog->name_selector);
+
+ e_name_selector_model_add_section (name_selector_model, section_name, section_name, NULL);
+
+ dialog->malarm_addresses =
+ GTK_WIDGET (e_name_selector_peek_section_entry (dialog->name_selector, section_name));
+ gtk_widget_show (dialog->malarm_addresses);
+ gtk_box_pack_end (GTK_BOX (dialog->malarm_address_group), dialog->malarm_addresses, TRUE, TRUE, 0);
+
+ g_signal_connect (
+ dialog->malarm_addressbook, "clicked",
+ G_CALLBACK (addressbook_clicked_cb), dialog);
+
+ name_selector_dialog = e_name_selector_peek_dialog (dialog->name_selector);
+ g_signal_connect (
+ name_selector_dialog, "response",
+ G_CALLBACK (addressbook_response_cb), dialog);
+
+ return TRUE;
+}
+
+/* Callback used when the repeat toggle button is toggled. We sensitize the
+ * repeat group options as appropriate.
+ */
+static void
+repeat_toggle_toggled_cb (GtkToggleButton *toggle,
+ gpointer data)
+{
+ Dialog *dialog = data;
+ gboolean active;
+
+ active = gtk_toggle_button_get_active (toggle);
+
+ gtk_widget_set_sensitive (dialog->repeat_group, active);
+}
+
+static void
+check_custom_sound (Dialog *dialog)
+{
+ gchar *str, *dir;
+ gboolean sens;
+
+ str = gtk_file_chooser_get_filename (
+ GTK_FILE_CHOOSER (dialog->aalarm_file_chooser));
+
+ if (str && *str) {
+ dir = g_path_get_dirname (str);
+ if (dir && *dir) {
+ calendar_config_set_dir_path (dir);
+ }
+ }
+
+ sens = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->aalarm_sound)) ? str && *str : TRUE;
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog->toplevel), GTK_RESPONSE_OK, sens);
+
+ g_free (str);
+}
+
+static void
+aalarm_sound_toggled_cb (GtkToggleButton *toggle,
+ gpointer data)
+{
+ Dialog *dialog = data;
+ gboolean active;
+
+ active = gtk_toggle_button_get_active (toggle);
+
+ gtk_widget_set_sensitive (dialog->aalarm_group, active);
+ check_custom_sound (dialog);
+}
+
+static void
+aalarm_attach_changed_cb (GtkWidget *widget,
+ gpointer data)
+{
+ Dialog *dialog = data;
+
+ check_custom_sound (dialog);
+}
+
+static void
+check_custom_message (Dialog *dialog)
+{
+ gchar *str;
+ GtkTextBuffer *text_buffer;
+ GtkTextIter text_iter_start, text_iter_end;
+ gboolean sens;
+
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->dalarm_description));
+ gtk_text_buffer_get_start_iter (text_buffer, &text_iter_start);
+ gtk_text_buffer_get_end_iter (text_buffer, &text_iter_end);
+ str = gtk_text_buffer_get_text (text_buffer, &text_iter_start, &text_iter_end, FALSE);
+
+ sens = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->dalarm_message)) ? str && *str : TRUE;
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog->toplevel), GTK_RESPONSE_OK, sens);
+
+ g_free (str);
+}
+
+static void
+dalarm_message_toggled_cb (GtkToggleButton *toggle,
+ gpointer data)
+{
+ Dialog *dialog = data;
+ gboolean active;
+
+ active = gtk_toggle_button_get_active (toggle);
+
+ gtk_widget_set_sensitive (dialog->dalarm_group, active);
+ check_custom_message (dialog);
+}
+
+static void
+dalarm_description_changed_cb (GtkWidget *widget,
+ gpointer data)
+{
+ Dialog *dialog = data;
+
+ check_custom_message (dialog);
+}
+
+static void
+check_custom_program (Dialog *dialog)
+{
+ GtkEntry *entry;
+ const gchar *text;
+ gboolean sensitive;
+
+ entry = GTK_ENTRY (dialog->palarm_program);
+ text = gtk_entry_get_text (entry);
+ sensitive = (text != NULL && *text != '\0');
+
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (dialog->toplevel),
+ GTK_RESPONSE_OK, sensitive);
+}
+
+static void
+palarm_program_changed_cb (GtkWidget *widget,
+ gpointer data)
+{
+ Dialog *dialog = data;
+
+ check_custom_program (dialog);
+}
+
+static void
+check_custom_email (Dialog *dialog)
+{
+ gchar *str;
+ GtkTextBuffer *text_buffer;
+ GtkTextIter text_iter_start, text_iter_end;
+ ENameSelectorModel *name_selector_model;
+ EDestinationStore *destination_store;
+ GList *destinations;
+ gboolean sens;
+
+ name_selector_model = e_name_selector_peek_model (dialog->name_selector);
+ e_name_selector_model_peek_section (name_selector_model, section_name, NULL, &destination_store);
+ destinations = e_destination_store_list_destinations (destination_store);
+
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->malarm_description));
+ gtk_text_buffer_get_start_iter (text_buffer, &text_iter_start);
+ gtk_text_buffer_get_end_iter (text_buffer, &text_iter_end);
+ str = gtk_text_buffer_get_text (text_buffer, &text_iter_start, &text_iter_end, FALSE);
+
+ sens = (destinations != NULL) && (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->malarm_message)) ? str && *str : TRUE);
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog->toplevel), GTK_RESPONSE_OK, sens);
+
+ g_list_free (destinations);
+}
+
+static void
+malarm_addresses_changed_cb (GtkWidget *editable,
+ gpointer data)
+{
+ Dialog *dialog = data;
+
+ check_custom_email (dialog);
+}
+
+static void
+malarm_message_toggled_cb (GtkToggleButton *toggle,
+ gpointer data)
+{
+ Dialog *dialog = data;
+ gboolean active;
+
+ active = gtk_toggle_button_get_active (toggle);
+
+ gtk_widget_set_sensitive (dialog->malarm_group, active);
+ check_custom_email (dialog);
+}
+
+static void
+malarm_description_changed_cb (GtkWidget *widget,
+ gpointer data)
+{
+ Dialog *dialog = data;
+
+ check_custom_email (dialog);
+}
+
+static void
+action_changed_cb (GtkWidget *action_combo,
+ gpointer data)
+{
+ Dialog *dialog = data;
+ gchar *dir;
+ ECalComponentAlarmAction action;
+ gint page = 0, i;
+
+ action = e_dialog_combo_box_get (dialog->action_combo, action_map);
+ for (i = 0; action_map[i] != -1; i++) {
+ if (action == action_map[i]) {
+ page = i;
+ break;
+ }
+ }
+
+ gtk_notebook_set_current_page (
+ GTK_NOTEBOOK (dialog->option_notebook), page);
+
+ switch (action) {
+ case E_CAL_COMPONENT_ALARM_AUDIO:
+ dir = calendar_config_get_dir_path ();
+ if (dir && *dir)
+ gtk_file_chooser_set_current_folder (
+ GTK_FILE_CHOOSER (dialog->aalarm_file_chooser),
+ dir);
+ g_free (dir);
+ check_custom_sound (dialog);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_DISPLAY:
+ check_custom_message (dialog);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_EMAIL:
+ check_custom_email (dialog);
+ break;
+
+ case E_CAL_COMPONENT_ALARM_PROCEDURE:
+ check_custom_program (dialog);
+ break;
+ default:
+ g_return_if_reached ();
+ return;
+ }
+}
+
+/* Hooks the widget signals */
+static void
+init_widgets (Dialog *dialog)
+{
+ GtkTextBuffer *text_buffer;
+
+ g_signal_connect (
+ dialog->action_combo, "changed",
+ G_CALLBACK (action_changed_cb), dialog);
+
+ g_signal_connect (
+ dialog->repeat_toggle, "toggled",
+ G_CALLBACK (repeat_toggle_toggled_cb), dialog);
+
+ /* Handle custom sounds */
+ g_signal_connect (
+ dialog->aalarm_sound, "toggled",
+ G_CALLBACK (aalarm_sound_toggled_cb), dialog);
+ g_signal_connect (
+ dialog->aalarm_file_chooser, "selection-changed",
+ G_CALLBACK (aalarm_attach_changed_cb), dialog);
+
+ /* Handle custom messages */
+ g_signal_connect (
+ dialog->dalarm_message, "toggled",
+ G_CALLBACK (dalarm_message_toggled_cb), dialog);
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->dalarm_description));
+ g_signal_connect (
+ text_buffer, "changed",
+ G_CALLBACK (dalarm_description_changed_cb), dialog);
+
+ /* Handle program */
+ g_signal_connect (
+ dialog->palarm_program, "changed",
+ G_CALLBACK (palarm_program_changed_cb), dialog);
+
+ /* Handle custom email */
+ g_signal_connect (
+ dialog->malarm_message, "toggled",
+ G_CALLBACK (malarm_message_toggled_cb), dialog);
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (dialog->malarm_description));
+ g_signal_connect (
+ text_buffer, "changed",
+ G_CALLBACK (malarm_description_changed_cb), dialog);
+
+ g_signal_connect (
+ dialog->malarm_addresses, "changed",
+ G_CALLBACK (malarm_addresses_changed_cb), dialog);
+}
+
+gboolean
+alarm_dialog_run (GtkWidget *parent,
+ EClientCache *client_cache,
+ ECalClient *cal_client,
+ ECalComponentAlarm *alarm)
+{
+ Dialog dialog;
+ GtkWidget *container;
+ gint response_id;
+
+ g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), FALSE);
+ g_return_val_if_fail (alarm != NULL, FALSE);
+
+ dialog.alarm = alarm;
+ dialog.cal_client = cal_client;
+ dialog.client_cache = client_cache;
+
+ dialog.builder = gtk_builder_new ();
+ e_load_ui_builder_definition (dialog.builder, "alarm-dialog.ui");
+
+ if (!get_widgets (&dialog)) {
+ g_object_unref (dialog.builder);
+ return FALSE;
+ }
+
+ if (!setup_select_names (&dialog)) {
+ g_object_unref (dialog.builder);
+ return FALSE;
+ }
+
+ init_widgets (&dialog);
+
+ alarm_to_dialog (&dialog);
+
+ gtk_widget_ensure_style (dialog.toplevel);
+
+ container = gtk_dialog_get_action_area (GTK_DIALOG (dialog.toplevel));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 12);
+
+ container = gtk_dialog_get_content_area (GTK_DIALOG (dialog.toplevel));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 0);
+
+ gtk_window_set_icon_name (
+ GTK_WINDOW (dialog.toplevel), "x-office-calendar");
+
+ gtk_window_set_transient_for (
+ GTK_WINDOW (dialog.toplevel),
+ GTK_WINDOW (parent));
+
+ response_id = gtk_dialog_run (GTK_DIALOG (dialog.toplevel));
+
+ if (response_id == GTK_RESPONSE_OK)
+ dialog_to_alarm (&dialog);
+
+ if (dialog.name_selector) {
+ e_name_selector_cancel_loading (dialog.name_selector);
+ g_object_unref (dialog.name_selector);
+ }
+ gtk_widget_destroy (dialog.toplevel);
+ g_object_unref (dialog.builder);
+
+ return response_id == GTK_RESPONSE_OK ? TRUE : FALSE;
+}
diff --git a/calendar/gui/dialogs/alarm-dialog.h b/calendar/gui/dialogs/alarm-dialog.h
new file mode 100644
index 0000000000..14653b3334
--- /dev/null
+++ b/calendar/gui/dialogs/alarm-dialog.h
@@ -0,0 +1,46 @@
+/*
+ *
+ * Evolution calendar - Alarm page of the calendar component dialogs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ * Miguel de Icaza <miguel@ximian.com>
+ * Seth Alves <alves@hungry.com>
+ * JP Rosevear <jpr@ximian.com>
+ * Hans Petter Jansson <hpj@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef ALARM_DIALOG_H
+#define ALARM_DIALOG_H
+
+#include <libecal/libecal.h>
+
+#include <e-util/e-util.h>
+
+G_BEGIN_DECLS
+
+gboolean alarm_dialog_run (GtkWidget *parent,
+ EClientCache *client_cache,
+ ECalClient *cal_client,
+ ECalComponentAlarm *alarm);
+
+G_END_DECLS
+
+#endif
diff --git a/calendar/gui/dialogs/alarm-dialog.ui b/calendar/gui/dialogs/alarm-dialog.ui
new file mode 100644
index 0000000000..c7c03106f4
--- /dev/null
+++ b/calendar/gui/dialogs/alarm-dialog.ui
@@ -0,0 +1,1068 @@
+<?xml version="1.0"?>
+<!--*- mode: xml -*-->
+<interface>
+ <object class="GtkAdjustment" id="adjustment1">
+ <property name="upper">999</property>
+ <property name="lower">0</property>
+ <property name="page_increment">10</property>
+ <property name="step_increment">1</property>
+ <property name="page_size">0</property>
+ <property name="value">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment2">
+ <property name="upper">999</property>
+ <property name="lower">1</property>
+ <property name="page_increment">10</property>
+ <property name="step_increment">1</property>
+ <property name="page_size">0</property>
+ <property name="value">1</property>
+ </object>
+ <object class="GtkAdjustment" id="adjustment3">
+ <property name="upper">999</property>
+ <property name="lower">0</property>
+ <property name="page_increment">10</property>
+ <property name="step_increment">1</property>
+ <property name="page_size">0</property>
+ <property name="value">5</property>
+ </object>
+ <object class="GtkListStore" id="model1">
+ <columns>
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes">minute(s)</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">hour(s)</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">day(s)</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkListStore" id="model2">
+ <columns>
+ <column type="gchararray"/>
+ </columns>
+ <data>
+ <row>
+ <col id="0" translatable="yes">minutes</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">hours</col>
+ </row>
+ <row>
+ <col id="0" translatable="yes">days</col>
+ </row>
+ </data>
+ </object>
+ <object class="GtkDialog" id="alarm-dialog">
+ <property name="border_width">6</property>
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Add Reminder</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <object class="GtkButton" id="cancelbutton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="okbutton">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox28">
+ <property name="border_width">12</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Reminder</property>
+ <property name="use_underline">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox56">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label20">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"/>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox54">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkComboBox" id="action-combobox">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="interval-value">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="climb_rate">1</property>
+ <property name="digits">0</property>
+ <property name="numeric">True</property>
+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+ <property name="snap_to_ticks">False</property>
+ <property name="wrap">False</property>
+ <property name="adjustment">adjustment1</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="value-units-combobox">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <property name="model">model1</property>
+ <child>
+ <object class="GtkCellRendererText" id="renderer1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="relative-combobox">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="time-combobox">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Repeat</property>
+ <property name="use_underline">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox57">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label21">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"/>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox5">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="repeat-toggle">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="label" translatable="yes">_Repeat the reminder</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="repeat-group">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkSpinButton" id="repeat-quantity">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="climb_rate">1</property>
+ <property name="digits">0</property>
+ <property name="numeric">True</property>
+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+ <property name="snap_to_ticks">False</property>
+ <property name="wrap">False</property>
+ <property name="adjustment">adjustment2</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes" comments="This is part of the sentence: 'Repeat the reminder %d extra times every %d minutes'. Where %d are numbers.">extra times every</property>
+ <property name="use_underline">False</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">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="repeat-value">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="climb_rate">1</property>
+ <property name="digits">0</property>
+ <property name="numeric">True</property>
+ <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+ <property name="snap_to_ticks">False</property>
+ <property name="wrap">False</property>
+ <property name="adjustment">adjustment3</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="repeat-unit-combobox">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ <property name="model">model2</property>
+ <child>
+ <object class="GtkCellRendererText" id="renderer4"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Options</property>
+ <property name="use_underline">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox55">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label22">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes"/>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkNotebook" id="option-notebook">
+ <property name="visible">True</property>
+ <property name="show_tabs">False</property>
+ <property name="show_border">False</property>
+ <property name="tab_pos">GTK_POS_TOP</property>
+ <property name="scrollable">False</property>
+ <property name="enable_popup">False</property>
+ <child>
+ <object class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="dalarm-message">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Custom _message</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="dalarm-group">
+ <property name="visible">True</property>
+ <property name="n_rows">1</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Mes_sage:</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">0</property>
+ <property name="yalign">0</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">dalarm-description</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+ <child>
+ <object class="GtkTextView" id="dalarm-description">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="overwrite">False</property>
+ <property name="accepts_tab">True</property>
+ <property name="justification">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap_mode">GTK_WRAP_WORD</property>
+ <property name="cursor_visible">True</property>
+ <property name="pixels_above_lines">0</property>
+ <property name="pixels_below_lines">0</property>
+ <property name="pixels_inside_wrap">0</property>
+ <property name="left_margin">0</property>
+ <property name="right_margin">0</property>
+ <property name="indent">0</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">label15</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="aalarm-sound">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Custom reminder sound</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="aalarm-group">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label8">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Sound:</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">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFileChooserButton" id="aalarm-file-chooser">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Select A File</property>
+ <property name="action">GTK_FILE_CHOOSER_ACTION_OPEN</property>
+ <property name="local_only">True</property>
+ <property name="show_hidden">False</property>
+ <property name="do_overwrite_confirmation">False</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label16">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">label16</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+ <child>
+ <object class="GtkTable" id="palarm-group">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Program:</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">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">palarm-program</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Arguments:</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">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">palarm-args</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">fill</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="palarm-program">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"/>
+ <property name="has_frame">True</property>
+ <property name="activates_default">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="palarm-args">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"/>
+ <property name="has_frame">True</property>
+ <property name="activates_default">False</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"/>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label17">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">label17</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox4">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+ <child>
+ <object class="GtkVBox" id="vbox6">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkHBox" id="malarm-address-group">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkButton" id="malarm-addressbook">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Send To:</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox27">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="malarm-message">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Custom _message</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="malarm-group">
+ <property name="visible">True</property>
+ <property name="n_rows">1</property>
+ <property name="n_columns">2</property>
+ <property name="homogeneous">False</property>
+ <property name="row_spacing">6</property>
+ <property name="column_spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow3">
+ <property name="visible">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+ <child>
+ <object class="GtkTextView" id="malarm-description">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="overwrite">False</property>
+ <property name="accepts_tab">True</property>
+ <property name="justification">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap_mode">GTK_WRAP_WORD</property>
+ <property name="cursor_visible">True</property>
+ <property name="pixels_above_lines">0</property>
+ <property name="pixels_below_lines">0</property>
+ <property name="pixels_inside_wrap">0</property>
+ <property name="left_margin">0</property>
+ <property name="right_margin">0</property>
+ <property name="indent">0</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label19">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Mes_sage:</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">0</property>
+ <property name="yalign">0</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="mnemonic_widget">option-notebook</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="right_attach">1</property>
+ <property name="top_attach">0</property>
+ <property name="bottom_attach">1</property>
+ <property name="x_options">fill</property>
+ <property name="y_options">fill</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">True</property>
+ </packing>
+ </child>
+ <child type="tab">
+ <object class="GtkLabel" id="label18">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">label18</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">cancelbutton</action-widget>
+ <action-widget response="-5">okbutton</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/calendar/gui/dialogs/alarm-list-dialog.c b/calendar/gui/dialogs/alarm-list-dialog.c
new file mode 100644
index 0000000000..ea17b92d0d
--- /dev/null
+++ b/calendar/gui/dialogs/alarm-list-dialog.c
@@ -0,0 +1,352 @@
+/*
+ * Evolution calendar - Alarm page of the calendar component dialogs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ * Miguel de Icaza <miguel@ximian.com>
+ * Seth Alves <alves@hungry.com>
+ * JP Rosevear <jpr@ximian.com>
+ * Hans Petter Jansson <hpj@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include "e-util/e-util-private.h"
+#include "alarm-dialog.h"
+#include "alarm-list-dialog.h"
+
+typedef struct {
+ GtkBuilder *builder;
+ EClientCache *client_cache;
+
+ /* The client */
+ ECalClient *cal_client;
+
+ /* The list store */
+ EAlarmList *list_store;
+
+ /* Toplevel */
+ GtkWidget *toplevel;
+
+ GtkWidget *list;
+ GtkWidget *add;
+ GtkWidget *edit;
+ GtkWidget *delete;
+ GtkWidget *box;
+
+} Dialog;
+
+/* Gets the widgets from the XML file and returns TRUE if they are all available. */
+static gboolean
+get_widgets (Dialog *dialog)
+{
+#define GW(name) e_builder_get_widget (dialog->builder, name)
+
+ dialog->toplevel = GW ("alarm-list-dialog");
+ if (!dialog->toplevel)
+ return FALSE;
+
+ dialog->box = GW ("vbox53");
+ dialog->list = GW ("list");
+ dialog->add = GW ("add");
+ dialog->edit = GW ("edit");
+ dialog->delete = GW ("delete");
+
+#undef GW
+
+ return (dialog->list
+ && dialog->add
+ && dialog->edit
+ && dialog->delete);
+}
+
+static void
+sensitize_buttons (Dialog *dialog)
+{
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ gboolean have_selected, read_only = FALSE;
+
+ read_only = e_client_is_readonly (E_CLIENT (dialog->cal_client));
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->list));
+ have_selected = gtk_tree_selection_get_selected (selection, NULL, &iter);
+
+ if ((e_cal_client_check_one_alarm_only (dialog->cal_client) &&have_selected) || read_only)
+ gtk_widget_set_sensitive (dialog->add, FALSE);
+ else
+ gtk_widget_set_sensitive (dialog->add, TRUE);
+ gtk_widget_set_sensitive (dialog->delete, have_selected && !read_only);
+ gtk_widget_set_sensitive (dialog->edit, have_selected && !read_only);
+}
+
+/* Callback used for the "add reminder" button */
+static void
+add_clicked_cb (GtkButton *button,
+ gpointer data)
+{
+ Dialog *dialog = data;
+ ECalComponentAlarm *alarm;
+ GtkTreeView *view;
+ GtkTreeIter iter;
+ icalcomponent *icalcomp;
+ icalproperty *icalprop;
+
+ view = GTK_TREE_VIEW (dialog->list);
+
+ alarm = e_cal_component_alarm_new ();
+
+ icalcomp = e_cal_component_alarm_get_icalcomponent (alarm);
+ icalprop = icalproperty_new_x ("1");
+ icalproperty_set_x_name (icalprop, "X-EVOLUTION-NEEDS-DESCRIPTION");
+ icalcomponent_add_property (icalcomp, icalprop);
+
+ if (alarm_dialog_run (dialog->toplevel, dialog->client_cache, dialog->cal_client, alarm)) {
+ e_alarm_list_append (dialog->list_store, &iter, alarm);
+ gtk_tree_selection_select_iter (gtk_tree_view_get_selection (view), &iter);
+ } else {
+ e_cal_component_alarm_free (alarm);
+ }
+
+ sensitize_buttons (dialog);
+}
+
+/* Callback used for the "edit reminder" button */
+static void
+edit_clicked_cb (GtkButton *button,
+ gpointer data)
+{
+ Dialog *dialog = data;
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ ECalComponentAlarm *alarm;
+ GtkTreeView *view;
+
+ view = GTK_TREE_VIEW (dialog->list);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->list));
+ if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
+ g_warning ("Could not get a selection to edit.");
+ return;
+ }
+
+ alarm = (ECalComponentAlarm *) e_alarm_list_get_alarm (dialog->list_store, &iter);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (dialog->list_store), &iter);
+
+ if (alarm_dialog_run (dialog->toplevel, dialog->client_cache, dialog->cal_client, alarm)) {
+ gtk_tree_selection_select_iter (gtk_tree_view_get_selection (view), &iter);
+ gtk_tree_model_row_changed (GTK_TREE_MODEL (dialog->list_store), path, &iter);
+ }
+}
+
+/* Callback used for the "delete reminder" button */
+static void
+delete_clicked_cb (GtkButton *button,
+ gpointer data)
+{
+ Dialog *dialog = data;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkTreePath *path;
+ gboolean valid_iter;
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->list));
+ if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
+ g_warning ("Could not get a selection to delete.");
+ return;
+ }
+
+ model = GTK_TREE_MODEL (dialog->list_store);
+ path = gtk_tree_model_get_path (model, &iter);
+ e_alarm_list_remove (dialog->list_store, &iter);
+
+ /* Select closest item after removal */
+ valid_iter = gtk_tree_model_get_iter (model, &iter, path);
+ if (!valid_iter) {
+ gtk_tree_path_prev (path);
+ valid_iter = gtk_tree_model_get_iter (model, &iter, path);
+ }
+
+ if (valid_iter)
+ gtk_tree_selection_select_iter (selection, &iter);
+
+ sensitize_buttons (dialog);
+
+ gtk_tree_path_free (path);
+}
+
+static void
+selection_changed_cb (GtkTreeSelection *selection,
+ gpointer data)
+{
+ Dialog *dialog = data;
+
+ sensitize_buttons (dialog);
+}
+
+void
+alarm_list_dialog_set_client (GtkWidget *dlg_box,
+ ECalClient *cal_client)
+{
+ Dialog *dialog;
+
+ if (!dlg_box) return;
+
+ dialog = g_object_get_data (G_OBJECT (dlg_box), "dialog");
+ if (dialog) {
+ dialog->cal_client = cal_client;
+ sensitize_buttons (dialog);
+ }
+}
+
+/* Hooks the widget signals */
+static void
+init_widgets (Dialog *dialog)
+{
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *cell_renderer;
+
+ /* View */
+ gtk_tree_view_set_model (
+ GTK_TREE_VIEW (dialog->list),
+ GTK_TREE_MODEL (dialog->list_store));
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_title (column, _("Action/Trigger"));
+ cell_renderer = GTK_CELL_RENDERER (gtk_cell_renderer_text_new ());
+ gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
+ gtk_tree_view_column_add_attribute (
+ column, cell_renderer,
+ "text", E_ALARM_LIST_COLUMN_DESCRIPTION);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->list), column);
+
+ /* Reminder buttons */
+ g_signal_connect (
+ dialog->add, "clicked",
+ G_CALLBACK (add_clicked_cb), dialog);
+ g_signal_connect (
+ dialog->delete, "clicked",
+ G_CALLBACK (delete_clicked_cb), dialog);
+ g_signal_connect (
+ dialog->edit, "clicked",
+ G_CALLBACK (edit_clicked_cb), dialog);
+
+ g_signal_connect (
+ gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->list)),
+ "changed", G_CALLBACK (selection_changed_cb), dialog);
+}
+
+gboolean
+alarm_list_dialog_run (GtkWidget *parent,
+ EClientCache *client_cache,
+ ECalClient *cal_client,
+ EAlarmList *list_store)
+{
+ Dialog dialog;
+ GtkWidget *container;
+ gint response_id;
+
+ g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), FALSE);
+
+ dialog.client_cache = client_cache;
+ dialog.cal_client = cal_client;
+ dialog.list_store = list_store;
+
+ dialog.builder = gtk_builder_new ();
+ e_load_ui_builder_definition (dialog.builder, "alarm-list-dialog.ui");
+
+ if (!get_widgets (&dialog)) {
+ g_object_unref (dialog.builder);
+ return FALSE;
+ }
+
+ init_widgets (&dialog);
+
+ sensitize_buttons (&dialog);
+
+ gtk_widget_ensure_style (dialog.toplevel);
+
+ container = gtk_dialog_get_action_area (GTK_DIALOG (dialog.toplevel));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 12);
+
+ container = gtk_dialog_get_content_area (GTK_DIALOG (dialog.toplevel));
+ gtk_container_set_border_width (GTK_CONTAINER (container), 0);
+
+ gtk_window_set_icon_name (
+ GTK_WINDOW (dialog.toplevel), "x-office-calendar");
+
+ gtk_window_set_transient_for (
+ GTK_WINDOW (dialog.toplevel),
+ GTK_WINDOW (parent));
+
+ response_id = gtk_dialog_run (GTK_DIALOG (dialog.toplevel));
+ gtk_widget_hide (dialog.toplevel);
+
+ gtk_widget_destroy (dialog.toplevel);
+ g_object_unref (dialog.builder);
+
+ return response_id == GTK_RESPONSE_OK ? TRUE : FALSE;
+}
+
+GtkWidget *
+alarm_list_dialog_peek (EClientCache *client_cache,
+ ECalClient *cal_client,
+ EAlarmList *list_store)
+{
+ Dialog *dialog;
+
+ dialog = (Dialog *) g_new (Dialog, 1);
+ dialog->client_cache = client_cache;
+ dialog->cal_client = cal_client;
+ dialog->list_store = list_store;
+
+ dialog->builder = gtk_builder_new ();
+ e_load_ui_builder_definition (dialog->builder, "alarm-list-dialog.ui");
+
+ if (!get_widgets (dialog)) {
+ g_object_unref (dialog->builder);
+ return NULL;
+ }
+
+ init_widgets (dialog);
+
+ sensitize_buttons (dialog);
+
+ g_object_unref (dialog->builder);
+
+ /* Free the other stuff when the parent really gets destroyed. */
+ g_object_set_data_full (
+ G_OBJECT (dialog->box),
+ "toplevel", dialog->toplevel,
+ (GDestroyNotify) gtk_widget_destroy);
+ g_object_set_data_full (
+ G_OBJECT (dialog->box), "dialog",
+ dialog, (GDestroyNotify) g_free);
+
+ return dialog->box;
+}
diff --git a/calendar/gui/dialogs/alarm-list-dialog.h b/calendar/gui/dialogs/alarm-list-dialog.h
new file mode 100644
index 0000000000..5fc8aa3b77
--- /dev/null
+++ b/calendar/gui/dialogs/alarm-list-dialog.h
@@ -0,0 +1,53 @@
+/*
+ *
+ * Evolution calendar - Alarm page of the calendar component dialogs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ * Miguel de Icaza <miguel@ximian.com>
+ * Seth Alves <alves@hungry.com>
+ * JP Rosevear <jpr@ximian.com>
+ * Hans Petter Jansson <hpj@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef ALARM_LIST_DIALOG_H
+#define ALARM_LIST_DIALOG_H
+
+#include <libecal/libecal.h>
+
+#include <e-util/e-util.h>
+
+#include "../e-alarm-list.h"
+
+G_BEGIN_DECLS
+
+gboolean alarm_list_dialog_run (GtkWidget *parent,
+ EClientCache *client_cache,
+ ECalClient *cal_client,
+ EAlarmList *list_store);
+GtkWidget * alarm_list_dialog_peek (EClientCache *client_cache,
+ ECalClient *cal_client,
+ EAlarmList *list_store);
+void alarm_list_dialog_set_client (GtkWidget *dlg_box,
+ ECalClient *cal_client);
+
+G_END_DECLS
+
+#endif
diff --git a/calendar/gui/dialogs/alarm-list-dialog.ui b/calendar/gui/dialogs/alarm-list-dialog.ui
new file mode 100644
index 0000000000..70fa138669
--- /dev/null
+++ b/calendar/gui/dialogs/alarm-list-dialog.ui
@@ -0,0 +1,216 @@
+<?xml version="1.0"?>
+<!--*- mode: xml -*-->
+<interface>
+ <object class="GtkDialog" id="alarm-list-dialog">
+ <property name="title" translatable="yes">Reminders</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="modal">True</property>
+ <property name="default_width">320</property>
+ <property name="default_height">240</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <object class="GtkButton" id="cancelbutton1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="okbutton1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox53">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkHBox" id="hbox55">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkScrolledWindow" id="scrolledwindow13">
+ <property name="visible">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+ <child>
+ <object class="GtkTreeView" id="list">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="headers_visible">True</property>
+ <property name="rules_hint">False</property>
+ <property name="reorderable">False</property>
+ <property name="enable_search">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVButtonBox" id="vbuttonbox2">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_START</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkButton" id="add">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <child>
+ <object class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
+ <child>
+ <object class="GtkHBox" id="hbox56">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-add</property>
+ <property name="icon_size">4</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label65">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">A_dd</property>
+ <property name="use_underline">True</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="delete">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-remove</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="edit">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-edit</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">cancelbutton1</action-widget>
+ <action-widget response="-5">okbutton1</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/calendar/gui/dialogs/alarm-options.c b/calendar/gui/dialogs/alarm-options.c
deleted file mode 100644
index e3d1431e6d..0000000000
--- a/calendar/gui/dialogs/alarm-options.c
+++ /dev/null
@@ -1,621 +0,0 @@
-/* Evolution calendar - Alarm options dialog
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtkcheckbutton.h>
-#include <gtk/gtksignal.h>
-#include <gtk/gtkwindow.h>
-#include <glade/glade.h>
-#include "e-util/e-dialog-widgets.h"
-#include "alarm-options.h"
-
-
-
-typedef struct {
- /* Whether the dialog was accepted or canceled */
- gboolean canceled;
-
- /* Glade XML data */
- GladeXML *xml;
-
- /* Toplevel */
- GtkWidget *toplevel;
-
- /* Buttons */
- GtkWidget *button_ok;
- GtkWidget *button_cancel;
-
- /* Alarm repeat widgets */
- GtkWidget *repeat_toggle;
- GtkWidget *repeat_group;
- GtkWidget *repeat_quantity;
- GtkWidget *repeat_value;
- GtkWidget *repeat_unit;
-
- /* Display alarm widgets */
- GtkWidget *dalarm_group;
- GtkWidget *dalarm_description;
-
- /* Audio alarm widgets */
- GtkWidget *aalarm_group;
- GtkWidget *aalarm_attach;
-
- /* FIXME: Mail alarm widgets */
- GtkWidget *malarm_group;
-
- /* Procedure alarm widgets */
- GtkWidget *palarm_group;
- GtkWidget *palarm_program;
- GtkWidget *palarm_args;
-} Dialog;
-
-
-
-/* Gets the widgets from the XML file and returns if they are all available. */
-static gboolean
-get_widgets (Dialog *dialog)
-{
-#define GW(name) glade_xml_get_widget (dialog->xml, name)
-
- dialog->toplevel = GW ("alarm-options-toplevel");
-
- dialog->button_ok = GW ("button-ok");
- dialog->button_cancel = GW ("button-cancel");
-
- dialog->repeat_toggle = GW ("repeat-toggle");
- dialog->repeat_group = GW ("repeat-group");
- dialog->repeat_quantity = GW ("repeat-quantity");
- dialog->repeat_value = GW ("repeat-value");
- dialog->repeat_unit = GW ("repeat-unit");
-
- dialog->dalarm_group = GW ("dalarm-group");
- dialog->dalarm_description = GW ("dalarm-description");
-
- dialog->aalarm_group = GW ("aalarm-group");
- dialog->aalarm_attach = GW ("aalarm-attach");
-
- dialog->malarm_group = GW ("malarm-group");
-
- dialog->palarm_group = GW ("palarm-group");
- dialog->palarm_program = GW ("palarm-program");
- dialog->palarm_args = GW ("palarm-args");
-
- return (dialog->toplevel
- && dialog->button_ok
- && dialog->button_cancel
- && dialog->repeat_toggle
- && dialog->repeat_group
- && dialog->repeat_quantity
- && dialog->repeat_value
- && dialog->repeat_unit
- && dialog->dalarm_group
- && dialog->dalarm_description
- && dialog->aalarm_group
- && dialog->aalarm_attach
- && dialog->malarm_group
- && dialog->palarm_group
- && dialog->palarm_program
- && dialog->palarm_args);
-}
-
-/* Closes the dialog by terminating its main loop */
-static void
-close_dialog (Dialog *dialog, gboolean canceled)
-{
- dialog->canceled = canceled;
- gtk_main_quit ();
-}
-
-/* Callback used when the toplevel window is deleted */
-static guint
-toplevel_delete_event_cb (GtkWidget *widget, GdkEventAny *event, gpointer data)
-{
- Dialog *dialog;
-
- dialog = data;
- close_dialog (dialog, TRUE);
- return TRUE;
-}
-
-/* Callback used when the OK button is clicked */
-static void
-button_ok_clicked_cb (GtkWidget *button, gpointer data)
-{
- Dialog *dialog;
-
- dialog = data;
- close_dialog (dialog, FALSE);
-}
-
-/* Callback used when the Cancel button is clicked */
-static void
-button_cancel_clicked_cb (GtkWidget *button, gpointer data)
-{
- Dialog *dialog;
-
- dialog = data;
- close_dialog (dialog, TRUE);
-}
-
-/* Callback used when the repeat toggle button is toggled. We sensitize the
- * repeat group options as appropriate.
- */
-static void
-repeat_toggle_toggled_cb (GtkToggleButton *toggle, gpointer data)
-{
- Dialog *dialog;
- gboolean active;
-
- dialog = data;
-
- active = gtk_toggle_button_get_active (toggle);
-
- gtk_widget_set_sensitive (dialog->repeat_group, active);
-}
-
-/* Hooks the widget signals */
-static void
-init_widgets (Dialog *dialog)
-{
- /* Toplevel, buttons */
-
- dialog->canceled = TRUE;
-
- gtk_signal_connect (GTK_OBJECT (dialog->toplevel), "delete_event",
- GTK_SIGNAL_FUNC (toplevel_delete_event_cb), dialog);
-
- gtk_signal_connect (GTK_OBJECT (dialog->button_ok), "clicked",
- GTK_SIGNAL_FUNC (button_ok_clicked_cb), dialog);
-
- gtk_signal_connect (GTK_OBJECT (dialog->button_cancel), "clicked",
- GTK_SIGNAL_FUNC (button_cancel_clicked_cb), dialog);
-
- /* Alarm repeat */
-
- gtk_signal_connect (GTK_OBJECT (dialog->repeat_toggle), "toggled",
- GTK_SIGNAL_FUNC (repeat_toggle_toggled_cb), dialog);
-}
-
-/* Fills the audio alarm widgets with the values from the alarm component */
-static void
-alarm_to_aalarm_widgets (Dialog *dialog, CalComponentAlarm *alarm)
-{
- icalattach *attach;
- const char *url;
-
- cal_component_alarm_get_attach (alarm, &attach);
-
- if (!attach) {
- e_dialog_editable_set (dialog->aalarm_attach, NULL);
- return;
- }
-
- /* FIXME: this does not support inline data */
-
- url = NULL;
-
- if (icalattach_get_is_url (attach))
- url = icalattach_get_url (attach);
- else
- g_message ("alarm_to_aalarm_widgets(): FIXME: we don't support inline data yet");
-
- e_dialog_editable_set (dialog->aalarm_attach, url);
-
- icalattach_unref (attach);
-}
-
-/* Fills the display alarm widgets with the values from the alarm component */
-static void
-alarm_to_dalarm_widgets (Dialog *dialog, CalComponentAlarm *alarm)
-{
- CalComponentText description;
-
- cal_component_alarm_get_description (alarm, &description);
-
- e_dialog_editable_set (dialog->dalarm_description, description.value);
-}
-
-/* Fills the mail alarm widgets with the values from the alarm component */
-static void
-alarm_to_malarm_widgets (Dialog *dialog, CalComponentAlarm *alarm)
-{
- /* FIXME: nothing for now; we don't support mail alarms */
-}
-
-/* Fills the procedure alarm widgets with the values from the alarm component */
-static void
-alarm_to_palarm_widgets (Dialog *dialog, CalComponentAlarm *alarm)
-{
- icalattach *attach;
- CalComponentText description;
-
- cal_component_alarm_get_attach (alarm, &attach);
- cal_component_alarm_get_description (alarm, &description);
-
- if (attach) {
- const char *url;
-
- if (icalattach_get_is_url (attach)) {
- url = icalattach_get_url (attach);
- e_dialog_editable_set (dialog->palarm_program, url);
- } else
- g_message ("alarm_to_palarm_widgets(): Don't know what to do with non-URL "
- "attachments");
-
- icalattach_unref (attach);
- }
-
- e_dialog_editable_set (dialog->palarm_args, description.value);
-}
-
-enum duration_units {
- DUR_MINUTES,
- DUR_HOURS,
- DUR_DAYS
-};
-
-static const int duration_units_map[] = {
- DUR_MINUTES,
- DUR_HOURS,
- DUR_DAYS,
- -1
-};
-
-/* Sigh. Takes an overcomplicated duration value and reduces it to its lowest
- * common denominator.
- */
-static void
-normalize_duration (struct icaldurationtype dur, int *value, enum duration_units *units)
-{
- if (dur.seconds != 0 || dur.minutes != 0) {
- *value = ((((dur.weeks * 7 + dur.days) * 24 + dur.hours) * 60) + dur.minutes
- + dur.seconds / 60 + ((dur.seconds % 60) >= 30 ? 1 : 0));
- *units = DUR_MINUTES;
- } else if (dur.hours) {
- *value = ((dur.weeks * 7) + dur.days) * 24 + dur.hours;
- *units = DUR_HOURS;
- } else if (dur.days != 0 || dur.weeks != 0) {
- *value = dur.weeks * 7 + dur.days;
- *units = DUR_DAYS;
- } else {
- *value = 0;
- *units = DUR_MINUTES;
- }
-}
-
-/* Fills the repeat widgets with the values from the alarm component */
-static void
-alarm_to_repeat_widgets (Dialog *dialog, CalComponentAlarm *alarm)
-{
- CalAlarmRepeat repeat;
- int value;
- enum duration_units units;
-
- cal_component_alarm_get_repeat (alarm, &repeat);
-
- /* Sensitivity */
-
- if (repeat.repetitions == 0) {
- gtk_widget_set_sensitive (dialog->repeat_group, FALSE);
- e_dialog_toggle_set (dialog->repeat_toggle, FALSE);
- return;
- }
-
- gtk_widget_set_sensitive (dialog->repeat_group, TRUE);
- e_dialog_toggle_set (dialog->repeat_toggle, TRUE);
-
- /* Repetitions */
- e_dialog_spin_set (dialog->repeat_quantity, repeat.repetitions);
-
- /* Duration */
-
- normalize_duration (repeat.duration, &value, &units);
-
- e_dialog_spin_set (dialog->repeat_value, value);
- e_dialog_option_menu_set (dialog->repeat_unit, units, duration_units_map);
-}
-
-/* Fills the widgets with the values from the alarm component */
-static void
-alarm_to_dialog (Dialog *dialog, CalComponentAlarm *alarm)
-{
- CalAlarmAction action;
-
- alarm_to_repeat_widgets (dialog, alarm);
-
- cal_component_alarm_get_action (alarm, &action);
-
- switch (action) {
- case CAL_ALARM_NONE:
- g_assert_not_reached ();
- return;
-
- case CAL_ALARM_AUDIO:
- gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Audio Alarm Options"));
- gtk_widget_show (dialog->aalarm_group);
- gtk_widget_hide (dialog->dalarm_group);
- gtk_widget_hide (dialog->malarm_group);
- gtk_widget_hide (dialog->palarm_group);
- alarm_to_aalarm_widgets (dialog, alarm);
- break;
-
- case CAL_ALARM_DISPLAY:
- gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Message Alarm Options"));
- gtk_widget_hide (dialog->aalarm_group);
- gtk_widget_show (dialog->dalarm_group);
- gtk_widget_hide (dialog->malarm_group);
- gtk_widget_hide (dialog->palarm_group);
- alarm_to_dalarm_widgets (dialog, alarm);
- break;
-
- case CAL_ALARM_EMAIL:
- gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Mail Alarm Options"));
- gtk_widget_hide (dialog->aalarm_group);
- gtk_widget_hide (dialog->dalarm_group);
- gtk_widget_show (dialog->malarm_group);
- gtk_widget_hide (dialog->palarm_group);
- alarm_to_malarm_widgets (dialog, alarm);
- break;
-
- case CAL_ALARM_PROCEDURE:
- gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Program Alarm Options"));
- gtk_widget_hide (dialog->aalarm_group);
- gtk_widget_hide (dialog->dalarm_group);
- gtk_widget_hide (dialog->malarm_group);
- gtk_widget_show (dialog->palarm_group);
- alarm_to_palarm_widgets (dialog, alarm);
- break;
-
- case CAL_ALARM_UNKNOWN:
- gtk_window_set_title (GTK_WINDOW (dialog->toplevel), _("Unknown Alarm Options"));
- break;
-
- default:
- g_assert_not_reached ();
- return;
- }
-}
-
-
-
-/* Fills the alarm data with the values from the repeat/duration widgets */
-static void
-repeat_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm)
-{
- CalAlarmRepeat repeat;
-
- if (!e_dialog_toggle_get (dialog->repeat_toggle)) {
- repeat.repetitions = 0;
-
- cal_component_alarm_set_repeat (alarm, repeat);
- return;
- }
-
- repeat.repetitions = e_dialog_spin_get_int (dialog->repeat_quantity);
-
- memset (&repeat.duration, 0, sizeof (repeat.duration));
- switch (e_dialog_option_menu_get (dialog->repeat_unit, duration_units_map)) {
- case DUR_MINUTES:
- repeat.duration.minutes = e_dialog_spin_get_int (dialog->repeat_value);
- break;
-
- case DUR_HOURS:
- repeat.duration.hours = e_dialog_spin_get_int (dialog->repeat_value);
- break;
-
- case DUR_DAYS:
- repeat.duration.days = e_dialog_spin_get_int (dialog->repeat_value);
- break;
-
- default:
- g_assert_not_reached ();
- }
-
- cal_component_alarm_set_repeat (alarm, repeat);
-
-}
-
-/* Fills the audio alarm data with the values from the widgets */
-static void
-aalarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm)
-{
- char *url;
- icalattach *attach;
-
- url = e_dialog_editable_get (dialog->aalarm_attach);
- attach = icalattach_new_from_url (url ? url : "");
- g_free (url);
-
- cal_component_alarm_set_attach (alarm, attach);
- icalattach_unref (attach);
-}
-
-/* Fills the display alarm data with the values from the widgets */
-static void
-dalarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm)
-{
- char *str;
- CalComponentText description;
- icalcomponent *icalcomp;
- icalproperty *icalprop;
-
- str = e_dialog_editable_get (dialog->dalarm_description);
- description.value = str;
- description.altrep = NULL;
-
- cal_component_alarm_set_description (alarm, &description);
- g_free (str);
-
- /* remove the X-EVOLUTION-NEEDS-DESCRIPTION property, so that
- * we don't re-set the alarm's description */
- icalcomp = cal_component_alarm_get_icalcomponent (alarm);
- icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
- while (icalprop) {
- const char *x_name;
-
- x_name = icalproperty_get_x_name (icalprop);
- if (!strcmp (x_name, "X-EVOLUTION-NEEDS-DESCRIPTION")) {
- icalcomponent_remove_property (icalcomp, icalprop);
- break;
- }
-
- icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
- }
-}
-
-/* Fills the mail alarm data with the values from the widgets */
-static void
-malarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm)
-{
- /* FIXME: nothing for now; we don't support mail alarms */
-}
-
-/* Fills the procedure alarm data with the values from the widgets */
-static void
-palarm_widgets_to_alarm (Dialog *dialog, CalComponentAlarm *alarm)
-{
- char *program;
- icalattach *attach;
- char *str;
- CalComponentText description;
- icalcomponent *icalcomp;
- icalproperty *icalprop;
-
- program = e_dialog_editable_get (dialog->palarm_program);
- attach = icalattach_new_from_url (program ? program : "");
- g_free (program);
-
- cal_component_alarm_set_attach (alarm, attach);
- icalattach_unref (attach);
-
- str = e_dialog_editable_get (dialog->palarm_args);
- description.value = str;
- description.altrep = NULL;
-
- cal_component_alarm_set_description (alarm, &description);
- g_free (str);
-
- /* remove the X-EVOLUTION-NEEDS-DESCRIPTION property, so that
- * we don't re-set the alarm's description */
- icalcomp = cal_component_alarm_get_icalcomponent (alarm);
- icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
- while (icalprop) {
- const char *x_name;
-
- x_name = icalproperty_get_x_name (icalprop);
- if (!strcmp (x_name, "X-EVOLUTION-NEEDS-DESCRIPTION")) {
- icalcomponent_remove_property (icalcomp, icalprop);
- break;
- }
-
- icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
- }
-}
-
-/* Fills the alarm data with the values from the widgets */
-static void
-dialog_to_alarm (Dialog *dialog, CalComponentAlarm *alarm)
-{
- CalAlarmAction action;
-
- repeat_widgets_to_alarm (dialog, alarm);
-
- cal_component_alarm_get_action (alarm, &action);
-
- switch (action) {
- case CAL_ALARM_NONE:
- g_assert_not_reached ();
- break;
-
- case CAL_ALARM_AUDIO:
- aalarm_widgets_to_alarm (dialog, alarm);
- break;
-
- case CAL_ALARM_DISPLAY:
- dalarm_widgets_to_alarm (dialog, alarm);
- break;
-
- case CAL_ALARM_EMAIL:
- malarm_widgets_to_alarm (dialog, alarm);
- break;
-
- case CAL_ALARM_PROCEDURE:
- palarm_widgets_to_alarm (dialog, alarm);
- break;
-
- case CAL_ALARM_UNKNOWN:
- break;
-
- default:
- g_assert_not_reached ();
- }
-}
-
-
-
-/**
- * alarm_options_dialog_run:
- * @alarm: Alarm that is to be edited.
- *
- * Runs an alarm options dialog modally.
- *
- * Return value: TRUE if the dialog could be created, FALSE otherwise.
- **/
-gboolean
-alarm_options_dialog_run (CalComponentAlarm *alarm)
-{
- Dialog dialog;
-
- g_return_val_if_fail (alarm != NULL, FALSE);
-
- dialog.xml = glade_xml_new (EVOLUTION_GLADEDIR "/alarm-options.glade", NULL);
- if (!dialog.xml) {
- g_message ("alarm_options_dialog_new(): Could not load the Glade XML file!");
- return FALSE;
- }
-
- if (!get_widgets (&dialog)) {
- gtk_object_unref (GTK_OBJECT (dialog.xml));
- return FALSE;
- }
-
- init_widgets (&dialog);
-
- alarm_to_dialog (&dialog, alarm);
-
- gtk_widget_show (dialog.toplevel);
- gtk_main ();
-
- if (!dialog.canceled)
- dialog_to_alarm (&dialog, alarm);
-
- gtk_widget_destroy (dialog.toplevel);
- gtk_object_unref (GTK_OBJECT (dialog.xml));
-
- return TRUE;
-}
diff --git a/calendar/gui/dialogs/alarm-options.glade b/calendar/gui/dialogs/alarm-options.glade
deleted file mode 100644
index 645d57758e..0000000000
--- a/calendar/gui/dialogs/alarm-options.glade
+++ /dev/null
@@ -1,398 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>Dialogs</name>
- <program_name>dialogs</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
-</project>
-
-<widget>
- <class>GtkWindow</class>
- <name>alarm-options-toplevel</name>
- <title></title>
- <type>GTK_WINDOW_DIALOG</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>True</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>True</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox1</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame1</name>
- <label>Alarm Repeat</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox1</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>repeat-toggle</name>
- <can_focus>True</can_focus>
- <has_focus>True</has_focus>
- <label>Repeat the alarm</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>repeat-group</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkSpinButton</class>
- <name>repeat-quantity</name>
- <can_focus>True</can_focus>
- <climb_rate>1</climb_rate>
- <digits>0</digits>
- <numeric>False</numeric>
- <update_policy>GTK_UPDATE_ALWAYS</update_policy>
- <snap>False</snap>
- <wrap>False</wrap>
- <value>1</value>
- <lower>1</lower>
- <upper>999</upper>
- <step>1</step>
- <page>10</page>
- <page_size>10</page_size>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label1</name>
- <label>extra times every</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkSpinButton</class>
- <name>repeat-value</name>
- <can_focus>True</can_focus>
- <climb_rate>1</climb_rate>
- <digits>0</digits>
- <numeric>False</numeric>
- <update_policy>GTK_UPDATE_ALWAYS</update_policy>
- <snap>False</snap>
- <wrap>False</wrap>
- <value>1</value>
- <lower>0</lower>
- <upper>999</upper>
- <step>1</step>
- <page>10</page>
- <page_size>10</page_size>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>repeat-unit</name>
- <can_focus>True</can_focus>
- <items>minutes
-hours
-days
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>dalarm-group</name>
- <visible>False</visible>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label2</name>
- <label>Message to Display</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow1</name>
- <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkText</class>
- <name>dalarm-description</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text></text>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>aalarm-group</name>
- <visible>False</visible>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label3</name>
- <label>Play sound:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GnomeFileEntry</class>
- <name>file-entry1</name>
- <max_saved>10</max_saved>
- <directory>False</directory>
- <modal>False</modal>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkEntry</class>
- <child_name>GnomeEntry:entry</child_name>
- <name>aalarm-attach</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>malarm-group</name>
- <visible>False</visible>
- <label>Evolution does not yet support email notification for reminders. You will not be able to edit the options for this reminder.</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>True</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>palarm-group</name>
- <visible>False</visible>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label5</name>
- <label>Run program:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>palarm-program</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label6</name>
- <label>With these arguments:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkEntry</class>
- <name>palarm-args</name>
- <can_focus>True</can_focus>
- <editable>True</editable>
- <text_visible>True</text_visible>
- <text_max_length>0</text_max_length>
- <text></text>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHButtonBox</class>
- <name>hbuttonbox1</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>30</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button-ok</name>
- <can_default>True</can_default>
- <has_default>True</has_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button-cancel</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- <relief>GTK_RELIEF_NORMAL</relief>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/calendar/gui/dialogs/alarm-options.h b/calendar/gui/dialogs/alarm-options.h
deleted file mode 100644
index 388b737541..0000000000
--- a/calendar/gui/dialogs/alarm-options.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Evolution calendar - Alarm options dialog
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@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 ALARM_OPTIONS_H
-#define ALARM_OPTIONS_H
-
-#include <cal-util/cal-component.h>
-
-gboolean alarm_options_dialog_run (CalComponentAlarm *alarm);
-
-#endif
diff --git a/calendar/gui/dialogs/alarm-page.c b/calendar/gui/dialogs/alarm-page.c
deleted file mode 100644
index 48494e7f54..0000000000
--- a/calendar/gui/dialogs/alarm-page.c
+++ /dev/null
@@ -1,902 +0,0 @@
-/* Evolution calendar - Alarm page of the calendar component dialogs
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@ximian.com>
- * Miguel de Icaza <miguel@ximian.com>
- * Seth Alves <alves@hungry.com>
- * JP Rosevear <jpr@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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <string.h>
-#include <gtk/gtksignal.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <glade/glade.h>
-#include <gal/widgets/e-unicode.h>
-#include "e-util/e-dialog-widgets.h"
-#include "e-util/e-time-utils.h"
-#include "cal-util/cal-util.h"
-#include "cal-util/timeutil.h"
-#include "../calendar-config.h"
-#include "comp-editor-util.h"
-#include "alarm-options.h"
-#include "alarm-page.h"
-
-
-
-/* Private part of the AlarmPage structure */
-struct _AlarmPagePrivate {
- /* Glade XML data */
- GladeXML *xml;
-
- /* Widgets from the Glade file */
-
- GtkWidget *main;
-
- GtkWidget *summary;
- GtkWidget *date_time;
-
- GtkWidget *list;
- GtkWidget *add;
- GtkWidget *delete;
-
- GtkWidget *action;
- GtkWidget *interval_value;
- GtkWidget *value_units;
- GtkWidget *relative;
- GtkWidget *time;
-
- GtkWidget *button_options;
-
- /* Alarm options dialog and the alarm we maintain */
- CalComponentAlarm *alarm;
-
- gboolean updating;
-};
-
-/* "relative" types */
-enum {
- BEFORE,
- AFTER
-};
-
-/* Time units */
-enum {
- MINUTES,
- HOURS,
- DAYS
-};
-
-/* Option menu maps */
-static const int action_map[] = {
- CAL_ALARM_DISPLAY,
- CAL_ALARM_AUDIO,
- CAL_ALARM_PROCEDURE,
- -1
-};
-
-static const int value_map[] = {
- MINUTES,
- HOURS,
- DAYS,
- -1
-};
-
-static const int relative_map[] = {
- BEFORE,
- AFTER,
- -1
-};
-
-static const int time_map[] = {
- CAL_ALARM_TRIGGER_RELATIVE_START,
- CAL_ALARM_TRIGGER_RELATIVE_END,
- -1
-};
-
-
-
-static void alarm_page_class_init (AlarmPageClass *class);
-static void alarm_page_init (AlarmPage *apage);
-static void alarm_page_destroy (GtkObject *object);
-
-static GtkWidget *alarm_page_get_widget (CompEditorPage *page);
-static void alarm_page_focus_main_widget (CompEditorPage *page);
-static void alarm_page_fill_widgets (CompEditorPage *page, CalComponent *comp);
-static gboolean alarm_page_fill_component (CompEditorPage *page, CalComponent *comp);
-static void alarm_page_set_summary (CompEditorPage *page, const char *summary);
-static void alarm_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates);
-
-static CompEditorPageClass *parent_class = NULL;
-
-
-
-/**
- * alarm_page_get_type:
- *
- * Registers the #AlarmPage class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the #AlarmPage class.
- **/
-GtkType
-alarm_page_get_type (void)
-{
- static GtkType alarm_page_type;
-
- if (!alarm_page_type) {
- static const GtkTypeInfo alarm_page_info = {
- "AlarmPage",
- sizeof (AlarmPage),
- sizeof (AlarmPageClass),
- (GtkClassInitFunc) alarm_page_class_init,
- (GtkObjectInitFunc) alarm_page_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- alarm_page_type = gtk_type_unique (TYPE_COMP_EDITOR_PAGE,
- &alarm_page_info);
- }
-
- return alarm_page_type;
-}
-
-/* Class initialization function for the alarm page */
-static void
-alarm_page_class_init (AlarmPageClass *class)
-{
- CompEditorPageClass *editor_page_class;
- GtkObjectClass *object_class;
-
- editor_page_class = (CompEditorPageClass *) class;
- object_class = (GtkObjectClass *) class;
-
- parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE);
-
- editor_page_class->get_widget = alarm_page_get_widget;
- editor_page_class->focus_main_widget = alarm_page_focus_main_widget;
- editor_page_class->fill_widgets = alarm_page_fill_widgets;
- editor_page_class->fill_component = alarm_page_fill_component;
- editor_page_class->set_summary = alarm_page_set_summary;
- editor_page_class->set_dates = alarm_page_set_dates;
-
- object_class->destroy = alarm_page_destroy;
-}
-
-/* Object initialization function for the alarm page */
-static void
-alarm_page_init (AlarmPage *apage)
-{
- AlarmPagePrivate *priv;
- icalcomponent *icalcomp;
- icalproperty *icalprop;
-
- priv = g_new0 (AlarmPagePrivate, 1);
- apage->priv = priv;
-
- priv->xml = NULL;
-
- priv->main = NULL;
- priv->summary = NULL;
- priv->date_time = NULL;
- priv->list = NULL;
- priv->add = NULL;
- priv->delete = NULL;
- priv->action = NULL;
- priv->interval_value = NULL;
- priv->value_units = NULL;
- priv->relative = NULL;
- priv->time = NULL;
- priv->button_options = NULL;
-
- /* create the default alarm, which will contain the
- * X-EVOLUTION-NEEDS-DESCRIPTION property, so that we
- * set a correct description if none is ser */
- priv->alarm = cal_component_alarm_new ();
-
- icalcomp = cal_component_alarm_get_icalcomponent (priv->alarm);
- icalprop = icalproperty_new_x ("1");
- icalproperty_set_x_name (icalprop, "X-EVOLUTION-NEEDS-DESCRIPTION");
- icalcomponent_add_property (icalcomp, icalprop);
-
- priv->updating = FALSE;
-}
-
-/* Destroy handler for the alarm page */
-static void
-alarm_page_destroy (GtkObject *object)
-{
- AlarmPage *apage;
- AlarmPagePrivate *priv;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_ALARM_PAGE (object));
-
- apage = ALARM_PAGE (object);
- priv = apage->priv;
-
- if (priv->xml) {
- gtk_object_unref (GTK_OBJECT (priv->xml));
- priv->xml = NULL;
- }
-
- if (priv->alarm) {
- cal_component_alarm_free (priv->alarm);
- priv->alarm = NULL;
- }
-
- g_free (priv);
- apage->priv = NULL;
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
-
-
-/* get_widget handler for the alarm page */
-static GtkWidget *
-alarm_page_get_widget (CompEditorPage *page)
-{
- AlarmPage *apage;
- AlarmPagePrivate *priv;
-
- apage = ALARM_PAGE (page);
- priv = apage->priv;
-
- return priv->main;
-}
-
-/* focus_main_widget handler for the alarm page */
-static void
-alarm_page_focus_main_widget (CompEditorPage *page)
-{
- AlarmPage *apage;
- AlarmPagePrivate *priv;
-
- apage = ALARM_PAGE (page);
- priv = apage->priv;
-
- gtk_widget_grab_focus (priv->action);
-}
-
-/* Fills the widgets with default values */
-static void
-clear_widgets (AlarmPage *apage)
-{
- AlarmPagePrivate *priv;
-
- priv = apage->priv;
-
- /* Summary */
- gtk_label_set_text (GTK_LABEL (priv->summary), "");
-
- /* Start date */
- gtk_label_set_text (GTK_LABEL (priv->date_time), "");
-
- /* Sane defaults */
- e_dialog_option_menu_set (priv->action, CAL_ALARM_DISPLAY, action_map);
- e_dialog_spin_set (priv->interval_value, 15);
- e_dialog_option_menu_set (priv->value_units, MINUTES, value_map);
- e_dialog_option_menu_set (priv->relative, BEFORE, relative_map);
- e_dialog_option_menu_set (priv->time, CAL_ALARM_TRIGGER_RELATIVE_START, time_map);
-
- /* List data */
- gtk_clist_clear (GTK_CLIST (priv->list));
-}
-
-/* Builds a string for the duration of the alarm. If the duration is zero, returns NULL. */
-static char *
-get_alarm_duration_string (struct icaldurationtype *duration)
-{
- GString *string = g_string_new (NULL);
- char *ret;
- gboolean have_something;
-
- have_something = FALSE;
-
- if (duration->days > 1) {
- g_string_sprintf (string, _("%d days"), duration->days);
- have_something = TRUE;
- } else if (duration->days == 1) {
- g_string_append (string, _("1 day"));
- have_something = TRUE;
- }
-
- if (duration->weeks > 1) {
- g_string_sprintf (string, _("%d weeks"), duration->weeks);
- have_something = TRUE;
- } else if (duration->weeks == 1) {
- g_string_append (string, _("1 week"));
- have_something = TRUE;
- }
-
- if (duration->hours > 1) {
- g_string_sprintf (string, _("%d hours"), duration->hours);
- have_something = TRUE;
- } else if (duration->hours == 1) {
- g_string_append (string, _("1 hour"));
- have_something = TRUE;
- }
-
- if (duration->minutes > 1) {
- g_string_sprintf (string, _("%d minutes"), duration->minutes);
- have_something = TRUE;
- } else if (duration->minutes == 1) {
- g_string_append (string, _("1 minute"));
- have_something = TRUE;
- }
-
- if (duration->seconds > 1) {
- g_string_sprintf (string, _("%d seconds"), duration->seconds);
- have_something = TRUE;
- } else if (duration->seconds == 1) {
- g_string_append (string, _("1 second"));
- have_something = TRUE;
- }
-
- if (have_something) {
- ret = string->str;
- g_string_free (string, FALSE);
- return ret;
- } else {
- g_string_free (string, TRUE);
- return NULL;
- }
-}
-
-static char *
-get_alarm_string (CalComponentAlarm *alarm)
-{
- CalAlarmAction action;
- CalAlarmTrigger trigger;
- char string[256];
- char *base, *str = NULL, *dur;
-
- string [0] = '\0';
-
- cal_component_alarm_get_action (alarm, &action);
- cal_component_alarm_get_trigger (alarm, &trigger);
-
- switch (action) {
- case CAL_ALARM_AUDIO:
- base = _("Play a sound");
- break;
-
- case CAL_ALARM_DISPLAY:
- base = _("Display a message");
- break;
-
- case CAL_ALARM_EMAIL:
- base = _("Send an email");
- break;
-
- case CAL_ALARM_PROCEDURE:
- base = _("Run a program");
- break;
-
- case CAL_ALARM_NONE:
- case CAL_ALARM_UNKNOWN:
- default:
- base = _("Unknown action to be performed");
- break;
- }
-
- /* FIXME: This does not look like it will localize correctly. */
-
- switch (trigger.type) {
- case CAL_ALARM_TRIGGER_RELATIVE_START:
- dur = get_alarm_duration_string (&trigger.u.rel_duration);
-
- if (dur) {
- if (trigger.u.rel_duration.is_neg)
- str = g_strdup_printf (_("%s %s before the start of the appointment"),
- base, dur);
- else
- str = g_strdup_printf (_("%s %s after the start of the appointment"),
- base, dur);
-
- g_free (dur);
- } else
- str = g_strdup_printf (_("%s at the start of the appointment"), base);
-
- break;
-
- case CAL_ALARM_TRIGGER_RELATIVE_END:
- dur = get_alarm_duration_string (&trigger.u.rel_duration);
-
- if (dur) {
- if (trigger.u.rel_duration.is_neg)
- str = g_strdup_printf (_("%s %s before the end of the appointment"),
- base, dur);
- else
- str = g_strdup_printf (_("%s %s after the end of the appointment"),
- base, dur);
-
- g_free (dur);
- } else
- str = g_strdup_printf (_("%s at the end of the appointment"), base);
-
- break;
-
- case CAL_ALARM_TRIGGER_ABSOLUTE: {
- struct icaltimetype itt;
- icaltimezone *utc_zone, *current_zone;
- char *location;
- struct tm tm;
- char buf[256];
-
- /* Absolute triggers come in UTC, so convert them to the local timezone */
-
- itt = trigger.u.abs_time;
-
- utc_zone = icaltimezone_get_utc_timezone ();
- location = calendar_config_get_timezone ();
- current_zone = icaltimezone_get_builtin_timezone (location);
-
- tm = icaltimetype_to_tm_with_zone (&itt, utc_zone, current_zone);
-
- e_time_format_date_and_time (&tm, calendar_config_get_24_hour_format (),
- FALSE, FALSE, buf, sizeof (buf));
-
- str = g_strdup_printf (_("%s at %s"), base, buf);
-
- break; }
-
- case CAL_ALARM_TRIGGER_NONE:
- default:
- str = g_strdup_printf (_("%s for an unknown trigger type"), base);
- break;
- }
-
- return str;
-}
-
-/* Appends an alarm to the list */
-static void
-append_reminder (AlarmPage *apage, CalComponentAlarm *alarm)
-{
- AlarmPagePrivate *priv;
- GtkCList *clist;
- char *c[1];
- int i;
-
- priv = apage->priv;
-
- clist = GTK_CLIST (priv->list);
-
- c[0] = get_alarm_string (alarm);
- i = gtk_clist_append (clist, c);
-
- gtk_clist_set_row_data_full (clist, i, alarm, (GtkDestroyNotify) cal_component_alarm_free);
- gtk_clist_select_row (clist, i, 0);
- g_free (c[0]);
-
- gtk_widget_set_sensitive (priv->delete, TRUE);
-}
-
-/* fill_widgets handler for the alarm page */
-static void
-alarm_page_fill_widgets (CompEditorPage *page, CalComponent *comp)
-{
- AlarmPage *apage;
- AlarmPagePrivate *priv;
- CalComponentText text;
- GList *alarms, *l;
- GtkCList *clist;
- CompEditorPageDates dates;
-
- apage = ALARM_PAGE (page);
- priv = apage->priv;
-
- /* Don't send off changes during this time */
- priv->updating = TRUE;
-
- /* Clean the page */
- clear_widgets (apage);
-
- /* Summary */
- cal_component_get_summary (comp, &text);
- alarm_page_set_summary (page, text.value);
-
- /* Dates */
- comp_editor_dates (&dates, comp);
- alarm_page_set_dates (page, &dates);
- comp_editor_free_dates (&dates);
-
- /* List */
- if (!cal_component_has_alarms (comp))
- goto out;
-
- alarms = cal_component_get_alarm_uids (comp);
-
- clist = GTK_CLIST (priv->list);
- for (l = alarms; l != NULL; l = l->next) {
- CalComponentAlarm *ca, *ca_copy;
- const char *auid;
-
- auid = l->data;
- ca = cal_component_get_alarm (comp, auid);
- g_assert (ca != NULL);
-
- ca_copy = cal_component_alarm_clone (ca);
- cal_component_alarm_free (ca);
-
- append_reminder (apage, ca_copy);
- }
- cal_obj_uid_list_free (alarms);
-
- out:
-
- priv->updating = FALSE;
-}
-
-/* fill_component handler for the alarm page */
-static gboolean
-alarm_page_fill_component (CompEditorPage *page, CalComponent *comp)
-{
- AlarmPage *apage;
- AlarmPagePrivate *priv;
- GList *list, *l;
- GtkCList *clist;
- int i;
-
- apage = ALARM_PAGE (page);
- priv = apage->priv;
-
- /* Remove all the alarms from the component */
-
- list = cal_component_get_alarm_uids (comp);
- for (l = list; l; l = l->next) {
- const char *auid;
-
- auid = l->data;
- cal_component_remove_alarm (comp, auid);
- }
- cal_obj_uid_list_free (list);
-
- /* Add the new alarms */
-
- clist = GTK_CLIST (priv->list);
- for (i = 0; i < clist->rows; i++) {
- CalComponentAlarm *alarm, *alarm_copy;
- icalcomponent *icalcomp;
- icalproperty *icalprop;
-
- alarm = gtk_clist_get_row_data (clist, i);
- g_assert (alarm != NULL);
-
- /* We set the description of the alarm if it's got
- * the X-EVOLUTION-NEEDS-DESCRIPTION property.
- */
- icalcomp = cal_component_alarm_get_icalcomponent (alarm);
- icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
- while (icalprop) {
- const char *x_name;
- CalComponentText summary;
-
- x_name = icalproperty_get_x_name (icalprop);
- if (!strcmp (x_name, "X-EVOLUTION-NEEDS-DESCRIPTION")) {
- cal_component_get_summary (comp, &summary);
- cal_component_alarm_set_description (alarm, &summary);
-
- icalcomponent_remove_property (icalcomp, icalprop);
- break;
- }
-
- icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
- }
-
- /* We clone the alarm to maintain the invariant that the alarm
- * structures in the list did *not* come from the component.
- */
-
- alarm_copy = cal_component_alarm_clone (alarm);
- cal_component_add_alarm (comp, alarm_copy);
- cal_component_alarm_free (alarm_copy);
- }
-
- return TRUE;
-}
-
-/* set_summary handler for the alarm page */
-static void
-alarm_page_set_summary (CompEditorPage *page, const char *summary)
-{
- AlarmPage *apage;
- AlarmPagePrivate *priv;
- gchar *s;
-
- apage = ALARM_PAGE (page);
- priv = apage->priv;
-
- s = e_utf8_to_gtk_string (priv->summary, summary);
- gtk_label_set_text (GTK_LABEL (priv->summary), s);
- g_free (s);
-}
-
-/* set_dates handler for the alarm page */
-static void
-alarm_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates)
-{
- AlarmPage *apage;
- AlarmPagePrivate *priv;
-
- apage = ALARM_PAGE (page);
- priv = apage->priv;
-
- comp_editor_date_label (dates, priv->date_time);
-}
-
-
-
-/* Gets the widgets from the XML file and returns if they are all available. */
-static gboolean
-get_widgets (AlarmPage *apage)
-{
- CompEditorPage *page = COMP_EDITOR_PAGE (apage);
- AlarmPagePrivate *priv;
- GSList *accel_groups;
- GtkWidget *toplevel;
-
- priv = apage->priv;
-
-#define GW(name) glade_xml_get_widget (priv->xml, name)
-
- priv->main = GW ("alarm-page");
- if (!priv->main)
- return FALSE;
-
- /* Get the GtkAccelGroup from the toplevel window, so we can install
- it when the notebook page is mapped. */
- toplevel = gtk_widget_get_toplevel (priv->main);
- accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel));
- if (accel_groups) {
- page->accel_group = accel_groups->data;
- gtk_accel_group_ref (page->accel_group);
- }
-
- gtk_widget_ref (priv->main);
- gtk_widget_unparent (priv->main);
-
- priv->summary = GW ("summary");
- priv->date_time = GW ("date-time");
-
- priv->list = GW ("list");
- priv->add = GW ("add");
- priv->delete = GW ("delete");
-
- priv->action = GW ("action");
- priv->interval_value = GW ("interval-value");
- priv->value_units = GW ("value-units");
- priv->relative = GW ("relative");
- priv->time = GW ("time");
-
- priv->button_options = GW ("button-options");
-
-#undef GW
-
- return (priv->summary
- && priv->date_time
- && priv->list
- && priv->add
- && priv->delete
- && priv->action
- && priv->interval_value
- && priv->value_units
- && priv->relative
- && priv->time
- && priv->button_options);
-}
-
-/* This is called when any field is changed; it notifies upstream. */
-static void
-field_changed_cb (GtkWidget *widget, gpointer data)
-{
- AlarmPage *apage;
- AlarmPagePrivate *priv;
-
- apage = ALARM_PAGE (data);
- priv = apage->priv;
-
- if (!priv->updating)
- comp_editor_page_notify_changed (COMP_EDITOR_PAGE (apage));
-}
-
-/* Callback used for the "add reminder" button */
-static void
-add_clicked_cb (GtkButton *button, gpointer data)
-{
- AlarmPage *apage;
- AlarmPagePrivate *priv;
- CalComponentAlarm *alarm;
- CalAlarmTrigger trigger;
-
- apage = ALARM_PAGE (data);
- priv = apage->priv;
-
- alarm = cal_component_alarm_clone (priv->alarm);
-
- memset (&trigger, 0, sizeof (CalAlarmTrigger));
- trigger.type = e_dialog_option_menu_get (priv->time, time_map);
- if (e_dialog_option_menu_get (priv->relative, relative_map) == BEFORE)
- trigger.u.rel_duration.is_neg = 1;
- else
- trigger.u.rel_duration.is_neg = 0;
-
- switch (e_dialog_option_menu_get (priv->value_units, value_map)) {
- case MINUTES:
- trigger.u.rel_duration.minutes =
- e_dialog_spin_get_int (priv->interval_value);
- break;
-
- case HOURS:
- trigger.u.rel_duration.hours =
- e_dialog_spin_get_int (priv->interval_value);
- break;
-
- case DAYS:
- trigger.u.rel_duration.days =
- e_dialog_spin_get_int (priv->interval_value);
- break;
-
- default:
- g_assert_not_reached ();
- }
- cal_component_alarm_set_trigger (alarm, trigger);
-
- cal_component_alarm_set_action (alarm, e_dialog_option_menu_get (priv->action, action_map));
-
- append_reminder (apage, alarm);
-}
-
-/* Callback used for the "delete reminder" button */
-static void
-delete_clicked_cb (GtkButton *button, gpointer data)
-{
- AlarmPage *apage;
- AlarmPagePrivate *priv;
- GtkCList *clist;
- int sel;
-
- apage = ALARM_PAGE (data);
- priv = apage->priv;
-
- clist = GTK_CLIST (priv->list);
- if (!clist->selection)
- return;
-
- sel = GPOINTER_TO_INT (clist->selection->data);
-
- gtk_clist_remove (clist, sel);
- if (sel >= clist->rows)
- sel--;
-
- if (clist->rows > 0)
- gtk_clist_select_row (clist, sel, 0);
- else
- gtk_widget_set_sensitive (priv->delete, FALSE);
-}
-
-/* Callback used when the alarm options button is clicked */
-static void
-button_options_clicked_cb (GtkWidget *widget, gpointer data)
-{
- AlarmPage *apage;
- AlarmPagePrivate *priv;
-
- apage = ALARM_PAGE (data);
- priv = apage->priv;
-
- cal_component_alarm_set_action (priv->alarm,
- e_dialog_option_menu_get (priv->action, action_map));
-
- if (!alarm_options_dialog_run (priv->alarm))
- g_message ("button_options_clicked_cb(): Could not create the alarm options dialog");
-}
-
-/* Hooks the widget signals */
-static void
-init_widgets (AlarmPage *apage)
-{
- AlarmPagePrivate *priv;
-
- priv = apage->priv;
-
- /* Reminder buttons */
- gtk_signal_connect (GTK_OBJECT (priv->add), "clicked",
- GTK_SIGNAL_FUNC (add_clicked_cb), apage);
- gtk_signal_connect (GTK_OBJECT (priv->delete), "clicked",
- GTK_SIGNAL_FUNC (delete_clicked_cb), apage);
-
- /* Connect the default signal handler to use to make sure we notify
- * upstream of changes to the widget values.
- */
- gtk_signal_connect (GTK_OBJECT (priv->add), "clicked",
- GTK_SIGNAL_FUNC (field_changed_cb), apage);
- gtk_signal_connect (GTK_OBJECT (priv->delete), "clicked",
- GTK_SIGNAL_FUNC (field_changed_cb), apage);
-
- /* Options button */
- gtk_signal_connect (GTK_OBJECT (priv->button_options), "clicked",
- GTK_SIGNAL_FUNC (button_options_clicked_cb), apage);
-}
-
-
-
-/**
- * alarm_page_construct:
- * @apage: An alarm page.
- *
- * Constructs an alarm page by loading its Glade data.
- *
- * Return value: The same object as @apage, or NULL if the widgets could not be
- * created.
- **/
-AlarmPage *
-alarm_page_construct (AlarmPage *apage)
-{
- AlarmPagePrivate *priv;
-
- priv = apage->priv;
-
- priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/alarm-page.glade",
- NULL);
- if (!priv->xml) {
- g_message ("alarm_page_construct(): "
- "Could not load the Glade XML file!");
- return NULL;
- }
-
- if (!get_widgets (apage)) {
- g_message ("alarm_page_construct(): "
- "Could not find all widgets in the XML file!");
- return NULL;
- }
-
- init_widgets (apage);
-
- return apage;
-}
-
-/**
- * alarm_page_new:
- *
- * Creates a new alarm page.
- *
- * Return value: A newly-created alarm page, or NULL if the page could not be
- * created.
- **/
-AlarmPage *
-alarm_page_new (void)
-{
- AlarmPage *apage;
-
- apage = gtk_type_new (TYPE_ALARM_PAGE);
- if (!alarm_page_construct (apage)) {
- gtk_object_unref (GTK_OBJECT (apage));
- return NULL;
- }
-
- return apage;
-}
diff --git a/calendar/gui/dialogs/alarm-page.glade b/calendar/gui/dialogs/alarm-page.glade
deleted file mode 100644
index 56c6f6ada1..0000000000
--- a/calendar/gui/dialogs/alarm-page.glade
+++ /dev/null
@@ -1,381 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>alarm-page</name>
- <program_name>alarm-page</program_name>
- <directory></directory>
- <source_directory>.</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
- <output_main_file>False</output_main_file>
- <output_support_files>False</output_support_files>
- <output_build_files>False</output_build_files>
-</project>
-
-<widget>
- <class>GtkWindow</class>
- <name>alarm-toplevel</name>
- <visible>False</visible>
- <title>window1</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
-
- <widget>
- <class>GtkVBox</class>
- <name>alarm-page</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame33</name>
- <label>Basics</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkTable</class>
- <name>table13</name>
- <border_width>4</border_width>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>2</row_spacing>
- <column_spacing>2</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label62</name>
- <label>Summary:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label63</name>
- <label>Date/Time:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>summary</name>
- <width>10</width>
- <label></label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>4</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>date-time</name>
- <width>10</width>
- <label></label>
- <justify>GTK_JUSTIFY_LEFT</justify>
- <wrap>False</wrap>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xpad>4</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame34</name>
- <label>Reminders</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox53</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox54</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>action</name>
- <can_focus>True</can_focus>
- <items>Display a message
-Play a sound
-Run a program
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkSpinButton</class>
- <name>interval-value</name>
- <can_focus>True</can_focus>
- <climb_rate>1</climb_rate>
- <digits>0</digits>
- <numeric>True</numeric>
- <update_policy>GTK_UPDATE_ALWAYS</update_policy>
- <snap>False</snap>
- <wrap>False</wrap>
- <value>1</value>
- <lower>0</lower>
- <upper>999</upper>
- <step>1</step>
- <page>10</page>
- <page_size>10</page_size>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>value-units</name>
- <can_focus>True</can_focus>
- <items>minute(s)
-hour(s)
-day(s)
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>relative</name>
- <can_focus>True</can_focus>
- <items>before
-after
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>time</name>
- <can_focus>True</can_focus>
- <items>start of appointment
-end of appointment
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button-options</name>
- <can_focus>True</can_focus>
- <label>_Options...</label>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox55</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkScrolledWindow</class>
- <name>scrolledwindow13</name>
- <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
- <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy>
- <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
- <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkCList</class>
- <name>list</name>
- <can_focus>True</can_focus>
- <columns>1</columns>
- <column_widths>80</column_widths>
- <selection_mode>GTK_SELECTION_BROWSE</selection_mode>
- <show_titles>False</show_titles>
- <shadow_type>GTK_SHADOW_IN</shadow_type>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>CList:title</child_name>
- <name>label64</name>
- <label>label55</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkVButtonBox</class>
- <name>vbuttonbox2</name>
- <layout_style>GTK_BUTTONBOX_START</layout_style>
- <spacing>10</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>add</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_Add</label>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>delete</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <label>_Delete</label>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/calendar/gui/dialogs/alarm-page.h b/calendar/gui/dialogs/alarm-page.h
deleted file mode 100644
index aa1a6be26b..0000000000
--- a/calendar/gui/dialogs/alarm-page.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Evolution calendar - Alarm page of the calendar component dialogs
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@ximian.com>
- * Miguel de Icaza <miguel@ximian.com>
- * Seth Alves <alves@hungry.com>
- * JP Rosevear <jpr@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 ALARM_PAGE_H
-#define ALARM_PAGE_H
-
-#include "comp-editor-page.h"
-
-BEGIN_GNOME_DECLS
-
-
-
-#define TYPE_ALARM_PAGE (alarm_page_get_type ())
-#define ALARM_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_ALARM_PAGE, AlarmPage))
-#define ALARM_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_ALARM_PAGE, AlarmPageClass))
-#define IS_ALARM_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_ALARM_PAGE))
-#define IS_ALARM_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_ALARM_PAGE))
-
-typedef struct _AlarmPagePrivate AlarmPagePrivate;
-
-typedef struct {
- CompEditorPage page;
-
- /* Private data */
- AlarmPagePrivate *priv;
-} AlarmPage;
-
-typedef struct {
- CompEditorPageClass parent_class;
-} AlarmPageClass;
-
-
-GtkType alarm_page_get_type (void);
-AlarmPage *alarm_page_construct (AlarmPage *apage);
-AlarmPage *alarm_page_new (void);
-
-
-
-END_GNOME_DECLS
-
-#endif
diff --git a/calendar/gui/dialogs/cal-prefs-dialog.c b/calendar/gui/dialogs/cal-prefs-dialog.c
deleted file mode 100644
index 6f4378f7a8..0000000000
--- a/calendar/gui/dialogs/cal-prefs-dialog.c
+++ /dev/null
@@ -1,688 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * Authors :
- * Damon Chaplin <damon@ximian.com>
- * Ettore Perazzoli <ettore@ximian.com>
- *
- * Copyright 2000, 2001, 2002 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
- */
-
-/*
- * CalPrefsDialog - a GtkObject which handles a libglade-loaded dialog
- * to edit the calendar preference settings.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "../e-timezone-entry.h"
-#include "cal-prefs-dialog.h"
-#include "../calendar-config.h"
-#include "../calendar-commands.h"
-#include "../e-tasks.h"
-
-#include <libgnomeui/gnome-color-picker.h>
-#include <glade/glade.h>
-#include <gal/util/e-util.h>
-#include <e-util/e-dialog-widgets.h>
-#include <widgets/misc/e-dateedit.h>
-
-
-struct _DialogData {
- /* Glade XML data */
- GladeXML *xml;
-
- GtkWidget *page;
-
- GtkWidget *timezone;
- GtkWidget *working_days[7];
- GtkWidget *week_start_day;
- GtkWidget *start_of_day;
- GtkWidget *end_of_day;
- GtkWidget *use_12_hour;
- GtkWidget *use_24_hour;
- GtkWidget *time_divisions;
- GtkWidget *show_end_times;
- GtkWidget *compress_weekend;
- GtkWidget *dnav_show_week_no;
-
- /* Widgets for the task list options */
- GtkWidget *tasks_due_today_color;
- GtkWidget *tasks_overdue_color;
-
- GtkWidget *tasks_hide_completed_checkbutton;
- GtkWidget *tasks_hide_completed_spinbutton;
- GtkWidget *tasks_hide_completed_optionmenu;
-
- /* Other page options */
- GtkWidget *confirm_delete;
- GtkWidget *default_reminder;
- GtkWidget *default_reminder_interval;
- GtkWidget *default_reminder_units;
-};
-typedef struct _DialogData DialogData;
-
-static const int week_start_day_map[] = {
- 1, 2, 3, 4, 5, 6, 0, -1
-};
-
-static const int time_division_map[] = {
- 60, 30, 15, 10, 5, -1
-};
-
-/* The following two are kept separate in case we need to re-order each menu individually */
-static const int hide_completed_units_map[] = {
- CAL_MINUTES, CAL_HOURS, CAL_DAYS, -1
-};
-
-static const int default_reminder_units_map[] = {
- CAL_MINUTES, CAL_HOURS, CAL_DAYS, -1
-};
-
-
-static gboolean get_widgets (DialogData *data);
-
-static void widget_changed_callback (GtkWidget *, void *data);
-static void connect_changed (GtkWidget *widget, const char *signal_name, EvolutionConfigControl *config_control);
-static void setup_changes (DialogData *data, EvolutionConfigControl *config_control);
-
-static void init_widgets (DialogData *data);
-static void show_config (DialogData *data);
-static void update_config (DialogData *dialog_data);
-
-static void config_control_apply_callback (EvolutionConfigControl *config_control, void *data);
-static void config_control_destroy_callback (GtkObject *object, void *data);
-
-static void cal_prefs_dialog_use_24_hour_toggled(GtkWidget *button, void *data);
-static void cal_prefs_dialog_end_of_day_changed (GtkWidget *button, void *data);
-static void cal_prefs_dialog_start_of_day_changed (GtkWidget *button, void *data);
-static void cal_prefs_dialog_hide_completed_tasks_toggled (GtkWidget *button, void *data);
-
-GtkWidget *cal_prefs_dialog_create_time_edit (void);
-
-
-/**
- * cal_prefs_dialog_new:
- *
- * Creates a new #CalPrefsDialog.
- *
- * Return value: a new #CalPrefsDialog.
- **/
-EvolutionConfigControl *
-cal_prefs_dialog_new (void)
-{
- DialogData *dialog_data;
- EvolutionConfigControl *config_control;
-
- dialog_data = g_new0 (DialogData, 1);
-
- /* Load the content widgets */
-
- dialog_data->xml = glade_xml_new (EVOLUTION_GLADEDIR "/cal-prefs-dialog.glade", NULL);
- if (!dialog_data->xml) {
- g_message ("cal_prefs_dialog_construct(): Could not load the Glade XML file!");
- return NULL;
- }
-
- if (!get_widgets (dialog_data)) {
- g_message ("cal_prefs_dialog_construct(): Could not find all widgets in the XML file!");
- return NULL;
- }
-
- init_widgets (dialog_data);
- show_config (dialog_data);
-
- gtk_widget_ref (dialog_data->page);
- gtk_container_remove (GTK_CONTAINER (dialog_data->page->parent), dialog_data->page);
- config_control = evolution_config_control_new (dialog_data->page);
- gtk_widget_unref (dialog_data->page);
-
- gtk_signal_connect (GTK_OBJECT (config_control), "apply",
- GTK_SIGNAL_FUNC (config_control_apply_callback), dialog_data);
- gtk_signal_connect (GTK_OBJECT (config_control), "destroy",
- GTK_SIGNAL_FUNC (config_control_destroy_callback), dialog_data);
-
- setup_changes (dialog_data, config_control);
-
- return config_control;
-}
-
-static void
-widget_changed_callback (GtkWidget *widget,
- void *data)
-{
- EvolutionConfigControl *config_control;
-
- config_control = EVOLUTION_CONFIG_CONTROL (data);
-
- evolution_config_control_changed (config_control);
-}
-
-/* ^*&%!!#! GnomeColorPicker. */
-static void
-color_set_callback (GnomeColorPicker *cp,
- guint r,
- guint g,
- guint b,
- guint a,
- void *data)
-{
- EvolutionConfigControl *config_control;
-
- config_control = EVOLUTION_CONFIG_CONTROL (data);
-
- evolution_config_control_changed (config_control);
-}
-
-static void
-connect_changed (GtkWidget *widget,
- const char *signal_name,
- EvolutionConfigControl *config_control)
-{
- gtk_signal_connect (GTK_OBJECT (widget), signal_name,
- GTK_SIGNAL_FUNC (widget_changed_callback), config_control);
-}
-
-static void
-setup_changes (DialogData *dialog_data,
- EvolutionConfigControl *config_control)
-{
- int i;
-
- for (i = 0; i < 7; i ++)
- connect_changed (dialog_data->working_days[i], "toggled", config_control);
-
- connect_changed (dialog_data->timezone, "changed", config_control);
-
- connect_changed (dialog_data->start_of_day, "changed", config_control);
- connect_changed (dialog_data->end_of_day, "changed", config_control);
-
- connect_changed (GTK_OPTION_MENU (dialog_data->week_start_day)->menu, "selection_done", config_control);
-
- connect_changed (dialog_data->use_12_hour, "toggled", config_control);
-
- connect_changed (GTK_OPTION_MENU (dialog_data->time_divisions)->menu, "selection_done", config_control);
-
- connect_changed (dialog_data->show_end_times, "toggled", config_control);
- connect_changed (dialog_data->compress_weekend, "toggled", config_control);
- connect_changed (dialog_data->dnav_show_week_no, "toggled", config_control);
-
- connect_changed (dialog_data->tasks_hide_completed_checkbutton, "toggled", config_control);
- connect_changed (dialog_data->tasks_hide_completed_spinbutton, "changed", config_control);
- connect_changed (GTK_OPTION_MENU (dialog_data->tasks_hide_completed_optionmenu)->menu, "selection_done", config_control);
-
- connect_changed (dialog_data->confirm_delete, "toggled", config_control);
- connect_changed (dialog_data->default_reminder, "toggled", config_control);
- connect_changed (dialog_data->default_reminder_interval, "changed", config_control);
- connect_changed (GTK_OPTION_MENU (dialog_data->default_reminder_units)->menu, "selection_done", config_control);
-
- /* These use GnomeColorPicker so we have to use a different signal. */
- gtk_signal_connect (GTK_OBJECT (dialog_data->tasks_due_today_color), "color_set",
- GTK_SIGNAL_FUNC (color_set_callback), config_control);
- gtk_signal_connect (GTK_OBJECT (dialog_data->tasks_overdue_color), "color_set",
- GTK_SIGNAL_FUNC (color_set_callback), config_control);
-}
-
-/* Gets the widgets from the XML file and returns if they are all available.
- */
-static gboolean
-get_widgets (DialogData *data)
-{
-#define GW(name) glade_xml_get_widget (data->xml, name)
-
- data->page = GW ("toplevel-notebook");
-
- /* The indices must be 0 (Sun) to 6 (Sat). */
- data->working_days[0] = GW ("sun_button");
- data->working_days[1] = GW ("mon_button");
- data->working_days[2] = GW ("tue_button");
- data->working_days[3] = GW ("wed_button");
- data->working_days[4] = GW ("thu_button");
- data->working_days[5] = GW ("fri_button");
- data->working_days[6] = GW ("sat_button");
-
- data->timezone = GW ("timezone");
- data->week_start_day = GW ("first_day_of_week");
- data->start_of_day = GW ("start_of_day");
- data->end_of_day = GW ("end_of_day");
- data->use_12_hour = GW ("use_12_hour");
- data->use_24_hour = GW ("use_24_hour");
- data->time_divisions = GW ("time_divisions");
- data->show_end_times = GW ("show_end_times");
- data->compress_weekend = GW ("compress_weekend");
- data->dnav_show_week_no = GW ("dnav_show_week_no");
-
- data->tasks_due_today_color = GW ("tasks_due_today_color");
- data->tasks_overdue_color = GW ("tasks_overdue_color");
-
- data->tasks_hide_completed_checkbutton = GW ("tasks-hide-completed-checkbutton");
- data->tasks_hide_completed_spinbutton = GW ("tasks-hide-completed-spinbutton");
- data->tasks_hide_completed_optionmenu = GW ("tasks-hide-completed-optionmenu");
-
- data->confirm_delete = GW ("confirm-delete");
- data->default_reminder = GW ("default-reminder");
- data->default_reminder_interval = GW ("default-reminder-interval");
- data->default_reminder_units = GW ("default-reminder-units");
-
-#undef GW
-
- return (data->page
- && data->timezone
- && data->working_days[0]
- && data->working_days[1]
- && data->working_days[2]
- && data->working_days[3]
- && data->working_days[4]
- && data->working_days[5]
- && data->working_days[6]
- && data->week_start_day
- && data->start_of_day
- && data->end_of_day
- && data->use_12_hour
- && data->use_24_hour
- && data->time_divisions
- && data->show_end_times
- && data->compress_weekend
- && data->dnav_show_week_no
- && data->tasks_due_today_color
- && data->tasks_overdue_color
- && data->tasks_hide_completed_checkbutton
- && data->tasks_hide_completed_spinbutton
- && data->tasks_hide_completed_optionmenu
- && data->confirm_delete
- && data->default_reminder
- && data->default_reminder_interval
- && data->default_reminder_units);
-}
-
-
-static void
-config_control_destroy_callback (GtkObject *object,
- void *data)
-{
- DialogData *dialog_data;
-
- dialog_data = (DialogData *) data;
-
- gtk_object_unref (GTK_OBJECT (dialog_data->xml));
-
- g_free (dialog_data);
-}
-
-
-static void
-config_control_apply_callback (EvolutionConfigControl *control,
- void *data)
-{
- DialogData *dialog_data;
-
- dialog_data = (DialogData *) data;
-
- update_config (dialog_data);
-}
-
-
-/* Called by libglade to create our custom EDateEdit widgets. */
-GtkWidget *
-cal_prefs_dialog_create_time_edit (void)
-{
- GtkWidget *dedit;
-
- dedit = e_date_edit_new ();
-
- e_date_edit_set_use_24_hour_format (E_DATE_EDIT (dedit), calendar_config_get_24_hour_format ());
- e_date_edit_set_time_popup_range (E_DATE_EDIT (dedit), 0, 24);
- e_date_edit_set_show_date (E_DATE_EDIT (dedit), FALSE);
-
- return dedit;
-}
-
-
-/* Connects any necessary signal handlers. */
-static void
-init_widgets (DialogData *dialog_data)
-{
- gtk_signal_connect (GTK_OBJECT (dialog_data->use_24_hour), "toggled",
- GTK_SIGNAL_FUNC (cal_prefs_dialog_use_24_hour_toggled),
- dialog_data);
-
- gtk_signal_connect (GTK_OBJECT (dialog_data->start_of_day), "changed",
- GTK_SIGNAL_FUNC (cal_prefs_dialog_start_of_day_changed),
- dialog_data);
-
- gtk_signal_connect (GTK_OBJECT (dialog_data->end_of_day), "changed",
- GTK_SIGNAL_FUNC (cal_prefs_dialog_end_of_day_changed),
- dialog_data);
-
- gtk_signal_connect (GTK_OBJECT (dialog_data->tasks_hide_completed_checkbutton),
- "toggled",
- GTK_SIGNAL_FUNC (cal_prefs_dialog_hide_completed_tasks_toggled),
- dialog_data);
-}
-
-
-static void
-cal_prefs_dialog_use_24_hour_toggled (GtkWidget *button,
- void *data)
-{
- DialogData *dialog_data;
- gboolean use_24_hour;
-
- dialog_data = (DialogData *) data;
-
- use_24_hour = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog_data->use_24_hour));
-
- e_date_edit_set_use_24_hour_format (E_DATE_EDIT (dialog_data->start_of_day), use_24_hour);
- e_date_edit_set_use_24_hour_format (E_DATE_EDIT (dialog_data->end_of_day), use_24_hour);
-}
-
-static void
-cal_prefs_dialog_start_of_day_changed (GtkWidget *button, void *data)
-{
- DialogData *dialog_data;
- EDateEdit *start, *end;
- int start_hour, start_minute, end_hour, end_minute;
-
- dialog_data = (DialogData *) data;
-
- start = E_DATE_EDIT (dialog_data->start_of_day);
- end = E_DATE_EDIT (dialog_data->end_of_day);
-
- e_date_edit_get_time_of_day (start, &start_hour, &start_minute);
- e_date_edit_get_time_of_day (end, &end_hour, &end_minute);
-
- if ((start_hour > end_hour)
- || (start_hour == end_hour && start_minute > end_minute)) {
-
- if (start_hour < 23)
- e_date_edit_set_time_of_day (end, start_hour + 1, start_minute);
- else
- e_date_edit_set_time_of_day (end, 23, 59);
- }
-}
-
-static void
-cal_prefs_dialog_end_of_day_changed (GtkWidget *button, void *data)
-{
- DialogData *dialog_data;
- EDateEdit *start, *end;
- int start_hour, start_minute, end_hour, end_minute;
-
- dialog_data = (DialogData *) data;
-
- start = E_DATE_EDIT (dialog_data->start_of_day);
- end = E_DATE_EDIT (dialog_data->end_of_day);
-
- e_date_edit_get_time_of_day (start, &start_hour, &start_minute);
- e_date_edit_get_time_of_day (end, &end_hour, &end_minute);
-
- if ((end_hour < start_hour)
- || (end_hour == start_hour && end_minute < start_minute)) {
- if (end_hour < 1)
- e_date_edit_set_time_of_day (start, 0, 0);
- else
- e_date_edit_set_time_of_day (start, end_hour - 1, end_minute);
- }
-}
-
-static void
-cal_prefs_dialog_hide_completed_tasks_toggled (GtkWidget *button,
- void *data)
-{
- DialogData *dialog_data;
- gboolean hide_completed_tasks;
-
- dialog_data = (DialogData *) data;
-
- hide_completed_tasks = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog_data->tasks_hide_completed_checkbutton));
-
- gtk_widget_set_sensitive (dialog_data->tasks_hide_completed_spinbutton, hide_completed_tasks);
- gtk_widget_set_sensitive (dialog_data->tasks_hide_completed_optionmenu, hide_completed_tasks);
-}
-
-/* Sets the color in a color picker from an X color spec */
-static void
-set_color_picker (GtkWidget *picker, const char *spec)
-{
- GdkColor color;
-
- g_assert (spec != NULL);
-
- if (!gdk_color_parse (spec, &color)) {
- color.red = color.green = color.blue = 0;
- return;
- }
-
- gnome_color_picker_set_i16 (GNOME_COLOR_PICKER (picker),
- color.red,
- color.green,
- color.blue,
- 65535);
-}
-
-/* Shows the current task list settings in the dialog */
-static void
-show_task_list_config (DialogData *dialog_data)
-{
- CalUnits units;
- gboolean hide_completed_tasks;
-
- set_color_picker (dialog_data->tasks_due_today_color, calendar_config_get_tasks_due_today_color ());
- set_color_picker (dialog_data->tasks_overdue_color, calendar_config_get_tasks_overdue_color ());
-
- /* Hide Completed Tasks. */
- hide_completed_tasks = calendar_config_get_hide_completed_tasks ();
- e_dialog_toggle_set (dialog_data->tasks_hide_completed_checkbutton,
- hide_completed_tasks);
-
- /* Hide Completed Tasks Units. */
- units = calendar_config_get_hide_completed_tasks_units ();
- e_dialog_option_menu_set (dialog_data->tasks_hide_completed_optionmenu,
- units, hide_completed_units_map);
-
- /* Hide Completed Tasks Value. */
- e_dialog_spin_set (dialog_data->tasks_hide_completed_spinbutton,
- calendar_config_get_hide_completed_tasks_value ());
-
- gtk_widget_set_sensitive (dialog_data->tasks_hide_completed_spinbutton,
- hide_completed_tasks);
- gtk_widget_set_sensitive (dialog_data->tasks_hide_completed_optionmenu,
- hide_completed_tasks);
-}
-
-/* Shows the current config settings in the dialog. */
-static void
-show_config (DialogData *dialog_data)
-{
- CalWeekdays working_days;
- gint mask, day, week_start_day, time_divisions;
- char *zone_name;
- icaltimezone *zone;
- gboolean sensitive;
-
- /* Timezone. */
- zone_name = calendar_config_get_timezone ();
- zone = icaltimezone_get_builtin_timezone (zone_name);
- e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (dialog_data->timezone),
- zone);
-
- /* Working Days. */
- working_days = calendar_config_get_working_days ();
- mask = 1 << 0;
- for (day = 0; day < 7; day++) {
- e_dialog_toggle_set (dialog_data->working_days[day], (working_days & mask) ? TRUE : FALSE);
- mask <<= 1;
- }
-
- /* Week Start Day. */
- week_start_day = calendar_config_get_week_start_day ();
- e_dialog_option_menu_set (dialog_data->week_start_day, week_start_day,
- week_start_day_map);
-
- /* Start of Day. */
- e_date_edit_set_time_of_day (E_DATE_EDIT (dialog_data->start_of_day),
- calendar_config_get_day_start_hour (),
- calendar_config_get_day_start_minute ());
-
- /* End of Day. */
- e_date_edit_set_time_of_day (E_DATE_EDIT (dialog_data->end_of_day),
- calendar_config_get_day_end_hour (),
- calendar_config_get_day_end_minute ());
-
- /* 12/24 Hour Format. */
- if (calendar_config_get_24_hour_format ())
- e_dialog_toggle_set (dialog_data->use_24_hour, TRUE);
- else
- e_dialog_toggle_set (dialog_data->use_12_hour, TRUE);
-
- sensitive = calendar_config_locale_supports_12_hour_format ();
- gtk_widget_set_sensitive (dialog_data->use_12_hour, sensitive);
- gtk_widget_set_sensitive (dialog_data->use_24_hour, sensitive);
-
-
- /* Time Divisions. */
- time_divisions = calendar_config_get_time_divisions ();
- e_dialog_option_menu_set (dialog_data->time_divisions, time_divisions,
- time_division_map);
-
- /* Show Appointment End Times. */
- e_dialog_toggle_set (dialog_data->show_end_times, calendar_config_get_show_event_end ());
-
- /* Compress Weekend. */
- e_dialog_toggle_set (dialog_data->compress_weekend, calendar_config_get_compress_weekend ());
-
- /* Date Navigator - Show Week Numbers. */
- e_dialog_toggle_set (dialog_data->dnav_show_week_no, calendar_config_get_dnav_show_week_no ());
-
- /* Task list */
-
- show_task_list_config (dialog_data);
-
- /* Other page */
-
- e_dialog_toggle_set (dialog_data->confirm_delete, calendar_config_get_confirm_delete ());
-
- e_dialog_toggle_set (dialog_data->default_reminder,
- calendar_config_get_use_default_reminder ());
- e_dialog_spin_set (dialog_data->default_reminder_interval,
- calendar_config_get_default_reminder_interval ());
- e_dialog_option_menu_set (dialog_data->default_reminder_units,
- calendar_config_get_default_reminder_units (),
- default_reminder_units_map);
-}
-
-/* Returns a pointer to a static string with an X color spec for the current
- * value of a color picker.
- */
-static const char *
-spec_from_picker (GtkWidget *picker)
-{
- static char spec[8];
- guint8 r, g, b;
-
- gnome_color_picker_get_i8 (GNOME_COLOR_PICKER (picker), &r, &g, &b, NULL);
- g_snprintf (spec, sizeof (spec), "#%02x%02x%02x", r, g, b);
-
- return spec;
-}
-
-/* Updates the task list config values from the settings in the dialog */
-static void
-update_task_list_config (DialogData *dialog_data)
-{
- calendar_config_set_tasks_due_today_color (spec_from_picker (dialog_data->tasks_due_today_color));
- calendar_config_set_tasks_overdue_color (spec_from_picker (dialog_data->tasks_overdue_color));
-
- calendar_config_set_hide_completed_tasks (e_dialog_toggle_get (dialog_data->tasks_hide_completed_checkbutton));
- calendar_config_set_hide_completed_tasks_units (e_dialog_option_menu_get (dialog_data->tasks_hide_completed_optionmenu, hide_completed_units_map));
- calendar_config_set_hide_completed_tasks_value (e_dialog_spin_get_int (dialog_data->tasks_hide_completed_spinbutton));
-}
-
-/* Updates the config values based on the settings in the dialog. */
-static void
-update_config (DialogData *dialog_data)
-{
- CalWeekdays working_days;
- gint mask, day, week_start_day, time_divisions, hour, minute;
- icaltimezone *zone;
-
- /* Timezone. */
- zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (dialog_data->timezone));
- calendar_config_set_timezone (icaltimezone_get_location (zone));
-
- /* Working Days. */
- working_days = 0;
- mask = 1 << 0;
- for (day = 0; day < 7; day++) {
- if (e_dialog_toggle_get (dialog_data->working_days[day]))
- working_days |= mask;
- mask <<= 1;
- }
- calendar_config_set_working_days (working_days);
-
- /* Week Start Day. */
- week_start_day = e_dialog_option_menu_get (dialog_data->week_start_day, week_start_day_map);
- calendar_config_set_week_start_day (week_start_day);
-
- /* Start of Day. */
- e_date_edit_get_time_of_day (E_DATE_EDIT (dialog_data->start_of_day), &hour, &minute);
- calendar_config_set_day_start_hour (hour);
- calendar_config_set_day_start_minute (minute);
-
- /* End of Day. */
- e_date_edit_get_time_of_day (E_DATE_EDIT (dialog_data->end_of_day), &hour, &minute);
- calendar_config_set_day_end_hour (hour);
- calendar_config_set_day_end_minute (minute);
-
- /* 12/24 Hour Format. */
- calendar_config_set_24_hour_format (e_dialog_toggle_get (dialog_data->use_24_hour));
-
- /* Time Divisions. */
- time_divisions = e_dialog_option_menu_get (dialog_data->time_divisions, time_division_map);
- calendar_config_set_time_divisions (time_divisions);
-
- /* Show Appointment End Times. */
- calendar_config_set_show_event_end (e_dialog_toggle_get (dialog_data->show_end_times));
-
- /* Compress Weekend. */
- calendar_config_set_compress_weekend (e_dialog_toggle_get (dialog_data->compress_weekend));
-
- /* Date Navigator - Show Week Numbers. */
- calendar_config_set_dnav_show_week_no (e_dialog_toggle_get (dialog_data->dnav_show_week_no));
-
- /* Task list */
- update_task_list_config (dialog_data);
-
- /* Other page */
-
- calendar_config_set_confirm_delete (e_dialog_toggle_get (dialog_data->confirm_delete));
-
- calendar_config_set_use_default_reminder (e_dialog_toggle_get (dialog_data->default_reminder));
-
- calendar_config_set_default_reminder_interval (
- e_dialog_spin_get_int (dialog_data->default_reminder_interval));
-
- calendar_config_set_default_reminder_units (
- e_dialog_option_menu_get (dialog_data->default_reminder_units, default_reminder_units_map));
-
- /* Done */
-
- update_all_config_settings ();
- e_tasks_update_all_config_settings ();
-}
diff --git a/calendar/gui/dialogs/cal-prefs-dialog.glade b/calendar/gui/dialogs/cal-prefs-dialog.glade
deleted file mode 100644
index 121da38f73..0000000000
--- a/calendar/gui/dialogs/cal-prefs-dialog.glade
+++ /dev/null
@@ -1,1051 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>preferences</name>
- <program_name>preferences</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
-</project>
-
-<widget>
- <class>GnomeDialog</class>
- <name>cal-prefs-dialog</name>
- <visible>False</visible>
- <title>Calendar and Tasks Settings</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>False</auto_close>
- <hide_on_close>True</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>vbox1</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>hbuttonbox1</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>button1</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button2</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_APPLY</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>button3</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CLOSE</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkNotebook</class>
- <name>toplevel-notebook</name>
- <can_focus>True</can_focus>
- <show_tabs>True</show_tabs>
- <show_border>True</show_border>
- <tab_pos>GTK_POS_TOP</tab_pos>
- <scrollable>False</scrollable>
- <tab_hborder>2</tab_hborder>
- <tab_vborder>2</tab_vborder>
- <popup_enable>False</popup_enable>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox10</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>6</spacing>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame12</name>
- <border_width>3</border_width>
- <label>Time</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkTable</class>
- <name>table5</name>
- <border_width>4</border_width>
- <rows>2</rows>
- <columns>3</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>4</row_spacing>
- <column_spacing>4</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label22</name>
- <label>Time _zone:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label20</name>
- <label>Time format:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox10</name>
- <homogeneous>True</homogeneous>
- <spacing>4</spacing>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment2</name>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xscale>3.35276e-08</xscale>
- <yscale>1</yscale>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>use_12_hour</name>
- <can_focus>True</can_focus>
- <label>_12 hour (AM/PM)</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <group>time_format_group</group>
- </widget>
- </widget>
-
- <widget>
- <class>GtkRadioButton</class>
- <name>use_24_hour</name>
- <can_focus>True</can_focus>
- <label>_24 hour</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <group>time_format_group</group>
- <child>
- <padding>0</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>timezone</name>
- <creation_function>make_timezone_entry</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Wed, 20 Jun 2001 02:22:46 GMT</last_modification_time>
- <child>
- <left_attach>1</left_attach>
- <right_attach>3</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame9</name>
- <border_width>3</border_width>
- <label>Work Week</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkTable</class>
- <name>table8</name>
- <border_width>4</border_width>
- <rows>3</rows>
- <columns>4</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>4</row_spacing>
- <column_spacing>4</column_spacing>
-
- <widget>
- <class>GtkLabel</class>
- <name>label33</name>
- <label>_Day begins:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox18</name>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <left_attach>1</left_attach>
- <right_attach>4</right_attach>
- <top_attach>2</top_attach>
- <bottom_attach>3</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>Custom</class>
- <name>start_of_day</name>
- <creation_function>cal_prefs_dialog_create_time_edit</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 30 May 2002 19:26:53 GMT</last_modification_time>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label34</name>
- <label>Day _ends:</label>
- <justify>GTK_JUSTIFY_RIGHT</justify>
- <wrap>False</wrap>
- <xalign>1</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>Custom</class>
- <name>end_of_day</name>
- <creation_function>cal_prefs_dialog_create_time_edit</creation_function>
- <int1>0</int1>
- <int2>0</int2>
- <last_modification_time>Thu, 30 May 2002 19:27:35 GMT</last_modification_time>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox17</name>
- <homogeneous>False</homogeneous>
- <spacing>6</spacing>
- <child>
- <left_attach>1</left_attach>
- <right_attach>4</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>True</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>True</yfill>
- </child>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>mon_button</name>
- <can_focus>True</can_focus>
- <label>_Mon</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>tue_button</name>
- <can_focus>True</can_focus>
- <label>_Tue</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>wed_button</name>
- <can_focus>True</can_focus>
- <label>_Wed</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>thu_button</name>
- <can_focus>True</can_focus>
- <label>T_hu</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>fri_button</name>
- <can_focus>True</can_focus>
- <label>_Fri</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>sat_button</name>
- <can_focus>True</can_focus>
- <label>_Sat</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>sun_button</name>
- <can_focus>True</can_focus>
- <label>S_un</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment3</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>1</yscale>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>first_day_of_week</name>
- <can_focus>True</can_focus>
- <items>Monday
-Tuesday
-Wednesday
-Thursday
-Friday
-Saturday
-Sunday
-</items>
- <initial_choice>0</initial_choice>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label32</name>
- <label>W_eek starts:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <focus_target>first_day_of_week</focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label31</name>
- <label>Work days:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame14</name>
- <border_width>3</border_width>
- <label>Alerts</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox13</name>
- <homogeneous>False</homogeneous>
- <spacing>0</spacing>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>confirm-delete</name>
- <border_width>3</border_width>
- <can_focus>True</can_focus>
- <label>_Ask for confirmation when deleting items</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox19</name>
- <border_width>3</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>default-reminder</name>
- <can_focus>True</can_focus>
- <label>Sh_ow a reminder</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkSpinButton</class>
- <name>default-reminder-interval</name>
- <can_focus>True</can_focus>
- <climb_rate>1</climb_rate>
- <digits>0</digits>
- <numeric>False</numeric>
- <update_policy>GTK_UPDATE_ALWAYS</update_policy>
- <snap>False</snap>
- <wrap>False</wrap>
- <value>0</value>
- <lower>0</lower>
- <upper>9999</upper>
- <step>1</step>
- <page>10</page>
- <page_size>10</page_size>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkAlignment</class>
- <name>alignment4</name>
- <xalign>7.45058e-09</xalign>
- <yalign>0.5</yalign>
- <xscale>0</xscale>
- <yscale>0</yscale>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>default-reminder-units</name>
- <can_focus>True</can_focus>
- <items>Minutes
-Hours
-Days
-</items>
- <initial_choice>0</initial_choice>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label35</name>
- <label>before every appointment</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label21</name>
- <label>_General</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox8</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>6</spacing>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox12</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label25</name>
- <label>_Time divisions:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>time_divisions</default_focus_target>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>time_divisions</name>
- <can_focus>True</can_focus>
- <items>60 minutes
-30 minutes
-15 minutes
-10 minutes
-05 minutes
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>show_end_times</name>
- <can_focus>True</can_focus>
- <label>_Show appointment end times in week and month views</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>compress_weekend</name>
- <can_focus>True</can_focus>
- <label>_Compress weekends in month view</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>dnav_show_week_no</name>
- <can_focus>True</can_focus>
- <label>Show week _numbers in date navigator</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkFrame</class>
- <name>frame13</name>
- <label>Task List</label>
- <label_xalign>0</label_xalign>
- <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkVBox</class>
- <name>vbox12</name>
- <border_width>4</border_width>
- <homogeneous>False</homogeneous>
- <spacing>3</spacing>
-
- <widget>
- <class>GtkTable</class>
- <name>table7</name>
- <rows>2</rows>
- <columns>2</columns>
- <homogeneous>False</homogeneous>
- <row_spacing>4</row_spacing>
- <column_spacing>4</column_spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label28</name>
- <label>T_asks due today:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>tasks_due_today_color</default_focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <name>label29</name>
- <label>_Overdue tasks:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <default_focus_target>tasks_overdue_color</default_focus_target>
- <child>
- <left_attach>0</left_attach>
- <right_attach>1</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GnomeColorPicker</class>
- <name>tasks_overdue_color</name>
- <can_focus>True</can_focus>
- <dither>True</dither>
- <use_alpha>False</use_alpha>
- <title>Color for overdue tasks</title>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>1</top_attach>
- <bottom_attach>2</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
-
- <widget>
- <class>GnomeColorPicker</class>
- <name>tasks_due_today_color</name>
- <can_focus>True</can_focus>
- <dither>True</dither>
- <use_alpha>False</use_alpha>
- <title>Color for tasks due today</title>
- <child>
- <left_attach>1</left_attach>
- <right_attach>2</right_attach>
- <top_attach>0</top_attach>
- <bottom_attach>1</bottom_attach>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <xexpand>False</xexpand>
- <yexpand>False</yexpand>
- <xshrink>False</xshrink>
- <yshrink>False</yshrink>
- <xfill>True</xfill>
- <yfill>False</yfill>
- </child>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>hbox15</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkCheckButton</class>
- <name>tasks-hide-completed-checkbutton</name>
- <can_focus>True</can_focus>
- <label>_Hide completed tasks after</label>
- <active>False</active>
- <draw_indicator>True</draw_indicator>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkSpinButton</class>
- <name>tasks-hide-completed-spinbutton</name>
- <can_focus>True</can_focus>
- <climb_rate>1</climb_rate>
- <digits>0</digits>
- <numeric>False</numeric>
- <update_policy>GTK_UPDATE_ALWAYS</update_policy>
- <snap>False</snap>
- <wrap>False</wrap>
- <value>1</value>
- <lower>0</lower>
- <upper>9999</upper>
- <step>1</step>
- <page>10</page>
- <page_size>10</page_size>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkOptionMenu</class>
- <name>tasks-hide-completed-optionmenu</name>
- <can_focus>True</can_focus>
- <items>Minutes
-Hours
-Days
-</items>
- <initial_choice>0</initial_choice>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
- </widget>
- </widget>
- </widget>
- </widget>
-
- <widget>
- <class>GtkLabel</class>
- <child_name>Notebook:tab</child_name>
- <name>label7</name>
- <label>_Display</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/calendar/gui/dialogs/cal-prefs-dialog.h b/calendar/gui/dialogs/cal-prefs-dialog.h
deleted file mode 100644
index ce3f46736c..0000000000
--- a/calendar/gui/dialogs/cal-prefs-dialog.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/*
- * Author :
- * Damon Chaplin <damon@ximian.com>
- *
- * Copyright 2000, Ximian, Inc.
- * Copyright 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
- */
-
-/*
- * CalPrefsDialog - a GtkObject which handles a libglade-loaded dialog
- * to edit the calendar preference settings.
- */
-
-#ifndef _CAL_PREFS_DIALOG_H_
-#define _CAL_PREFS_DIALOG_H_
-
-#include "evolution-config-control.h"
-
-EvolutionConfigControl *cal_prefs_dialog_new (void);
-
-END_GNOME_DECLS
-
-#endif /* _CAL_PREFS_DIALOG_H_ */
diff --git a/calendar/gui/dialogs/cancel-comp.c b/calendar/gui/dialogs/cancel-comp.c
index 9156877016..29038f4483 100644
--- a/calendar/gui/dialogs/cancel-comp.c
+++ b/calendar/gui/dialogs/cancel-comp.c
@@ -1,92 +1,115 @@
-/* Evolution calendar - Send calendar component dialog
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: JP Rosevear <jpr@ximian.com>
+/*
+ * Evolution calendar - Send calendar component dialog
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * JP Rosevear <jpr@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <libgnomeui/gnome-dialog-util.h>
-#include <libgnomeui/gnome-uidefs.h>
-#include <gal/widgets/e-unicode.h>
#include "cancel-comp.h"
-
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include "e-util/e-util.h"
+
+/* is_past_event:
+ *
+ * returns TRUE if @comp is in the past, FALSE otherwise.
+ * Comparision is based only on date part, time part is ignored.
+ */
+static gboolean
+is_past_event (ECalComponent *comp)
+{
+ ECalComponentDateTime end_date;
+ gboolean res;
+
+ if (!comp) return TRUE;
+
+ e_cal_component_get_dtend (comp, &end_date);
+ res = icaltime_compare_date_only (
+ *end_date.value,
+ icaltime_current_time_with_zone (
+ icaltime_get_timezone (*end_date.value))) == -1;
+ e_cal_component_free_datetime (&end_date);
+
+ return res;
+}
/**
* cancel_component_dialog:
- *
+ *
* Pops up a dialog box asking the user whether he wants to send a
* cancel and delete an iTip/iMip message
- *
+ *
* Return value: TRUE if the user clicked Yes, FALSE otherwise.
**/
gboolean
-cancel_component_dialog (CalComponent *comp, gboolean deleting)
+cancel_component_dialog (GtkWindow *parent,
+ ECalClient *cal_client,
+ ECalComponent *comp,
+ gboolean deleting)
{
- GtkWidget *dialog;
- CalComponentVType vtype;
- char *str;
+ ECalComponentVType vtype;
+ const gchar *id;
+
+ if (deleting && e_cal_client_check_save_schedules (cal_client))
+ return TRUE;
- vtype = cal_component_get_vtype (comp);
+ vtype = e_cal_component_get_vtype (comp);
switch (vtype) {
- case CAL_COMPONENT_EVENT:
+ case E_CAL_COMPONENT_EVENT:
+ if (is_past_event (comp)) {
+ /* don't ask neither send notification to others on past events */
+ return FALSE;
+ }
if (deleting)
- str = g_strdup_printf (_("The event being deleted is a meeting, "
- "would you like to send a cancellation notice?"));
+ id = "calendar:prompt-cancel-meeting";
else
- str = g_strdup_printf (_("Are you sure you want to cancel "
- "and delete this meeting?"));
+ id = "calendar:prompt-delete-meeting";
break;
- case CAL_COMPONENT_TODO:
+ case E_CAL_COMPONENT_TODO:
if (deleting)
- str = g_strdup_printf (_("The task being deleted is assigned, "
- "would you like to send a cancellation notice?"));
+ id = "calendar:prompt-cancel-task";
else
- str = g_strdup_printf (_("Are you sure you want to cancel "
- "and delete this task?"));
+ id = "calendar:prompt-delete-task";
break;
- case CAL_COMPONENT_JOURNAL:
+ case E_CAL_COMPONENT_JOURNAL:
if (deleting)
- str = g_strdup_printf (_("The journal entry being deleted is published, "
- "would you like to send a cancellation notice?"));
+ id = "calendar:prompt-cancel-memo";
else
- str = g_strdup_printf (_("Are you sure you want to cancel "
- "and delete this journal entry?"));
+ id = "calendar:prompt-delete-memo";
break;
default:
- g_message ("send_component_dialog(): "
- "Cannot handle object of type %d", vtype);
+ g_message (G_STRLOC ": Cannot handle object of type %d", vtype);
return FALSE;
}
-
- dialog = gnome_question_dialog_modal (str, NULL, NULL);
- if (gnome_dialog_run (GNOME_DIALOG (dialog)) == GNOME_YES)
+ if (e_alert_run_dialog_for_args (parent, id, NULL) == GTK_RESPONSE_YES)
return TRUE;
else
return FALSE;
diff --git a/calendar/gui/dialogs/cancel-comp.h b/calendar/gui/dialogs/cancel-comp.h
index b05d6a5cab..5e6ea88076 100644
--- a/calendar/gui/dialogs/cancel-comp.h
+++ b/calendar/gui/dialogs/cancel-comp.h
@@ -1,29 +1,34 @@
-/* Evolution calendar - Send calendar component dialog
+/*
*
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: JP Rosevear <jpr@ximian.com>
+ * Evolution calendar - Send calendar component dialog
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * JP Rosevear <jpr@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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 CANCEL_COMP_H
#define CANCEL_COMP_H
-#include <glib.h>
-#include <cal-util/cal-component.h>
+#include <gtk/gtk.h>
+#include <libecal/libecal.h>
-gboolean cancel_component_dialog (CalComponent *comp, gboolean deleting);
+gboolean cancel_component_dialog (GtkWindow *parent, ECalClient *cal_client, ECalComponent *comp, gboolean deleting);
#endif
diff --git a/calendar/gui/dialogs/changed-comp.c b/calendar/gui/dialogs/changed-comp.c
index 4282307859..fdbc228ae2 100644
--- a/calendar/gui/dialogs/changed-comp.c
+++ b/calendar/gui/dialogs/changed-comp.c
@@ -1,110 +1,121 @@
-/* Evolution calendar - Send calendar component dialog
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: JP Rosevear <jpr@ximian.com>
+/*
+ * Evolution calendar - Send calendar component dialog
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * JP Rosevear <jpr@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <libgnomeui/gnome-dialog-util.h>
-#include <libgnomeui/gnome-uidefs.h>
-#include <gal/widgets/e-unicode.h>
+#include <glib/gi18n.h>
#include "changed-comp.h"
-
-
/**
* changed_component_dialog:
+ * @parent: Parent window for the dialog.
* @comp: A calendar component
* @deleted: Whether the object is being deleted or updated
* @changed: Whether or not the user has made changes
- *
+ *
* Pops up a dialog box asking the user whether changes made (if any)
* should be thrown away because the item has been updated elsewhere
- *
+ *
* Return value: TRUE if the user clicked Yes, FALSE otherwise.
**/
gboolean
-changed_component_dialog (CalComponent *comp, gboolean deleted, gboolean changed)
+changed_component_dialog (GtkWindow *parent,
+ ECalComponent *comp,
+ gboolean deleted,
+ gboolean changed)
{
GtkWidget *dialog;
- CalComponentVType vtype;
- char *str;
+ ECalComponentVType vtype;
+ gchar *str;
+ gint response;
- vtype = cal_component_get_vtype (comp);
+ vtype = e_cal_component_get_vtype (comp);
if (deleted) {
switch (vtype) {
- case CAL_COMPONENT_EVENT:
+ case E_CAL_COMPONENT_EVENT:
str = _("This event has been deleted.");
break;
- case CAL_COMPONENT_TODO:
+ case E_CAL_COMPONENT_TODO:
str = _("This task has been deleted.");
break;
- case CAL_COMPONENT_JOURNAL:
- str = _("This journal entry has been deleted.");
+ case E_CAL_COMPONENT_JOURNAL:
+ str = _("This memo has been deleted.");
break;
default:
- g_message ("changed_component_dialog(): "
- "Cannot handle object of type %d", vtype);
+ g_message (
+ "changed_component_dialog(): "
+ "Cannot handle object of type %d", vtype);
return FALSE;
}
if (changed)
str = g_strdup_printf (_("%s You have made changes. Forget those changes and close the editor?"), str);
else
- str = g_strdup_printf (_("%s You have made no changes, close the editor?"), str);
+ str = g_strdup_printf (_("%s You have made no changes, close the editor?"), str);
} else {
switch (vtype) {
- case CAL_COMPONENT_EVENT:
+ case E_CAL_COMPONENT_EVENT:
str = _("This event has been changed.");
break;
- case CAL_COMPONENT_TODO:
+ case E_CAL_COMPONENT_TODO:
str = _("This task has been changed.");
break;
- case CAL_COMPONENT_JOURNAL:
- str = _("This journal entry has been changed.");
+ case E_CAL_COMPONENT_JOURNAL:
+ str = _("This memo has been changed.");
break;
default:
- g_message ("changed_component_dialog(): "
- "Cannot handle object of type %d", vtype);
+ g_message (
+ "changed_component_dialog(): "
+ "Cannot handle object of type %d", vtype);
return FALSE;
}
if (changed)
str = g_strdup_printf (_("%s You have made changes. Forget those changes and update the editor?"), str);
else
- str = g_strdup_printf (_("%s You have made no changes, update the editor?"), str);
+ str = g_strdup_printf (_("%s You have made no changes, update the editor?"), str);
}
-
- dialog = gnome_question_dialog_modal (str, NULL, NULL);
- if (gnome_dialog_run (GNOME_DIALOG (dialog)) == GNOME_YES)
+ dialog = gtk_message_dialog_new (
+ parent, GTK_DIALOG_MODAL,
+ GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_YES_NO, "%s", str);
+
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "x-office-calendar");
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ if (response == GTK_RESPONSE_YES)
return TRUE;
else
return FALSE;
diff --git a/calendar/gui/dialogs/changed-comp.h b/calendar/gui/dialogs/changed-comp.h
index 915d7a5372..88905a2581 100644
--- a/calendar/gui/dialogs/changed-comp.h
+++ b/calendar/gui/dialogs/changed-comp.h
@@ -1,29 +1,31 @@
-/* Evolution calendar - Changed calendar component dialog
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: JP Rosevear <jpr@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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * JP Rosevear <jpr@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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 CHANGED_COMP_H
#define CHANGED_COMP_H
-#include <glib.h>
-#include <cal-util/cal-component.h>
+#include <gtk/gtk.h>
+#include <libecal/libecal.h>
-gboolean changed_component_dialog (CalComponent *comp, gboolean deleted, gboolean changed);
+gboolean changed_component_dialog (GtkWindow *window, ECalComponent *comp, gboolean deleted, gboolean changed);
#endif
diff --git a/calendar/gui/dialogs/comp-editor-page.c b/calendar/gui/dialogs/comp-editor-page.c
index d2de97586e..3a6d67107b 100644
--- a/calendar/gui/dialogs/comp-editor-page.c
+++ b/calendar/gui/dialogs/comp-editor-page.c
@@ -1,167 +1,109 @@
-/* Evolution calendar - Base class for calendar component editor pages
+/*
*
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@ximian.com>
+ * Evolution calendar - Base class for calendar component editor pages
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-#include <gtk/gtksignal.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <libgnomeui/gnome-dialog-util.h>
+#include <glib/gi18n.h>
+#include "comp-editor.h"
#include "comp-editor-page.h"
-
-
-static void comp_editor_page_class_init (CompEditorPageClass *class);
-static void comp_editor_page_init (CompEditorPage *page);
-static void comp_editor_page_destroy (GtkObject *object);
+#define COMP_EDITOR_PAGE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), TYPE_COMP_EDITOR_PAGE, CompEditorPagePrivate))
-static GtkObjectClass *parent_class = NULL;
+struct _CompEditorPagePrivate {
+ CompEditor *editor; /* not referenced */
+ gboolean updating;
+};
-/* Signal IDs */
+enum {
+ PROP_0,
+ PROP_EDITOR,
+ PROP_UPDATING
+};
enum {
- CHANGED,
- NEEDS_SEND,
- SUMMARY_CHANGED,
DATES_CHANGED,
LAST_SIGNAL
};
static guint comp_editor_page_signals[LAST_SIGNAL];
-#define CLASS(page) (COMP_EDITOR_PAGE_CLASS (GTK_OBJECT (page)->klass))
-
-
+G_DEFINE_TYPE (CompEditorPage, comp_editor_page, G_TYPE_OBJECT)
-/**
- * comp_editor_page_get_type:
- *
- * Registers the #CompEditorPage class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the #CompEditorPage class.
- **/
-GtkType
-comp_editor_page_get_type (void)
+static void
+comp_editor_page_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- static GtkType comp_editor_page_type = 0;
-
- if (!comp_editor_page_type) {
- static const GtkTypeInfo comp_editor_page_info = {
- "CompEditorPage",
- sizeof (CompEditorPage),
- sizeof (CompEditorPageClass),
- (GtkClassInitFunc) comp_editor_page_class_init,
- (GtkObjectInitFunc) comp_editor_page_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- comp_editor_page_type =
- gtk_type_unique (GTK_TYPE_OBJECT,
- &comp_editor_page_info);
+ CompEditorPagePrivate *priv;
+
+ priv = COMP_EDITOR_PAGE_GET_PRIVATE (object);
+
+ switch (property_id) {
+ case PROP_EDITOR:
+ priv->editor = g_value_get_object (value);
+ return;
+
+ case PROP_UPDATING:
+ comp_editor_page_set_updating (
+ COMP_EDITOR_PAGE (object),
+ g_value_get_boolean (value));
+ return;
}
- return comp_editor_page_type;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
-/* Class initialization function for the abstract editor page */
static void
-comp_editor_page_class_init (CompEditorPageClass *class)
+comp_editor_page_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- GtkObjectClass *object_class;
-
- object_class = (GtkObjectClass *) class;
-
- parent_class = gtk_type_class (GTK_TYPE_OBJECT);
-
- comp_editor_page_signals[CHANGED] =
- gtk_signal_new ("changed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CompEditorPageClass,
- changed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- comp_editor_page_signals[NEEDS_SEND] =
- gtk_signal_new ("needs_send",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CompEditorPageClass,
- needs_send),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- comp_editor_page_signals[SUMMARY_CHANGED] =
- gtk_signal_new ("summary_changed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CompEditorPageClass,
- summary_changed),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
-
- comp_editor_page_signals[DATES_CHANGED] =
- gtk_signal_new ("dates_changed",
- GTK_RUN_FIRST,
- object_class->type,
- GTK_SIGNAL_OFFSET (CompEditorPageClass,
- dates_changed),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
-
- gtk_object_class_add_signals (object_class,
- comp_editor_page_signals,
- LAST_SIGNAL);
-
- class->changed = NULL;
- class->summary_changed = NULL;
- class->dates_changed = NULL;
-
- class->get_widget = NULL;
- class->focus_main_widget = NULL;
- class->fill_widgets = NULL;
- class->fill_component = NULL;
- class->set_summary = NULL;
- class->set_dates = NULL;
-
- object_class->destroy = comp_editor_page_destroy;
-}
-
-
+ switch (property_id) {
+ case PROP_EDITOR:
+ g_value_set_object (
+ value, comp_editor_page_get_editor (
+ COMP_EDITOR_PAGE (object)));
+ return;
+
+ case PROP_UPDATING:
+ g_value_set_boolean (
+ value, comp_editor_page_get_updating (
+ COMP_EDITOR_PAGE (object)));
+ }
-static void
-comp_editor_page_init (CompEditorPage *page)
-{
- page->client = NULL;
- page->accel_group = NULL;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
-
static void
-comp_editor_page_destroy (GtkObject *object)
+comp_editor_page_dispose (GObject *object)
{
CompEditorPage *page;
@@ -170,44 +112,146 @@ comp_editor_page_destroy (GtkObject *object)
page = COMP_EDITOR_PAGE (object);
- if (page->client) {
- gtk_object_ref (GTK_OBJECT (page->client));
- page->client = NULL;
- }
-
if (page->accel_group) {
- gtk_accel_group_unref (page->accel_group);
+ g_object_unref (page->accel_group);
page->accel_group = NULL;
}
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (comp_editor_page_parent_class)->dispose (object);
+}
+
+static void
+comp_editor_page_class_init (CompEditorPageClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (CompEditorPagePrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = comp_editor_page_set_property;
+ object_class->get_property = comp_editor_page_get_property;
+ object_class->dispose = comp_editor_page_dispose;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITOR,
+ g_param_spec_object (
+ "editor",
+ NULL,
+ NULL,
+ TYPE_COMP_EDITOR,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_UPDATING,
+ g_param_spec_boolean (
+ "updating",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ comp_editor_page_signals[DATES_CHANGED] = g_signal_new (
+ "dates_changed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (CompEditorPageClass, dates_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+}
+
+static void
+comp_editor_page_init (CompEditorPage *page)
+{
+ page->priv = COMP_EDITOR_PAGE_GET_PRIVATE (page);
}
+/**
+ * comp_editor_page_get_editor:
+ * @page: a #CompEditorPage
+ *
+ * Returns the #CompEditor to which @page belongs.
+ *
+ * Returns: the parent #CompEditor
+ **/
+CompEditor *
+comp_editor_page_get_editor (CompEditorPage *page)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), NULL);
+
+ return page->priv->editor;
+}
/**
* comp_editor_page_get_widget:
* @page: An editor page.
- *
+ *
* Queries the main widget of an editor page.
- *
+ *
* Return value: The widget that is the page's upper container. It should
* normally be inserted in a notebook widget.
**/
GtkWidget *
comp_editor_page_get_widget (CompEditorPage *page)
{
- g_return_val_if_fail (page != NULL, NULL);
+ CompEditorPageClass *class;
+
g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), NULL);
- g_assert (CLASS (page)->get_widget != NULL);
- return (* CLASS (page)->get_widget) (page);
+ class = COMP_EDITOR_PAGE_GET_CLASS (page);
+ g_return_val_if_fail (class->get_widget != NULL, NULL);
+
+ return class->get_widget (page);
+}
+
+gboolean
+comp_editor_page_get_updating (CompEditorPage *page)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), FALSE);
+
+ return page->priv->updating;
+}
+
+void
+comp_editor_page_set_updating (CompEditorPage *page,
+ gboolean updating)
+{
+ g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+
+ if (page->priv->updating == updating)
+ return;
+
+ page->priv->updating = updating;
+
+ g_object_notify (G_OBJECT (page), "updating");
+}
+
+void
+comp_editor_page_changed (CompEditorPage *page)
+{
+ CompEditor *editor;
+
+ g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+
+ /* Block change notifications if the page is updating. This right
+ * here is why we have an 'updating' flag. It's up to subclasses
+ * to set and clear it at appropriate times. */
+ if (page->priv->updating)
+ return;
+
+ editor = comp_editor_page_get_editor (page);
+ comp_editor_set_changed (editor, TRUE);
}
/**
* comp_editor_page_focus_main_widget:
* @page: An editor page.
- *
+ *
* Makes an editor page focus its main widget. This is used by the component
* editor when it first pops up so that it can focus the main widget in the
* first page.
@@ -215,36 +259,48 @@ comp_editor_page_get_widget (CompEditorPage *page)
void
comp_editor_page_focus_main_widget (CompEditorPage *page)
{
- g_return_if_fail (page != NULL);
+ CompEditorPageClass *class;
+
g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
- g_assert (CLASS (page)->focus_main_widget != NULL);
- (* CLASS (page)->focus_main_widget) (page);
+ class = COMP_EDITOR_PAGE_GET_CLASS (page);
+ g_return_if_fail (class->focus_main_widget != NULL);
+
+ class->focus_main_widget (page);
}
/**
* comp_editor_page_fill_widgets:
* @page: An editor page.
* @comp: A calendar component.
- *
+ *
* Fills the widgets of an editor page with the data from a calendar component.
**/
-void
-comp_editor_page_fill_widgets (CompEditorPage *page, CalComponent *comp)
+gboolean
+comp_editor_page_fill_widgets (CompEditorPage *page,
+ ECalComponent *comp)
{
- g_return_if_fail (page != NULL);
- g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
- g_return_if_fail (comp != NULL);
+ CompEditorPageClass *class;
+ gboolean success;
- g_assert (CLASS (page)->fill_widgets != NULL);
- (* CLASS (page)->fill_widgets) (page, comp);
+ g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), FALSE);
+ g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
+
+ class = COMP_EDITOR_PAGE_GET_CLASS (page);
+ g_return_val_if_fail (class->fill_widgets != NULL, FALSE);
+
+ comp_editor_page_set_updating (page, TRUE);
+ success = class->fill_widgets (page, comp);
+ comp_editor_page_set_updating (page, FALSE);
+
+ return success;
}
/**
* comp_editor_page_fill_component:
* @page: An editor page.
* @comp: A calendar component.
- *
+ *
* Takes the data from the widgets of an editor page and sets it on a calendar
* component, replacing the contents of the properties that the editor page
* knows how to manipulate.
@@ -252,141 +308,109 @@ comp_editor_page_fill_widgets (CompEditorPage *page, CalComponent *comp)
* Returns: TRUE if the component could be filled, FALSE otherwise
**/
gboolean
-comp_editor_page_fill_component (CompEditorPage *page, CalComponent *comp)
+comp_editor_page_fill_component (CompEditorPage *page,
+ ECalComponent *comp)
{
- g_return_val_if_fail (page != NULL, FALSE);
+ CompEditorPageClass *class;
+
g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), FALSE);
g_return_val_if_fail (comp != NULL, FALSE);
- if (CLASS (page)->fill_component != NULL)
- return (* CLASS (page)->fill_component) (page, comp);
+ class = COMP_EDITOR_PAGE_GET_CLASS (page);
+
+ if (class->fill_component != NULL)
+ return class->fill_component (page, comp);
return TRUE;
}
/**
- * comp_editor_page_set_cal_client:
- * @page: An editor page
- * @client: A #CalClient object
+ * comp_editor_page_fill_timezones:
+ * @page: An editor page.
+ * @timezones: Hash table to which timezones will be added.
*
- * Sets the #CalClient for the dialog page to use.
- **/
-void
-comp_editor_page_set_cal_client (CompEditorPage *page, CalClient *client)
+ * Fills the given hash table with all the timezones used by the dates in the
+ * specific editor page.
+ *
+ * Returns: TRUE if the timezones were added, FALSE otherwise.
+ */
+gboolean
+comp_editor_page_fill_timezones (CompEditorPage *page,
+ GHashTable *timezones)
{
- g_return_if_fail (page != NULL);
- g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+ CompEditorPageClass *class;
- if (page->client)
- gtk_object_unref (GTK_OBJECT (client));
+ g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), FALSE);
+ g_return_val_if_fail (timezones != NULL, FALSE);
- page->client = client;
- if (page->client)
- gtk_object_ref (GTK_OBJECT (client));
-}
+ class = COMP_EDITOR_PAGE_GET_CLASS (page);
-/**
- * comp_editor_page_set_summary:
- * @page: An editor page
- * @summary: The text of the new summary value
- *
- * Sets the summary value for this group of widgets
- **/
-void
-comp_editor_page_set_summary (CompEditorPage *page, const char *summary)
-{
- g_return_if_fail (page != NULL);
- g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+ if (class->fill_timezones != NULL)
+ return class->fill_timezones (page, timezones);
- if (CLASS (page)->set_summary != NULL)
- (* CLASS (page)->set_summary) (page, summary);
+ return TRUE;
}
/**
* comp_editor_page_set_dates:
* @page: An editor page
* @dates: A collection of various dates in time_t format
- *
+ *
* Sets the date values for this group of widgets
**/
void
-comp_editor_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates)
+comp_editor_page_set_dates (CompEditorPage *page,
+ CompEditorPageDates *dates)
{
- g_return_if_fail (page != NULL);
- g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
-
- if (CLASS (page)->set_dates != NULL)
- (* CLASS (page)->set_dates) (page, dates);
-}
+ CompEditorPageClass *class;
-/**
- * comp_editor_page_notify_changed:
- * @page: An editor page.
- *
- * Makes an editor page emit the "changed" signal. This is meant to be
- * used only by page implementations.
- **/
-void
-comp_editor_page_notify_changed (CompEditorPage *page)
-{
- g_return_if_fail (page != NULL);
g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
- gtk_signal_emit (GTK_OBJECT (page), comp_editor_page_signals[CHANGED]);
-}
-
-/**
- * comp_editor_page_notify_needs_send:
- * @page:
- *
- *
- **/
-void
-comp_editor_page_notify_needs_send (CompEditorPage *page)
-{
- g_return_if_fail (page != NULL);
- g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+ class = COMP_EDITOR_PAGE_GET_CLASS (page);
- gtk_signal_emit (GTK_OBJECT (page), comp_editor_page_signals[NEEDS_SEND]);
+ if (class->set_dates != NULL)
+ class->set_dates (page, dates);
}
/**
- * comp_editor_page_notify_summary_changed:
- * @page: An editor page.
- *
- * Makes an editor page emit the "summary_changed" signal. This is meant to be
- * used only by page implementations.
+ * comp_editor_page_add_attendee:
+ * @page: a #CompEditorPage
+ * @attendee: an #EMeetingAttendee
+ *
+ * Adds @attendee to an internal meeting store.
**/
void
-comp_editor_page_notify_summary_changed (CompEditorPage *page,
- const char *summary)
+comp_editor_page_add_attendee (CompEditorPage *page,
+ EMeetingAttendee *attendee)
{
- g_return_if_fail (page != NULL);
+ CompEditorPageClass *class;
+
g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
+ g_return_if_fail (E_IS_MEETING_ATTENDEE (attendee));
-
- gtk_signal_emit (GTK_OBJECT (page),
- comp_editor_page_signals[SUMMARY_CHANGED],
- summary);
+ class = COMP_EDITOR_PAGE_GET_CLASS (page);
+ g_return_if_fail (class->add_attendee != NULL);
+
+ class->add_attendee (page, attendee);
}
/**
* comp_editor_page_notify_dates_changed:
* @page: An editor page.
- *
+ *
* Makes an editor page emit the "dates_changed" signal. This is meant to be
* used only by page implementations.
**/
void
comp_editor_page_notify_dates_changed (CompEditorPage *page,
- CompEditorPageDates *dates)
+ CompEditorPageDates *dates)
{
- g_return_if_fail (page != NULL);
g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
- gtk_signal_emit (GTK_OBJECT (page),
- comp_editor_page_signals[DATES_CHANGED],
- dates);
+ g_signal_emit (
+ page,
+ comp_editor_page_signals[DATES_CHANGED], 0,
+ dates);
}
/**
@@ -401,21 +425,22 @@ comp_editor_page_notify_dates_changed (CompEditorPage *page,
*/
void
comp_editor_page_display_validation_error (CompEditorPage *page,
- const char *msg,
- GtkWidget *field)
+ const gchar *msg,
+ GtkWidget *field)
{
GtkWidget *dialog;
- char *real_msg;
g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
g_return_if_fail (msg != NULL);
g_return_if_fail (GTK_IS_WIDGET (field));
- real_msg = g_strdup_printf (_("Validation error: %s"), msg);
- dialog = gnome_error_dialog (real_msg);
- gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
+ dialog = gtk_message_dialog_new (
+ NULL, 0,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ _("Validation error: %s"), msg);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
gtk_widget_grab_focus (field);
-
- g_free (real_msg);
}
diff --git a/calendar/gui/dialogs/comp-editor-page.h b/calendar/gui/dialogs/comp-editor-page.h
index 4e5eadebda..a13e7ff549 100644
--- a/calendar/gui/dialogs/comp-editor-page.h
+++ b/calendar/gui/dialogs/comp-editor-page.h
@@ -1,112 +1,133 @@
-/* Evolution calendar - Base class for calendar component editor pages
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@ximian.com>
+/*
+ * Evolution calendar - Base class for calendar component editor pages
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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 COMP_EDITOR_PAGE_H
#define COMP_EDITOR_PAGE_H
#include <time.h>
-#include <libgnome/gnome-defs.h>
-#include <gtk/gtkwidget.h>
-#include <cal-util/cal-component.h>
-#include "cal-client.h"
-
-BEGIN_GNOME_DECLS
-
-
-
-#define TYPE_COMP_EDITOR_PAGE (comp_editor_page_get_type ())
-#define COMP_EDITOR_PAGE(obj) (GTK_CHECK_CAST ((obj), TYPE_COMP_EDITOR_PAGE, CompEditorPage))
-#define COMP_EDITOR_PAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_COMP_EDITOR_PAGE, CompEditorPageClass))
-#define IS_COMP_EDITOR_PAGE(obj) (GTK_CHECK_TYPE ((obj), TYPE_COMP_EDITOR_PAGE))
-#define IS_COMP_EDITOR_PAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), TYPE_COMP_EDITOR_PAGE))
+#include <gtk/gtk.h>
+#include <libecal/libecal.h>
+
+#include <calendar/gui/e-meeting-attendee.h>
+
+/* Standard GObject macros */
+#define TYPE_COMP_EDITOR_PAGE \
+ (comp_editor_page_get_type ())
+#define COMP_EDITOR_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), TYPE_COMP_EDITOR_PAGE, CompEditorPage))
+#define COMP_EDITOR_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), TYPE_COMP_EDITOR_PAGE, CompEditorPageClass))
+#define IS_COMP_EDITOR_PAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), TYPE_COMP_EDITOR_PAGE))
+#define IS_COMP_EDITOR_PAGE_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), TYPE_COMP_EDITOR_PAGE))
+#define COMP_EDITOR_PAGE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), TYPE_COMP_EDITOR_PAGE, CompEditorPageClass))
+
+G_BEGIN_DECLS
+
+/* Use a forward declaration to avoid a circular reference. */
+struct _CompEditor;
+
+typedef struct _CompEditorPage CompEditorPage;
+typedef struct _CompEditorPageClass CompEditorPageClass;
+typedef struct _CompEditorPagePrivate CompEditorPagePrivate;
typedef struct {
- CalComponentDateTime *start;
- CalComponentDateTime *end;
- CalComponentDateTime *due;
+ ECalComponentDateTime *start;
+ ECalComponentDateTime *end;
+ ECalComponentDateTime *due;
struct icaltimetype *complete;
} CompEditorPageDates;
-typedef struct {
- GtkObject object;
-
- /* Some of the pages need the CalClient to access timezone data. */
- CalClient *client;
+struct _CompEditorPage {
+ GObject object;
/* The GtkAccelGroup for the page. We install this when the page is
- mapped, and uninstall when it is unmapped. libglade would do this
- normally, but we create our pages individually so have to do it
- ourselves. */
+ * mapped, and uninstall when it is unmapped. libglade would do this
+ * normally, but we create our pages individually so have to do it
+ * ourselves. */
GtkAccelGroup *accel_group;
-} CompEditorPage;
-
-typedef struct {
- GtkObjectClass parent_class;
-
- /* Notification signals */
-
- void (* changed) (CompEditorPage *page);
- void (* needs_send) (CompEditorPage *page);
-
- void (* summary_changed) (CompEditorPage *page, const char *summary);
- void (* dates_changed) (CompEditorPage *page, const char *dates);
-
- /* Virtual methods */
-
- GtkWidget *(* get_widget) (CompEditorPage *page);
- void (* focus_main_widget) (CompEditorPage *page);
-
- void (* fill_widgets) (CompEditorPage *page, CalComponent *comp);
- gboolean (* fill_component) (CompEditorPage *page, CalComponent *comp);
-
- void (* set_summary) (CompEditorPage *page, const char *summary);
- void (* set_dates) (CompEditorPage *page, CompEditorPageDates *dates);
-} CompEditorPageClass;
-
-
-GtkType comp_editor_page_get_type (void);
-GtkWidget *comp_editor_page_get_widget (CompEditorPage *page);
-void comp_editor_page_focus_main_widget (CompEditorPage *page);
-void comp_editor_page_fill_widgets (CompEditorPage *page,
- CalComponent *comp);
-gboolean comp_editor_page_fill_component (CompEditorPage *page,
- CalComponent *comp);
-void comp_editor_page_set_cal_client (CompEditorPage *page,
- CalClient *client);
-void comp_editor_page_set_summary (CompEditorPage *page,
- const char *summary);
-void comp_editor_page_set_dates (CompEditorPage *page,
- CompEditorPageDates *dates);
-void comp_editor_page_notify_changed (CompEditorPage *page);
-void comp_editor_page_notify_needs_send (CompEditorPage *page);
-void comp_editor_page_notify_summary_changed (CompEditorPage *page,
- const char *summary);
-void comp_editor_page_notify_dates_changed (CompEditorPage *page,
- CompEditorPageDates *dates);
-void comp_editor_display_validation_error (CompEditorPage *page,
- const char *msg,
- GtkWidget *field);
-
-
-
-
-END_GNOME_DECLS
-#endif
+ CompEditorPagePrivate *priv;
+};
+
+struct _CompEditorPageClass {
+ GObjectClass parent_class;
+
+ /* Signals */
+ void (*dates_changed) (CompEditorPage *page,
+ const gchar *dates);
+
+ /* Methods */
+ GtkWidget * (*get_widget) (CompEditorPage *page);
+ void (*focus_main_widget) (CompEditorPage *page);
+ gboolean (*fill_widgets) (CompEditorPage *page,
+ ECalComponent *comp);
+ gboolean (*fill_component) (CompEditorPage *page,
+ ECalComponent *comp);
+ gboolean (*fill_timezones) (CompEditorPage *page,
+ GHashTable *timezones);
+ void (*set_dates) (CompEditorPage *page,
+ CompEditorPageDates *dates);
+ void (*add_attendee) (CompEditorPage *page,
+ EMeetingAttendee *attendee);
+};
+
+GType comp_editor_page_get_type (void);
+struct _CompEditor *
+ comp_editor_page_get_editor (CompEditorPage *page);
+GtkWidget * comp_editor_page_get_widget (CompEditorPage *page);
+gboolean comp_editor_page_get_updating (CompEditorPage *page);
+void comp_editor_page_set_updating (CompEditorPage *page,
+ gboolean updating);
+void comp_editor_page_changed (CompEditorPage *page);
+void comp_editor_page_focus_main_widget
+ (CompEditorPage *page);
+gboolean comp_editor_page_fill_widgets (CompEditorPage *page,
+ ECalComponent *comp);
+gboolean comp_editor_page_fill_component (CompEditorPage *page,
+ ECalComponent *comp);
+gboolean comp_editor_page_fill_timezones (CompEditorPage *page,
+ GHashTable *timezones);
+void comp_editor_page_set_dates (CompEditorPage *page,
+ CompEditorPageDates *dates);
+void comp_editor_page_add_attendee (CompEditorPage *page,
+ EMeetingAttendee *attendee);
+void comp_editor_page_notify_dates_changed
+ (CompEditorPage *page,
+ CompEditorPageDates *dates);
+void comp_editor_page_display_validation_error
+ (CompEditorPage *page,
+ const gchar *msg,
+ GtkWidget *field);
+
+G_END_DECLS
+
+#endif /* COMP_EDITOR_PAGE_H */
diff --git a/calendar/gui/dialogs/comp-editor-util.c b/calendar/gui/dialogs/comp-editor-util.c
index 5d414a640c..52651190ac 100644
--- a/calendar/gui/dialogs/comp-editor-util.c
+++ b/calendar/gui/dialogs/comp-editor-util.c
@@ -1,21 +1,25 @@
-/* Evolution calendar - Widget utilities
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@ximian.com>
+/*
+ * Evolution calendar - Widget utilities
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
#ifdef HAVE_CONFIG_H
@@ -24,184 +28,83 @@
#include <ctype.h>
#include <string.h>
-#include <ical.h>
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <liboaf/liboaf.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-widget.h>
-#include <gal/unicode/gunicode.h>
-#include <ebook/e-destination.h>
-#include <e-util/e-time-utils.h>
-#include <cal-util/timeutil.h>
-#include "../calendar-config.h"
-#include "comp-editor-util.h"
+#include <libical/ical.h>
+#include <glib/gi18n.h>
-
+#include "shell/e-shell.h"
+
+#include "../itip-utils.h"
+#include "comp-editor-util.h"
/**
* comp_editor_dates:
* @dates: A structure to be filled out with dates of a component
* @comp: The component to extract the dates from
- *
+ *
* Extracts the dates from the calendar component into the
* CompEditorPageDates structure. Call comp_editor_free_dates() to free the
* results.
**/
void
-comp_editor_dates (CompEditorPageDates *dates, CalComponent *comp)
+comp_editor_dates (CompEditorPageDates *dates,
+ ECalComponent *comp)
{
- CalComponentDateTime dt;
+ ECalComponentDateTime dt;
dates->start = NULL;
dates->end = NULL;
dates->due = NULL;
dates->complete = NULL;
-
- /* Note that the CalComponentDateTime's returned contain allocated
- icaltimetype and tzid values, so we just take over ownership of
- those. */
- cal_component_get_dtstart (comp, &dt);
+
+ /* Note that the ECalComponentDateTime's returned contain allocated
+ * icaltimetype and tzid values, so we just take over ownership of
+ * those. */
+ e_cal_component_get_dtstart (comp, &dt);
if (dt.value) {
- dates->start = g_new (CalComponentDateTime, 1);
+ dates->start = g_new (ECalComponentDateTime, 1);
*dates->start = dt;
}
- cal_component_get_dtend (comp, &dt);
+ e_cal_component_get_dtend (comp, &dt);
if (dt.value) {
- dates->end = g_new (CalComponentDateTime, 1);
+ dates->end = g_new (ECalComponentDateTime, 1);
*dates->end = dt;
}
- cal_component_get_due (comp, &dt);
+ e_cal_component_get_due (comp, &dt);
if (dt.value) {
- dates->due = g_new (CalComponentDateTime, 1);
+ dates->due = g_new (ECalComponentDateTime, 1);
*dates->due = dt;
}
- cal_component_get_completed (comp, &dates->complete);
+ e_cal_component_get_completed (comp, &dates->complete);
}
-
/* This frees the dates in the CompEditorPageDates struct. But it doesn't free
* the struct (as that is usually static).
*/
void
comp_editor_free_dates (CompEditorPageDates *dates)
{
- /* Note that cal_component_free_datetime() only frees the fields in
- the struct. It doesn't free the struct itself, so we do that. */
+ /* Note that e_cal_component_free_datetime() only frees the fields in
+ * the struct. It doesn't free the struct itself, so we do that. */
if (dates->start) {
- cal_component_free_datetime (dates->start);
+ e_cal_component_free_datetime (dates->start);
g_free (dates->start);
}
if (dates->end) {
- cal_component_free_datetime (dates->end);
+ e_cal_component_free_datetime (dates->end);
g_free (dates->end);
}
if (dates->due) {
- cal_component_free_datetime (dates->due);
+ e_cal_component_free_datetime (dates->due);
g_free (dates->due);
}
if (dates->complete)
- cal_component_free_icaltimetype (dates->complete);
-}
-
-
-/* dtstart is only passed in if tt is the dtend. */
-static void
-write_label_piece (struct icaltimetype *tt, char *buffer, int size,
- char *stext, char *etext, struct icaltimetype *dtstart)
-{
- struct tm tmp_tm = { 0 };
- struct icaltimetype tt_copy = *tt;
- int len;
-
- /* FIXME: May want to convert the time to an appropriate zone. */
-
- if (stext != NULL)
- strcat (buffer, stext);
-
- /* If we are writing the DTEND (i.e. DTSTART is set), and
- DTEND > DTSTART, subtract 1 day. The DTEND date is not inclusive. */
- if (tt_copy.is_date && dtstart
- && icaltime_compare_date_only (tt_copy, *dtstart) > 0) {
- icaltime_adjust (&tt_copy, -1, 0, 0, 0);
- }
-
- tmp_tm.tm_year = tt_copy.year - 1900;
- tmp_tm.tm_mon = tt_copy.month - 1;
- tmp_tm.tm_mday = tt_copy.day;
- tmp_tm.tm_hour = tt_copy.hour;
- tmp_tm.tm_min = tt_copy.minute;
- tmp_tm.tm_sec = tt_copy.second;
- tmp_tm.tm_isdst = -1;
-
- tmp_tm.tm_wday = time_day_of_week (tt_copy.day, tt_copy.month - 1,
- tt_copy.year);
-
- len = strlen (buffer);
- e_time_format_date_and_time (&tmp_tm,
- calendar_config_get_24_hour_format (),
- !tt_copy.is_date, FALSE,
- &buffer[len], size - len);
- if (etext != NULL)
- strcat (buffer, etext);
-}
-
-/**
- * comp_editor_date_label:
- * @dates: The dates to use in constructing a label
- * @label: The label whose text is to be set
- *
- * Set the text of a label based on the dates available and the user's
- * formatting preferences
- **/
-void
-comp_editor_date_label (CompEditorPageDates *dates, GtkWidget *label)
-{
- char buffer[1024];
- gboolean start_set = FALSE, end_set = FALSE;
- gboolean complete_set = FALSE, due_set = FALSE;
-
- buffer[0] = '\0';
-
- if (dates->start && !icaltime_is_null_time (*dates->start->value))
- start_set = TRUE;
- if (dates->end && !icaltime_is_null_time (*dates->end->value))
- end_set = TRUE;
- if (dates->complete && !icaltime_is_null_time (*dates->complete))
- complete_set = TRUE;
- if (dates->due && !icaltime_is_null_time (*dates->due->value))
- due_set = TRUE;
-
- if (start_set)
- write_label_piece (dates->start->value, buffer, 1024,
- NULL, NULL, NULL);
-
- if (start_set && end_set)
- write_label_piece (dates->end->value, buffer, 1024,
- _(" to "), NULL, dates->start->value);
-
- if (complete_set) {
- if (start_set)
- write_label_piece (dates->complete, buffer, 1024, _(" (Completed "), ")", NULL);
- else
- write_label_piece (dates->complete, buffer, 1024, _("Completed "), NULL, NULL);
- }
-
- if (due_set && dates->complete == NULL) {
- if (start_set)
- write_label_piece (dates->due->value, buffer, 1024, _(" (Due "), ")", NULL);
- else
- write_label_piece (dates->due->value, buffer, 1024, _("Due "), NULL, NULL);
- }
-
- gtk_label_set_text (GTK_LABEL (label), buffer);
+ e_cal_component_free_icaltimetype (dates->complete);
}
/**
@@ -211,14 +114,15 @@ comp_editor_date_label (CompEditorPageDates *dates, GtkWidget *label)
* @make_time_insensitive: Whether the time field is made insensitive rather
* than hiding it. This is useful if you want to preserve the layout of the
* widgets.
- *
+ *
* Creates a new #EDateEdit widget, configured using the calendar's preferences.
- *
+ *
* Return value: A newly-created #EDateEdit widget.
**/
GtkWidget *
-comp_editor_new_date_edit (gboolean show_date, gboolean show_time,
- gboolean make_time_insensitive)
+comp_editor_new_date_edit (gboolean show_date,
+ gboolean show_time,
+ gboolean make_time_insensitive)
{
EDateEdit *dedit;
@@ -231,27 +135,24 @@ comp_editor_new_date_edit (gboolean show_date, gboolean show_time,
#else
e_date_edit_set_make_time_insensitive (dedit, FALSE);
#endif
- calendar_config_configure_e_date_edit (dedit);
return GTK_WIDGET (dedit);
}
-
/* Returns the current time, for EDateEdit widgets and ECalendar items in the
- dialogs.
- FIXME: Should probably use the timezone from somewhere in the component
- rather than the current timezone. */
+ * dialogs.
+ * FIXME: Should probably use the timezone from somewhere in the component
+ * rather than the current timezone. */
struct tm
-comp_editor_get_current_time (GtkObject *object, gpointer data)
+comp_editor_get_current_time (EDateEdit *date_edit,
+ CompEditor *editor)
{
- char *location;
icaltimezone *zone;
struct icaltimetype tt;
struct tm tmp_tm = { 0 };
/* Get the current timezone. */
- location = calendar_config_get_timezone ();
- zone = icaltimezone_get_builtin_timezone (location);
+ zone = comp_editor_get_timezone (editor);
tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone);
@@ -267,324 +168,256 @@ comp_editor_get_current_time (GtkObject *object, gpointer data)
return tmp_tm;
}
+/**
+ * comp_editor_strip_categories:
+ * @categories: A string of category names entered by the user.
+ *
+ * Takes a string of the form "categ, categ, categ, ..." and removes the
+ * whitespace between categories to result in "categ,categ,categ,..."
+ *
+ * Return value: The category names stripped of surrounding whitespace
+ * and separated with commas.
+ **/
+gchar *
+comp_editor_strip_categories (const gchar *categories)
+{
+ gchar *new_categories;
+ const gchar *start, *end;
+ const gchar *p;
+ gchar *new_p;
+ if (!categories)
+ return NULL;
-/*
- * These are utility functions to handle the SelectNames control we use
- * for the contacts field, and its related dialog.
- */
+ new_categories = g_new (char, strlen (categories) + 1);
-#define SELECT_NAMES_OAFID "OAFIID:GNOME_Evolution_Addressbook_SelectNames"
+ start = end = NULL;
+ new_p = new_categories;
-GNOME_Evolution_Addressbook_SelectNames
-comp_editor_create_contacts_component (void)
-{
- GNOME_Evolution_Addressbook_SelectNames corba_select_names;
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- corba_select_names = oaf_activate_from_id (SELECT_NAMES_OAFID, 0,
- NULL, &ev);
-
- /* OAF seems to be broken -- it can return a CORBA_OBJECT_NIL without
- raising an exception in `ev'. */
- if (ev._major != CORBA_NO_EXCEPTION
- || corba_select_names == CORBA_OBJECT_NIL) {
- g_warning ("Cannot activate -- %s", SELECT_NAMES_OAFID);
- CORBA_exception_free (&ev);
- return CORBA_OBJECT_NIL;
- }
+ for (p = categories; *p; p = g_utf8_next_char (p)) {
+ gunichar c;
- CORBA_exception_free (&ev);
+ c = g_utf8_get_char (p);
- return corba_select_names;
-}
+ if (g_unichar_isspace (c))
+ continue;
+ else if (c == ',') {
+ gint len;
+ if (!start)
+ continue;
-GtkWidget *
-comp_editor_create_contacts_control (GNOME_Evolution_Addressbook_SelectNames corba_select_names)
-{
- Bonobo_Control corba_control;
- GtkWidget *control_widget;
- CORBA_Environment ev;
- char *name = _("Contacts");
+ g_return_val_if_fail (start <= end, NULL);
- CORBA_exception_init (&ev);
+ len = end - start + 1;
+ strncpy (new_p, start, len);
+ new_p[len] = ',';
+ new_p += len + 1;
- GNOME_Evolution_Addressbook_SelectNames_addSection (
- corba_select_names, name, name, &ev);
- if (ev._major != CORBA_NO_EXCEPTION) {
- CORBA_exception_free (&ev);
- return NULL;
+ start = end = NULL;
+ } else {
+ if (!start) {
+ start = p;
+ end = p;
+ } else
+ end = g_utf8_next_char (p) - 1;
+ }
}
- corba_control =
- GNOME_Evolution_Addressbook_SelectNames_getEntryBySection (
- corba_select_names, name, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- CORBA_exception_free (&ev);
- return NULL;
- }
+ if (start) {
+ gint len;
- CORBA_exception_free (&ev);
+ g_return_val_if_fail (start <= end, NULL);
- control_widget = bonobo_widget_new_control_from_objref (
- corba_control, CORBA_OBJECT_NIL);
+ len = end - start + 1;
+ strncpy (new_p, start, len);
+ new_p += len;
+ }
- gtk_widget_show (control_widget);
+ *new_p = '\0';
- return control_widget;
+ return new_categories;
}
-
-Bonobo_EventSource_ListenerId
-comp_editor_connect_contacts_changed (GtkWidget *contacts_entry,
- BonoboListenerCallbackFn changed_cb,
- gpointer changed_cb_data)
+static GSList *
+manage_new_attendees (const GSList *lst,
+ const gchar *eml,
+ gboolean add)
{
- BonoboControlFrame *cf;
- Bonobo_PropertyBag pb = CORBA_OBJECT_NIL;
+ GSList *copy = NULL;
+ const GSList *l;
+ gboolean found = FALSE;
- cf = bonobo_widget_get_control_frame (BONOBO_WIDGET (contacts_entry));
- pb = bonobo_control_frame_get_control_property_bag (cf, NULL);
+ g_return_val_if_fail (eml != NULL, NULL);
- return bonobo_event_source_client_add_listener (
- pb, changed_cb,
- "Bonobo/Property:change:entry_changed",
- NULL, changed_cb_data);
-}
+ for (l = lst; l; l = l->next) {
+ const gchar *eml2 = l->data;
+
+ if (!eml2)
+ continue;
+ if (g_ascii_strcasecmp (eml, eml2) == 0) {
+ found = TRUE;
+ if (add)
+ copy = g_slist_append (copy, g_strdup (eml2));
+ } else {
+ copy = g_slist_append (copy, g_strdup (eml2));
+ }
+ }
-void
-comp_editor_show_contacts_dialog (GNOME_Evolution_Addressbook_SelectNames corba_select_names)
-{
- CORBA_Environment ev;
+ if (!found && add) {
+ copy = g_slist_append (copy, g_strdup (eml));
+ }
- CORBA_exception_init (&ev);
- GNOME_Evolution_Addressbook_SelectNames_activateDialog (
- corba_select_names, _("Contacts"), &ev);
- CORBA_exception_free (&ev);
+ return copy;
}
-
-/* A simple 'name <email>' parser. Input should be UTF8.
- FIXME: Should probably use camel functions or something. */
static void
-parse_contact_string (const char *value, char **name, char **email)
+free_slist_strs (gpointer data)
{
- char *lbracket, *rbracket, *name_end, *tmp_name, *tmp_email;
-
- if (!value) {
- *name = g_strdup ("");
- *email = g_strdup ("");
- return;
- }
-
- lbracket = g_utf8_strchr (value, '<');
- rbracket = g_utf8_strchr (value, '>');
+ GSList *lst = data;
- if (!lbracket || !rbracket || rbracket < lbracket) {
- *name = g_strdup (value);
- *email = g_strdup ("");
- return;
+ if (lst) {
+ g_slist_foreach (lst, (GFunc) g_free, NULL);
+ g_slist_free (lst);
}
-
- name_end = g_utf8_prev_char (lbracket);
- while (name_end > value && g_unichar_isspace (g_utf8_get_char (name_end)))
- name_end = g_utf8_prev_char (name_end);
-
- tmp_name = g_malloc (name_end - value + 2);
- strncpy (tmp_name, value, name_end - value + 1);
- tmp_name[name_end - value + 1] = '\0';
- *name = tmp_name;
-
- tmp_email = g_malloc (rbracket - lbracket);
- strncpy (tmp_email, lbracket + 1, rbracket - lbracket - 1);
- tmp_email[rbracket - lbracket - 1] = '\0';
- *email = tmp_email;
-
-#if 0
- g_print ("Parsed: %s\n Name:'%s'\nEmail:'%s'\n",
- value, *name, *email);
-#endif
}
-
+/**
+ * comp_editor_manage_new_attendees:
+ * @comp: The component.
+ * @ma: An attendee.
+ * @add: %TRUE to add attendee's email to new-attendees, %FALSE to remove
+ * from it.
+ *
+ * Manages the 'new-attendees' string of new attendees of the component.
+ *
+ * <note>
+ * <para>
+ * The list is just string of emails separated by ';'
+ * </para>
+ * </note>
+ **/
void
-comp_editor_contacts_to_widget (GtkWidget *contacts_entry,
- CalComponent *comp)
+comp_editor_manage_new_attendees (ECalComponent *comp,
+ EMeetingAttendee *ma,
+ gboolean add)
{
- GPtrArray *dest_array;
- EDestination *dest;
- GSList *contact_list, *elem;
- char *contacts_string;
- int i;
-
- cal_component_get_contact_list (comp, &contact_list);
- dest_array = g_ptr_array_new ();
- for (elem = contact_list; elem; elem = elem->next) {
- CalComponentText *t = elem->data;
- char *name, *email;
-
- parse_contact_string (t->value, &name, &email);
-
- dest = e_destination_new ();
- e_destination_set_name (dest, name);
- e_destination_set_email (dest, email);
- g_ptr_array_add (dest_array, dest);
- g_free (name);
- g_free (email);
- }
- cal_component_free_text_list (contact_list);
-
- /* we need destv to be NULL terminated */
- g_ptr_array_add (dest_array, NULL);
-
- contacts_string = e_destination_exportv ((EDestination**) dest_array->pdata);
-#if 0
- g_print ("Destinations: %s\n", contacts_string ? contacts_string : "");
-#endif
+ const gchar *eml;
- bonobo_widget_set_property (BONOBO_WIDGET (contacts_entry),
- "destinations", contacts_string, NULL);
+ g_return_if_fail (comp != NULL);
+ g_return_if_fail (ma != NULL);
- g_free (contacts_string);
+ eml = e_meeting_attendee_get_address (ma);
+ if (eml)
+ eml = itip_strip_mailto (eml);
+ g_return_if_fail (eml != NULL);
- /* We free all dest_array except the last NULL we added. */
- for (i = 0; i < dest_array->len - 1; i++) {
- dest = g_ptr_array_index (dest_array, i);
- gtk_object_unref (GTK_OBJECT (dest));
- }
- g_ptr_array_free (dest_array, TRUE);
+ g_object_set_data_full (
+ G_OBJECT (comp), "new-attendees",
+ manage_new_attendees (
+ g_object_get_data (G_OBJECT (comp), "new-attendees"),
+ eml, add), free_slist_strs);
}
-
+/**
+ * comp_editor_copy_new_attendees:
+ * @des: Component, to copy to.
+ * @src: Component, to copy from.
+ *
+ * Copies "new-attendees" information from @src to @des component.
+ **/
void
-comp_editor_contacts_to_component (GtkWidget *contacts_entry,
- CalComponent *comp)
+comp_editor_copy_new_attendees (ECalComponent *des,
+ ECalComponent *src)
{
- EDestination **contact_destv;
- GSList *contact_list = NULL, *elem;
- char *contacts_string = NULL;
- CalComponentText *t;
- const char *name, *email;
- int i;
-
- bonobo_widget_get_property (BONOBO_WIDGET (contacts_entry),
- "destinations", &contacts_string, NULL);
-#if 0
- g_print ("Contacts string: %s\n", contacts_string ? contacts_string : "");
-#endif
-
- contact_destv = e_destination_importv (contacts_string);
- if (contact_destv) {
- for (i = 0; contact_destv[i] != NULL; i++) {
- name = e_destination_get_name (contact_destv[i]);
- email = e_destination_get_email (contact_destv[i]);
-
- t = g_new0 (CalComponentText, 1);
- t->altrep = NULL;
-
- /* If both name and email are given, use the standard
- '"name" <email>' form, otherwise use just the name
- or the email address.
- FIXME: I'm not sure this is correct syntax etc. */
- if (name && name[0] && email && email[0])
- t->value = g_strdup_printf ("\"%s\" <%s>",
- name, email);
- else if (name && name[0])
- t->value = g_strdup_printf ("\"%s\"",
- name);
- else
- t->value = g_strdup_printf ("<%s>",
- email);
-
- contact_list = g_slist_prepend (contact_list, t);
-
- gtk_object_unref (GTK_OBJECT (contact_destv[i]));
- }
- }
- g_free (contact_destv);
+ GSList *copy = NULL, *l;
- contact_list = g_slist_reverse (contact_list);
- cal_component_set_contact_list (comp, contact_list);
+ g_return_if_fail (src != NULL);
+ g_return_if_fail (des != NULL);
- for (elem = contact_list; elem; elem = elem->next) {
- t = elem->data;
- g_free ((char*)t->value);
- g_free (t);
+ for (l = g_object_get_data (G_OBJECT (src), "new-attendees"); l; l = l->next) {
+ copy = g_slist_append (copy, g_strdup (l->data));
}
- g_slist_free (contact_list);
+
+ g_object_set_data_full (G_OBJECT (des), "new-attendees", copy, free_slist_strs);
}
/**
- * comp_editor_strip_categories:
- * @categories: A string of category names entered by the user.
- *
- * Takes a string of the form "categ, categ, categ, ..." and removes the
- * whitespace between categories to result in "categ,categ,categ,..."
- *
- * Return value: The category names stripped of surrounding whitespace
- * and separated with commas.
+ * comp_editor_have_in_new_attendees:
+ * @comp: Component with the "new-attendees" possibly set.
+ * @ma: Meeting attendee to check.
+ *
+ * Returns: Whether @ma is present in the list of new attendees of the comp.
**/
-char *
-comp_editor_strip_categories (const char *categories)
+gboolean
+comp_editor_have_in_new_attendees (ECalComponent *comp,
+ EMeetingAttendee *ma)
{
- char *new_categories;
- const char *start, *end;
- const char *p;
- char *new_p;
-
- if (!categories)
- return NULL;
+ const gchar *eml;
- new_categories = g_new (char, strlen (categories) + 1);
+ g_return_val_if_fail (comp != NULL, FALSE);
+ g_return_val_if_fail (ma != NULL, FALSE);
- start = end = NULL;
- new_p = new_categories;
-
- for (p = categories; *p; p++) {
- int c;
-
- c = *p;
-
- if (isspace (c))
- continue;
- else if (c == ',') {
- int len;
+ eml = e_meeting_attendee_get_address (ma);
+ if (eml)
+ eml = itip_strip_mailto (eml);
+ g_return_val_if_fail (eml != NULL, FALSE);
- if (!start)
- continue;
+ return comp_editor_have_in_new_attendees_lst (
+ g_object_get_data (G_OBJECT (comp), "new-attendees"), eml);
+}
- g_assert (start <= end);
+/**
+ * comp_editor_have_in_new_attendees_lst:
+ *
+ * Same as comp_editor_have_in_new_attendees() only parameters are
+ * direct GSList and string.
+ **/
+gboolean
+comp_editor_have_in_new_attendees_lst (const GSList *new_attendees,
+ const gchar *eml)
+{
+ const GSList *l;
- len = end - start + 1;
- strncpy (new_p, start, len);
- new_p[len] = ',';
- new_p += len + 1;
+ if (!eml)
+ return FALSE;
- start = end = NULL;
- } else {
- if (!start) {
- start = p;
- end = p;
- } else
- end = p;
- }
+ for (l = new_attendees; l; l = l->next) {
+ if (l->data && g_ascii_strcasecmp (eml, l->data) == 0)
+ return TRUE;
}
- if (start) {
- int len;
-
- g_assert (start <= end);
+ return FALSE;
+}
- len = end - start + 1;
- strncpy (new_p, start, len);
- new_p += len;
+/**
+ * comp_editor_test_time_in_the_past:
+ * @time_tt: Time to check.
+ * @parent: Parent window for a question dialog.
+ * @tag: Question message tag to use.
+ * Returns whether given time is in the past.
+ *
+ * Tests the given @time_tt whether occurs in the past,
+ * and if so, returns TRUE.
+ **/
+gboolean
+comp_editor_test_time_in_the_past (const struct icaltimetype time_tt)
+{
+ struct icaltimetype now_tt;
+ gboolean is_past;
+
+ if (icaltime_is_null_time (time_tt))
+ return FALSE;
+
+ if (time_tt.is_date) {
+ now_tt = icaltime_today ();
+ is_past = icaltime_compare_date_only (time_tt, now_tt) < 0;
+ } else {
+ now_tt = icaltime_current_time_with_zone (time_tt.zone);
+ now_tt.zone = time_tt.zone;
+ is_past = icaltime_compare (time_tt, now_tt) < 0;
}
- *new_p = '\0';
-
- return new_categories;
+ return is_past;
}
diff --git a/calendar/gui/dialogs/comp-editor-util.h b/calendar/gui/dialogs/comp-editor-util.h
index 948b34221c..8c80683696 100644
--- a/calendar/gui/dialogs/comp-editor-util.h
+++ b/calendar/gui/dialogs/comp-editor-util.h
@@ -1,54 +1,52 @@
-/* Evolution calendar - Widget utilities
- *
- * Copyright (C) 2000 Ximian, Inc.
- *
- * Author: JP Rosevear <jpr@ximian.com>
+/*
+ * Evolution calendar - Widget utilities
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * JP Rosevear <jpr@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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 _COMP_EDITOR_UTIL_H_
#define _COMP_EDITOR_UTIL_H_
-#include <gtk/gtkwidget.h>
-#include <bonobo/bonobo-control.h>
-#include "Evolution-Addressbook-SelectNames.h"
-#include "comp-editor-page.h"
+#include <gtk/gtk.h>
+#include "comp-editor.h"
+#include "../e-meeting-attendee.h"
-void comp_editor_dates (CompEditorPageDates *date, CalComponent *comp);
+void comp_editor_dates (CompEditorPageDates *date, ECalComponent *comp);
void comp_editor_free_dates (CompEditorPageDates *dates);
void comp_editor_date_label (CompEditorPageDates *dates, GtkWidget *label);
-GtkWidget *comp_editor_new_date_edit (gboolean show_date, gboolean show_time,
- gboolean make_time_insensitive);
-
-struct tm comp_editor_get_current_time (GtkObject *object, gpointer data);
+GtkWidget * comp_editor_new_date_edit (gboolean show_date,
+ gboolean show_time,
+ gboolean make_time_insensitive);
+struct tm comp_editor_get_current_time (EDateEdit *date_edit, CompEditor *editor);
-GNOME_Evolution_Addressbook_SelectNames comp_editor_create_contacts_component (void);
-GtkWidget * comp_editor_create_contacts_control (GNOME_Evolution_Addressbook_SelectNames corba_select_names);
-Bonobo_EventSource_ListenerId comp_editor_connect_contacts_changed (GtkWidget *contacts_entry,
- BonoboListenerCallbackFn changed_cb,
- gpointer changed_cb_data);
-void comp_editor_show_contacts_dialog (GNOME_Evolution_Addressbook_SelectNames corba_select_names);
+gchar *comp_editor_strip_categories (const gchar *categories);
-void comp_editor_contacts_to_widget (GtkWidget *contacts_entry,
- CalComponent *comp);
-void comp_editor_contacts_to_component (GtkWidget *contacts_entry,
- CalComponent *comp);
+void comp_editor_manage_new_attendees (ECalComponent *comp, EMeetingAttendee *ma, gboolean add);
+void comp_editor_copy_new_attendees (ECalComponent *des, ECalComponent *src);
+gboolean comp_editor_have_in_new_attendees (ECalComponent *comp, EMeetingAttendee *ma);
+gboolean comp_editor_have_in_new_attendees_lst (const GSList *new_attendees, const gchar *eml);
-char *comp_editor_strip_categories (const char *categories);
+gboolean comp_editor_test_time_in_the_past (const struct icaltimetype time_tt);
#endif
diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c
index a1bf930579..39ca3a81e1 100644
--- a/calendar/gui/dialogs/comp-editor.c
+++ b/calendar/gui/dialogs/comp-editor.c
@@ -1,368 +1,668 @@
-/* Evolution calendar - Framework for a calendar component editor dialog
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@ximian.com>
+/*
+ * Evolution calendar - Framework for a calendar component editor dialog
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <fcntl.h>
#include <unistd.h>
-#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <glib/gstdio.h>
+#include <gio/gio.h>
#include <gdk/gdkkeysyms.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-uidefs.h>
-#include <libgnomeui/gnome-dialog.h>
-#include <libgnomeui/gnome-dialog-util.h>
-#include <libgnomeui/gnome-stock.h>
-#include <libgnomeui/gnome-window-icon.h>
-#include <libgnomeui/gnome-messagebox.h>
-#include <bonobo/bonobo-ui-container.h>
-#include <bonobo/bonobo-ui-util.h>
-#include <gal/widgets/e-unicode.h>
-#include <gal/widgets/e-gui-utils.h>
-#include <e-util/e-dialog-utils.h>
-#include <evolution-shell-component-utils.h>
+#include <libebackend/libebackend.h>
+
+#include <shell/e-shell.h>
+
#include "../print.h"
+#include "../comp-util.h"
#include "save-comp.h"
#include "delete-comp.h"
#include "send-comp.h"
#include "changed-comp.h"
#include "cancel-comp.h"
+#include "recur-comp.h"
#include "comp-editor.h"
+#include "comp-editor-util.h"
+#include "../calendar-config-keys.h"
-
+#define COMP_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), TYPE_COMP_EDITOR, CompEditorPrivate))
+
+#define d(x)
/* Private part of the CompEditor structure */
struct _CompEditorPrivate {
+
+ gpointer shell; /* weak pointer */
+
+ GSettings *calendar_settings;
+
+ /* EFocusTracker keeps selection actions up-to-date. */
+ EFocusTracker *focus_tracker;
+
+ /* Each CompEditor window gets its own GtkWindowGroup, so it
+ * doesn't block the main window or other CompEditor windows. */
+ GtkWindowGroup *window_group;
+
/* Client to use */
- CalClient *client;
+ ECalClient *cal_client;
+
+ /* Source client (where comp lives currently) */
+ ECalClient *source_client;
+
+ /* View to listen for changes */
+ ECalClientView *view;
+ GCancellable *view_cancellable;
/* Calendar object/uid we are editing; this is an internal copy */
- CalComponent *comp;
+ ECalComponent *comp;
/* The pages we have */
GList *pages;
- /* UI Component for the dialog */
- BonoboUIComponent *uic;
-
/* Notebook to hold the pages */
GtkNotebook *notebook;
- GtkWidget *filesel;
+ /* Attachment handling */
+ GtkWidget *attachment_view;
+
+ /* Manages menus and toolbars */
+ GtkUIManager *ui_manager;
+
+ gchar *summary;
+
+ guint32 attachment_bar_visible : 1;
+
+ /* TODO use this flags for setting all the boolean variables
+ * below */
+ CompEditorFlags flags;
+
+ icaltimezone *zone;
+ gboolean use_24_hour_format;
+
+ GDateWeekday week_start_day;
+
+ gint work_day_end_hour;
+ gint work_day_end_minute;
+ gint work_day_start_hour;
+ gint work_day_start_minute;
gboolean changed;
gboolean needs_send;
- gboolean existing_org;
- gboolean user_org;
-
- gboolean warned;
-
- gboolean updating;
-};
+ gboolean saved;
+
+ CalObjModType mod;
-
+ gboolean existing_org;
+ gboolean user_org;
+ gboolean is_group_item;
-static void comp_editor_class_init (CompEditorClass *class);
-static void comp_editor_init (CompEditor *editor);
-static gint comp_editor_key_press_event (GtkWidget *d, GdkEventKey *e);
-static void comp_editor_destroy (GtkObject *object);
+ gboolean warned;
+};
-static void real_set_cal_client (CompEditor *editor, CalClient *client);
-static void real_edit_comp (CompEditor *editor, CalComponent *comp);
-static gboolean real_send_comp (CompEditor *editor, CalComponentItipMethod method);
-static gboolean prompt_to_save_changes (CompEditor *editor, gboolean send);
-static void delete_comp (CompEditor *editor);
-static void close_dialog (CompEditor *editor);
+enum {
+ PROP_0,
+ PROP_CHANGED,
+ PROP_CLIENT,
+ PROP_FLAGS,
+ PROP_FOCUS_TRACKER,
+ PROP_SHELL,
+ PROP_SUMMARY,
+ PROP_TIMEZONE,
+ PROP_USE_24_HOUR_FORMAT,
+ PROP_WEEK_START_DAY,
+ PROP_WORK_DAY_END_HOUR,
+ PROP_WORK_DAY_END_MINUTE,
+ PROP_WORK_DAY_START_HOUR,
+ PROP_WORK_DAY_START_MINUTE
+};
-static void page_changed_cb (GtkObject *obj, gpointer data);
-static void page_summary_changed_cb (GtkObject *obj, const char *summary, gpointer data);
-static void page_dates_changed_cb (GtkObject *obj, CompEditorPageDates *dates, gpointer data);
+static const gchar *ui =
+"<ui>"
+" <menubar action='main-menu'>"
+" <menu action='file-menu'>"
+" <menuitem action='save'/>"
+" <menuitem action='save-and-close'/>"
+" <separator/>"
+" <menuitem action='print-preview'/>"
+" <menuitem action='print'/>"
+" <separator/>"
+" <menuitem action='close'/>"
+" </menu>"
+" <menu action='edit-menu'>"
+" <menuitem action='cut-clipboard'/>"
+" <menuitem action='copy-clipboard'/>"
+" <menuitem action='paste-clipboard'/>"
+" <menuitem action='delete-selection'/>"
+" <separator/>"
+" <menuitem action='select-all'/>"
+" </menu>"
+" <menu action='view-menu'/>"
+" <menu action='insert-menu'>"
+" <menuitem action='attach'/>"
+" </menu>"
+" <menu action='options-menu'/>"
+" <menu action='help-menu'>"
+" <menuitem action='help'/>"
+" </menu>"
+" </menubar>"
+" <toolbar name='main-toolbar'>"
+" <toolitem action='save-and-close'/>\n"
+" <toolitem action='save'/>\n"
+" <toolitem action='print'/>\n"
+" <separator/>"
+" <placeholder name='content'/>\n"
+" </toolbar>"
+"</ui>";
+
+static void comp_editor_show_help (CompEditor *editor);
+
+static void real_edit_comp (CompEditor *editor,
+ ECalComponent *comp);
+static gboolean real_send_comp (CompEditor *editor,
+ ECalComponentItipMethod method,
+ gboolean strip_alarms);
+static gboolean prompt_and_save_changes (CompEditor *editor,
+ gboolean send);
+static void close_dialog (CompEditor *editor);
+
+static void page_dates_changed_cb (CompEditor *editor,
+ CompEditorPageDates *dates,
+ CompEditorPage *page);
+
+static void obj_modified_cb (ECalClientView *view,
+ const GSList *objs,
+ CompEditor *editor);
+static void obj_removed_cb (ECalClientView *view,
+ const GSList *uids,
+ CompEditor *editor);
+
+G_DEFINE_TYPE_WITH_CODE (
+ CompEditor, comp_editor, GTK_TYPE_WINDOW,
+ G_IMPLEMENT_INTERFACE (E_TYPE_ALERT_SINK, NULL)
+ G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE, NULL))
+
+enum {
+ OBJECT_CREATED,
+ COMP_CLOSED,
+ LAST_SIGNAL
+};
-static void obj_updated_cb (CalClient *client, const char *uid, gpointer data);
-static void obj_removed_cb (CalClient *client, const char *uid, gpointer data);
+static guint signals[LAST_SIGNAL];
+static GList *active_editors;
-static void save_cmd (GtkWidget *widget, gpointer data);
-static void save_close_cmd (GtkWidget *widget, gpointer data);
-static void save_as_cmd (GtkWidget *widget, gpointer data);
-static void delete_cmd (GtkWidget *widget, gpointer data);
-static void print_cmd (GtkWidget *widget, gpointer data);
-static void print_preview_cmd (GtkWidget *widget, gpointer data);
-static void print_setup_cmd (GtkWidget *widget, gpointer data);
-static void close_cmd (GtkWidget *widget, gpointer data);
+static void
+comp_editor_weak_notify_cb (gpointer unused,
+ GObject *where_the_object_was)
+{
+ active_editors = g_list_remove (active_editors, where_the_object_was);
+}
-static gint delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data);
+static void
+attachment_store_changed_cb (CompEditor *editor)
+{
+ /* Mark the editor as changed so it prompts about unsaved
+ * changes on close */
+ comp_editor_set_changed (editor, TRUE);
+}
-static EPixmap pixmaps [] =
+static void
+attachment_save_finished (EAttachmentStore *store,
+ GAsyncResult *result,
+ gpointer user_data)
{
- E_PIXMAP ("/menu/File/FileSave", "save-16.png"),
- E_PIXMAP ("/menu/File/FileSaveAndClose", "save-16.png"),
- E_PIXMAP ("/menu/File/FileSaveAs", "save-as-16.png"),
+ GtkWidget *dialog;
+ const gchar *primary_text;
+ gchar **uris;
+ GError *error = NULL;
- E_PIXMAP ("/menu/File/FileDelete", "evolution-trash-mini.png"),
+ struct {
+ gchar **uris;
+ gboolean done;
+ GtkWindow *parent;
+ } *status = user_data;
- E_PIXMAP ("/menu/File/FilePrint", "print.xpm"),
- E_PIXMAP ("/menu/File/FilePrintPreview", "print-preview.xpm"),
+ uris = e_attachment_store_save_finish (store, result, &error);
- E_PIXMAP ("/Toolbar/FileSaveAndClose", "buttons/save-24.png"),
- E_PIXMAP ("/Toolbar/FilePrint", "buttons/print.png"),
- E_PIXMAP ("/Toolbar/FileDelete", "buttons/delete-message.png"),
+ status->uris = uris;
+ status->done = TRUE;
- E_PIXMAP_END
-};
+ if (uris != NULL)
+ goto exit;
-static BonoboUIVerb verbs [] = {
- BONOBO_UI_UNSAFE_VERB ("FileSave", save_cmd),
- BONOBO_UI_UNSAFE_VERB ("FileSaveAndClose", save_close_cmd),
- BONOBO_UI_UNSAFE_VERB ("FileSaveAs", save_as_cmd),
- BONOBO_UI_UNSAFE_VERB ("FileDelete", delete_cmd),
- BONOBO_UI_UNSAFE_VERB ("FilePrint", print_cmd),
- BONOBO_UI_UNSAFE_VERB ("FilePrintPreview", print_preview_cmd),
- BONOBO_UI_UNSAFE_VERB ("FilePrintSetup", print_setup_cmd),
- BONOBO_UI_UNSAFE_VERB ("FileClose", close_cmd),
-
- BONOBO_UI_VERB_END
-};
+ /* Ignore cancellations. */
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ goto exit;
-static GtkObjectClass *parent_class;
+ primary_text = _("Could not save attachments");
-
+ dialog = gtk_message_dialog_new_with_markup (
+ status->parent, GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+ "<big><b>%s</b></big>", primary_text);
-GtkType
-comp_editor_get_type (void)
-{
- static GtkType comp_editor_type = 0;
+ gtk_message_dialog_format_secondary_text (
+ GTK_MESSAGE_DIALOG (dialog), "%s", error->message);
- if (!comp_editor_type) {
- static const GtkTypeInfo comp_editor_info = {
- "CompEditor",
- sizeof (CompEditor),
- sizeof (CompEditorClass),
- (GtkClassInitFunc) comp_editor_class_init,
- (GtkObjectInitFunc) comp_editor_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
+ gtk_dialog_run (GTK_DIALOG (dialog));
- comp_editor_type = gtk_type_unique (BONOBO_TYPE_WINDOW,
- &comp_editor_info);
- }
+ gtk_widget_destroy (dialog);
+
+exit:
+ if (error != NULL)
+ g_error_free (error);
- return comp_editor_type;
+ g_object_unref (status->parent);
}
-/* Class initialization function for the calendar component editor */
-static void
-comp_editor_class_init (CompEditorClass *klass)
+static GSList *
+get_attachment_list (CompEditor *editor)
{
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
-
- object_class = GTK_OBJECT_CLASS (klass);
- widget_class = GTK_WIDGET_CLASS (klass);
+ EAttachmentStore *store;
+ EAttachmentView *view;
+ GFile *destination;
+ GSList *list = NULL;
+ const gchar *comp_uid = NULL;
+ const gchar *local_store;
+ gchar *filename_prefix, *tmp;
+ gint ii;
+
+ struct {
+ gchar **uris;
+ gboolean done;
+ GtkWindow *parent;
+ } status;
+
+ e_cal_component_get_uid (editor->priv->comp, &comp_uid);
+ g_return_val_if_fail (comp_uid != NULL, NULL);
+
+ status.uris = NULL;
+ status.done = FALSE;
+ status.parent = g_object_ref (editor);
+
+ view = E_ATTACHMENT_VIEW (editor->priv->attachment_view);
+ store = e_attachment_view_get_store (view);
+
+ tmp = g_strdup (comp_uid);
+ e_filename_make_safe (tmp);
+ filename_prefix = g_strconcat (tmp, "-", NULL);
+ g_free (tmp);
+
+ local_store = e_cal_client_get_local_attachment_store (editor->priv->cal_client);
+ destination = g_file_new_for_path (local_store);
+
+ e_attachment_store_save_async (
+ store, destination, filename_prefix,
+ (GAsyncReadyCallback) attachment_save_finished, &status);
+
+ g_object_unref (destination);
+ g_free (filename_prefix);
+
+ /* We can't return until we have results, so crank
+ * the main loop until the callback gets triggered. */
+ while (!status.done)
+ gtk_main_iteration ();
+
+ if (status.uris == NULL)
+ return NULL;
- parent_class = gtk_type_class (BONOBO_TYPE_WINDOW);
+ /* Transfer the URI strings to the GSList. */
+ for (ii = 0; status.uris[ii] != NULL; ii++) {
+ list = g_slist_prepend (list, status.uris[ii]);
+ status.uris[ii] = NULL;
+ }
- klass->set_cal_client = real_set_cal_client;
- klass->edit_comp = real_edit_comp;
- klass->send_comp = real_send_comp;
+ g_free (status.uris);
- widget_class->key_press_event = comp_editor_key_press_event;
- object_class->destroy = comp_editor_destroy;
+ return g_slist_reverse (list);
}
-/* Creates the basic in the editor */
+/* This sets the focus to the toplevel, so any field being edited is committed.
+ * FIXME: In future we may also want to check some of the fields are valid,
+ * e.g. the EDateEdit fields. */
static void
-setup_widgets (CompEditor *editor)
+commit_all_fields (CompEditor *editor)
{
- CompEditorPrivate *priv;
- BonoboUIContainer *container;
- GtkWidget *vbox;
-
- priv = editor->priv;
+ gtk_window_set_focus (GTK_WINDOW (editor), NULL);
+}
- /* Window and basic vbox */
- bonobo_window_construct (BONOBO_WINDOW (editor),
- "event-editor", "iCalendar Editor");
- gtk_signal_connect (GTK_OBJECT (editor), "delete_event",
- GTK_SIGNAL_FUNC (delete_event_cb), editor);
-
- priv->uic = bonobo_ui_component_new_default ();
- container = bonobo_ui_container_new ();
- bonobo_ui_container_set_win (container, BONOBO_WINDOW (editor));
- bonobo_ui_component_set_container (priv->uic, BONOBO_OBJREF (container));
- bonobo_ui_engine_config_set_path (bonobo_window_get_ui_engine (BONOBO_WINDOW (editor)),
- "/evolution/UIConf/kvps");
-
- bonobo_ui_component_add_verb_list_with_data (priv->uic, verbs, editor);
- bonobo_ui_util_set_ui (priv->uic, EVOLUTION_DATADIR,
- "evolution-comp-editor.xml",
- "evolution-calendar");
- e_pixmaps_update (priv->uic, pixmaps);
-
- vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
- gtk_widget_show (vbox);
- gtk_container_set_border_width (GTK_CONTAINER (vbox), GNOME_PAD_SMALL);
- bonobo_window_set_contents (BONOBO_WINDOW (editor), vbox);
-
- /* Notebook */
- priv->notebook = GTK_NOTEBOOK (gtk_notebook_new ());
- gtk_widget_show (GTK_WIDGET (priv->notebook));
- gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->notebook),
- TRUE, TRUE, 0);
-}
-
-/* Object initialization function for the calendar component editor */
static void
-comp_editor_init (CompEditor *editor)
+changes_view_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- CompEditorPrivate *priv;
+ CompEditor *editor = user_data;
+ ECalClientView *view = NULL;
+ gboolean success;
+ GError *error = NULL;
- priv = g_new0 (CompEditorPrivate, 1);
- editor->priv = priv;
+ g_return_if_fail (editor != NULL);
- setup_widgets (editor);
+ success = e_cal_client_get_view_finish (
+ E_CAL_CLIENT (source_object), result, &view, &error);
- priv->pages = NULL;
- priv->changed = FALSE;
- priv->needs_send = FALSE;
- priv->existing_org = FALSE;
- priv->user_org = FALSE;
- priv->warned = FALSE;
-}
+ if (!success)
+ view = NULL;
+ if (view) {
+ editor->priv->view = view;
+ g_signal_connect (
+ view, "objects_modified",
+ G_CALLBACK (obj_modified_cb), editor);
+ g_signal_connect (
+ view, "objects_removed",
+ G_CALLBACK (obj_removed_cb), editor);
-static gint
-comp_editor_key_press_event (GtkWidget *d, GdkEventKey *e)
-{
- if (e->keyval == GDK_Escape) {
- if (prompt_to_save_changes (COMP_EDITOR (d), TRUE))
- close_dialog (COMP_EDITOR (d));
- return TRUE;
- }
+ e_cal_client_view_start (view, &error);
- if (GTK_WIDGET_CLASS (parent_class)->key_press_event)
- return (* GTK_WIDGET_CLASS (parent_class)->key_press_event) (d, e);
-
- return FALSE;
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to start view: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+ } else if (error) {
+ if (!g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) &&
+ !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning (
+ "%s: Failed to get view: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
}
-/* Destroy handler for the calendar component editor */
static void
-comp_editor_destroy (GtkObject *object)
+listen_for_changes (CompEditor *editor)
{
- CompEditor *editor;
CompEditorPrivate *priv;
- GList *l;
+ const gchar *uid = NULL;
- editor = COMP_EDITOR (object);
priv = editor->priv;
- gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), editor);
+ /* Discard change listener */
+ if (priv->view_cancellable) {
+ g_cancellable_cancel (priv->view_cancellable);
+ g_object_unref (priv->view_cancellable);
+ priv->view_cancellable = NULL;
+ }
- /* We want to destroy the pages after the widgets get destroyed,
- since they have lots of signal handlers connected to the widgets
- with the pages as the data. */
- for (l = priv->pages; l != NULL; l = l->next)
- gtk_object_unref (GTK_OBJECT (l->data));
+ if (priv->view) {
+ g_signal_handlers_disconnect_matched (
+ priv->view, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, editor);
- if (priv->comp) {
- gtk_object_unref (GTK_OBJECT (priv->comp));
- priv->comp = NULL;
+ g_object_unref (priv->view);
+ priv->view = NULL;
+ }
+
+ /* Listen for changes */
+ if (priv->comp)
+ e_cal_component_get_uid (priv->comp, &uid);
+
+ if (uid) {
+ gchar *query;
+
+ priv->view_cancellable = g_cancellable_new ();
+ query = g_strdup_printf ("(uid? \"%s\")", uid);
+ e_cal_client_get_view (
+ priv->source_client,
+ query, priv->view_cancellable,
+ changes_view_ready_cb, editor);
+ g_free (query);
}
+}
+
+static void
+send_timezone (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ icaltimezone *zone = value;
+ CompEditor *editor = user_data;
+ GError *error = NULL;
- g_free (priv);
- editor->priv = NULL;
+ e_cal_client_add_timezone_sync (editor->priv->cal_client, zone, NULL, &error);
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to add timezone: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
}
static gboolean
save_comp (CompEditor *editor)
{
CompEditorPrivate *priv;
- CalComponent *clone;
+ CompEditorFlags flags;
+ ECalComponent *clone;
+ ESourceRegistry *registry;
+ EShell *shell;
GList *l;
- CalClientResult result;
+ gboolean result;
+ GError *error = NULL;
+ GHashTable *timezones;
+ const gchar *orig_uid = NULL;
+ gchar *orig_uid_copy;
+ icalcomponent *icalcomp;
priv = editor->priv;
if (!priv->changed)
return TRUE;
- clone = cal_component_clone (priv->comp);
+ flags = comp_editor_get_flags (editor);
+ shell = comp_editor_get_shell (editor);
+
+ registry = e_shell_get_registry (shell);
+
+ /* Stop listening because we are about to change things */
+ if (priv->view) {
+ g_signal_handlers_disconnect_matched (
+ priv->view,
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL,
+ editor);
+
+ g_object_unref (priv->view);
+ priv->view = NULL;
+ }
+
+ /* Update on the server */
+ timezones = g_hash_table_new (g_str_hash, g_str_equal);
+
+ clone = e_cal_component_clone (priv->comp);
+ comp_editor_copy_new_attendees (clone, priv->comp);
for (l = priv->pages; l != NULL; l = l->next) {
- if (!comp_editor_page_fill_component (l->data, clone)) {
- gtk_object_unref (GTK_OBJECT (clone));
+ if (IS_COMP_EDITOR_PAGE (l->data) &&
+ !comp_editor_page_fill_component (l->data, clone)) {
+ g_object_unref (clone);
+ g_hash_table_destroy (timezones);
comp_editor_show_page (editor, COMP_EDITOR_PAGE (l->data));
return FALSE;
}
+
+ /* retrieve all timezones */
+ if (IS_COMP_EDITOR_PAGE (l->data))
+ comp_editor_page_fill_timezones (l->data, timezones);
}
-
+
/* If we are not the organizer, we don't update the sequence number */
- if (!cal_component_has_organizer (clone) || itip_organizer_is_user (clone))
- cal_component_commit_sequence (clone);
+ if (!e_cal_component_has_organizer (clone) ||
+ itip_organizer_is_user (registry, clone, priv->cal_client) ||
+ itip_sentby_is_user (registry, clone, priv->cal_client))
+ e_cal_component_commit_sequence (clone);
else
- cal_component_abort_sequence (clone);
+ e_cal_component_abort_sequence (clone);
- gtk_object_unref (GTK_OBJECT (priv->comp));
+ g_object_unref (priv->comp);
priv->comp = clone;
- priv->updating = TRUE;
+ e_cal_component_get_uid (priv->comp, &orig_uid);
+ /* Make a copy of it, because call of e_cal_create_object()
+ * rewrites the internal uid. */
+ orig_uid_copy = g_strdup (orig_uid);
+
+ /* send timezones */
+ g_hash_table_foreach (timezones, (GHFunc) send_timezone, editor);
+ g_hash_table_destroy (timezones);
+
+ /* Attachments*/
+
+ e_cal_component_set_attachment_list (
+ priv->comp, get_attachment_list (editor));
+ icalcomp = e_cal_component_get_icalcomponent (priv->comp);
+ /* send the component to the server */
+ if (!cal_comp_is_on_server (priv->comp, priv->cal_client)) {
+ gchar *uid = NULL;
+ result = e_cal_client_create_object_sync (
+ priv->cal_client, icalcomp, &uid, NULL, &error);
+ if (result) {
+ icalcomponent_set_uid (icalcomp, uid);
+ g_free (uid);
+ g_signal_emit_by_name (editor, "object_created");
+ }
+ } else {
+ gboolean has_recurrences;
- result = cal_client_update_object (priv->client, priv->comp);
- if (result != CAL_CLIENT_RESULT_SUCCESS) {
- GtkWidget *dlg;
- char *msg;
+ has_recurrences =
+ e_cal_component_has_recurrences (priv->comp);
- switch (result) {
- case CAL_CLIENT_RESULT_INVALID_OBJECT :
- msg = g_strdup (_("Could not update invalid object"));
- break;
- case CAL_CLIENT_RESULT_NOT_FOUND :
- msg = g_strdup (_("Object not found, not updated"));
- break;
- case CAL_CLIENT_RESULT_PERMISSION_DENIED :
- msg = g_strdup (_("You don't have permissions to update this object"));
- break;
- default :
- msg = g_strdup (_("Could not update object"));
- break;
+ if (has_recurrences && priv->mod == CALOBJ_MOD_ALL)
+ comp_util_sanitize_recurrence_master (
+ priv->comp, priv->cal_client);
+
+ if (priv->mod == CALOBJ_MOD_THIS) {
+ e_cal_component_set_rdate_list (priv->comp, NULL);
+ e_cal_component_set_rrule_list (priv->comp, NULL);
+ e_cal_component_set_exdate_list (priv->comp, NULL);
+ e_cal_component_set_exrule_list (priv->comp, NULL);
+ }
+ result = e_cal_client_modify_object_sync (
+ priv->cal_client, icalcomp, priv->mod, NULL, &error);
+
+ if (priv->mod == CALOBJ_MOD_THIS) {
+ if (result && ((flags & COMP_EDITOR_DELEGATE) ||
+ !e_cal_component_has_organizer (clone) ||
+ itip_organizer_is_user (registry, clone, priv->cal_client) ||
+ itip_sentby_is_user (registry, clone, priv->cal_client)))
+ e_cal_component_commit_sequence (clone);
+ else
+ e_cal_component_abort_sequence (clone);
+ }
+ }
+
+ /* If the delay delivery is set, the items will not be created in
+ * the server immediately, so we need not show them in the view.
+ * They will appear as soon as the server creates it after the
+ * delay period. */
+ if (result && e_cal_component_has_attendees (priv->comp)) {
+ gboolean delay_set = FALSE;
+ icalproperty *icalprop;
+ icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
+ while (icalprop) {
+ const gchar *x_name;
+
+ x_name = icalproperty_get_x_name (icalprop);
+ if (!strcmp (x_name, "X-EVOLUTION-OPTIONS-DELAY")) {
+ delay_set = TRUE;
+ break;
+ }
+
+ icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
+ }
+ if (delay_set) {
+ g_free (orig_uid_copy);
+ return TRUE;
}
+ }
+
+ if (!result) {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (
+ NULL, 0,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ "%s", (error != NULL) ? error->message :
+ _("Could not update object"));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
- dlg = gnome_error_dialog (msg);
- gnome_dialog_run_and_close (GNOME_DIALOG (dlg));
- g_free (msg);
+ if (error)
+ g_error_free (error);
+
+ g_free (orig_uid_copy);
return FALSE;
} else {
- priv->changed = FALSE;
+ if (priv->source_client &&
+ !e_source_equal (e_client_get_source (E_CLIENT (priv->cal_client)),
+ e_client_get_source (E_CLIENT (priv->source_client))) &&
+ cal_comp_is_on_server (priv->comp, priv->source_client)) {
+ /* Comp found a new home. Remove it from old one. */
+ GError *error = NULL;
+
+ if (e_cal_component_is_instance (priv->comp) ||
+ e_cal_component_has_recurrences (priv->comp))
+ e_cal_client_remove_object_sync (
+ priv->source_client, orig_uid_copy,
+ NULL, CALOBJ_MOD_ALL, NULL, &error);
+ else
+ e_cal_client_remove_object_sync (
+ priv->source_client,
+ orig_uid_copy, NULL, CALOBJ_MOD_THIS, NULL, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to remove object: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ /* Let priv->source_client point to new home,
+ * so we can move it again this session. */
+ g_object_unref (priv->source_client);
+ priv->source_client = g_object_ref (priv->cal_client);
+
+ listen_for_changes (editor);
+ }
+
+ comp_editor_set_changed (editor, FALSE);
+ priv->saved = TRUE;
}
- priv->updating = FALSE;
+ g_free (orig_uid_copy);
return TRUE;
}
@@ -371,144 +671,2055 @@ static gboolean
save_comp_with_send (CompEditor *editor)
{
CompEditorPrivate *priv;
- gboolean send;
+ CompEditorFlags flags;
+ ESourceRegistry *registry;
+ EShell *shell;
+ gboolean send, delegated, only_new_attendees = FALSE;
+ gboolean delegate;
+ gboolean strip_alarms = TRUE;
priv = editor->priv;
+ flags = comp_editor_get_flags (editor);
+ shell = comp_editor_get_shell (editor);
+
+ registry = e_shell_get_registry (shell);
+
send = priv->changed && priv->needs_send;
+ delegate = flags & COMP_EDITOR_DELEGATE;
+
+ if (delegate) {
+ icalcomponent *icalcomp = e_cal_component_get_icalcomponent (priv->comp);
+ icalproperty *icalprop;
+
+ icalprop = icalproperty_new_x ("1");
+ icalproperty_set_x_name (icalprop, "X-EVOLUTION-DELEGATED");
+ icalcomponent_add_property (icalcomp, icalprop);
+ }
if (!save_comp (editor))
return FALSE;
- if (send && send_component_dialog (priv->comp, !priv->existing_org)) {
- if (itip_organizer_is_user (priv->comp))
- return comp_editor_send_comp (editor, CAL_COMPONENT_METHOD_REQUEST);
- else
- return comp_editor_send_comp (editor, CAL_COMPONENT_METHOD_REPLY);
- }
+ delegated = delegate && !e_cal_client_check_save_schedules (priv->cal_client);
+ if (delegated || (send && send_component_dialog (
+ (GtkWindow *) editor, priv->cal_client, priv->comp,
+ !priv->existing_org, &strip_alarms, !priv->existing_org ?
+ NULL : &only_new_attendees))) {
+ if (delegated)
+ only_new_attendees = FALSE;
+
+ comp_editor_set_flags (
+ editor, (comp_editor_get_flags (editor) &
+ (~COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY)) |
+ (only_new_attendees ?
+ COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY : 0));
+
+ if ((itip_organizer_is_user (registry, priv->comp, priv->cal_client) ||
+ itip_sentby_is_user (registry, priv->comp, priv->cal_client))) {
+ if (e_cal_component_get_vtype (priv->comp) == E_CAL_COMPONENT_JOURNAL)
+ return comp_editor_send_comp (
+ editor, E_CAL_COMPONENT_METHOD_PUBLISH,
+ strip_alarms);
+ else
+ return comp_editor_send_comp (
+ editor, E_CAL_COMPONENT_METHOD_REQUEST,
+ strip_alarms);
+ } else {
+ if (!comp_editor_send_comp (
+ editor, E_CAL_COMPONENT_METHOD_REQUEST,
+ strip_alarms))
+ return FALSE;
+
+ if (delegate)
+ return comp_editor_send_comp (
+ editor, E_CAL_COMPONENT_METHOD_REPLY,
+ strip_alarms);
+ }
+ }
return TRUE;
}
static void
-delete_comp (CompEditor *editor)
+update_window_border (CompEditor *editor,
+ const gchar *description)
+{
+ const gchar *icon_name;
+ const gchar *format;
+ gchar *title;
+
+ if (editor->priv->comp == NULL) {
+ title = g_strdup (_("Edit Appointment"));
+ icon_name = "x-office-calendar";
+ goto exit;
+
+ } else switch (e_cal_component_get_vtype (editor->priv->comp)) {
+ case E_CAL_COMPONENT_EVENT:
+ if (editor->priv->is_group_item)
+ format = _("Meeting - %s");
+ else
+ format = _("Appointment - %s");
+ icon_name = "appointment-new";
+ break;
+
+ case E_CAL_COMPONENT_TODO:
+ if (editor->priv->is_group_item)
+ format = _("Assigned Task - %s");
+ else
+ format = _("Task - %s");
+ icon_name = "stock_task";
+ break;
+
+ case E_CAL_COMPONENT_JOURNAL:
+ format = _("Memo - %s");
+ icon_name = "stock_insert-note";
+ break;
+
+ default:
+ g_return_if_reached ();
+ }
+
+ if (description == NULL || *description == '\0') {
+ ECalComponentText text;
+
+ e_cal_component_get_summary (editor->priv->comp, &text);
+ description = text.value;
+ }
+
+ if (description == NULL || *description == '\0')
+ description = _("No Summary");
+
+ title = g_strdup_printf (format, description);
+
+exit:
+ gtk_window_set_icon_name (GTK_WINDOW (editor), icon_name);
+ gtk_window_set_title (GTK_WINDOW (editor), title);
+
+ g_free (title);
+}
+
+static void
+action_attach_cb (GtkAction *action,
+ CompEditor *editor)
+{
+ EAttachmentStore *store;
+ EAttachmentView *view;
+
+ view = E_ATTACHMENT_VIEW (editor->priv->attachment_view);
+ store = e_attachment_view_get_store (view);
+
+ e_attachment_store_run_load_dialog (store, GTK_WINDOW (editor));
+}
+
+static void
+action_classification_cb (GtkRadioAction *action,
+ GtkRadioAction *current,
+ CompEditor *editor)
+{
+ comp_editor_set_changed (editor, TRUE);
+}
+
+static void
+action_close_cb (GtkAction *action,
+ CompEditor *editor)
+{
+ commit_all_fields (editor);
+
+ if (prompt_and_save_changes (editor, TRUE))
+ close_dialog (editor);
+}
+
+static void
+action_help_cb (GtkAction *action,
+ CompEditor *editor)
+{
+ comp_editor_show_help (editor);
+}
+
+static void
+action_print_cb (GtkAction *action,
+ CompEditor *editor)
+{
+ CompEditorPrivate *priv = editor->priv;
+ ECalComponent *comp;
+ GList *l;
+ icalcomponent *component;
+ icalcomponent *clone;
+ icaltimezone *zone;
+ gboolean use_24_hour_format;
+
+ comp = e_cal_component_new ();
+ component = e_cal_component_get_icalcomponent (priv->comp);
+ clone = icalcomponent_new_clone (component);
+ e_cal_component_set_icalcomponent (comp, clone);
+
+ for (l = priv->pages; l != NULL; l = l->next)
+ comp_editor_page_fill_component (l->data, comp);
+
+ zone = comp_editor_get_timezone (editor);
+ use_24_hour_format = comp_editor_get_use_24_hour_format (editor);
+
+ print_comp (
+ comp, priv->cal_client, zone, use_24_hour_format,
+ GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
+
+ g_object_unref (comp);
+}
+
+static void
+action_print_preview_cb (GtkAction *action,
+ CompEditor *editor)
+{
+ CompEditorPrivate *priv = editor->priv;
+ ECalComponent *comp;
+ GList *l;
+ icalcomponent *component;
+ icalcomponent *clone;
+ icaltimezone *zone;
+ gboolean use_24_hour_format;
+
+ comp = e_cal_component_new ();
+ component = e_cal_component_get_icalcomponent (priv->comp);
+ clone = icalcomponent_new_clone (component);
+ e_cal_component_set_icalcomponent (comp, clone);
+
+ for (l = priv->pages; l != NULL; l = l->next)
+ comp_editor_page_fill_component (l->data, comp);
+
+ zone = comp_editor_get_timezone (editor);
+ use_24_hour_format = comp_editor_get_use_24_hour_format (editor);
+
+ print_comp (
+ comp, priv->cal_client, zone, use_24_hour_format,
+ GTK_PRINT_OPERATION_ACTION_PREVIEW);
+
+ g_object_unref (comp);
+}
+
+static gboolean
+remove_event_dialog (ECalClient *client,
+ ECalComponent *comp,
+ GtkWindow *parent)
+{
+ GtkWidget *dialog;
+ gboolean ret;
+
+ g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), TRUE);
+
+ dialog = gtk_message_dialog_new (
+ parent, 0, GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_YES_NO, "%s", _("Keep original item?"));
+ gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+ ret = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES;
+ gtk_widget_destroy (dialog);
+
+ return ret;
+}
+
+static void
+save_and_close_editor (CompEditor *editor,
+ gboolean can_close)
+{
+ CompEditorPrivate *priv = editor->priv;
+ EAttachmentStore *store;
+ EAttachmentView *view;
+ ECalComponentText text;
+ gboolean delegated = FALSE;
+ gboolean correct = FALSE;
+ ECalComponent *comp;
+ const gchar *uid = NULL;
+
+ view = E_ATTACHMENT_VIEW (priv->attachment_view);
+ store = e_attachment_view_get_store (view);
+
+ if (e_attachment_store_get_num_loading (store) > 0) {
+ gboolean response = 1;
+ /*FIXME: Cannot use mail functions from calendar!!!! */
+#if 0
+ ECalComponentVType vtype = e_cal_component_get_vtype (editor->priv->comp);
+
+ if (vtype == E_CAL_COMPONENT_EVENT)
+ response = em_utils_prompt_user (
+ (GtkWindow *) widget,
+ NULL,
+ "calendar:ask-send-event-pending-download",
+ NULL);
+ else
+ response = em_utils_prompt_user (
+ (GtkWindow *) widget,
+ NULL,
+ "calendar:ask-send-task-pending-download",
+ NULL);
+#endif
+ if (!response)
+ return;
+ }
+
+ if (e_client_is_readonly (E_CLIENT (priv->cal_client))) {
+ e_alert_submit (
+ E_ALERT_SINK (editor),
+ "calendar:prompt-read-only-cal-editor",
+ e_source_get_display_name (
+ e_client_get_source (E_CLIENT (priv->cal_client))),
+ NULL);
+ return;
+ }
+
+ if ((comp_editor_get_flags (editor) & COMP_EDITOR_IS_ASSIGNED) != 0
+ && e_cal_component_get_vtype (priv->comp) == E_CAL_COMPONENT_TODO
+ && e_client_check_capability (E_CLIENT (priv->cal_client), CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT)) {
+ e_alert_submit (
+ E_ALERT_SINK (editor),
+ "calendar:prompt-no-task-assignment-editor",
+ e_source_get_display_name (
+ e_client_get_source (E_CLIENT (priv->cal_client))),
+ NULL);
+ return;
+ }
+
+ commit_all_fields (editor);
+ if (e_cal_component_has_recurrences (priv->comp)) {
+ if (!recur_component_dialog (
+ priv->cal_client, priv->comp, &priv->mod,
+ GTK_WINDOW (editor), delegated))
+ return;
+ } else if (e_cal_component_is_instance (priv->comp))
+ priv->mod = CALOBJ_MOD_THIS;
+
+ comp = comp_editor_get_current_comp (editor, &correct);
+ e_cal_component_get_summary (comp, &text);
+ g_object_unref (comp);
+
+ if (!correct)
+ return;
+
+ if (!text.value)
+ if (!send_component_prompt_subject (
+ (GtkWindow *) editor, priv->cal_client, priv->comp))
+ return;
+
+ gtk_widget_set_sensitive (GTK_WIDGET (editor), FALSE);
+
+ if (save_comp_with_send (editor)) {
+ CompEditorFlags flags;
+ gboolean delegate;
+
+ flags = comp_editor_get_flags (editor);
+ delegate = flags & COMP_EDITOR_DELEGATE;
+
+ if (delegate && !remove_event_dialog (
+ priv->cal_client, priv->comp, GTK_WINDOW (editor))) {
+ GError *error = NULL;
+
+ e_cal_component_get_uid (priv->comp, &uid);
+
+ if (e_cal_component_is_instance (priv->comp) ||
+ e_cal_component_has_recurrences (priv->comp)) {
+ gchar *rid;
+ rid = e_cal_component_get_recurid_as_string (priv->comp);
+ e_cal_client_remove_object_sync (
+ priv->cal_client, uid, rid,
+ priv->mod, NULL, &error);
+ g_free (rid);
+ } else
+ e_cal_client_remove_object_sync (
+ priv->cal_client, uid, NULL,
+ CALOBJ_MOD_THIS, NULL, &error);
+
+ g_clear_error (&error);
+ }
+ } else
+ correct = FALSE;
+
+ gtk_widget_set_sensitive (GTK_WIDGET (editor), TRUE);
+
+ if (correct) {
+ if (can_close)
+ close_dialog (editor);
+ else {
+ ECalComponent *comp;
+ ECalClientSourceType source_type;
+ icalcomponent *icalcomp = NULL;
+ const gchar *uid = NULL;
+ gchar *rid = NULL;
+ GError *error = NULL;
+
+ comp_editor_set_changed (editor, FALSE);
+
+ /*
+ * A server can modify the event on save. Considering this, it is needed to fetch the updated
+ * version of the event from server, updating the component, then user can keep editing the
+ * event
+ */
+ e_cal_component_get_uid (priv->comp, &uid);
+ rid = e_cal_component_get_recurid_as_string (priv->comp);
+
+ source_type = e_cal_client_get_source_type (priv->cal_client);
+ if (!e_cal_client_get_object_sync (priv->cal_client, uid, rid, &icalcomp, NULL, &error)) {
+ if (error != NULL) {
+ switch (source_type) {
+ case (E_CAL_CLIENT_SOURCE_TYPE_TASKS):
+ g_warning ("Unable to retrieve saved component from the task list, returned error was: %s", error->message);
+ break;
+ case (E_CAL_CLIENT_SOURCE_TYPE_MEMOS):
+ g_warning ("Unable to retrieve saved component from the memo list, returned error was: %s", error->message);
+ break;
+ case (E_CAL_CLIENT_SOURCE_TYPE_EVENTS):
+ default:
+ g_warning ("Unable to retrieve saved component from the calendar, returned error was: %s", error->message);
+ break;
+ }
+ g_clear_error (&error);
+ } else {
+ switch (source_type) {
+ case (E_CAL_CLIENT_SOURCE_TYPE_TASKS):
+ g_warning ("Unable to retrieve saved component from the task list");
+ break;
+ case (E_CAL_CLIENT_SOURCE_TYPE_MEMOS):
+ g_warning ("Unable to retrieve saved component from the memo list");
+ break;
+ case (E_CAL_CLIENT_SOURCE_TYPE_EVENTS):
+ default:
+ g_warning ("Unable to retrieve saved component from the calendar");
+ break;
+ }
+ }
+ e_notice (
+ GTK_WINDOW (editor),
+ GTK_MESSAGE_ERROR,
+ _("Unable to synchronize with the server"));
+ } else {
+ comp = e_cal_component_new ();
+ if (e_cal_component_set_icalcomponent (comp, icalcomp)) {
+ gboolean has_recurrences;
+
+ has_recurrences = e_cal_component_has_recurrences (comp);
+
+ if (has_recurrences && priv->mod == CALOBJ_MOD_ALL)
+ comp_util_sanitize_recurrence_master (comp, priv->cal_client);
+
+ comp_editor_edit_comp (editor, comp);
+ } else {
+ switch (source_type) {
+ case (E_CAL_CLIENT_SOURCE_TYPE_TASKS):
+ g_warning ("Unable to update the editor with the retrieved component from the task list");
+ break;
+ case (E_CAL_CLIENT_SOURCE_TYPE_MEMOS):
+ g_warning ("Unable to update the editor with the retrieved component from the memo list");
+ break;
+ case (E_CAL_CLIENT_SOURCE_TYPE_EVENTS):
+ default:
+ g_warning ("Unable to update the editor with the retrieved component from the calendar");
+ break;
+ }
+ e_notice (
+ GTK_WINDOW (editor),
+ GTK_MESSAGE_ERROR,
+ _("Unable to synchronize with the server"));
+ icalcomponent_free (icalcomp);
+ }
+ g_object_unref (comp);
+ }
+ g_free (rid);
+ }
+ }
+}
+
+static void
+action_save_cb (GtkAction *action,
+ CompEditor *editor)
+{
+ save_and_close_editor (editor, FALSE);
+}
+
+static void
+action_save_and_close_cb (GtkAction *action,
+ CompEditor *editor)
+{
+ save_and_close_editor (editor, TRUE);
+}
+
+static void
+action_view_categories_cb (GtkToggleAction *action,
+ CompEditor *editor)
+{
+ CompEditorClass *class;
+ gboolean active;
+
+ class = COMP_EDITOR_GET_CLASS (editor);
+ active = gtk_toggle_action_get_active (action);
+
+ if (class->show_categories != NULL)
+ class->show_categories (editor, active);
+}
+
+static void
+action_view_role_cb (GtkToggleAction *action,
+ CompEditor *editor)
+{
+ CompEditorClass *class;
+ gboolean active;
+
+ class = COMP_EDITOR_GET_CLASS (editor);
+ active = gtk_toggle_action_get_active (action);
+
+ if (class->show_role != NULL)
+ class->show_role (editor, active);
+}
+
+static void
+action_view_rsvp_cb (GtkToggleAction *action,
+ CompEditor *editor)
+{
+ CompEditorClass *class;
+ gboolean active;
+
+ class = COMP_EDITOR_GET_CLASS (editor);
+ active = gtk_toggle_action_get_active (action);
+
+ if (class->show_rsvp != NULL)
+ class->show_rsvp (editor, active);
+}
+
+static void
+action_view_status_cb (GtkToggleAction *action,
+ CompEditor *editor)
+{
+ CompEditorClass *class;
+ gboolean active;
+
+ class = COMP_EDITOR_GET_CLASS (editor);
+ active = gtk_toggle_action_get_active (action);
+
+ if (class->show_status != NULL)
+ class->show_status (editor, active);
+}
+
+static void
+action_view_time_zone_cb (GtkToggleAction *action,
+ CompEditor *editor)
+{
+ CompEditorClass *class;
+ gboolean active;
+
+ class = COMP_EDITOR_GET_CLASS (editor);
+ active = gtk_toggle_action_get_active (action);
+
+ if (class->show_time_zone != NULL)
+ class->show_time_zone (editor, active);
+}
+
+static void
+action_view_type_cb (GtkToggleAction *action,
+ CompEditor *editor)
+{
+ CompEditorClass *class;
+ gboolean active;
+
+ class = COMP_EDITOR_GET_CLASS (editor);
+ active = gtk_toggle_action_get_active (action);
+
+ if (class->show_type != NULL)
+ class->show_type (editor, active);
+}
+
+static GtkActionEntry core_entries[] = {
+
+ { "close",
+ GTK_STOCK_CLOSE,
+ NULL,
+ NULL,
+ N_("Close the current window"),
+ G_CALLBACK (action_close_cb) },
+
+ { "copy-clipboard",
+ GTK_STOCK_COPY,
+ NULL,
+ NULL,
+ N_("Copy the selection"),
+ NULL }, /* Handled by EFocusTracker */
+
+ { "cut-clipboard",
+ GTK_STOCK_CUT,
+ NULL,
+ NULL,
+ N_("Cut the selection"),
+ NULL }, /* Handled by EFocusTracker */
+
+ { "delete-selection",
+ GTK_STOCK_DELETE,
+ NULL,
+ NULL,
+ N_("Delete the selection"),
+ NULL }, /* Handled by EFocusTracker */
+
+ { "help",
+ GTK_STOCK_HELP,
+ NULL,
+ NULL,
+ N_("View help"),
+ G_CALLBACK (action_help_cb) },
+
+ { "paste-clipboard",
+ GTK_STOCK_PASTE,
+ NULL,
+ NULL,
+ N_("Paste the clipboard"),
+ NULL }, /* Handled by EFocusTracker */
+
+ { "print",
+ GTK_STOCK_PRINT,
+ NULL,
+ "<Control>p",
+ NULL,
+ G_CALLBACK (action_print_cb) },
+
+ { "print-preview",
+ GTK_STOCK_PRINT_PREVIEW,
+ NULL,
+ NULL,
+ NULL,
+ G_CALLBACK (action_print_preview_cb) },
+
+ { "save",
+ GTK_STOCK_SAVE,
+ NULL,
+ NULL,
+ N_("Save current changes"),
+ G_CALLBACK (action_save_cb) },
+
+ { "save-and-close",
+ NULL,
+ N_("Save and Close"),
+ NULL,
+ N_("Save current changes and close editor"),
+ G_CALLBACK (action_save_and_close_cb) },
+
+ { "select-all",
+ GTK_STOCK_SELECT_ALL,
+ NULL,
+ "<Control>a",
+ N_("Select all text"),
+ NULL }, /* Handled by EFocusTracker */
+
+ /* Menus */
+
+ { "classification-menu",
+ NULL,
+ N_("_Classification"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "edit-menu",
+ NULL,
+ N_("_Edit"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "file-menu",
+ NULL,
+ N_("_File"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "help-menu",
+ NULL,
+ N_("_Help"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "insert-menu",
+ NULL,
+ N_("_Insert"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "options-menu",
+ NULL,
+ N_("_Options"),
+ NULL,
+ NULL,
+ NULL },
+
+ { "view-menu",
+ NULL,
+ N_("_View"),
+ NULL,
+ NULL,
+ NULL }
+};
+
+static GtkActionEntry individual_entries[] = {
+
+ { "attach",
+ "mail-attachment",
+ N_("_Attachment..."),
+ "<Control>m",
+ N_("Attach a file"),
+ G_CALLBACK (action_attach_cb) }
+};
+
+static GtkToggleActionEntry core_toggle_entries[] = {
+
+ { "view-categories",
+ NULL,
+ N_("_Categories"),
+ NULL,
+ N_("Toggles whether to display categories"),
+ G_CALLBACK (action_view_categories_cb),
+ FALSE },
+
+ { "view-time-zone",
+ "stock_timezone",
+ N_("Time _Zone"),
+ NULL,
+ N_("Toggles whether the time zone is displayed"),
+ G_CALLBACK (action_view_time_zone_cb),
+ FALSE }
+};
+
+static GtkRadioActionEntry classification_radio_entries[] = {
+
+ { "classify-public",
+ NULL,
+ N_("Pu_blic"),
+ NULL,
+ N_("Classify as public"),
+ E_CAL_COMPONENT_CLASS_PUBLIC },
+
+ { "classify-private",
+ NULL,
+ N_("_Private"),
+ NULL,
+ N_("Classify as private"),
+ E_CAL_COMPONENT_CLASS_PRIVATE },
+
+ { "classify-confidential",
+ NULL,
+ N_("_Confidential"),
+ NULL,
+ N_("Classify as confidential"),
+ E_CAL_COMPONENT_CLASS_CONFIDENTIAL }
+};
+
+static GtkToggleActionEntry coordinated_toggle_entries[] = {
+
+ { "view-role",
+ NULL,
+ N_("R_ole Field"),
+ NULL,
+ N_("Toggles whether the Role field is displayed"),
+ G_CALLBACK (action_view_role_cb),
+ FALSE },
+
+ { "view-rsvp",
+ NULL,
+ N_("_RSVP"),
+ NULL,
+ N_("Toggles whether the RSVP field is displayed"),
+ G_CALLBACK (action_view_rsvp_cb),
+ FALSE },
+
+ { "view-status",
+ NULL,
+ N_("_Status Field"),
+ NULL,
+ N_("Toggles whether the Status field is displayed"),
+ G_CALLBACK (action_view_status_cb),
+ FALSE },
+
+ { "view-type",
+ NULL,
+ N_("_Type Field"),
+ NULL,
+ N_("Toggles whether the Attendee Type is displayed"),
+ G_CALLBACK (action_view_type_cb),
+ FALSE }
+};
+
+static void
+comp_editor_set_shell (CompEditor *editor,
+ EShell *shell)
+{
+ g_return_if_fail (E_IS_SHELL (shell));
+ g_return_if_fail (editor->priv->shell == NULL);
+
+ editor->priv->shell = shell;
+
+ g_object_add_weak_pointer (G_OBJECT (shell), &editor->priv->shell);
+}
+
+static void
+comp_editor_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CHANGED:
+ comp_editor_set_changed (
+ COMP_EDITOR (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_CLIENT:
+ comp_editor_set_client (
+ COMP_EDITOR (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_FLAGS:
+ comp_editor_set_flags (
+ COMP_EDITOR (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_SHELL:
+ comp_editor_set_shell (
+ COMP_EDITOR (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_SUMMARY:
+ comp_editor_set_summary (
+ COMP_EDITOR (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_TIMEZONE:
+ comp_editor_set_timezone (
+ COMP_EDITOR (object),
+ g_value_get_pointer (value));
+ return;
+
+ case PROP_USE_24_HOUR_FORMAT:
+ comp_editor_set_use_24_hour_format (
+ COMP_EDITOR (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_WEEK_START_DAY:
+ comp_editor_set_week_start_day (
+ COMP_EDITOR (object),
+ g_value_get_enum (value));
+ return;
+
+ case PROP_WORK_DAY_END_HOUR:
+ comp_editor_set_work_day_end_hour (
+ COMP_EDITOR (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_WORK_DAY_END_MINUTE:
+ comp_editor_set_work_day_end_minute (
+ COMP_EDITOR (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_WORK_DAY_START_HOUR:
+ comp_editor_set_work_day_start_hour (
+ COMP_EDITOR (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_WORK_DAY_START_MINUTE:
+ comp_editor_set_work_day_start_minute (
+ COMP_EDITOR (object),
+ g_value_get_int (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+comp_editor_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CHANGED:
+ g_value_set_boolean (
+ value, comp_editor_get_changed (
+ COMP_EDITOR (object)));
+ return;
+
+ case PROP_CLIENT:
+ g_value_set_object (
+ value, comp_editor_get_client (
+ COMP_EDITOR (object)));
+ return;
+
+ case PROP_FLAGS:
+ g_value_set_int (
+ value, comp_editor_get_flags (
+ COMP_EDITOR (object)));
+ return;
+
+ case PROP_FOCUS_TRACKER:
+ g_value_set_object (
+ value, comp_editor_get_focus_tracker (
+ COMP_EDITOR (object)));
+ return;
+
+ case PROP_SHELL:
+ g_value_set_object (
+ value, comp_editor_get_shell (
+ COMP_EDITOR (object)));
+ return;
+
+ case PROP_SUMMARY:
+ g_value_set_string (
+ value, comp_editor_get_summary (
+ COMP_EDITOR (object)));
+ return;
+
+ case PROP_TIMEZONE:
+ g_value_set_pointer (
+ value, comp_editor_get_timezone (
+ COMP_EDITOR (object)));
+ return;
+
+ case PROP_USE_24_HOUR_FORMAT:
+ g_value_set_boolean (
+ value, comp_editor_get_use_24_hour_format (
+ COMP_EDITOR (object)));
+ return;
+
+ case PROP_WEEK_START_DAY:
+ g_value_set_enum (
+ value, comp_editor_get_week_start_day (
+ COMP_EDITOR (object)));
+ return;
+
+ case PROP_WORK_DAY_END_HOUR:
+ g_value_set_int (
+ value, comp_editor_get_work_day_end_hour (
+ COMP_EDITOR (object)));
+ return;
+
+ case PROP_WORK_DAY_END_MINUTE:
+ g_value_set_int (
+ value, comp_editor_get_work_day_end_minute (
+ COMP_EDITOR (object)));
+ return;
+
+ case PROP_WORK_DAY_START_HOUR:
+ g_value_set_int (
+ value, comp_editor_get_work_day_start_hour (
+ COMP_EDITOR (object)));
+ return;
+
+ case PROP_WORK_DAY_START_MINUTE:
+ g_value_set_int (
+ value, comp_editor_get_work_day_start_minute (
+ COMP_EDITOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+unref_page_cb (gpointer editor_page,
+ gpointer comp_editor)
+{
+ if (IS_COMP_EDITOR_PAGE (editor_page)) {
+ GtkWidget *page_widget;
+ CompEditorPage *page = COMP_EDITOR_PAGE (editor_page);
+ CompEditor *editor = COMP_EDITOR (comp_editor);
+
+ g_return_if_fail (page != NULL);
+ g_return_if_fail (editor != NULL);
+
+ page_widget = comp_editor_page_get_widget (page);
+ g_signal_handlers_disconnect_matched (
+ page_widget, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, page);
+ }
+
+ g_signal_handlers_disconnect_matched (
+ editor_page, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, comp_editor);
+ g_object_unref (editor_page);
+}
+
+static void
+comp_editor_dispose (GObject *object)
{
CompEditorPrivate *priv;
- const char *uid;
- priv = editor->priv;
+ priv = COMP_EDITOR_GET_PRIVATE (object);
- cal_component_get_uid (priv->comp, &uid);
- priv->updating = TRUE;
- cal_client_remove_object (priv->client, uid);
- priv->updating = FALSE;
- close_dialog (editor);
+ if (priv->shell != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell), &priv->shell);
+ priv->shell = NULL;
+ }
+
+ if (priv->focus_tracker != NULL) {
+ g_object_unref (priv->focus_tracker);
+ priv->focus_tracker = NULL;
+ }
+
+ if (priv->window_group != NULL) {
+ g_object_unref (priv->window_group);
+ priv->window_group = NULL;
+ }
+
+ if (priv->cal_client) {
+ g_object_unref (priv->cal_client);
+ priv->cal_client = NULL;
+ }
+
+ if (priv->source_client) {
+ g_object_unref (priv->source_client);
+ priv->source_client = NULL;
+ }
+
+ if (priv->view_cancellable) {
+ g_cancellable_cancel (priv->view_cancellable);
+ g_object_unref (priv->view_cancellable);
+ priv->view_cancellable = NULL;
+ }
+
+ if (priv->view) {
+ g_signal_handlers_disconnect_matched (
+ priv->view, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->view);
+ priv->view = NULL;
+ }
+
+ if (priv->attachment_view) {
+ EAttachmentStore *store;
+
+ store = e_attachment_view_get_store (
+ E_ATTACHMENT_VIEW (priv->attachment_view));
+ g_signal_handlers_disconnect_matched (
+ store, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->attachment_view);
+ priv->attachment_view = NULL;
+ }
+
+ /* We want to destroy the pages after the widgets get destroyed,
+ * since they have lots of signal handlers connected to the widgets
+ * with the pages as the data. */
+ g_list_foreach (priv->pages, (GFunc) unref_page_cb, object);
+ g_list_free (priv->pages);
+ priv->pages = NULL;
+
+ if (priv->comp) {
+ g_object_unref (priv->comp);
+ priv->comp = NULL;
+ }
+
+ if (priv->ui_manager != NULL) {
+ g_object_unref (priv->ui_manager);
+ priv->ui_manager = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (comp_editor_parent_class)->dispose (object);
+}
+
+static void
+comp_editor_finalize (GObject *object)
+{
+ CompEditorPrivate *priv;
+
+ priv = COMP_EDITOR_GET_PRIVATE (object);
+
+ g_object_unref (priv->calendar_settings);
+ g_free (priv->summary);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (comp_editor_parent_class)->finalize (object);
+}
+
+static void
+comp_editor_constructed (GObject *object)
+{
+ e_extensible_load_extensions (E_EXTENSIBLE (object));
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (comp_editor_parent_class)->constructed (object);
+}
+
+static void
+comp_editor_bind_settings (CompEditor *editor)
+{
+ GtkAction *action;
+
+ g_return_if_fail (editor != NULL);
+
+ action = comp_editor_get_action (editor, "view-categories");
+ g_settings_bind (
+ editor->priv->calendar_settings, "editor-show-categories",
+ action, "active",
+ G_SETTINGS_BIND_DEFAULT);
+
+ action = comp_editor_get_action (editor, "view-role");
+ g_settings_bind (
+ editor->priv->calendar_settings, "editor-show-role",
+ action, "active",
+ G_SETTINGS_BIND_DEFAULT);
+
+ action = comp_editor_get_action (editor, "view-rsvp");
+ g_settings_bind (
+ editor->priv->calendar_settings, "editor-show-rsvp",
+ action, "active",
+ G_SETTINGS_BIND_DEFAULT);
+
+ action = comp_editor_get_action (editor, "view-status");
+ g_settings_bind (
+ editor->priv->calendar_settings, "editor-show-status",
+ action, "active",
+ G_SETTINGS_BIND_DEFAULT);
+
+ action = comp_editor_get_action (editor, "view-time-zone");
+ g_settings_bind (
+ editor->priv->calendar_settings, "editor-show-timezone",
+ action, "active",
+ G_SETTINGS_BIND_DEFAULT);
+
+ action = comp_editor_get_action (editor, "view-type");
+ g_settings_bind (
+ editor->priv->calendar_settings, "editor-show-type",
+ action, "active",
+ G_SETTINGS_BIND_DEFAULT);
+}
+
+static gboolean
+comp_editor_delete_event (GtkWidget *widget,
+ GdkEventAny *event)
+{
+ CompEditor *editor;
+
+ editor = COMP_EDITOR (widget);
+
+ commit_all_fields (editor);
+
+ if (prompt_and_save_changes (editor, TRUE))
+ close_dialog (editor);
+
+ return TRUE;
+}
+
+static gboolean
+comp_editor_key_press_event (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ CompEditor *editor;
+
+ editor = COMP_EDITOR (widget);
+
+ if (event->keyval == GDK_KEY_Escape) {
+ commit_all_fields (editor);
+
+ if (prompt_and_save_changes (editor, TRUE))
+ close_dialog (editor);
+
+ return TRUE;
+ }
+
+ /* Chain up to parent's key_press_event() method. */
+ return GTK_WIDGET_CLASS (comp_editor_parent_class)->
+ key_press_event (widget, event);
+}
+
+static gboolean
+comp_editor_drag_motion (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ guint time)
+{
+ CompEditorPrivate *priv;
+ EAttachmentView *view;
+
+ priv = COMP_EDITOR_GET_PRIVATE (widget);
+ view = E_ATTACHMENT_VIEW (priv->attachment_view);
+
+ return e_attachment_view_drag_motion (view, context, x, y, time);
+}
+
+static void
+comp_editor_drag_data_received (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection,
+ guint info,
+ guint time)
+{
+ CompEditorPrivate *priv;
+ EAttachmentView *view;
+
+ priv = COMP_EDITOR_GET_PRIVATE (widget);
+ view = E_ATTACHMENT_VIEW (priv->attachment_view);
+
+ /* Forward the data to the attachment view. Note that calling
+ * e_attachment_view_drag_data_received() will not work because
+ * that function only handles the case where all the other drag
+ * handlers have failed. */
+ e_attachment_paned_drag_data_received (
+ E_ATTACHMENT_PANED (view),
+ context, x, y, selection, info, time);
+}
+
+static void
+comp_editor_class_init (CompEditorClass *class)
+{
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ g_type_class_add_private (class, sizeof (CompEditorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = comp_editor_set_property;
+ object_class->get_property = comp_editor_get_property;
+ object_class->dispose = comp_editor_dispose;
+ object_class->finalize = comp_editor_finalize;
+ object_class->constructed = comp_editor_constructed;
+
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->delete_event = comp_editor_delete_event;
+ widget_class->key_press_event = comp_editor_key_press_event;
+ widget_class->drag_motion = comp_editor_drag_motion;
+ widget_class->drag_data_received = comp_editor_drag_data_received;
+
+ class->help_section = "memos-usage";
+ class->edit_comp = real_edit_comp;
+ class->send_comp = real_send_comp;
+ class->object_created = NULL;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CHANGED,
+ g_param_spec_boolean (
+ "changed",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLIENT,
+ g_param_spec_object (
+ "client",
+ NULL,
+ NULL,
+ E_TYPE_CAL_CLIENT,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ /* FIXME: Use a proper flags type instead of int. */
+ g_object_class_install_property (
+ object_class,
+ PROP_FLAGS,
+ g_param_spec_int (
+ "flags",
+ NULL,
+ NULL,
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FOCUS_TRACKER,
+ g_param_spec_object (
+ "focus-tracker",
+ NULL,
+ NULL,
+ E_TYPE_FOCUS_TRACKER,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL,
+ g_param_spec_object (
+ "shell",
+ NULL,
+ NULL,
+ E_TYPE_SHELL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SUMMARY,
+ g_param_spec_string (
+ "summary",
+ NULL,
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TIMEZONE,
+ g_param_spec_pointer (
+ "timezone",
+ "Time Zone",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_USE_24_HOUR_FORMAT,
+ g_param_spec_boolean (
+ "use-24-hour-format",
+ "Use 24-hour Format",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WEEK_START_DAY,
+ g_param_spec_enum (
+ "week-start-day",
+ "Week Start Day",
+ NULL,
+ E_TYPE_DATE_WEEKDAY,
+ G_DATE_MONDAY,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WORK_DAY_END_HOUR,
+ g_param_spec_int (
+ "work-day-end-hour",
+ "Work Day End Hour",
+ NULL,
+ 0,
+ 23,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WORK_DAY_END_MINUTE,
+ g_param_spec_int (
+ "work-day-end-minute",
+ "Work Day End Minute",
+ NULL,
+ 0,
+ 59,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WORK_DAY_START_HOUR,
+ g_param_spec_int (
+ "work-day-start-hour",
+ "Work Day Start Hour",
+ NULL,
+ 0,
+ 23,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WORK_DAY_START_MINUTE,
+ g_param_spec_int (
+ "work-day-start-minute",
+ "Work Day Start Minute",
+ NULL,
+ 0,
+ 59,
+ 0,
+ G_PARAM_READWRITE));
+
+ signals[OBJECT_CREATED] = g_signal_new (
+ "object_created",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CompEditorClass, object_created),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[COMP_CLOSED] = g_signal_new (
+ "comp_closed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (CompEditorClass, comp_closed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+}
+
+static void
+comp_editor_init (CompEditor *editor)
+{
+ CompEditorPrivate *priv;
+ EAttachmentView *view;
+ EAttachmentStore *store;
+ EFocusTracker *focus_tracker;
+ GdkDragAction drag_actions;
+ GtkTargetList *target_list;
+ GtkTargetEntry *targets;
+ GtkActionGroup *action_group;
+ GtkActionGroup *action_group_2;
+ GtkAction *action;
+ GtkWidget *container;
+ GtkWidget *widget;
+ GtkWindow *window;
+ EShell *shell;
+ gboolean express_mode;
+ gint n_targets;
+ GError *error = NULL;
+
+ /* FIXME We already have a 'shell' property. Move stuff
+ * that depends on it to a constructed() method. */
+ shell = e_shell_get_default ();
+ express_mode = e_shell_get_express_mode (shell);
+
+ editor->priv = priv = COMP_EDITOR_GET_PRIVATE (editor);
+
+ g_object_weak_ref (
+ G_OBJECT (editor), (GWeakNotify)
+ comp_editor_weak_notify_cb, NULL);
+
+ active_editors = g_list_prepend (active_editors, editor);
+
+ priv->calendar_settings = g_settings_new ("org.gnome.evolution.calendar");
+
+ /* Each editor window gets its own window group. */
+ window = GTK_WINDOW (editor);
+ priv->window_group = gtk_window_group_new ();
+ gtk_window_group_add_window (priv->window_group, window);
+
+ priv->pages = NULL;
+ priv->changed = FALSE;
+ priv->needs_send = FALSE;
+ priv->mod = CALOBJ_MOD_ALL;
+ priv->existing_org = FALSE;
+ priv->user_org = FALSE;
+ priv->warned = FALSE;
+ priv->is_group_item = FALSE;
+ priv->saved = FALSE;
+
+ priv->ui_manager = gtk_ui_manager_new ();
+
+ gtk_window_add_accel_group (
+ GTK_WINDOW (editor),
+ gtk_ui_manager_get_accel_group (priv->ui_manager));
+
+ /* Setup Action Groups */
+
+ action_group = gtk_action_group_new ("core");
+ gtk_action_group_set_translation_domain (
+ action_group, GETTEXT_PACKAGE);
+ gtk_action_group_add_actions (
+ action_group, core_entries,
+ G_N_ELEMENTS (core_entries), editor);
+ gtk_action_group_add_toggle_actions (
+ action_group, core_toggle_entries,
+ G_N_ELEMENTS (core_toggle_entries), editor);
+ gtk_ui_manager_insert_action_group (
+ priv->ui_manager, action_group, 0);
+ g_object_unref (action_group);
+
+ action = gtk_action_group_get_action (action_group, "save-and-close");
+ if (action) {
+ GtkAction *save_action;
+ GIcon *icon;
+ GIcon *emblemed_icon;
+ GEmblem *emblem;
+
+ icon = g_themed_icon_new (GTK_STOCK_CLOSE);
+ emblemed_icon = g_themed_icon_new (GTK_STOCK_SAVE);
+ emblem = g_emblem_new (emblemed_icon);
+ g_object_unref (emblemed_icon);
+
+ emblemed_icon = g_emblemed_icon_new (icon, emblem);
+ g_object_unref (emblem);
+ g_object_unref (icon);
+
+ gtk_action_set_gicon (action, emblemed_icon);
+
+ g_object_unref (emblemed_icon);
+
+ save_action = gtk_action_group_get_action (action_group, "save");
+ g_object_bind_property (
+ save_action, "sensitive",
+ action, "sensitive",
+ G_BINDING_SYNC_CREATE);
+ }
+
+ action_group = gtk_action_group_new ("individual");
+ gtk_action_group_set_translation_domain (
+ action_group, GETTEXT_PACKAGE);
+ gtk_action_group_add_actions (
+ action_group, individual_entries,
+ G_N_ELEMENTS (individual_entries), editor);
+ gtk_action_group_add_radio_actions (
+ action_group, classification_radio_entries,
+ G_N_ELEMENTS (classification_radio_entries),
+ E_CAL_COMPONENT_CLASS_PUBLIC,
+ G_CALLBACK (action_classification_cb), editor);
+ gtk_ui_manager_insert_action_group (
+ priv->ui_manager, action_group, 0);
+ g_object_unref (action_group);
+
+ action_group = gtk_action_group_new ("editable");
+ gtk_action_group_set_translation_domain (
+ action_group, GETTEXT_PACKAGE);
+ gtk_ui_manager_insert_action_group (
+ priv->ui_manager, action_group, 0);
+ g_object_unref (action_group);
+
+ action_group = gtk_action_group_new ("coordinated");
+ gtk_action_group_set_translation_domain (
+ action_group, GETTEXT_PACKAGE);
+ gtk_action_group_add_toggle_actions (
+ action_group, coordinated_toggle_entries,
+ G_N_ELEMENTS (coordinated_toggle_entries), editor);
+ gtk_ui_manager_insert_action_group (
+ priv->ui_manager, action_group, 0);
+ g_object_unref (action_group);
+
+ /* Configure an EFocusTracker to manage selection actions. */
+
+ focus_tracker = e_focus_tracker_new (GTK_WINDOW (editor));
+
+ action = comp_editor_get_action (editor, "cut-clipboard");
+ e_focus_tracker_set_cut_clipboard_action (focus_tracker, action);
+
+ action = comp_editor_get_action (editor, "copy-clipboard");
+ e_focus_tracker_set_copy_clipboard_action (focus_tracker, action);
+
+ action = comp_editor_get_action (editor, "paste-clipboard");
+ e_focus_tracker_set_paste_clipboard_action (focus_tracker, action);
+
+ action = comp_editor_get_action (editor, "delete-selection");
+ e_focus_tracker_set_delete_selection_action (focus_tracker, action);
+
+ action = comp_editor_get_action (editor, "select-all");
+ e_focus_tracker_set_select_all_action (focus_tracker, action);
+
+ priv->focus_tracker = focus_tracker;
+
+ /* Fine Tuning */
+
+ action = comp_editor_get_action (editor, "attach");
+ g_object_set (action, "short-label", _("Attach"), NULL);
+
+ /* Desensitize the "save" action. */
+ action = comp_editor_get_action (editor, "save");
+ gtk_action_set_sensitive (action, FALSE);
+
+ gtk_ui_manager_add_ui_from_string (priv->ui_manager, ui, -1, &error);
+ if (error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ /* Setup Widgets */
+
+ container = GTK_WIDGET (editor);
+
+ widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_container_add (GTK_CONTAINER (container), widget);
+ gtk_widget_show (widget);
+
+ container = widget;
+
+ widget = comp_editor_get_managed_widget (editor, "/main-menu");
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_set_visible (widget, TRUE);
+
+ widget = comp_editor_get_managed_widget (editor, "/main-toolbar");
+ gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0);
+ gtk_widget_show (widget);
+
+ gtk_style_context_add_class (
+ gtk_widget_get_style_context (widget),
+ GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
+
+ widget = e_attachment_paned_new ();
+ e_attachment_paned_set_resize_toplevel (
+ E_ATTACHMENT_PANED (widget), TRUE);
+ gtk_container_set_border_width (GTK_CONTAINER (widget), 6);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ priv->attachment_view = g_object_ref (widget);
+ gtk_widget_show (widget);
+
+ if (express_mode) {
+ widget = e_attachment_paned_get_view_combo (
+ E_ATTACHMENT_PANED (widget));
+ gtk_widget_hide (widget);
+ }
+
+ container = e_attachment_paned_get_content_area (
+ E_ATTACHMENT_PANED (priv->attachment_view));
+
+ widget = gtk_notebook_new ();
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), express_mode);
+ gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
+ priv->notebook = GTK_NOTEBOOK (widget);
+ gtk_widget_show (widget);
+
+ /* Drag-and-Drop Support */
+
+ view = E_ATTACHMENT_VIEW (priv->attachment_view);
+ target_list = e_attachment_view_get_target_list (view);
+ drag_actions = e_attachment_view_get_drag_actions (view);
+
+ targets = gtk_target_table_new_from_list (target_list, &n_targets);
+
+ gtk_drag_dest_set (
+ GTK_WIDGET (editor), GTK_DEST_DEFAULT_ALL,
+ targets, n_targets, drag_actions);
+
+ gtk_target_table_free (targets, n_targets);
+
+ gtk_window_set_type_hint (
+ GTK_WINDOW (editor), GDK_WINDOW_TYPE_HINT_NORMAL);
+
+ action_group = comp_editor_get_action_group (editor, "individual");
+ action_group_2 = e_attachment_view_get_action_group (view, "editable");
+
+ g_object_bind_property (
+ action_group, "sensitive",
+ action_group_2, "sensitive",
+ G_BINDING_SYNC_CREATE);
+
+ /* Listen for attachment store changes. */
+
+ store = e_attachment_view_get_store (view);
+
+ g_signal_connect_swapped (
+ store, "row-deleted",
+ G_CALLBACK (attachment_store_changed_cb), editor);
+
+ g_signal_connect_swapped (
+ store, "row-inserted",
+ G_CALLBACK (attachment_store_changed_cb), editor);
+
+ comp_editor_bind_settings (editor);
+
+ gtk_application_add_window (
+ GTK_APPLICATION (shell), GTK_WINDOW (editor));
}
static gboolean
-prompt_to_save_changes (CompEditor *editor, gboolean send)
+prompt_and_save_changes (CompEditor *editor,
+ gboolean send)
{
CompEditorPrivate *priv;
+ gboolean correct = FALSE;
+ ECalComponent *comp;
+ ECalComponentText text;
priv = editor->priv;
if (!priv->changed)
return TRUE;
- switch (save_component_dialog (GTK_WINDOW (editor))) {
- case 0: /* Save */
+ switch (save_component_dialog (GTK_WINDOW (editor), priv->comp)) {
+ case GTK_RESPONSE_YES: /* Save */
+ if (e_client_is_readonly (E_CLIENT (priv->cal_client))) {
+ e_alert_submit (
+ E_ALERT_SINK (editor),
+ "calendar:prompt-read-only-cal-editor",
+ e_source_get_display_name (
+ e_client_get_source (E_CLIENT (priv->cal_client))),
+ NULL);
+ /* don't discard changes when selected readonly calendar */
+ return FALSE;
+ }
+
+ if ((comp_editor_get_flags (editor) & COMP_EDITOR_IS_ASSIGNED) != 0
+ && e_cal_component_get_vtype (priv->comp) == E_CAL_COMPONENT_TODO
+ && e_client_check_capability (E_CLIENT (priv->cal_client), CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT)) {
+ e_alert_submit (
+ E_ALERT_SINK (editor),
+ "calendar:prompt-no-task-assignment-editor",
+ e_source_get_display_name (
+ e_client_get_source (E_CLIENT (priv->cal_client))),
+ NULL);
+ return FALSE;
+ }
+
+ comp = comp_editor_get_current_comp (editor, &correct);
+ e_cal_component_get_summary (comp, &text);
+ g_object_unref (comp);
+
+ if (!correct)
+ return FALSE;
+
+ if (!text.value)
+ if (!send_component_prompt_subject (
+ (GtkWindow *) editor, priv->cal_client, priv->comp))
+ return FALSE;
+
+ if (e_cal_component_is_instance (priv->comp))
+ if (!recur_component_dialog (
+ priv->cal_client, priv->comp, &priv->mod,
+ GTK_WINDOW (editor), FALSE))
+ return FALSE;
+
if (send && save_comp_with_send (editor))
return TRUE;
else if (!send && save_comp (editor))
return TRUE;
else
return FALSE;
- case 1: /* Discard */
+ case GTK_RESPONSE_NO: /* Discard */
return TRUE;
- case 2: /* Cancel */
+ case GTK_RESPONSE_CANCEL: /* Cancel */
default:
return FALSE;
}
}
-/* This sets the focus to the toplevel, so any field being edited is committed.
- FIXME: In future we may also want to check some of the fields are valid,
- e.g. the EDateEdit fields. */
+/* Menu callbacks */
+
static void
-commit_all_fields (CompEditor *editor)
+comp_editor_show_help (CompEditor *editor)
{
- CompEditorPrivate *priv;
+ CompEditorClass *class;
- priv = editor->priv;
+ class = COMP_EDITOR_GET_CLASS (editor);
+ g_return_if_fail (class->help_section != NULL);
- gtk_window_set_focus (GTK_WINDOW (editor), NULL);
+ e_display_help (GTK_WINDOW (editor), class->help_section);
}
/* Closes the dialog box and emits the appropriate signals */
static void
close_dialog (CompEditor *editor)
{
- CompEditorPrivate *priv;
+ CompEditorPrivate *priv = editor->priv;
- priv = editor->priv;
+ g_signal_emit_by_name (editor, "comp_closed", priv->saved);
+
+ /* FIXME Unfortunately we do this here because otherwise corba
+ * calls happen during destruction and we might get a change
+ * notification back when we are in an inconsistent state */
+ if (priv->view)
+ g_signal_handlers_disconnect_matched (
+ priv->view, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, editor);
- gtk_object_destroy (GTK_OBJECT (editor));
+ gtk_widget_destroy (GTK_WIDGET (editor));
}
-
+static gint
+comp_editor_compare (CompEditor *editor_a,
+ const gchar *uid_b)
+{
+ const gchar *uid_a = NULL;
+
+ e_cal_component_get_uid (editor_a->priv->comp, &uid_a);
+
+ return g_strcmp0 (uid_a, uid_b);
+}
void
-comp_editor_set_existing_org (CompEditor *editor, gboolean existing_org)
+comp_editor_set_existing_org (CompEditor *editor,
+ gboolean existing_org)
{
- CompEditorPrivate *priv;
-
- g_return_if_fail (editor != NULL);
g_return_if_fail (IS_COMP_EDITOR (editor));
- priv = editor->priv;
-
- priv->existing_org = existing_org;
+ editor->priv->existing_org = existing_org;
}
gboolean
comp_editor_get_existing_org (CompEditor *editor)
{
- CompEditorPrivate *priv;
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE);
+
+ return editor->priv->existing_org;
+}
+
+void
+comp_editor_set_user_org (CompEditor *editor,
+ gboolean user_org)
+{
+ g_return_if_fail (IS_COMP_EDITOR (editor));
- g_return_val_if_fail (editor != NULL, FALSE);
+ editor->priv->user_org = user_org;
+}
+
+gboolean
+comp_editor_get_user_org (CompEditor *editor)
+{
g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE);
- priv = editor->priv;
+ return editor->priv->user_org;
+}
- return priv->existing_org;
+void
+comp_editor_set_group_item (CompEditor *editor,
+ gboolean group_item)
+{
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+
+ editor->priv->is_group_item = group_item;
+}
+
+gboolean
+comp_editor_get_group_item (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE);
+
+ return editor->priv->is_group_item;
}
void
-comp_editor_set_user_org (CompEditor *editor, gboolean user_org)
+comp_editor_set_classification (CompEditor *editor,
+ ECalComponentClassification classification)
{
- CompEditorPrivate *priv;
+ GtkAction *action;
- g_return_if_fail (editor != NULL);
g_return_if_fail (IS_COMP_EDITOR (editor));
- priv = editor->priv;
+ switch (classification) {
+ case E_CAL_COMPONENT_CLASS_PUBLIC:
+ case E_CAL_COMPONENT_CLASS_PRIVATE:
+ case E_CAL_COMPONENT_CLASS_CONFIDENTIAL:
+ break;
+ default:
+ classification = E_CAL_COMPONENT_CLASS_PUBLIC;
+ break;
+ }
- priv->user_org = user_org;
+ action = comp_editor_get_action (editor, "classify-public");
+ gtk_radio_action_set_current_value (
+ GTK_RADIO_ACTION (action), classification);
}
-gboolean
-comp_editor_get_user_org (CompEditor *editor)
+ECalComponentClassification
+comp_editor_get_classification (CompEditor *editor)
{
- CompEditorPrivate *priv;
+ GtkAction *action;
+
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), 0);
+
+ action = comp_editor_get_action (editor, "classify-public");
+ return gtk_radio_action_get_current_value (GTK_RADIO_ACTION (action));
+}
+
+EShell *
+comp_editor_get_shell (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
+
+ return editor->priv->shell;
+}
+
+void
+comp_editor_set_summary (CompEditor *editor,
+ const gchar *summary)
+{
+ gboolean show_warning;
+
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+
+ if (g_strcmp0 (editor->priv->summary, summary) == 0)
+ return;
+
+ g_free (editor->priv->summary);
+ editor->priv->summary = g_strdup (summary);
+
+ show_warning =
+ !editor->priv->warned &&
+ !(editor->priv->flags & COMP_EDITOR_DELEGATE) &&
+ editor->priv->existing_org &&
+ !editor->priv->user_org && !(editor->priv->flags & COMP_EDITOR_NEW_ITEM);
+
+ if (show_warning) {
+ e_notice (
+ editor->priv->notebook, GTK_MESSAGE_INFO,
+ _("Changes made to this item may be "
+ "discarded if an update arrives"));
+ editor->priv->warned = TRUE;
+ }
+
+ update_window_border (editor, summary);
+
+ g_object_notify (G_OBJECT (editor), "summary");
+}
+
+const gchar *
+comp_editor_get_summary (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
+
+ return editor->priv->summary;
+}
+
+icaltimezone *
+comp_editor_get_timezone (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
+
+ return editor->priv->zone;
+}
+
+void
+comp_editor_set_timezone (CompEditor *editor,
+ icaltimezone *zone)
+{
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+
+ if (editor->priv->zone == zone)
+ return;
+
+ editor->priv->zone = zone;
- g_return_val_if_fail (editor != NULL, FALSE);
+ g_object_notify (G_OBJECT (editor), "timezone");
+}
+
+gboolean
+comp_editor_get_use_24_hour_format (CompEditor *editor)
+{
g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE);
- priv = editor->priv;
+ return editor->priv->use_24_hour_format;
+}
+
+void
+comp_editor_set_use_24_hour_format (CompEditor *editor,
+ gboolean use_24_hour_format)
+{
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+
+ if (editor->priv->use_24_hour_format == use_24_hour_format)
+ return;
+
+ editor->priv->use_24_hour_format = use_24_hour_format;
+
+ g_object_notify (G_OBJECT (editor), "use-24-hour-format");
+}
+
+GDateWeekday
+comp_editor_get_week_start_day (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), 0);
- return priv->user_org;
+ return editor->priv->week_start_day;
}
+void
+comp_editor_set_week_start_day (CompEditor *editor,
+ GDateWeekday week_start_day)
+{
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+ g_return_if_fail (g_date_valid_weekday (week_start_day));
+
+ if (week_start_day == editor->priv->week_start_day)
+ return;
+
+ editor->priv->week_start_day = week_start_day;
+
+ g_object_notify (G_OBJECT (editor), "week-start-day");
+}
+
+gint
+comp_editor_get_work_day_end_hour (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), 0);
+
+ return editor->priv->work_day_end_hour;
+}
+
+void
+comp_editor_set_work_day_end_hour (CompEditor *editor,
+ gint work_day_end_hour)
+{
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+
+ if (editor->priv->work_day_end_hour == work_day_end_hour)
+ return;
+
+ editor->priv->work_day_end_hour = work_day_end_hour;
+
+ g_object_notify (G_OBJECT (editor), "work-day-end-hour");
+}
+
+gint
+comp_editor_get_work_day_end_minute (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), 0);
+
+ return editor->priv->work_day_end_minute;
+}
+
+void
+comp_editor_set_work_day_end_minute (CompEditor *editor,
+ gint work_day_end_minute)
+{
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+
+ if (editor->priv->work_day_end_minute == work_day_end_minute)
+ return;
+
+ editor->priv->work_day_end_minute = work_day_end_minute;
+
+ g_object_notify (G_OBJECT (editor), "work-day-end-minute");
+}
+
+gint
+comp_editor_get_work_day_start_hour (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), 0);
+
+ return editor->priv->work_day_start_hour;
+}
+
+void
+comp_editor_set_work_day_start_hour (CompEditor *editor,
+ gint work_day_start_hour)
+{
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+
+ if (editor->priv->work_day_start_hour == work_day_start_hour)
+ return;
+
+ editor->priv->work_day_start_hour = work_day_start_hour;
+
+ g_object_notify (G_OBJECT (editor), "work-day-start-hour");
+}
+
+gint
+comp_editor_get_work_day_start_minute (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), 0);
+
+ return editor->priv->work_day_start_minute;
+}
+
+void
+comp_editor_set_work_day_start_minute (CompEditor *editor,
+ gint work_day_start_minute)
+{
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+
+ if (editor->priv->work_day_start_minute == work_day_start_minute)
+ return;
+
+ editor->priv->work_day_start_minute = work_day_start_minute;
+
+ g_object_notify (G_OBJECT (editor), "work-day-start-minute");
+}
/**
* comp_editor_set_changed:
@@ -518,13 +2729,41 @@ comp_editor_get_user_org (CompEditor *editor)
* Set the dialog changed state to the given value
**/
void
-comp_editor_set_changed (CompEditor *editor, gboolean changed)
+comp_editor_set_changed (CompEditor *editor,
+ gboolean changed)
{
- CompEditorPrivate *priv;
+ GtkAction *action;
+ gboolean show_warning;
- priv = editor->priv;
+ g_return_if_fail (IS_COMP_EDITOR (editor));
- priv->changed = changed;
+ /* always process below changes, because other parts of
+ * the editor listen for 'changed' notifications to update
+ * its widgets, thus do it even the value actually didn't change
+ */
+ if (editor->priv->changed != changed) {
+ editor->priv->changed = changed;
+
+ action = comp_editor_get_action (editor, "save");
+ g_return_if_fail (action != NULL);
+ gtk_action_set_sensitive (action, changed);
+ }
+
+ show_warning =
+ changed && !editor->priv->warned &&
+ !(editor->priv->flags & COMP_EDITOR_DELEGATE) &&
+ editor->priv->existing_org && !editor->priv->user_org
+ && !(editor->priv->flags & COMP_EDITOR_NEW_ITEM);
+
+ if (show_warning) {
+ e_notice (
+ editor->priv->notebook, GTK_MESSAGE_INFO,
+ _("Changes made to this item may be "
+ "discarded if an update arrives"));
+ editor->priv->warned = TRUE;
+ }
+
+ g_object_notify (G_OBJECT (editor), "changed");
}
/**
@@ -539,11 +2778,107 @@ comp_editor_set_changed (CompEditor *editor, gboolean changed)
gboolean
comp_editor_get_changed (CompEditor *editor)
{
- CompEditorPrivate *priv;
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE);
- priv = editor->priv;
+ return editor->priv->changed;
+}
+
+EFocusTracker *
+comp_editor_get_focus_tracker (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
+
+ return editor->priv->focus_tracker;
+}
+
+void
+comp_editor_set_flags (CompEditor *editor,
+ CompEditorFlags flags)
+{
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+
+ if (editor->priv->flags == flags)
+ return;
+
+ editor->priv->flags = flags;
+ editor->priv->user_org = flags & COMP_EDITOR_USER_ORG;
+
+ g_object_notify (G_OBJECT (editor), "flags");
+}
+
+CompEditorFlags
+comp_editor_get_flags (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), 0);
+
+ return editor->priv->flags;
+}
+
+GtkUIManager *
+comp_editor_get_ui_manager (CompEditor *editor)
+{
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
- return priv->changed;
+ return editor->priv->ui_manager;
+}
+
+GtkAction *
+comp_editor_get_action (CompEditor *editor,
+ const gchar *action_name)
+{
+ GtkUIManager *ui_manager;
+
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
+ g_return_val_if_fail (action_name != NULL, NULL);
+
+ ui_manager = comp_editor_get_ui_manager (editor);
+
+ return e_lookup_action (ui_manager, action_name);
+}
+
+GtkActionGroup *
+comp_editor_get_action_group (CompEditor *editor,
+ const gchar *group_name)
+{
+ GtkUIManager *ui_manager;
+
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
+ g_return_val_if_fail (group_name != NULL, NULL);
+
+ ui_manager = comp_editor_get_ui_manager (editor);
+
+ return e_lookup_action_group (ui_manager, group_name);
+}
+
+GtkWidget *
+comp_editor_get_managed_widget (CompEditor *editor,
+ const gchar *widget_path)
+{
+ GtkUIManager *ui_manager;
+ GtkWidget *widget;
+
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
+ g_return_val_if_fail (widget_path != NULL, NULL);
+
+ ui_manager = comp_editor_get_ui_manager (editor);
+ widget = gtk_ui_manager_get_widget (ui_manager, widget_path);
+ g_return_val_if_fail (widget != NULL, NULL);
+
+ return widget;
+}
+
+CompEditor *
+comp_editor_find_instance (const gchar *uid)
+{
+ GList *link;
+
+ g_return_val_if_fail (uid != NULL, NULL);
+
+ link = g_list_find_custom (
+ active_editors, uid,
+ (GCompareFunc) comp_editor_compare);
+
+ return (link != NULL) ? link->data : NULL;
}
/**
@@ -554,13 +2889,12 @@ comp_editor_get_changed (CompEditor *editor)
* Set the dialog needs send state to the given value
**/
void
-comp_editor_set_needs_send (CompEditor *editor, gboolean needs_send)
+comp_editor_set_needs_send (CompEditor *editor,
+ gboolean needs_send)
{
- CompEditorPrivate *priv;
-
- priv = editor->priv;
+ g_return_if_fail (IS_COMP_EDITOR (editor));
- priv->needs_send = needs_send;
+ editor->priv->needs_send = needs_send;
}
/**
@@ -575,15 +2909,14 @@ comp_editor_set_needs_send (CompEditor *editor, gboolean needs_send)
gboolean
comp_editor_get_needs_send (CompEditor *editor)
{
- CompEditorPrivate *priv;
-
- priv = editor->priv;
+ g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE);
- return priv->needs_send;
+ return editor->priv->needs_send;
}
-static void page_mapped_cb (GtkWidget *page_widget,
- CompEditorPage *page)
+static void
+page_mapped_cb (GtkWidget *page_widget,
+ CompEditorPage *page)
{
GtkWidget *toplevel;
@@ -592,13 +2925,15 @@ static void page_mapped_cb (GtkWidget *page_widget,
return;
if (page->accel_group) {
- gtk_window_add_accel_group (GTK_WINDOW (toplevel),
- page->accel_group);
+ gtk_window_add_accel_group (
+ GTK_WINDOW (toplevel),
+ page->accel_group);
}
}
-static void page_unmapped_cb (GtkWidget *page_widget,
- CompEditorPage *page)
+static void
+page_unmapped_cb (GtkWidget *page_widget,
+ CompEditorPage *page)
{
GtkWidget *toplevel;
@@ -607,72 +2942,127 @@ static void page_unmapped_cb (GtkWidget *page_widget,
return;
if (page->accel_group) {
- gtk_window_remove_accel_group (GTK_WINDOW (toplevel),
- page->accel_group);
+ gtk_window_remove_accel_group (GTK_WINDOW (toplevel), page->accel_group);
+ }
+}
+
+/**
+ * comp_editor_append_widget:
+ * @editor: A component editor
+ * @page: A component editor page
+ * @label: Label of the page. Should be NULL if add is FALSE.
+ * @add: Add's the page into the notebook if TRUE
+ *
+ * Appends a page to the notebook if add is TRUE else
+ * just adds it to the list of pages.
+ **/
+void
+comp_editor_append_widget (CompEditor *editor,
+ GtkWidget *page,
+ const gchar *label,
+ gboolean add)
+{
+ CompEditorPrivate *priv;
+ GtkWidget *label_widget = NULL;
+
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+
+ priv = editor->priv;
+
+ g_object_ref (page);
+
+ if (label)
+ label_widget = gtk_label_new_with_mnemonic (label);
+
+ priv->pages = g_list_append (priv->pages, page);
+
+ if (add) {
+ gtk_notebook_append_page (priv->notebook, page, label_widget);
+ gtk_container_child_set (
+ GTK_CONTAINER (priv->notebook), page,
+ "tab-fill", FALSE, "tab-expand", FALSE, NULL);
}
+
+ /* Listen for when the page is mapped/unmapped so we can
+ * install/uninstall the appropriate GtkAccelGroup.
+ g_signal_connect (
+ page, "map",
+ G_CALLBACK (page_mapped_cb), page);
+ g_signal_connect (
+ page, "unmap",
+ G_CALLBACK (page_unmapped_cb), page);
+ */
+
}
/**
* comp_editor_append_page:
* @editor: A component editor
* @page: A component editor page
- * @label: Label of the page
+ * @label: Label of the page. Should be NULL if add is FALSE.
+ * @add: Add's the page into the notebook if TRUE
*
- * Appends a page to the editor notebook with the given label
+ * Appends a page to the notebook if add is TRUE else
+ * just adds it to the list of pages.
**/
void
comp_editor_append_page (CompEditor *editor,
- CompEditorPage *page,
- const char *label)
+ CompEditorPage *page,
+ const gchar *label,
+ gboolean add)
{
CompEditorPrivate *priv;
GtkWidget *page_widget;
- GtkWidget *label_widget;
+ GtkWidget *label_widget = NULL;
gboolean is_first_page;
- g_return_if_fail (editor != NULL);
g_return_if_fail (IS_COMP_EDITOR (editor));
- g_return_if_fail (page != NULL);
g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
- g_return_if_fail (label != NULL);
priv = editor->priv;
- gtk_object_ref (GTK_OBJECT (page));
+ g_object_ref (page);
/* If we are editing something, fill the widgets with current info */
if (priv->comp != NULL) {
- CalComponent *comp;
+ ECalComponent *comp;
- comp = comp_editor_get_current_comp (editor);
+ comp = comp_editor_get_current_comp (editor, NULL);
comp_editor_page_fill_widgets (page, comp);
- gtk_object_unref (GTK_OBJECT (comp));
+ g_object_unref (comp);
}
page_widget = comp_editor_page_get_widget (page);
- g_assert (page_widget != NULL);
+ g_return_if_fail (page_widget != NULL);
- label_widget = gtk_label_new (label);
+ if (label)
+ label_widget = gtk_label_new_with_mnemonic (label);
is_first_page = (priv->pages == NULL);
priv->pages = g_list_append (priv->pages, page);
- gtk_notebook_append_page (priv->notebook, page_widget, label_widget);
+
+ if (add) {
+ gtk_notebook_append_page (
+ priv->notebook, page_widget, label_widget);
+ gtk_container_child_set (
+ GTK_CONTAINER (priv->notebook), page_widget,
+ "tab-fill", FALSE, "tab-expand", FALSE, NULL);
+ }
/* Listen for things happening on the page */
- gtk_signal_connect (GTK_OBJECT (page), "changed",
- GTK_SIGNAL_FUNC (page_changed_cb), editor);
- gtk_signal_connect (GTK_OBJECT (page), "summary_changed",
- GTK_SIGNAL_FUNC (page_summary_changed_cb), editor);
- gtk_signal_connect (GTK_OBJECT (page), "dates_changed",
- GTK_SIGNAL_FUNC (page_dates_changed_cb), editor);
+ g_signal_connect_swapped (
+ page, "dates_changed",
+ G_CALLBACK (page_dates_changed_cb), editor);
/* Listen for when the page is mapped/unmapped so we can
- install/uninstall the appropriate GtkAccelGroup. */
- gtk_signal_connect (GTK_OBJECT (page_widget), "map",
- GTK_SIGNAL_FUNC (page_mapped_cb), page);
- gtk_signal_connect (GTK_OBJECT (page_widget), "unmap",
- GTK_SIGNAL_FUNC (page_unmapped_cb), page);
+ * install/uninstall the appropriate GtkAccelGroup. */
+ g_signal_connect (
+ page_widget, "map",
+ G_CALLBACK (page_mapped_cb), page);
+ g_signal_connect (
+ page_widget, "unmap",
+ G_CALLBACK (page_unmapped_cb), page);
/* The first page is the main page of the editor, so we ask it to focus
* its main widget.
@@ -689,15 +3079,14 @@ comp_editor_append_page (CompEditor *editor,
* Removes the page from the component editor
**/
void
-comp_editor_remove_page (CompEditor *editor, CompEditorPage *page)
+comp_editor_remove_page (CompEditor *editor,
+ CompEditorPage *page)
{
CompEditorPrivate *priv;
GtkWidget *page_widget;
gint page_num;
- g_return_if_fail (editor != NULL);
g_return_if_fail (IS_COMP_EDITOR (editor));
- g_return_if_fail (page != NULL);
g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
priv = editor->priv;
@@ -706,15 +3095,17 @@ comp_editor_remove_page (CompEditor *editor, CompEditorPage *page)
page_num = gtk_notebook_page_num (priv->notebook, page_widget);
if (page_num == -1)
return;
-
+
/* Disconnect all the signals added in append_page(). */
- gtk_signal_disconnect_by_data (GTK_OBJECT (page), editor);
- gtk_signal_disconnect_by_data (GTK_OBJECT (page_widget), page);
+ g_signal_handlers_disconnect_matched (
+ page, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor);
+ g_signal_handlers_disconnect_matched (
+ page_widget, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, page);
gtk_notebook_remove_page (priv->notebook, page_num);
priv->pages = g_list_remove (priv->pages, page);
- gtk_object_unref (GTK_OBJECT (page));
+ g_object_unref (page);
}
/**
@@ -725,259 +3116,412 @@ comp_editor_remove_page (CompEditor *editor, CompEditorPage *page)
*
**/
void
-comp_editor_show_page (CompEditor *editor, CompEditorPage *page)
+comp_editor_show_page (CompEditor *editor,
+ CompEditorPage *page)
{
CompEditorPrivate *priv;
GtkWidget *page_widget;
gint page_num;
- g_return_if_fail (editor != NULL);
g_return_if_fail (IS_COMP_EDITOR (editor));
- g_return_if_fail (page != NULL);
g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
priv = editor->priv;
page_widget = comp_editor_page_get_widget (page);
page_num = gtk_notebook_page_num (priv->notebook, page_widget);
- gtk_notebook_set_page (priv->notebook, page_num);
+ gtk_notebook_set_current_page (priv->notebook, page_num);
}
/**
- * comp_editor_set_cal_client:
+ * comp_editor_set_client:
* @editor: A component editor
- * @client: The calendar client to use
+ * @cal_client: The calendar client to use
*
* Sets the calendar client used by the editor to update components
**/
void
-comp_editor_set_cal_client (CompEditor *editor, CalClient *client)
+comp_editor_set_client (CompEditor *editor,
+ ECalClient *cal_client)
{
- CompEditorClass *klass;
-
- g_return_if_fail (editor != NULL);
g_return_if_fail (IS_COMP_EDITOR (editor));
+ g_return_if_fail (cal_client == NULL || E_IS_CAL_CLIENT (cal_client));
+
+ if (editor->priv->cal_client == cal_client)
+ return;
+
+ if (cal_client != NULL)
+ g_object_ref (cal_client);
- klass = COMP_EDITOR_CLASS (GTK_OBJECT (editor)->klass);
+ if (editor->priv->cal_client != NULL)
+ g_object_unref (editor->priv->cal_client);
- if (klass->set_cal_client)
- klass->set_cal_client (editor, client);
+ editor->priv->cal_client = cal_client;
+
+ if (editor->priv->source_client == NULL && cal_client != NULL)
+ editor->priv->source_client = g_object_ref (cal_client);
+
+ g_object_notify (G_OBJECT (editor), "client");
}
/**
- * comp_editor_get_cal_client:
+ * comp_editor_get_client:
* @editor: A component editor
*
* Returns the calendar client of the editor
*
* Return value: The calendar client of the editor
**/
-CalClient *
-comp_editor_get_cal_client (CompEditor *editor)
+ECalClient *
+comp_editor_get_client (CompEditor *editor)
{
- CompEditorPrivate *priv;
-
- g_return_val_if_fail (editor != NULL, NULL);
g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
- priv = editor->priv;
-
- return priv->client;
+ return editor->priv->cal_client;
}
-/* Creates an appropriate title for the event editor dialog */
-static char *
-make_title_from_comp (CalComponent *comp)
+static void
+attachment_loaded_cb (EAttachment *attachment,
+ GAsyncResult *result,
+ GtkWindow *parent)
{
- char *title;
- const char *type_string;
- CalComponentVType type;
- CalComponentText text;
-
- if (!comp)
- return g_strdup (_("Edit Appointment"));
+ GFileInfo *file_info;
+ const gchar *display_name;
+ const gchar *uid;
+ gchar *new_name;
+
+ /* Prior to 2.27.2, attachment files were named:
+ *
+ * <component-uid> '-' <actual-filename>
+ * -------------------------------------
+ * (one long filename)
+ *
+ * Here we fix the display name if this form is detected so we
+ * don't show the component UID in the user interface. If the
+ * user saves changes in the editor, the attachment will be
+ * written to disk as:
+ *
+ * <component-uid> / <actual-filename>
+ * --------------- -----------------
+ * (directory) (original name)
+ *
+ * So this is a lazy migration from the old form to the new.
+ */
- type = cal_component_get_vtype (comp);
- switch (type) {
- case CAL_COMPONENT_EVENT:
- type_string = _("Appointment - %s");
- break;
- case CAL_COMPONENT_TODO:
- type_string = _("Task - %s");
- break;
- case CAL_COMPONENT_JOURNAL:
- type_string = _("Journal entry - %s");
- break;
- default:
- g_message ("make_title_from_comp(): Cannot handle object of type %d", type);
- return NULL;
+ file_info = e_attachment_ref_file_info (attachment);
+ if (file_info == NULL) {
+ /* failed to load an attachment file */
+ e_attachment_load_handle_error (attachment, result, parent);
+ return;
}
- cal_component_get_summary (comp, &text);
- if (text.value) {
- char *summary;
- summary = e_utf8_to_locale_string (text.value);
- title = g_strdup_printf (type_string, summary);
- g_free (summary);
- } else
- title = g_strdup_printf (type_string, _("No summary"));
-
- return title;
-}
+ display_name = g_file_info_get_display_name (file_info);
+ uid = g_object_get_data (G_OBJECT (attachment), "uid");
-static const char *
-make_icon_from_comp (CalComponent *comp)
-{
- CalComponentVType type;
-
- if (!comp)
- return EVOLUTION_ICONSDIR "/evolution-calendar-mini.png";
-
- type = cal_component_get_vtype (comp);
- switch (type) {
- case CAL_COMPONENT_EVENT:
- return EVOLUTION_ICONSDIR "/buttons/new_appointment.png";
- break;
- case CAL_COMPONENT_TODO:
- return EVOLUTION_ICONSDIR "/buttons/new_task.png";
- break;
- default:
- return EVOLUTION_ICONSDIR "/evolution-calendar-mini.png";
+ if (g_str_has_prefix (display_name, uid)) {
+ new_name = g_strdup (display_name + strlen (uid) + 1);
+ g_file_info_set_display_name (file_info, new_name);
+ g_object_notify (G_OBJECT (attachment), "file-info");
+ g_free (new_name);
}
-}
-/* Sets the event editor's window title from a calendar component */
-static void
-set_title_from_comp (CompEditor *editor)
-{
- CompEditorPrivate *priv;
- char *title;
+ g_object_unref (file_info);
- priv = editor->priv;
- title = make_title_from_comp (priv->comp);
- gtk_window_set_title (GTK_WINDOW (editor), title);
- g_free (title);
+ e_attachment_load_handle_error (attachment, result, parent);
}
static void
-set_icon_from_comp (CompEditor *editor)
+set_attachment_list (CompEditor *editor,
+ GSList *uri_list)
{
- CompEditorPrivate *priv;
- const char *file;
+ EAttachmentStore *store;
+ EAttachmentView *view;
+ const gchar *uid = NULL;
+ GSList *iter;
+
+ view = E_ATTACHMENT_VIEW (editor->priv->attachment_view);
+ store = e_attachment_view_get_store (view);
+
+ if (e_attachment_store_get_num_attachments (store) > 0) {
+ /* To prevent repopulating the
+ * bar due to redraw functions in fill_widget.
+ * Assumes it can be set only once.
+ */
+ return;
+ }
- priv = editor->priv;
- file = make_icon_from_comp (priv->comp);
- gnome_window_icon_set_from_file (GTK_WINDOW (editor), file);
+ /* XXX What an awkward API this is. Takes a return location
+ * for a constant string instead of just returning it. */
+ e_cal_component_get_uid (editor->priv->comp, &uid);
+
+ for (iter = uri_list; iter != NULL; iter = iter->next) {
+ EAttachment *attachment;
+
+ attachment = e_attachment_new_for_uri (iter->data);
+ e_attachment_store_add_attachment (store, attachment);
+ g_object_set_data_full (
+ G_OBJECT (attachment),
+ "uid", g_strdup (uid),
+ (GDestroyNotify) g_free);
+ e_attachment_load_async (
+ attachment, (GAsyncReadyCallback)
+ attachment_loaded_cb, editor);
+ g_object_unref (attachment);
+ }
}
static void
fill_widgets (CompEditor *editor)
{
+ EAttachmentStore *store;
+ EAttachmentView *view;
CompEditorPrivate *priv;
- GList *l;
+ GtkAction *action;
+ GList *iter;
+
+ view = E_ATTACHMENT_VIEW (editor->priv->attachment_view);
+ store = e_attachment_view_get_store (view);
priv = editor->priv;
- for (l = priv->pages; l != NULL; l = l->next)
- comp_editor_page_fill_widgets (l->data, priv->comp);
+ /*Check if attachments are available here and set them*/
+ if (e_cal_component_has_attachments (priv->comp)) {
+ GSList *attachment_list = NULL;
+ e_cal_component_get_attachment_list (priv->comp, &attachment_list);
+ g_signal_handlers_block_by_func (
+ store, G_CALLBACK (attachment_store_changed_cb),
+ editor);
+ set_attachment_list (editor, attachment_list);
+ g_signal_handlers_unblock_by_func (
+ store, G_CALLBACK (attachment_store_changed_cb),
+ editor);
+ g_slist_foreach (attachment_list, (GFunc) g_free, NULL);
+ g_slist_free (attachment_list);
+ }
+
+ action = comp_editor_get_action (editor, "classify-public");
+ g_signal_handlers_block_by_func (
+ action, G_CALLBACK (action_classification_cb), editor);
+
+ for (iter = priv->pages; iter != NULL; iter = iter->next) {
+ if (IS_COMP_EDITOR_PAGE (iter->data))
+ comp_editor_page_fill_widgets (iter->data, priv->comp);
+ }
+
+ g_signal_handlers_unblock_by_func (
+ action, G_CALLBACK (action_classification_cb), editor);
}
static void
-real_set_cal_client (CompEditor *editor, CalClient *client)
+real_edit_comp (CompEditor *editor,
+ ECalComponent *comp)
{
CompEditorPrivate *priv;
- GList *elem;
- g_return_if_fail (editor != NULL);
g_return_if_fail (IS_COMP_EDITOR (editor));
priv = editor->priv;
- if (client == priv->client)
- return;
-
- if (client) {
- g_return_if_fail (IS_CAL_CLIENT (client));
- g_return_if_fail (cal_client_get_load_state (client) ==
- CAL_CLIENT_LOAD_LOADED);
- gtk_object_ref (GTK_OBJECT (client));
+ if (priv->comp) {
+ g_object_unref (priv->comp);
+ priv->comp = NULL;
}
- if (priv->client) {
- gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client),
- editor);
- gtk_object_unref (GTK_OBJECT (priv->client));
+ if (comp) {
+ priv->comp = e_cal_component_clone (comp);
+ comp_editor_copy_new_attendees (priv->comp, comp);
}
- priv->client = client;
+ priv->existing_org = e_cal_component_has_organizer (comp);
+ priv->warned = FALSE;
+
+ update_window_border (editor, NULL);
- /* Pass the client to any pages that need it. */
- for (elem = priv->pages; elem; elem = elem->next)
- comp_editor_page_set_cal_client (elem->data, client);
+ fill_widgets (editor);
- gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated",
- GTK_SIGNAL_FUNC (obj_updated_cb), editor);
+ comp_editor_set_changed (editor, FALSE);
- gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed",
- GTK_SIGNAL_FUNC (obj_removed_cb), editor);
+ listen_for_changes (editor);
}
+/* TODO These functions should be available in e-cal-component.c */
static void
-real_edit_comp (CompEditor *editor, CalComponent *comp)
+set_attendees_for_delegation (ECalComponent *comp,
+ const gchar *address,
+ ECalComponentItipMethod method)
{
- CompEditorPrivate *priv;
-
- g_return_if_fail (editor != NULL);
- g_return_if_fail (IS_COMP_EDITOR (editor));
+ icalproperty *prop;
+ icalparameter *param;
+ icalcomponent *icalcomp;
+
+ icalcomp = e_cal_component_get_icalcomponent (comp);
+
+ for (prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
+ prop;
+ prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY)) {
+ const gchar *attendee = icalproperty_get_attendee (prop);
+ const gchar *delfrom = NULL;
+
+ param = icalproperty_get_first_parameter (prop, ICAL_DELEGATEDFROM_PARAMETER);
+ if (param)
+ delfrom = icalparameter_get_delegatedfrom (param);
+ if (!(g_str_equal (itip_strip_mailto (attendee), address) ||
+ ((delfrom && *delfrom) &&
+ g_str_equal (itip_strip_mailto (delfrom), address)))) {
+ icalcomponent_remove_property (icalcomp, prop);
+ }
- priv = editor->priv;
+ }
- if (priv->comp) {
- gtk_object_unref (GTK_OBJECT (priv->comp));
- priv->comp = NULL;
+}
+
+static void
+get_users_from_memo_comp (ECalComponent *comp,
+ GSList **users)
+{
+ icalcomponent *icalcomp;
+ icalproperty *icalprop;
+ const gchar *attendees = NULL;
+ gchar **emails, **iter;
+
+ icalcomp = e_cal_component_get_icalcomponent (comp);
+
+ for (icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
+ icalprop != NULL;
+ icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY)) {
+ const gchar *x_name;
+
+ x_name = icalproperty_get_x_name (icalprop);
+
+ if (g_str_equal (x_name, "X-EVOLUTION-RECIPIENTS"))
+ break;
}
- if (comp)
- priv->comp = cal_component_clone (comp);
+ if (icalprop) {
+ attendees = icalproperty_get_x (icalprop);
+ emails = g_strsplit (attendees, ";", -1);
- priv->existing_org = cal_component_has_organizer (comp);
- priv->user_org = itip_organizer_is_user (comp);
- priv->warned = FALSE;
-
- set_title_from_comp (editor);
- set_icon_from_comp (editor);
- fill_widgets (editor);
+ iter = emails;
+ while (*iter) {
+ *users = g_slist_append (*users, g_strdup (*iter));
+ iter++;
+ }
+ g_strfreev (emails);
+ }
}
-
static gboolean
-real_send_comp (CompEditor *editor, CalComponentItipMethod method)
+real_send_comp (CompEditor *editor,
+ ECalComponentItipMethod method,
+ gboolean strip_alarms)
{
CompEditorPrivate *priv;
- CalComponent *tmp_comp;
-
- g_return_val_if_fail (editor != NULL, FALSE);
+ CompEditorFlags flags;
+ EShell *shell;
+ ESourceRegistry *registry;
+ ECalComponent *send_comp = NULL;
+ gchar *address = NULL;
+ GSList *users = NULL;
+
g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE);
priv = editor->priv;
- if (itip_send_comp (method, priv->comp, priv->client, NULL)) {
- tmp_comp = priv->comp;
- gtk_object_ref (GTK_OBJECT (tmp_comp));
- comp_editor_edit_comp (editor, tmp_comp);
- gtk_object_unref (GTK_OBJECT (tmp_comp));
-
- comp_editor_set_changed (editor, TRUE);
- save_comp (editor);
+ flags = comp_editor_get_flags (editor);
+ shell = comp_editor_get_shell (editor);
- return TRUE;
+ registry = e_shell_get_registry (shell);
+
+ if (priv->mod == CALOBJ_MOD_ALL && e_cal_component_is_instance (priv->comp)) {
+ /* Ensure we send the master object, not the instance only */
+ icalcomponent *icalcomp = NULL;
+ const gchar *uid = NULL;
+
+ e_cal_component_get_uid (priv->comp, &uid);
+ if (e_cal_client_get_object_sync (priv->cal_client, uid, NULL, &icalcomp, NULL, NULL) && icalcomp) {
+ send_comp = e_cal_component_new ();
+ if (!e_cal_component_set_icalcomponent (send_comp, icalcomp)) {
+ icalcomponent_free (icalcomp);
+ g_object_unref (send_comp);
+ send_comp = NULL;
+ }
+ }
+ }
+
+ if (!send_comp)
+ send_comp = e_cal_component_clone (priv->comp);
+
+ comp_editor_copy_new_attendees (send_comp, priv->comp);
+
+ if (e_cal_component_get_vtype (send_comp) == E_CAL_COMPONENT_JOURNAL)
+ get_users_from_memo_comp (send_comp, &users);
+
+ /* The user updates the delegated status to the Organizer,
+ * so remove all other attendees. */
+ if (flags & COMP_EDITOR_DELEGATE) {
+ address = itip_get_comp_attendee (
+ registry, send_comp, priv->cal_client);
+
+ if (address)
+ set_attendees_for_delegation (send_comp, address, method);
+ }
+
+ if (!e_cal_component_has_attachments (priv->comp) ||
+ e_client_check_capability (
+ E_CLIENT (priv->cal_client),
+ CAL_STATIC_CAPABILITY_CREATE_MESSAGES)) {
+ if (itip_send_comp (
+ registry, method, send_comp, priv->cal_client,
+ NULL, NULL, users, strip_alarms,
+ priv->flags & COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY)) {
+ g_object_unref (send_comp);
+ return TRUE;
+ }
+ } else {
+ /* Clone the component with attachments set to CID:... */
+ GSList *attach_list = NULL;
+ GSList *mime_attach_list, *attach;
+
+ /* mime_attach_list is freed by itip_send_comp */
+ mime_attach_list = comp_editor_get_mime_attach_list (editor);
+
+ for (attach = mime_attach_list; attach; attach = attach->next) {
+ struct CalMimeAttach *cma = (struct CalMimeAttach *) attach->data;
+
+ attach_list = g_slist_append (
+ attach_list, g_strconcat (
+ "cid:", cma->content_id, NULL));
+ }
+
+ if (attach_list) {
+ e_cal_component_set_attachment_list (send_comp, attach_list);
+
+ g_slist_foreach (attach_list, (GFunc) g_free, NULL);
+ g_slist_free (attach_list);
+ }
+
+ if (itip_send_comp (
+ registry, method, send_comp, priv->cal_client,
+ NULL, mime_attach_list, users, strip_alarms,
+ priv->flags & COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY)) {
+ gboolean saved = save_comp (editor);
+
+ g_object_unref (send_comp);
+
+ if (!saved)
+ comp_editor_set_changed (editor, TRUE);
+
+ return saved;
+ }
}
+ g_object_unref (send_comp);
+ g_free (address);
comp_editor_set_changed (editor, TRUE);
return FALSE;
-}
+}
/**
* comp_editor_edit_comp:
@@ -987,52 +3531,61 @@ real_send_comp (CompEditor *editor, CalComponentItipMethod method)
* Starts the editor editing the given component
**/
void
-comp_editor_edit_comp (CompEditor *editor, CalComponent *comp)
+comp_editor_edit_comp (CompEditor *editor,
+ ECalComponent *comp)
{
- CompEditorClass *klass;
+ CompEditorClass *class;
- g_return_if_fail (editor != NULL);
g_return_if_fail (IS_COMP_EDITOR (editor));
- g_return_if_fail (comp != NULL);
- g_return_if_fail (IS_CAL_COMPONENT (comp));
+ g_return_if_fail (E_IS_CAL_COMPONENT (comp));
- klass = COMP_EDITOR_CLASS (GTK_OBJECT (editor)->klass);
+ class = COMP_EDITOR_GET_CLASS (editor);
- if (klass->edit_comp)
- klass->edit_comp (editor, comp);
+ if (class->edit_comp)
+ class->edit_comp (editor, comp);
}
-CalComponent *
+ECalComponent *
comp_editor_get_comp (CompEditor *editor)
{
- CompEditorPrivate *priv;
-
- g_return_val_if_fail (editor != NULL, NULL);
g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
- priv = editor->priv;
-
- return priv->comp;
+ return editor->priv->comp;
}
-CalComponent *
-comp_editor_get_current_comp (CompEditor *editor)
+/**
+ * comp_editor_get_current_comp
+ * @editor: a #CompEditor
+ * @correct: Set this no non-%NULL if you are interested to know if all
+ * pages reported success when filling component.
+ *
+ * Returns: Newly allocated component, should be unref-ed by g_object_unref().
+ **/
+ECalComponent *
+comp_editor_get_current_comp (CompEditor *editor,
+ gboolean *correct)
{
CompEditorPrivate *priv;
- CalComponent *comp;
+ ECalComponent *comp;
GList *l;
+ gboolean all_ok = TRUE;
- g_return_val_if_fail (editor != NULL, NULL);
g_return_val_if_fail (IS_COMP_EDITOR (editor), NULL);
priv = editor->priv;
- comp = cal_component_clone (priv->comp);
+ comp = e_cal_component_clone (priv->comp);
+ comp_editor_copy_new_attendees (comp, priv->comp);
if (priv->changed) {
- for (l = priv->pages; l != NULL; l = l->next)
- comp_editor_page_fill_component (l->data, comp);
+ for (l = priv->pages; l != NULL; l = l->next) {
+ if (IS_COMP_EDITOR_PAGE (l->data))
+ all_ok = comp_editor_page_fill_component (l->data, comp) && all_ok;
+ }
}
+ if (correct)
+ *correct = all_ok;
+
return comp;
}
@@ -1043,9 +3596,10 @@ comp_editor_get_current_comp (CompEditor *editor)
*
**/
gboolean
-comp_editor_save_comp (CompEditor *editor, gboolean send)
+comp_editor_save_comp (CompEditor *editor,
+ gboolean send)
{
- return prompt_to_save_changes (editor, send);
+ return prompt_and_save_changes (editor, send);
}
/**
@@ -1057,7 +3611,24 @@ comp_editor_save_comp (CompEditor *editor, gboolean send)
void
comp_editor_delete_comp (CompEditor *editor)
{
- delete_comp (editor);
+ CompEditorPrivate *priv;
+ const gchar *uid;
+
+ g_return_if_fail (IS_COMP_EDITOR (editor));
+
+ priv = editor->priv;
+
+ e_cal_component_get_uid (priv->comp, &uid);
+ if (e_cal_component_is_instance (priv->comp) ||
+ e_cal_component_has_recurrences (priv->comp))
+ e_cal_client_remove_object_sync (
+ priv->cal_client, uid, NULL,
+ CALOBJ_MOD_ALL, NULL, NULL);
+ else
+ e_cal_client_remove_object_sync (
+ priv->cal_client, uid, NULL,
+ CALOBJ_MOD_THIS, NULL, NULL);
+ close_dialog (editor);
}
/**
@@ -1068,17 +3639,18 @@ comp_editor_delete_comp (CompEditor *editor)
*
**/
gboolean
-comp_editor_send_comp (CompEditor *editor, CalComponentItipMethod method)
+comp_editor_send_comp (CompEditor *editor,
+ ECalComponentItipMethod method,
+ gboolean strip_alarms)
{
- CompEditorClass *klass;
+ CompEditorClass *class;
- g_return_val_if_fail (editor != NULL, FALSE);
g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE);
- klass = COMP_EDITOR_CLASS (GTK_OBJECT (editor)->klass);
+ class = COMP_EDITOR_GET_CLASS (editor);
- if (klass->send_comp)
- return klass->send_comp (editor, method);
+ if (class->send_comp)
+ return class->send_comp (editor, method, strip_alarms);
return FALSE;
}
@@ -1087,344 +3659,167 @@ gboolean
comp_editor_close (CompEditor *editor)
{
gboolean close;
-
- g_return_val_if_fail (editor != NULL, FALSE);
+
g_return_val_if_fail (IS_COMP_EDITOR (editor), FALSE);
commit_all_fields (editor);
-
- close = prompt_to_save_changes (editor, TRUE);
+
+ close = prompt_and_save_changes (editor, TRUE);
if (close)
close_dialog (editor);
return close;
}
-/**
- * comp_editor_merge_ui:
- * @editor:
- * @filename:
- * @verbs:
- *
- *
- **/
-void
-comp_editor_merge_ui (CompEditor *editor,
- const char *filename,
- BonoboUIVerb *verbs,
- EPixmap *component_pixmaps)
-{
- CompEditorPrivate *priv;
-
- g_return_if_fail (editor != NULL);
- g_return_if_fail (IS_COMP_EDITOR (editor));
-
- priv = editor->priv;
-
- bonobo_ui_util_set_ui (priv->uic, EVOLUTION_DATADIR, filename, "evolution-calendar");
- bonobo_ui_component_add_verb_list_with_data (priv->uic, verbs, editor);
-
- if (component_pixmaps != NULL)
- e_pixmaps_update (priv->uic, component_pixmaps);
-}
-
-/**
- * comp_editor_set_ui_prop:
- * @editor:
- * @path:
- * @attr:
- * @val:
- *
- *
- **/
-void
-comp_editor_set_ui_prop (CompEditor *editor,
- const char *path,
- const char *attr,
- const char *val)
-{
- CompEditorPrivate *priv;
-
- g_return_if_fail (editor != NULL);
- g_return_if_fail (IS_COMP_EDITOR (editor));
-
- priv = editor->priv;
-
- bonobo_ui_component_set_prop (priv->uic, path, attr, val, NULL);
-}
-
-
-/* Brings attention to a window by raising it and giving it focus */
-static void
-raise_and_focus (GtkWidget *widget)
-{
- g_assert (GTK_WIDGET_REALIZED (widget));
- gdk_window_show (widget->window);
- gtk_widget_grab_focus (widget);
-}
-
-/**
- * comp_editor_focus:
- * @editor: A component editor
- *
- * Brings the editor window to the front and gives it focus
- **/
-void
-comp_editor_focus (CompEditor *editor)
-{
- CompEditorPrivate *priv;
-
- g_return_if_fail (editor != NULL);
- g_return_if_fail (IS_COMP_EDITOR (editor));
-
- priv = editor->priv;
-
- gtk_widget_show (GTK_WIDGET (editor));
- raise_and_focus (GTK_WIDGET (editor));
-}
-
-/* Menu Commands */
-static void
-save_cmd (GtkWidget *widget, gpointer data)
-{
- CompEditor *editor = COMP_EDITOR (data);
-
- commit_all_fields (editor);
-
- save_comp_with_send (editor);
-}
-
-static void
-save_close_cmd (GtkWidget *widget, gpointer data)
-{
- CompEditor *editor = COMP_EDITOR (data);
-
- commit_all_fields (editor);
-
- if (save_comp_with_send (editor))
- close_dialog (editor);
-}
-
-static void
-save_as_cmd (GtkWidget *widget, gpointer data)
-{
- CompEditor *editor = COMP_EDITOR (data);
- CompEditorPrivate *priv;
- char *filename;
- char *ical_string;
- FILE *file;
-
- priv = editor->priv;
-
- commit_all_fields (editor);
-
- filename = e_file_dialog_save (_("Save as..."));
- if (filename == NULL)
- return;
-
- ical_string = cal_client_get_component_as_string (priv->client, priv->comp);
- if (ical_string == NULL) {
- g_warning ("Couldn't convert item to a string");
- return;
- }
-
- file = fopen (filename, "w");
- if (file == NULL) {
- g_warning ("Couldn't save item");
- return;
- }
-
- fprintf (file, ical_string);
- g_free (ical_string);
- fclose (file);
-}
-
-static void
-delete_cmd (GtkWidget *widget, gpointer data)
-{
- CompEditor *editor = COMP_EDITOR (data);
- CompEditorPrivate *priv;
- CalComponentVType vtype;
-
- priv = editor->priv;
-
- vtype = cal_component_get_vtype (priv->comp);
-
- if (delete_component_dialog (priv->comp, FALSE, 1, vtype, GTK_WIDGET (editor))) {
- if (itip_organizer_is_user (priv->comp)
- && cancel_component_dialog (priv->comp, TRUE))
- itip_send_comp (CAL_COMPONENT_METHOD_CANCEL, priv->comp, priv->client, NULL);
-
- delete_comp (editor);
- }
-}
-
-static void
-print_cmd (GtkWidget *widget, gpointer data)
-{
- CompEditor *editor = COMP_EDITOR (data);
- CalComponent *comp;
-
- commit_all_fields (editor);
-
- comp = comp_editor_get_current_comp (editor);
- print_comp (comp, editor->priv->client, FALSE);
- gtk_object_unref (GTK_OBJECT (comp));
-}
-
-static void
-print_preview_cmd (GtkWidget *widget, gpointer data)
-{
- CompEditor *editor = COMP_EDITOR (data);
- CalComponent *comp;
-
- commit_all_fields (editor);
-
- comp = comp_editor_get_current_comp (editor);
- print_comp (comp, editor->priv->client, TRUE);
- gtk_object_unref (GTK_OBJECT (comp));
-}
-
-static void
-print_setup_cmd (GtkWidget *widget, gpointer data)
-{
- CompEditor *editor = COMP_EDITOR (data);
- CompEditorPrivate *priv;
-
- priv = editor->priv;
-
- print_setup ();
-}
-
-static void
-close_cmd (GtkWidget *widget, gpointer data)
-{
- CompEditor *editor = COMP_EDITOR (data);
-
- commit_all_fields (editor);
-
- if (prompt_to_save_changes (editor, TRUE))
- close_dialog (editor);
-}
-
-static void
-page_changed_cb (GtkObject *obj, gpointer data)
+/* Utility function to get the mime-attachment list from the attachment
+ * bar for sending the comp via itip. The list and its contents must
+ * be freed by the caller.
+ */
+GSList *
+comp_editor_get_mime_attach_list (CompEditor *editor)
{
- CompEditor *editor = COMP_EDITOR (data);
- CompEditorPrivate *priv;
+ EAttachmentStore *store;
+ EAttachmentView *view;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ struct CalMimeAttach *cal_mime_attach;
+ GSList *attach_list = NULL;
+ gboolean valid;
+
+ view = E_ATTACHMENT_VIEW (editor->priv->attachment_view);
+ store = e_attachment_view_get_store (view);
+
+ model = GTK_TREE_MODEL (store);
+ valid = gtk_tree_model_get_iter_first (model, &iter);
+
+ while (valid) {
+ EAttachment *attachment;
+ CamelDataWrapper *wrapper;
+ CamelMimePart *mime_part;
+ CamelStream *stream;
+ GByteArray *byte_array;
+ guchar *buffer = NULL;
+ const gchar *description;
+ const gchar *disposition;
+ gint column_id;
+
+ column_id = E_ATTACHMENT_STORE_COLUMN_ATTACHMENT;
+ gtk_tree_model_get (model, &iter, column_id, &attachment, -1);
+ mime_part = e_attachment_ref_mime_part (attachment);
+ g_object_unref (attachment);
+
+ valid = gtk_tree_model_iter_next (model, &iter);
+
+ if (mime_part == NULL)
+ continue;
+
+ cal_mime_attach = g_malloc0 (sizeof (struct CalMimeAttach));
+ wrapper = camel_medium_get_content (CAMEL_MEDIUM (mime_part));
+
+ byte_array = g_byte_array_new ();
+ stream = camel_stream_mem_new_with_byte_array (byte_array);
+
+ camel_data_wrapper_decode_to_stream_sync (
+ wrapper, stream, NULL, NULL);
+ buffer = g_memdup (byte_array->data, byte_array->len);
+
+ camel_mime_part_set_content_id (mime_part, NULL);
+
+ cal_mime_attach->encoded_data = (gchar *) buffer;
+ cal_mime_attach->length = byte_array->len;
+ cal_mime_attach->filename =
+ g_strdup (camel_mime_part_get_filename (mime_part));
+ description = camel_mime_part_get_description (mime_part);
+ if (description == NULL || *description == '\0')
+ description = _("attachment");
+ cal_mime_attach->description = g_strdup (description);
+ cal_mime_attach->content_type = g_strdup (
+ camel_data_wrapper_get_mime_type (wrapper));
+ cal_mime_attach->content_id = g_strdup (
+ camel_mime_part_get_content_id (mime_part));
+
+ disposition = camel_mime_part_get_disposition (mime_part);
+ cal_mime_attach->disposition =
+ (disposition != NULL) &&
+ (g_ascii_strcasecmp (disposition, "inline") == 0);
+
+ attach_list = g_slist_append (attach_list, cal_mime_attach);
+
+ g_object_unref (mime_part);
+ g_object_unref (stream);
- priv = editor->priv;
-
- priv->changed = TRUE;
-
- if (!priv->warned && priv->existing_org && !priv->user_org) {
- e_notice (NULL, GNOME_MESSAGE_BOX_INFO,
- _("Changes made to this item may be discarded if an update arrives via email"));
- priv->warned = TRUE;
}
-
-}
-/* Page signal callbacks */
-static void
-page_summary_changed_cb (GtkObject *obj, const char *summary, gpointer data)
-{
- CompEditor *editor = COMP_EDITOR (data);
- CompEditorPrivate *priv;
- GList *l;
-
- priv = editor->priv;
-
- for (l = priv->pages; l != NULL; l = l->next)
- if (obj != l->data)
- comp_editor_page_set_summary (l->data, summary);
-
- priv->changed = TRUE;
-
- if (!priv->warned && priv->existing_org && !priv->user_org) {
- e_notice (NULL, GNOME_MESSAGE_BOX_INFO,
- _("Changes made to this item may be discarded if an update arrives via email"));
- priv->warned = TRUE;
- }
+ return attach_list;
}
static void
-page_dates_changed_cb (GtkObject *obj,
- CompEditorPageDates *dates,
- gpointer data)
+page_dates_changed_cb (CompEditor *editor,
+ CompEditorPageDates *dates,
+ CompEditorPage *page)
{
- CompEditor *editor = COMP_EDITOR (data);
- CompEditorPrivate *priv;
+ CompEditorPrivate *priv = editor->priv;
GList *l;
- priv = editor->priv;
-
for (l = priv->pages; l != NULL; l = l->next)
- if (obj != l->data)
+ if (page != (CompEditorPage *) l->data && IS_COMP_EDITOR_PAGE (l->data))
comp_editor_page_set_dates (l->data, dates);
- priv->changed = TRUE;
-
- if (!priv->warned && priv->existing_org && !priv->user_org) {
- e_notice (NULL, GNOME_MESSAGE_BOX_INFO,
- _("Changes made to this item may be discarded if an update arrives via email"));
+ if (!priv->warned && priv->existing_org && !priv->user_org &&
+ !(editor->priv->flags & COMP_EDITOR_NEW_ITEM)) {
+ e_notice (
+ priv->notebook, GTK_MESSAGE_INFO,
+ _("Changes made to this item may be discarded "
+ "if an update arrives"));
priv->warned = TRUE;
}
}
static void
-obj_updated_cb (CalClient *client, const char *uid, gpointer data)
+obj_modified_cb (ECalClientView *view,
+ const GSList *objects,
+ CompEditor *editor)
{
- CompEditor *editor = COMP_EDITOR (data);
CompEditorPrivate *priv;
- CalComponent *comp = NULL;
- CalClientGetStatus status;
- const char *edit_uid;
+ ECalComponent *comp = NULL;
priv = editor->priv;
- cal_component_get_uid (priv->comp, &edit_uid);
-
- if (!strcmp (uid, edit_uid) && !priv->updating) {
- if (changed_component_dialog (priv->comp, FALSE, priv->changed)) {
- status = cal_client_get_object (priv->client, uid, &comp);
- if (status == CAL_CLIENT_GET_SUCCESS) {
- comp_editor_edit_comp (editor, comp);
- gtk_object_unref (GTK_OBJECT (comp));
- } else {
- GtkWidget *dlg;
-
- dlg = gnome_error_dialog (_("Unable to obtain current version!"));
- gnome_dialog_run_and_close (GNOME_DIALOG (dlg));
- }
+ /* We queried based on a specific UID so we definitely changed */
+ if (changed_component_dialog (
+ (GtkWindow *) editor, priv->comp, FALSE, priv->changed)) {
+ icalcomponent *icalcomp = icalcomponent_new_clone (objects->data);
+
+ comp = e_cal_component_new ();
+ if (e_cal_component_set_icalcomponent (comp, icalcomp)) {
+ comp_editor_edit_comp (editor, comp);
+ } else {
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (
+ NULL, 0,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ "%s",
+ _("Unable to use current version!"));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ icalcomponent_free (icalcomp);
}
- }
-}
-
-static void
-obj_removed_cb (CalClient *client, const char *uid, gpointer data)
-{
- CompEditor *editor = COMP_EDITOR (data);
- CompEditorPrivate *priv;
- const char *edit_uid;
- priv = editor->priv;
-
- cal_component_get_uid (priv->comp, &edit_uid);
-
- if (!strcmp (uid, edit_uid) && !priv->updating) {
- if (changed_component_dialog (priv->comp, TRUE, priv->changed))
- close_dialog (editor);
+ g_object_unref (comp);
}
}
-static gint
-delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+static void
+obj_removed_cb (ECalClientView *view,
+ const GSList *uids,
+ CompEditor *editor)
{
- CompEditor *editor = COMP_EDITOR (data);
+ CompEditorPrivate *priv = editor->priv;
- if (prompt_to_save_changes (editor, TRUE))
+ if (changed_component_dialog (
+ GTK_WINDOW (editor), priv->comp, TRUE, priv->changed))
close_dialog (editor);
-
- return TRUE;
}
diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h
index 1f678c1950..6721a87978 100644
--- a/calendar/gui/dialogs/comp-editor.h
+++ b/calendar/gui/dialogs/comp-editor.h
@@ -1,109 +1,209 @@
-/* Evolution calendar - Framework for a calendar component editor dialog
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@ximian.com>
+/*
+ * Evolution calendar - Framework for a calendar component editor dialog
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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 COMP_EDITOR_H
#define COMP_EDITOR_H
#include <gtk/gtk.h>
-#include <bonobo/bonobo-win.h>
-#include <bonobo/bonobo-ui-engine.h>
-#include <bonobo/bonobo-ui-component.h>
-#include "cal-client.h"
+#include <libecal/libecal.h>
+
+#include <shell/e-shell.h>
+
#include "../itip-utils.h"
#include "comp-editor-page.h"
-#include "evolution-shell-component-utils.h"
-BEGIN_GNOME_DECLS
+/* Standard GObject macros */
+#define TYPE_COMP_EDITOR \
+ (comp_editor_get_type ())
+#define COMP_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), TYPE_COMP_EDITOR, CompEditor))
+#define COMP_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), TYPE_COMP_EDITOR, CompEditorClass))
+#define IS_COMP_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), TYPE_COMP_EDITOR))
+#define IS_COMP_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), TYPE_COMP_EDITOR))
+#define COMP_EDITOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), TYPE_COMP_EDITOR, CompEditorClass))
-
-
-#define TYPE_COMP_EDITOR (comp_editor_get_type ())
-#define COMP_EDITOR(obj) (GTK_CHECK_CAST ((obj), TYPE_COMP_EDITOR, CompEditor))
-#define COMP_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_COMP_EDITOR, CompEditorClass))
-#define IS_COMP_EDITOR(obj) (GTK_CHECK_TYPE ((obj), TYPE_COMP_EDITOR))
-#define IS_COMP_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_COMP_EDITOR))
+G_BEGIN_DECLS
+typedef struct _CompEditor CompEditor;
+typedef struct _CompEditorClass CompEditorClass;
typedef struct _CompEditorPrivate CompEditorPrivate;
-typedef struct {
- BonoboWindow object;
-
- /* Private data */
+struct _CompEditor {
+ GtkWindow parent;
CompEditorPrivate *priv;
-} CompEditor;
+};
-typedef struct {
- BonoboWindowClass parent_class;
+struct _CompEditorClass {
+ GtkWindowClass parent_class;
+ const gchar *help_section;
/* Virtual functions */
- void (* set_cal_client) (CompEditor *page, CalClient *client);
- void (* edit_comp) (CompEditor *page, CalComponent *comp);
- gboolean (* send_comp) (CompEditor *page, CalComponentItipMethod method);
-} CompEditorClass;
-
-GtkType comp_editor_get_type (void);
-void comp_editor_set_changed (CompEditor *editor,
- gboolean changed);
-gboolean comp_editor_get_changed (CompEditor *editor);
-void comp_editor_set_needs_send (CompEditor *editor,
- gboolean needs_send);
-gboolean comp_editor_get_needs_send (CompEditor *editor);
-void comp_editor_set_existing_org (CompEditor *editor,
- gboolean existing_org);
-gboolean comp_editor_get_existing_org (CompEditor *editor);
-void comp_editor_set_user_org (CompEditor *editor,
- gboolean user_org);
-gboolean comp_editor_get_user_org (CompEditor *editor);
-void comp_editor_append_page (CompEditor *editor,
- CompEditorPage *page,
- const char *label);
-void comp_editor_remove_page (CompEditor *editor,
- CompEditorPage *page);
-void comp_editor_show_page (CompEditor *editor,
- CompEditorPage *page);
-void comp_editor_set_cal_client (CompEditor *editor,
- CalClient *client);
-CalClient *comp_editor_get_cal_client (CompEditor *editor);
-void comp_editor_edit_comp (CompEditor *ee,
- CalComponent *comp);
-CalComponent *comp_editor_get_comp (CompEditor *editor);
-CalComponent *comp_editor_get_current_comp (CompEditor *editor);
-gboolean comp_editor_save_comp (CompEditor *editor,
- gboolean send);
-void comp_editor_delete_comp (CompEditor *editor);
-gboolean comp_editor_send_comp (CompEditor *editor,
- CalComponentItipMethod method);
-gboolean comp_editor_close (CompEditor *editor);
-void comp_editor_merge_ui (CompEditor *editor,
- const char *filename,
- BonoboUIVerb *verbs,
- EPixmap *pixmaps);
-void comp_editor_set_ui_prop (CompEditor *editor,
- const char *path,
- const char *attr,
- const char *val);
-void comp_editor_focus (CompEditor *editor);
-
-
-
-
-END_GNOME_DECLS
+ void (*edit_comp) (CompEditor *page,
+ ECalComponent *comp);
+ void (*object_created) (CompEditor *page);
+ gboolean (*send_comp) (CompEditor *page,
+ ECalComponentItipMethod method,
+ gboolean strip_alarms);
+
+ void (*show_categories) (CompEditor *editor,
+ gboolean visible);
+ void (*show_role) (CompEditor *editor,
+ gboolean visible);
+ void (*show_rsvp) (CompEditor *editor,
+ gboolean visible);
+ void (*show_status) (CompEditor *editor,
+ gboolean visible);
+ void (*show_time_zone) (CompEditor *editor,
+ gboolean visible);
+ void (*show_type) (CompEditor *editor,
+ gboolean visible);
+ void (*comp_closed) (CompEditor *editor,
+ gboolean saved);
+};
+
+typedef enum {
+ COMP_EDITOR_NEW_ITEM = 1 << 0,
+ COMP_EDITOR_MEETING = 1 << 1,
+ COMP_EDITOR_DELEGATE = 1 << 2,
+ COMP_EDITOR_USER_ORG = 1 << 3,
+ COMP_EDITOR_IS_ASSIGNED = 1 << 4,
+ COMP_EDITOR_IS_SHARED = 1 << 5,
+ COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY = 1 << 6
+} CompEditorFlags;
+
+GType comp_editor_get_type (void);
+void comp_editor_set_changed (CompEditor *editor,
+ gboolean changed);
+gboolean comp_editor_get_changed (CompEditor *editor);
+EFocusTracker * comp_editor_get_focus_tracker (CompEditor *editor);
+void comp_editor_set_needs_send (CompEditor *editor,
+ gboolean needs_send);
+gboolean comp_editor_get_needs_send (CompEditor *editor);
+void comp_editor_set_existing_org (CompEditor *editor,
+ gboolean existing_org);
+gboolean comp_editor_get_existing_org (CompEditor *editor);
+void comp_editor_set_user_org (CompEditor *editor,
+ gboolean user_org);
+gboolean comp_editor_get_user_org (CompEditor *editor);
+void comp_editor_set_group_item (CompEditor *editor,
+ gboolean is_group_item);
+gboolean comp_editor_get_group_item (CompEditor *editor);
+void comp_editor_set_classification (CompEditor *editor,
+ ECalComponentClassification classification);
+ECalComponentClassification
+ comp_editor_get_classification (CompEditor *editor);
+EShell * comp_editor_get_shell (CompEditor *editor);
+void comp_editor_set_summary (CompEditor *editor,
+ const gchar *summary);
+const gchar * comp_editor_get_summary (CompEditor *editor);
+icaltimezone * comp_editor_get_timezone (CompEditor *editor);
+void comp_editor_set_timezone (CompEditor *editor,
+ icaltimezone *zone);
+gboolean comp_editor_get_use_24_hour_format
+ (CompEditor *editor);
+void comp_editor_set_use_24_hour_format
+ (CompEditor *editor,
+ gboolean use_24_hour_format);
+GDateWeekday comp_editor_get_week_start_day (CompEditor *editor);
+void comp_editor_set_week_start_day (CompEditor *editor,
+ GDateWeekday week_start_day);
+gint comp_editor_get_work_day_end_hour
+ (CompEditor *editor);
+void comp_editor_set_work_day_end_hour
+ (CompEditor *editor,
+ gint work_day_end_hour);
+gint comp_editor_get_work_day_end_minute
+ (CompEditor *editor);
+void comp_editor_set_work_day_end_minute
+ (CompEditor *editor,
+ gint work_day_end_minute);
+gint comp_editor_get_work_day_start_hour
+ (CompEditor *editor);
+void comp_editor_set_work_day_start_hour
+ (CompEditor *editor,
+ gint work_day_start_hour);
+gint comp_editor_get_work_day_start_minute
+ (CompEditor *editor);
+void comp_editor_set_work_day_start_minute
+ (CompEditor *editor,
+ gint work_day_start_minute);
+void comp_editor_append_page (CompEditor *editor,
+ CompEditorPage *page,
+ const gchar *label,
+ gboolean add);
+void comp_editor_append_widget (CompEditor *editor,
+ GtkWidget *page,
+ const gchar *label,
+ gboolean add);
+
+void comp_editor_remove_page (CompEditor *editor,
+ CompEditorPage *page);
+void comp_editor_show_page (CompEditor *editor,
+ CompEditorPage *page);
+void comp_editor_set_client (CompEditor *editor,
+ ECalClient *cal_client);
+ECalClient * comp_editor_get_client (CompEditor *editor);
+void comp_editor_edit_comp (CompEditor *ee,
+ ECalComponent *comp);
+ECalComponent * comp_editor_get_comp (CompEditor *editor);
+ECalComponent * comp_editor_get_current_comp (CompEditor *editor,
+ gboolean *correct);
+gboolean comp_editor_save_comp (CompEditor *editor,
+ gboolean send);
+void comp_editor_delete_comp (CompEditor *editor);
+gboolean comp_editor_send_comp (CompEditor *editor,
+ ECalComponentItipMethod method,
+ gboolean strip_alarms);
+GSList * comp_editor_get_mime_attach_list (CompEditor *editor);
+gboolean comp_editor_close (CompEditor *editor);
+
+void comp_editor_sensitize_attachment_bar
+ (CompEditor *editor,
+ gboolean set);
+void comp_editor_set_flags (CompEditor *editor,
+ CompEditorFlags flags);
+CompEditorFlags
+ comp_editor_get_flags (CompEditor *editor);
+GtkUIManager * comp_editor_get_ui_manager (CompEditor *editor);
+GtkAction * comp_editor_get_action (CompEditor *editor,
+ const gchar *action_name);
+GtkActionGroup *
+ comp_editor_get_action_group (CompEditor *editor,
+ const gchar *group_name);
+GtkWidget * comp_editor_get_managed_widget (CompEditor *editor,
+ const gchar *widget_path);
+CompEditor * comp_editor_find_instance (const gchar *uid);
+
+G_END_DECLS
#endif
diff --git a/calendar/gui/dialogs/copy-source-dialog.c b/calendar/gui/dialogs/copy-source-dialog.c
new file mode 100644
index 0000000000..0f0dc0545e
--- /dev/null
+++ b/calendar/gui/dialogs/copy-source-dialog.c
@@ -0,0 +1,259 @@
+/*
+ * Evolution calendar - Copy source dialog
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Rodrigo Moya <rodrigo@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+
+#include "e-util/e-util.h"
+
+#include "copy-source-dialog.h"
+#include "select-source-dialog.h"
+
+typedef struct {
+ GtkWindow *parent;
+ ESource *orig_source;
+ ECalClientSourceType obj_type;
+ ESource *selected_source;
+ ECalClient *source_client, *dest_client;
+} CopySourceDialogData;
+
+static void
+show_error (CopySourceDialogData *csdd,
+ const gchar *msg,
+ const GError *error)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (
+ csdd->parent, 0, GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE, error ? "%s\n%s" : "%s", msg, error ? error->message : "");
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
+
+struct ForeachTzidData
+{
+ ECalClient *source_client;
+ ECalClient *dest_client;
+};
+
+static void
+add_timezone_to_cal_cb (icalparameter *param,
+ gpointer data)
+{
+ struct ForeachTzidData *ftd = data;
+ icaltimezone *tz = NULL;
+ const gchar *tzid;
+
+ g_return_if_fail (ftd != NULL);
+ g_return_if_fail (ftd->source_client != NULL);
+ g_return_if_fail (ftd->dest_client != NULL);
+
+ tzid = icalparameter_get_tzid (param);
+ if (!tzid || !*tzid)
+ return;
+
+ if (e_cal_client_get_timezone_sync (ftd->source_client, tzid, &tz, NULL, NULL) && tz)
+ e_cal_client_add_timezone_sync (ftd->dest_client, tz, NULL, NULL);
+}
+
+static void
+free_copy_data (CopySourceDialogData *csdd)
+{
+ if (!csdd)
+ return;
+
+ if (csdd->orig_source)
+ g_object_unref (csdd->orig_source);
+ if (csdd->selected_source)
+ g_object_unref (csdd->selected_source);
+ if (csdd->source_client)
+ g_object_unref (csdd->source_client);
+ if (csdd->dest_client)
+ g_object_unref (csdd->dest_client);
+ g_free (csdd);
+}
+
+static void
+dest_source_connected_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ CopySourceDialogData *csdd = user_data;
+ EClient *client;
+ GError *error = NULL;
+
+ client = e_cal_client_connect_finish (result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ if (error != NULL) {
+ show_error (csdd, _("Could not open destination"), error);
+ g_error_free (error);
+ free_copy_data (csdd);
+ return;
+ }
+
+ csdd->dest_client = E_CAL_CLIENT (client);
+
+ /* check if the destination is read only */
+ if (e_client_is_readonly (E_CLIENT (csdd->dest_client))) {
+ show_error (csdd, _("Destination is read only"), NULL);
+ } else {
+ GSList *obj_list = NULL;
+ if (e_cal_client_get_object_list_sync (csdd->source_client, "#t", &obj_list, NULL, NULL)) {
+ GSList *l;
+ icalcomponent *icalcomp;
+ struct ForeachTzidData ftd;
+
+ ftd.source_client = csdd->source_client;
+ ftd.dest_client = csdd->dest_client;
+
+ for (l = obj_list; l != NULL; l = l->next) {
+ /* FIXME: process recurrences */
+ /* FIXME: process errors */
+ if (e_cal_client_get_object_sync (csdd->dest_client, icalcomponent_get_uid (l->data), NULL,
+ &icalcomp, NULL, NULL)) {
+ e_cal_client_modify_object_sync (csdd->dest_client, l->data, CALOBJ_MOD_ALL, NULL, NULL);
+ icalcomponent_free (icalcomp);
+ } else {
+ gchar *uid = NULL;
+ GError *error = NULL;
+
+ icalcomp = l->data;
+
+ /* Add timezone information from source
+ * ECal to the destination ECal. */
+ icalcomponent_foreach_tzid (
+ icalcomp,
+ add_timezone_to_cal_cb, &ftd);
+
+ if (e_cal_client_create_object_sync (csdd->dest_client, icalcomp, &uid, NULL, &error)) {
+ g_free (uid);
+ } else {
+ if (error) {
+ show_error (csdd, _("Cannot create object"), error);
+ g_error_free (error);
+ }
+ break;
+ }
+ }
+ }
+
+ e_cal_client_free_icalcomp_slist (obj_list);
+ }
+ }
+
+ free_copy_data (csdd);
+}
+
+static void
+orig_source_connected_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ CopySourceDialogData *csdd = user_data;
+ EClient *client;
+ GError *error = NULL;
+
+ client = e_cal_client_connect_finish (result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ if (error != NULL) {
+ show_error (csdd, _("Could not open source"), error);
+ g_error_free (error);
+ free_copy_data (csdd);
+ return;
+ }
+
+ csdd->source_client = E_CAL_CLIENT (client);
+
+ e_cal_client_connect (
+ csdd->selected_source, csdd->obj_type, NULL,
+ dest_source_connected_cb, csdd);
+}
+
+static void
+copy_source (const CopySourceDialogData *const_csdd)
+{
+ CopySourceDialogData *csdd;
+
+ if (!const_csdd->selected_source)
+ return;
+
+ csdd = g_new0 (CopySourceDialogData, 1);
+ csdd->parent = const_csdd->parent;
+ csdd->orig_source = g_object_ref (const_csdd->orig_source);
+ csdd->obj_type = const_csdd->obj_type;
+ csdd->selected_source = g_object_ref (const_csdd->selected_source);
+
+ e_cal_client_connect (
+ csdd->orig_source, csdd->obj_type, NULL,
+ orig_source_connected_cb, csdd);
+}
+
+/**
+ * copy_source_dialog
+ *
+ * Implements the Copy command for sources, allowing the user to select a target
+ * source to copy to.
+ */
+void
+copy_source_dialog (GtkWindow *parent,
+ ESourceRegistry *registry,
+ ESource *source,
+ ECalClientSourceType obj_type)
+{
+ CopySourceDialogData csdd;
+
+ g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+ g_return_if_fail (E_IS_SOURCE (source));
+ g_return_if_fail (obj_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS ||
+ obj_type == E_CAL_CLIENT_SOURCE_TYPE_TASKS ||
+ obj_type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS);
+
+ csdd.parent = parent;
+ csdd.orig_source = source;
+ csdd.selected_source = NULL;
+ csdd.obj_type = obj_type;
+
+ csdd.selected_source = select_source_dialog (
+ parent, registry, obj_type, source);
+ if (csdd.selected_source) {
+ copy_source (&csdd);
+
+ /* free memory */
+ g_object_unref (csdd.selected_source);
+ }
+}
diff --git a/calendar/gui/dialogs/copy-source-dialog.h b/calendar/gui/dialogs/copy-source-dialog.h
new file mode 100644
index 0000000000..eccd0b5763
--- /dev/null
+++ b/calendar/gui/dialogs/copy-source-dialog.h
@@ -0,0 +1,37 @@
+/*
+ *
+ * Evolution calendar - Copy source dialog
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Rodrigo Moya <rodrigo@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef COPY_SOURCE_DIALOG_H
+#define COPY_SOURCE_DIALOG_H
+
+#include <gtk/gtk.h>
+#include <libecal/libecal.h>
+
+void copy_source_dialog (GtkWindow *parent,
+ ESourceRegistry *registry,
+ ESource *source,
+ ECalClientSourceType type);
+
+#endif /* COPY_SOURCE_DIALOG_H */
diff --git a/calendar/gui/dialogs/delete-comp.c b/calendar/gui/dialogs/delete-comp.c
index 405a9445b4..0ec054cd39 100644
--- a/calendar/gui/dialogs/delete-comp.c
+++ b/calendar/gui/dialogs/delete-comp.c
@@ -1,37 +1,36 @@
-/* Evolution calendar - Delete calendar component dialog
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@ximian.com>
+/*
+ * Evolution calendar - Delete calendar component dialog
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-stock.h>
-#include <gal/widgets/e-unicode.h>
-#include "widgets/misc/e-messagebox.h"
-#include "../calendar-config.h"
#include "delete-comp.h"
-
+#include <glib/gi18n.h>
+
+#include "e-util/e-util.h"
/**
* delete_component_dialog:
@@ -46,120 +45,218 @@
* the component instead.
* @widget: A widget to use as a basis for conversion from UTF8 into font
* encoding.
- *
+ *
* Pops up a dialog box asking the user whether he wants to delete a number of
* calendar components. The dialog will not appear, however, if the
* configuration option for confirmation is turned off.
- *
+ *
* Return value: TRUE if the user clicked Yes, FALSE otherwise. If the
* configuration option for confirmation is turned off, this function will
* unconditionally return TRUE.
**/
gboolean
-delete_component_dialog (CalComponent *comp,
- gboolean consider_as_untitled,
- int n_comps, CalComponentVType vtype,
- GtkWidget *widget)
+delete_component_dialog (ECalComponent *comp,
+ gboolean consider_as_untitled,
+ gint n_comps,
+ ECalComponentVType vtype,
+ GtkWidget *widget)
{
- char *str;
- GtkWidget *dialog;
+ const gchar *id;
+ gchar *arg0 = NULL;
+ gint response;
+ gboolean attendees;
if (comp) {
- g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE);
+ g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
g_return_val_if_fail (n_comps == 1, FALSE);
} else {
g_return_val_if_fail (n_comps > 1, FALSE);
- g_return_val_if_fail (vtype != CAL_COMPONENT_NO_TYPE, FALSE);
+ g_return_val_if_fail (vtype != E_CAL_COMPONENT_NO_TYPE, FALSE);
}
- g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
- if (!calendar_config_get_confirm_delete ())
- return TRUE;
-
if (comp) {
- CalComponentText summary;
- char *tmp;
+ ECalComponentText summary;
- vtype = cal_component_get_vtype (comp);
+ vtype = e_cal_component_get_vtype (comp);
if (!consider_as_untitled) {
- cal_component_get_summary (comp, &summary);
- tmp = e_utf8_to_gtk_string (widget, summary.value);
- } else
- tmp = NULL;
+ e_cal_component_get_summary (comp, &summary);
+ arg0 = g_strdup (summary.value);
+ }
switch (vtype) {
- case CAL_COMPONENT_EVENT:
- if (tmp)
- str = g_strdup_printf (_("Are you sure you want to delete "
- "the appointment `%s'?"), tmp);
- else
- str = g_strdup (_("Are you sure you want to delete this "
- "untitled appointment?"));
+ case E_CAL_COMPONENT_EVENT:
+ attendees = e_cal_component_has_attendees (comp);
+ if (arg0) {
+ if (attendees)
+ id = "calendar:prompt-delete-titled-meeting";
+ else
+ id = "calendar:prompt-delete-titled-appointment";
+ } else {
+ if (attendees)
+ id = "calendar:prompt-delete-meeting";
+ else
+ id = "calendar:prompt-delete-appointment";
+ }
break;
- case CAL_COMPONENT_TODO:
- if (tmp)
- str = g_strdup_printf (_("Are you sure you want to delete "
- "the task `%s'?"), tmp);
+ case E_CAL_COMPONENT_TODO:
+ if (arg0)
+ id = "calendar:prompt-delete-named-task";
else
- str = g_strdup (_("Are you sure you want to delete this "
- "untitled task?"));
+ id = "calendar:prompt-delete-task";
break;
- case CAL_COMPONENT_JOURNAL:
- if (tmp)
- str = g_strdup_printf (_("Are you sure you want to delete "
- "the journal entry `%s'?"), tmp);
+ case E_CAL_COMPONENT_JOURNAL:
+ if (arg0)
+ id = "calendar:prompt-delete-named-memo";
else
- str = g_strdup (_("Are you sure want to delete this "
- "untitled journal entry?"));
+ id = "calendar:prompt-delete-memo";
break;
default:
- g_message ("delete_component_dialog(): Cannot handle object of type %d",
- vtype);
- g_free (tmp);
+ g_message (
+ "delete_component_dialog(): Cannot handle object of type %d",
+ vtype);
+ g_free (arg0);
return FALSE;
}
-
- g_free (tmp);
} else {
switch (vtype) {
- case CAL_COMPONENT_EVENT:
- str = g_strdup_printf (_("Are you sure you want to delete "
- "%d appointments?"), n_comps);
+ case E_CAL_COMPONENT_EVENT:
+ if (n_comps == 1)
+ id = "calendar:prompt-delete-appointment";
+ else
+ id = "calendar:prompt-delete-appointments";
break;
- case CAL_COMPONENT_TODO:
- str = g_strdup_printf (_("Are you sure you want to delete "
- "%d tasks?"), n_comps);
+ case E_CAL_COMPONENT_TODO:
+ if (n_comps == 1)
+ id = "calendar:prompt-delete-task";
+ else
+ id = "calendar:prompt-delete-tasks";
break;
- case CAL_COMPONENT_JOURNAL:
- str = g_strdup_printf (_("Are you sure you want to delete "
- "%d journal entries?"), n_comps);
+ case E_CAL_COMPONENT_JOURNAL:
+ if (n_comps == 1)
+ id = "calendar:prompt-delete-memo";
+ else
+ id = "calendar:prompt-delete-memos";
break;
default:
- g_message ("delete_component_dialog(): Cannot handle objects of type %d",
- vtype);
+ g_message (
+ "delete_component_dialog(): Cannot handle objects of type %d",
+ vtype);
return FALSE;
}
+
+ if (n_comps > 1)
+ arg0 = g_strdup_printf ("%d", n_comps);
}
- dialog = e_message_box_new (str, E_MESSAGE_BOX_QUESTION,
- GNOME_STOCK_BUTTON_YES,
- GNOME_STOCK_BUTTON_NO,
- NULL);
- g_free (str);
+ response = e_alert_run_dialog_for_args ((GtkWindow *) gtk_widget_get_toplevel (widget), id, arg0, NULL);
+ g_free (arg0);
+
+ return response == GTK_RESPONSE_YES;
+}
+
+static void
+cb_toggled_cb (GtkToggleButton *toggle,
+ gpointer data)
+{
+ gboolean active = FALSE;
+ GtkWidget *entry = (GtkWidget *) data;
+
+ active = gtk_toggle_button_get_active (toggle);
+ gtk_widget_set_sensitive (entry, active);
+}
+
+gboolean
+prompt_retract_dialog (ECalComponent *comp,
+ gchar **retract_text,
+ GtkWidget *parent,
+ gboolean *retract)
+{
+ gchar *message = NULL;
+ ECalComponentVType type = E_CAL_COMPONENT_NO_TYPE;
+ GtkMessageDialog *dialog = NULL;
+ GtkWidget *cb, *label, *entry, *vbox, *sw, *frame;
+ gboolean ret_val = FALSE;
+
+ type = e_cal_component_get_vtype (comp);
+
+ switch (type) {
+ case E_CAL_COMPONENT_EVENT:
+ message = g_strdup_printf (_("Are you sure you want to delete this meeting?"));
+ break;
+ case E_CAL_COMPONENT_TODO:
+ message = g_strdup_printf (_("Are you sure you want to delete this task?"));
+ break;
+ case E_CAL_COMPONENT_JOURNAL:
+ message = g_strdup_printf (_("Are you sure you want to delete this memo?"));
+ break;
+ default:
+ g_message ("Retract: Unsupported object type \n");
+ return FALSE;
+ }
+
+ dialog = (GtkMessageDialog *) gtk_message_dialog_new_with_markup
+ ((GtkWindow *) gtk_widget_get_toplevel (parent), GTK_DIALOG_MODAL,
+ GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, "<b>%s</b>", message);
+ g_free (message);
+
+ gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+
+ vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ gtk_box_set_spacing (GTK_BOX (vbox), 12);
+
+ cb = gtk_check_button_new_with_mnemonic (_("_Delete this item from all other recipient's mailboxes?"));
+ gtk_container_add (GTK_CONTAINER (vbox), cb);
+
+ label = gtk_label_new_with_mnemonic (_("_Retract comment"));
+
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_label_widget ((GtkFrame *) frame, label);
+ gtk_frame_set_label_align ((GtkFrame *) frame, 0, 0);
+ gtk_container_add (GTK_CONTAINER (vbox), frame);
+ gtk_frame_set_shadow_type ((GtkFrame *) frame, GTK_SHADOW_NONE);
+
+ sw = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy ((GtkScrolledWindow *) sw, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ entry = gtk_text_view_new ();
+ gtk_scrolled_window_add_with_viewport ((GtkScrolledWindow *) sw, entry);
+ gtk_label_set_mnemonic_widget ((GtkLabel *) label, entry);
+ gtk_container_add (GTK_CONTAINER (frame), sw);
+
+ g_signal_connect (
+ cb, "toggled",
+ G_CALLBACK (cb_toggled_cb), entry);
+
+ gtk_widget_show_all ((GtkWidget *) dialog);
+
+ ret_val = (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK);
+
+ if (ret_val) {
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cb))) {
+ GtkTextIter text_iter_start, text_iter_end;
+ GtkTextBuffer *text_buffer;
+
+ *retract = TRUE;
+ text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (entry));
+ gtk_text_buffer_get_start_iter (text_buffer, &text_iter_start);
+ gtk_text_buffer_get_end_iter (text_buffer, &text_iter_end);
+
+ *retract_text = gtk_text_buffer_get_text (text_buffer, &text_iter_start,
+ &text_iter_end, FALSE);
+ } else
+ *retract = FALSE;
+ }
- gtk_widget_hide (e_message_box_get_checkbox (E_MESSAGE_BOX (dialog)));
+ gtk_widget_destroy ((GtkWidget *) dialog);
- if (gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == 0)
- return TRUE;
- else
- return FALSE;
+ return ret_val;
}
diff --git a/calendar/gui/dialogs/delete-comp.h b/calendar/gui/dialogs/delete-comp.h
index 64945b5bee..c6fa3996fd 100644
--- a/calendar/gui/dialogs/delete-comp.h
+++ b/calendar/gui/dialogs/delete-comp.h
@@ -1,32 +1,38 @@
-/* Evolution calendar - Delete calendar component dialog
+/*
*
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Author: Federico Mena-Quintero <federico@ximian.com>
+ * Evolution calendar - Delete calendar component dialog
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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 DELETE_COMP_H
#define DELETE_COMP_H
-#include <gtk/gtkwidget.h>
-#include <cal-util/cal-component.h>
+#include <gtk/gtk.h>
+#include <libecal/libecal.h>
-gboolean delete_component_dialog (CalComponent *comp,
+gboolean delete_component_dialog (ECalComponent *comp,
gboolean consider_as_untitled,
- int n_comps, CalComponentVType vtype,
+ gint n_comps, ECalComponentVType vtype,
GtkWidget *widget);
+gboolean prompt_retract_dialog (ECalComponent *comp, gchar **retract_text, GtkWidget *parent, gboolean *retract);
#endif
diff --git a/calendar/gui/dialogs/delete-error.c b/calendar/gui/dialogs/delete-error.c
new file mode 100644
index 0000000000..313bcea82f
--- /dev/null
+++ b/calendar/gui/dialogs/delete-error.c
@@ -0,0 +1,126 @@
+/*
+ * Evolution calendar - Send calendar component dialog
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * JP Rosevear <jpr@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include "delete-error.h"
+
+/**
+ * delete_error_dialog:
+ *
+ * Shows any applicable error messages as the result of deleting and object
+ *
+ **/
+void
+delete_error_dialog (const GError *error,
+ ECalComponentVType vtype)
+{
+ GtkWidget *dialog;
+ const gchar *str;
+ const gchar *icon_name = NULL;
+
+ if (!error || error->domain != E_CLIENT_ERROR)
+ return;
+
+ switch (error->code) {
+ case E_CLIENT_ERROR_DBUS_ERROR:
+ switch (vtype) {
+ case E_CAL_COMPONENT_EVENT:
+ /* Translators: The '%s' is replaced with a detailed error message */
+ str = _("The event could not be deleted due to a dbus error: %s");
+ break;
+ case E_CAL_COMPONENT_TODO:
+ /* Translators: The '%s' is replaced with a detailed error message */
+ str = _("The task could not be deleted due to a dbus error: %s");
+ break;
+ case E_CAL_COMPONENT_JOURNAL:
+ /* Translators: The '%s' is replaced with a detailed error message */
+ str = _("The memo could not be deleted due to a dbus error: %s");
+ break;
+ default:
+ /* Translators: The '%s' is replaced with a detailed error message */
+ str = _("The item could not be deleted due to a dbus error: %s");
+ break;
+ }
+ break;
+ case E_CLIENT_ERROR_PERMISSION_DENIED:
+ switch (vtype) {
+ case E_CAL_COMPONENT_EVENT:
+ str = _("The event could not be deleted because permission was denied");
+ break;
+ case E_CAL_COMPONENT_TODO:
+ str = _("The task could not be deleted because permission was denied");
+ break;
+ case E_CAL_COMPONENT_JOURNAL:
+ str = _("The memo could not be deleted because permission was denied");
+ break;
+ default:
+ str = _("The item could not be deleted because permission was denied");
+ break;
+ }
+ break;
+ case E_CLIENT_ERROR_OTHER_ERROR:
+ switch (vtype) {
+ case E_CAL_COMPONENT_EVENT:
+ /* Translators: The '%s' is replaced with a detailed error message */
+ str = _("The event could not be deleted due to an error: %s");
+ break;
+ case E_CAL_COMPONENT_TODO:
+ /* Translators: The '%s' is replaced with a detailed error message */
+ str = _("The task could not be deleted due to an error: %s");
+ break;
+ case E_CAL_COMPONENT_JOURNAL:
+ /* Translators: The '%s' is replaced with a detailed error message */
+ str = _("The memo could not be deleted due to an error: %s");
+ break;
+ default:
+ /* Translators: The '%s' is replaced with a detailed error message */
+ str = _("The item could not be deleted due to an error: %s");
+ break;
+ }
+ break;
+ default:
+ /* If not found, we don't care - its gone anyhow */
+ return;
+ }
+
+ dialog = gtk_message_dialog_new (
+ NULL, GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK, str, error->message);
+ if (vtype == E_CAL_COMPONENT_EVENT)
+ icon_name = "x-office-calendar";
+ else if (vtype == E_CAL_COMPONENT_TODO)
+ icon_name = "stock_todo";
+
+ if (icon_name)
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), icon_name);
+
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
diff --git a/calendar/gui/dialogs/delete-error.h b/calendar/gui/dialogs/delete-error.h
new file mode 100644
index 0000000000..9aa3ff8376
--- /dev/null
+++ b/calendar/gui/dialogs/delete-error.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * Evolution calendar - Send calendar component dialog
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * JP Rosevear <jpr@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef DELETE_ERROR_H
+#define DELETE_ERROR_H
+
+#include <libecal/libecal.h>
+
+void delete_error_dialog (const GError *error, ECalComponentVType vtype);
+
+#endif
diff --git a/calendar/gui/dialogs/e-delegate-dialog.c b/calendar/gui/dialogs/e-delegate-dialog.c
index d37fbce51c..366d978e0e 100644
--- a/calendar/gui/dialogs/e-delegate-dialog.c
+++ b/calendar/gui/dialogs/e-delegate-dialog.c
@@ -1,220 +1,165 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* Evolution calendar - Delegate selector dialog
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Damon Chaplin <damon@ximian.com>
+/*
+ * Evolution calendar - Delegate selector dialog
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Damon Chaplin <damon@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
-#include <liboaf/liboaf.h>
-#include <bonobo/bonobo-control.h>
-#include <bonobo/bonobo-exception.h>
-#include <bonobo/bonobo-widget.h>
-#include <gtk/gtksignal.h>
-#include <gtk/gtkcombo.h>
-#include <gtk/gtkentry.h>
-#include <gtk/gtklabel.h>
-#include <gnome.h>
-#include <ical.h>
-#include <glade/glade.h>
-#include <widgets/misc/e-map.h>
-#include <ebook/e-destination.h>
-#include "Evolution-Addressbook-SelectNames.h"
+#endif
+
+#include <gtk/gtk.h>
+#include <libical/ical.h>
+#include <libebook/libebook.h>
+
+#include "e-util/e-util.h"
+#include "e-util/e-util-private.h"
#include "e-delegate-dialog.h"
+#define E_DELEGATE_DIALOG_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_DELEGATE_DIALOG, EDelegateDialogPrivate))
+
struct _EDelegateDialogPrivate {
- char *name;
- char *address;
+ gchar *name;
+ gchar *address;
- /* Glade XML data */
- GladeXML *xml;
+ GtkBuilder *builder;
- /* Widgets from the Glade file */
+ /* Widgets from the UI file */
GtkWidget *app;
GtkWidget *hbox;
GtkWidget *addressbook;
- GNOME_Evolution_Addressbook_SelectNames corba_select_names;
- GtkWidget *entry;
+ ENameSelector *name_selector;
+ GtkWidget *entry;
};
-#define SELECT_NAMES_OAFID "OAFIID:GNOME_Evolution_Addressbook_SelectNames"
-static const char *section_name = "Delegate To";
-
-static void e_delegate_dialog_class_init (EDelegateDialogClass *class);
-static void e_delegate_dialog_init (EDelegateDialog *edd);
-static void e_delegate_dialog_destroy (GtkObject *object);
+static const gchar *section_name = "Delegate To";
static gboolean get_widgets (EDelegateDialog *edd);
static void addressbook_clicked_cb (GtkWidget *widget, gpointer data);
+static void addressbook_response_cb (GtkWidget *widget, gint response, gpointer data);
-static GtkObjectClass *parent_class;
+G_DEFINE_TYPE (EDelegateDialog, e_delegate_dialog, G_TYPE_OBJECT)
-
-GtkType
-e_delegate_dialog_get_type (void)
+static void
+e_delegate_dialog_finalize (GObject *object)
{
- static GtkType e_delegate_dialog_type = 0;
-
- if (!e_delegate_dialog_type) {
- static const GtkTypeInfo e_delegate_dialog_info = {
- "EDelegateDialog",
- sizeof (EDelegateDialog),
- sizeof (EDelegateDialogClass),
- (GtkClassInitFunc) e_delegate_dialog_class_init,
- (GtkObjectInitFunc) e_delegate_dialog_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- e_delegate_dialog_type = gtk_type_unique (GTK_TYPE_OBJECT,
- &e_delegate_dialog_info);
- }
+ EDelegateDialogPrivate *priv;
+ GtkWidget *dialog;
- return e_delegate_dialog_type;
-}
+ priv = E_DELEGATE_DIALOG_GET_PRIVATE (object);
-/* Class initialization function for the event editor */
-static void
-e_delegate_dialog_class_init (EDelegateDialogClass *class)
-{
- GtkObjectClass *object_class;
+ e_name_selector_cancel_loading (priv->name_selector);
+ g_object_unref (priv->name_selector);
- object_class = (GtkObjectClass *) class;
+ /* Destroy the actual dialog. */
+ dialog = e_delegate_dialog_get_toplevel (E_DELEGATE_DIALOG (object));
+ gtk_widget_destroy (dialog);
- parent_class = gtk_type_class (GTK_TYPE_OBJECT);
+ g_free (priv->address);
- object_class->destroy = e_delegate_dialog_destroy;
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_delegate_dialog_parent_class)->finalize (object);
}
-/* Object initialization function for the event editor */
static void
-e_delegate_dialog_init (EDelegateDialog *edd)
+e_delegate_dialog_class_init (EDelegateDialogClass *class)
{
- EDelegateDialogPrivate *priv;
+ GObjectClass *object_class;
- priv = g_new0 (EDelegateDialogPrivate, 1);
- edd->priv = priv;
+ g_type_class_add_private (class, sizeof (EDelegateDialogPrivate));
- priv->address = NULL;
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = e_delegate_dialog_finalize;
}
-/* Destroy handler for the event editor */
static void
-e_delegate_dialog_destroy (GtkObject *object)
+e_delegate_dialog_init (EDelegateDialog *edd)
{
- EDelegateDialog *edd;
- EDelegateDialogPrivate *priv;
- GtkWidget *dialog;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (E_IS_DELEGATE_DIALOG (object));
-
- edd = E_DELEGATE_DIALOG (object);
- priv = edd->priv;
-
- /* Destroy the actual dialog. */
- dialog = e_delegate_dialog_get_toplevel (edd);
- gtk_widget_destroy (dialog);
-
- g_free (priv->address);
- priv->address = NULL;
-
- g_free (priv);
- edd->priv = NULL;
-
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+ edd->priv = E_DELEGATE_DIALOG_GET_PRIVATE (edd);
}
-
EDelegateDialog *
-e_delegate_dialog_construct (EDelegateDialog *edd, const char *name, const char *address)
+e_delegate_dialog_construct (EDelegateDialog *edd,
+ EClientCache *client_cache,
+ const gchar *name,
+ const gchar *address)
{
EDelegateDialogPrivate *priv;
+ EDestinationStore *destination_store;
EDestination *dest;
- EDestination *destv[2] = {NULL, NULL};
- Bonobo_Control corba_control;
- CORBA_Environment ev;
+ ENameSelectorModel *name_selector_model;
+ ENameSelectorDialog *name_selector_dialog;
- g_return_val_if_fail (edd != NULL, NULL);
g_return_val_if_fail (E_IS_DELEGATE_DIALOG (edd), NULL);
+ g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL);
priv = edd->priv;
/* Load the content widgets */
- priv->xml = glade_xml_new (EVOLUTION_GLADEDIR "/e-delegate-dialog.glade",
- NULL);
- if (!priv->xml) {
- g_message ("e_delegate_dialog_construct(): Could not load the Glade XML file!");
- goto error;
- }
+ priv->builder = gtk_builder_new ();
+ e_load_ui_builder_definition (priv->builder, "e-delegate-dialog.ui");
if (!get_widgets (edd)) {
g_message ("e_delegate_dialog_construct(): Could not find all widgets in the XML file!");
goto error;
}
-
- CORBA_exception_init (&ev);
-
- priv->corba_select_names = oaf_activate_from_id (SELECT_NAMES_OAFID, 0, NULL, &ev);
- GNOME_Evolution_Addressbook_SelectNames_addSectionWithLimit (priv->corba_select_names,
- section_name,
- section_name,
- 1, &ev);
-
- if (BONOBO_EX (&ev)) {
- g_message ("e_delegate_dialog_construct(): Unable to add section!");
- goto error;
- }
- corba_control = GNOME_Evolution_Addressbook_SelectNames_getEntryBySection (priv->corba_select_names,
- section_name, &ev);
+ priv->name_selector = e_name_selector_new (client_cache);
+ e_name_selector_load_books (priv->name_selector);
+ name_selector_model = e_name_selector_peek_model (priv->name_selector);
+ e_name_selector_model_add_section (name_selector_model, section_name, section_name, NULL);
- if (BONOBO_EX (&ev)) {
- g_message ("e_delegate_dialog_construct(): Unable to get addressbook entry!");
- goto error;
- }
-
- CORBA_exception_free (&ev);
-
- priv->entry = bonobo_widget_new_control_from_objref (corba_control, CORBA_OBJECT_NIL);
+ priv->entry = GTK_WIDGET (e_name_selector_peek_section_entry (priv->name_selector, section_name));
gtk_widget_show (priv->entry);
- gtk_box_pack_start (GTK_BOX (priv->hbox), priv->entry, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->entry, TRUE, TRUE, 6);
dest = e_destination_new ();
- destv[0] = dest;
+
if (name != NULL && *name)
e_destination_set_name (dest, name);
if (address != NULL && *address)
e_destination_set_email (dest, address);
- bonobo_widget_set_property (BONOBO_WIDGET (priv->entry), "destinations", e_destination_exportv (destv), NULL);
- gtk_object_unref (GTK_OBJECT (dest));
-
- gtk_signal_connect (GTK_OBJECT (priv->addressbook), "clicked",
- GTK_SIGNAL_FUNC (addressbook_clicked_cb), edd);
+
+ e_name_selector_model_peek_section (name_selector_model, section_name, NULL, &destination_store);
+ e_destination_store_append_destination (destination_store, dest);
+ g_object_unref (dest);
+
+ g_signal_connect (
+ priv->addressbook, "clicked",
+ G_CALLBACK (addressbook_clicked_cb), edd);
+
+ name_selector_dialog = e_name_selector_peek_dialog (priv->name_selector);
+ g_signal_connect (
+ name_selector_dialog, "response",
+ G_CALLBACK (addressbook_response_cb), edd);
return edd;
error:
- gtk_object_unref (GTK_OBJECT (edd));
+ g_object_unref (edd);
return NULL;
}
@@ -225,11 +170,9 @@ get_widgets (EDelegateDialog *edd)
priv = edd->priv;
-#define GW(name) glade_xml_get_widget (priv->xml, name)
-
- priv->app = GW ("delegate-dialog");
- priv->hbox = GW ("delegate-hbox");
- priv->addressbook = GW ("addressbook");
+ priv->app = e_builder_get_widget (priv->builder, "delegate-dialog");
+ priv->hbox = e_builder_get_widget (priv->builder, "delegate-hbox");
+ priv->addressbook = e_builder_get_widget (priv->builder, "addressbook");
return (priv->app
&& priv->hbox
@@ -237,22 +180,31 @@ get_widgets (EDelegateDialog *edd)
}
static void
-addressbook_clicked_cb (GtkWidget *widget, gpointer data)
+addressbook_clicked_cb (GtkWidget *widget,
+ gpointer data)
+{
+ EDelegateDialog *edd = data;
+
+ e_name_selector_show_dialog (
+ edd->priv->name_selector,
+ e_delegate_dialog_get_toplevel (edd));
+}
+
+static void
+addressbook_response_cb (GtkWidget *widget,
+ gint response,
+ gpointer data)
{
EDelegateDialog *edd = data;
EDelegateDialogPrivate *priv;
- CORBA_Environment ev;
-
- priv = edd->priv;
+ ENameSelectorDialog *name_selector_dialog;
- CORBA_exception_init (&ev);
+ priv = edd->priv;
- GNOME_Evolution_Addressbook_SelectNames_activateDialog (priv->corba_select_names, section_name, &ev);
-
- CORBA_exception_free (&ev);
+ name_selector_dialog = e_name_selector_peek_dialog (priv->name_selector);
+ gtk_widget_hide (GTK_WIDGET (name_selector_dialog));
}
-
/**
* e_delegate_dialog_new:
*
@@ -262,79 +214,85 @@ addressbook_clicked_cb (GtkWidget *widget, gpointer data)
* editor could not be created.
**/
EDelegateDialog *
-e_delegate_dialog_new (const char *name, const char *address)
+e_delegate_dialog_new (EClientCache *client_cache,
+ const gchar *name,
+ const gchar *address)
{
EDelegateDialog *edd;
- edd = E_DELEGATE_DIALOG (gtk_type_new (E_TYPE_DELEGATE_DIALOG));
- return e_delegate_dialog_construct (E_DELEGATE_DIALOG (edd), name, address);
+ g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL);
+
+ edd = g_object_new (E_TYPE_DELEGATE_DIALOG, NULL);
+
+ return e_delegate_dialog_construct (
+ E_DELEGATE_DIALOG (edd), client_cache, name, address);
}
-char *
-e_delegate_dialog_get_delegate (EDelegateDialog *edd)
+gchar *
+e_delegate_dialog_get_delegate (EDelegateDialog *edd)
{
EDelegateDialogPrivate *priv;
- EDestination **destv;
- char *string = NULL;
-
- g_return_val_if_fail (edd != NULL, NULL);
+ ENameSelectorModel *name_selector_model;
+ EDestinationStore *destination_store;
+ GList *destinations;
+ EDestination *destination;
+
g_return_val_if_fail (E_IS_DELEGATE_DIALOG (edd), NULL);
priv = edd->priv;
-
- bonobo_widget_get_property (BONOBO_WIDGET (priv->entry), "destinations", &string, NULL);
- destv = e_destination_importv (string);
-
- if (destv && destv[0] != NULL) {
+
+ name_selector_model = e_name_selector_peek_model (priv->name_selector);
+ e_name_selector_model_peek_section (name_selector_model, section_name, NULL, &destination_store);
+ destinations = e_destination_store_list_destinations (destination_store);
+ if (!destinations)
+ return NULL;
+
+ destination = destinations->data;
+
+ if (destination) {
g_free (priv->address);
- priv->address = g_strdup (e_destination_get_email (destv[0]));
- g_free (destv);
+ priv->address = g_strdup (e_destination_get_email (destination));
}
-
- g_free (string);
-
+
+ g_list_free (destinations);
return g_strdup (priv->address);
}
-
-char *
-e_delegate_dialog_get_delegate_name (EDelegateDialog *edd)
+gchar *
+e_delegate_dialog_get_delegate_name (EDelegateDialog *edd)
{
EDelegateDialogPrivate *priv;
- EDestination **destv;
- char *string = NULL;
-
- g_return_val_if_fail (edd != NULL, NULL);
+ ENameSelectorModel *name_selector_model;
+ EDestinationStore *destination_store;
+ GList *destinations;
+ EDestination *destination;
+
g_return_val_if_fail (E_IS_DELEGATE_DIALOG (edd), NULL);
priv = edd->priv;
- bonobo_widget_get_property (BONOBO_WIDGET (priv->entry), "destinations", &string, NULL);
- destv = e_destination_importv (string);
-
- g_message ("importv: [%s]", string);
-
- if (destv && destv[0] != NULL) {
+ name_selector_model = e_name_selector_peek_model (priv->name_selector);
+ e_name_selector_model_peek_section (name_selector_model, section_name, NULL, &destination_store);
+ destinations = e_destination_store_list_destinations (destination_store);
+ if (!destinations)
+ return NULL;
+
+ destination = destinations->data;
+
+ if (destination) {
g_free (priv->name);
- priv->name = g_strdup (e_destination_get_name (destv[0]));
- g_free (destv);
+ priv->name = g_strdup (e_destination_get_name (destination));
}
-
- g_free (string);
-
+
+ g_list_free (destinations);
return g_strdup (priv->name);
}
-GtkWidget*
-e_delegate_dialog_get_toplevel (EDelegateDialog *edd)
+GtkWidget *
+e_delegate_dialog_get_toplevel (EDelegateDialog *edd)
{
- EDelegateDialogPrivate *priv;
-
- g_return_val_if_fail (edd != NULL, NULL);
g_return_val_if_fail (E_IS_DELEGATE_DIALOG (edd), NULL);
- priv = edd->priv;
-
- return priv->app;
+ return edd->priv->app;
}
diff --git a/calendar/gui/dialogs/e-delegate-dialog.glade b/calendar/gui/dialogs/e-delegate-dialog.glade
deleted file mode 100644
index 394c191682..0000000000
--- a/calendar/gui/dialogs/e-delegate-dialog.glade
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0"?>
-<GTK-Interface>
-
-<project>
- <name>timezone-dialog</name>
- <program_name>timezone-dialog</program_name>
- <directory></directory>
- <source_directory>src</source_directory>
- <pixmaps_directory>pixmaps</pixmaps_directory>
- <language>C</language>
- <gnome_support>True</gnome_support>
- <gettext_support>True</gettext_support>
-</project>
-
-<widget>
- <class>GnomeDialog</class>
- <name>delegate-dialog</name>
- <visible>False</visible>
- <title>Enter Delegate</title>
- <type>GTK_WINDOW_TOPLEVEL</type>
- <position>GTK_WIN_POS_NONE</position>
- <modal>False</modal>
- <allow_shrink>False</allow_shrink>
- <allow_grow>True</allow_grow>
- <auto_shrink>False</auto_shrink>
- <auto_close>True</auto_close>
- <hide_on_close>True</hide_on_close>
-
- <widget>
- <class>GtkVBox</class>
- <child_name>GnomeDialog:vbox</child_name>
- <name>dialog-vbox1</name>
- <homogeneous>False</homogeneous>
- <spacing>8</spacing>
- <child>
- <padding>4</padding>
- <expand>True</expand>
- <fill>True</fill>
- </child>
-
- <widget>
- <class>GtkHButtonBox</class>
- <child_name>GnomeDialog:action_area</child_name>
- <name>dialog-action_area1</name>
- <layout_style>GTK_BUTTONBOX_END</layout_style>
- <spacing>8</spacing>
- <child_min_width>85</child_min_width>
- <child_min_height>27</child_min_height>
- <child_ipad_x>7</child_ipad_x>
- <child_ipad_y>0</child_ipad_y>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>True</fill>
- <pack>GTK_PACK_END</pack>
- </child>
-
- <widget>
- <class>GtkButton</class>
- <name>ok-button</name>
- <can_default>True</can_default>
- <has_default>True</has_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_OK</stock_button>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>cancel-button</name>
- <can_default>True</can_default>
- <can_focus>True</can_focus>
- <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button>
- </widget>
- </widget>
-
- <widget>
- <class>GtkHBox</class>
- <name>delegate-hbox</name>
- <homogeneous>False</homogeneous>
- <spacing>4</spacing>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
-
- <widget>
- <class>GtkLabel</class>
- <name>label3</name>
- <label>Delegate To:</label>
- <justify>GTK_JUSTIFY_CENTER</justify>
- <wrap>False</wrap>
- <xalign>0.5</xalign>
- <yalign>0.5</yalign>
- <xpad>0</xpad>
- <ypad>0</ypad>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- </child>
- </widget>
-
- <widget>
- <class>GtkButton</class>
- <name>addressbook</name>
- <can_focus>True</can_focus>
- <label>Addressbook...</label>
- <child>
- <padding>0</padding>
- <expand>False</expand>
- <fill>False</fill>
- <pack>GTK_PACK_END</pack>
- </child>
- </widget>
- </widget>
- </widget>
-</widget>
-
-</GTK-Interface>
diff --git a/calendar/gui/dialogs/e-delegate-dialog.h b/calendar/gui/dialogs/e-delegate-dialog.h
index 311d22b4c7..8a9b38e5ca 100644
--- a/calendar/gui/dialogs/e-delegate-dialog.h
+++ b/calendar/gui/dialogs/e-delegate-dialog.h
@@ -1,73 +1,82 @@
-/* Evolution calendar - Delegate selector dialog
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: JP Rosevear <jpr@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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * JP Rosevear <jpr@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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_DELEGATE_DIALOG_H__
-#define __E_DELEGATE_DIALOG_H__
-
-#include <libgnome/gnome-defs.h>
-#include <gtk/gtkwidget.h>
-
-
-
-#define E_TYPE_DELEGATE_DIALOG (e_delegate_dialog_get_type ())
-#define E_DELEGATE_DIALOG(obj) (GTK_CHECK_CAST ((obj), E_TYPE_DELEGATE_DIALOG, EDelegateDialog))
-#define E_DELEGATE_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_DELEGATE_DIALOG, \
- EDelegateDialogClass))
-#define E_IS_DELEGATE_DIALOG(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_DELEGATE_DIALOG))
-#define E_IS_DELEGATE_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), E_TYPE_DELEGATE_DIALOG))
-
-
-typedef struct _EDelegateDialog EDelegateDialog;
-typedef struct _EDelegateDialogClass EDelegateDialogClass;
-typedef struct _EDelegateDialogPrivate EDelegateDialogPrivate;
+#ifndef E_DELEGATE_DIALOG_H
+#define E_DELEGATE_DIALOG_H
+
+#include <e-util/e-util.h>
+
+/* Standard GObject macros */
+#define E_TYPE_DELEGATE_DIALOG \
+ (e_delegate_dialog_get_type ())
+#define E_DELEGATE_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_DELEGATE_DIALOG, EDelegateDialog))
+#define E_DELEGATE_DIALOG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_DELEGATE_DIALOG, EDelegateDialogClass))
+#define E_IS_DELEGATE_DIALOG(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_DELEGATE_DIALOG))
+#define E_IS_DELEGATE_DIALOG_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_DELEGATE_DIALOG))
+#define E_DELEGATE_DIALOG_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_DELEGATE_DIALOG, EDelegateDialogClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EDelegateDialog EDelegateDialog;
+typedef struct _EDelegateDialogClass EDelegateDialogClass;
+typedef struct _EDelegateDialogPrivate EDelegateDialogPrivate;
struct _EDelegateDialog {
- GtkObject object;
-
- /* Private data */
+ GObject object;
EDelegateDialogPrivate *priv;
};
struct _EDelegateDialogClass {
- GtkObjectClass parent_class;
+ GObjectClass parent_class;
};
-GtkType e_delegate_dialog_get_type (void);
-
-EDelegateDialog* e_delegate_dialog_construct (EDelegateDialog *etd,
- const char *name,
- const char *address);
-
-EDelegateDialog* e_delegate_dialog_new (const char *name,
- const char *address);
-
-char* e_delegate_dialog_get_delegate (EDelegateDialog *etd);
-
-char* e_delegate_dialog_get_delegate_name (EDelegateDialog *etd);
-
-void e_delegate_dialog_set_delegate (EDelegateDialog *etd,
- const char *address);
-
-GtkWidget* e_delegate_dialog_get_toplevel (EDelegateDialog *etd);
-
-
-
-
-#endif /* __E_DELEGATE_DIALOG_H__ */
+GType e_delegate_dialog_get_type (void);
+EDelegateDialog *
+ e_delegate_dialog_construct (EDelegateDialog *etd,
+ EClientCache *client_cache,
+ const gchar *name,
+ const gchar *address);
+EDelegateDialog *
+ e_delegate_dialog_new (EClientCache *client_cache,
+ const gchar *name,
+ const gchar *address);
+gchar * e_delegate_dialog_get_delegate (EDelegateDialog *etd);
+gchar * e_delegate_dialog_get_delegate_name
+ (EDelegateDialog *etd);
+void e_delegate_dialog_set_delegate (EDelegateDialog *etd,
+ const gchar *address);
+GtkWidget * e_delegate_dialog_get_toplevel (EDelegateDialog *etd);
+
+G_END_DECLS
+
+#endif /* E_DELEGATE_DIALOG_H */
diff --git a/calendar/gui/dialogs/e-delegate-dialog.ui b/calendar/gui/dialogs/e-delegate-dialog.ui
new file mode 100644
index 0000000000..95356d95cb
--- /dev/null
+++ b/calendar/gui/dialogs/e-delegate-dialog.ui
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<!--*- mode: xml -*-->
+<interface>
+ <object class="GtkDialog" id="delegate-dialog">
+ <property name="title" translatable="yes">Enter Delegate</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">8</property>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <object class="GtkButton" id="cancel-button">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok-button">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="delegate-hbox">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Delegate To:</property>
+ <property name="use_underline">False</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">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="addressbook">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">Contacts...</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="-6">cancel-button</action-widget>
+ <action-widget response="-5">ok-button</action-widget>
+ </action-widgets>
+ </object>
+</interface>
diff --git a/calendar/gui/dialogs/e-send-options-utils.c b/calendar/gui/dialogs/e-send-options-utils.c
new file mode 100644
index 0000000000..8157e10fab
--- /dev/null
+++ b/calendar/gui/dialogs/e-send-options-utils.c
@@ -0,0 +1,246 @@
+/*
+ * Evolution calendar - Timezone selector dialog
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Damon Chaplin <damon@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-send-options-utils.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+void
+e_send_options_utils_set_default_data (ESendOptionsDialog *sod,
+ ESource *source,
+ const gchar *type)
+{
+ ESendOptionsGeneral *gopts = NULL;
+ ESendOptionsStatusTracking *sopts;
+ ESourceExtension *extension;
+ const gchar *extension_name;
+ gchar *value;
+
+ /* FIXME These is all GroupWise-specific settings.
+ * They absolutely do not belong here. */
+
+ extension_name = "GroupWise Backend";
+
+ if (!e_source_has_extension (source, extension_name))
+ return;
+
+ extension = e_source_get_extension (source, extension_name);
+
+ gopts = sod->data->gopts;
+ sopts = sod->data->sopts;
+
+ /* priority */
+ g_object_get (extension, "priority", &value, NULL);
+ if (value) {
+ if (!strcmp (value, "high"))
+ gopts->priority = E_PRIORITY_HIGH;
+ else if (!strcmp (value, "standard"))
+ gopts->priority = E_PRIORITY_STANDARD;
+ else if (!strcmp (value, "low"))
+ gopts->priority = E_PRIORITY_LOW;
+ else
+ gopts->priority = E_PRIORITY_UNDEFINED;
+ }
+ g_free (value);
+
+ /* Reply requested */
+ g_object_get (extension, "reply-requested", &value, NULL);
+ if (value) {
+ if (!strcmp (value, "none"))
+ gopts->reply_enabled = FALSE;
+ else if (!strcmp (value, "convinient")) {
+ gopts->reply_enabled = TRUE;
+ gopts->reply_convenient = TRUE;
+ } else {
+ gint i = atoi (value);
+ gopts->reply_within = i;
+ }
+ }
+ g_free (value);
+
+ /* Delay delivery */
+ g_object_get (extension, "delivery-delay", &value, NULL);
+ if (value) {
+ if (!strcmp (value, "none"))
+ gopts->delay_enabled = FALSE;
+ else {
+ gopts->delay_enabled = TRUE;
+ gopts->delay_until = icaltime_as_timet (icaltime_from_string (value));
+ }
+ }
+ g_free (value);
+
+ /* Expiration Date */
+ g_object_get (extension, "expiration", &value, NULL);
+ if (value) {
+ if (!strcmp (value, "none"))
+ gopts->expiration_enabled = FALSE;
+ else {
+ gint i = atoi (value);
+ if (i == 0)
+ gopts->expiration_enabled = FALSE;
+ else
+ gopts->expiration_enabled = TRUE;
+ gopts->expire_after = i;
+ }
+ }
+ g_free (value);
+
+ /* status tracking */
+ g_object_get (extension, "status-tracking", &value, NULL);
+ if (value) {
+ if (!strcmp (value, "none"))
+ sopts->tracking_enabled = FALSE;
+ else {
+ sopts->tracking_enabled = TRUE;
+ if (!strcmp (value, "delivered"))
+ sopts->track_when = E_DELIVERED;
+ else if (!strcmp (value, "delivered-opened"))
+ sopts->track_when = E_DELIVERED_OPENED;
+ else
+ sopts->track_when = E_ALL;
+ }
+ }
+ g_free (value);
+
+ /* Return Notifications */
+
+ g_object_get (extension, "return-open", &value, NULL);
+ if (value) {
+ if (!strcmp (value, "none"))
+ sopts->opened = E_RETURN_NOTIFY_NONE;
+ else
+ sopts->opened = E_RETURN_NOTIFY_MAIL;
+ }
+ g_free (value);
+
+ g_object_get (extension, "return-accept", &value, NULL);
+ if (value) {
+ if (!strcmp (value, "none"))
+ sopts->accepted = E_RETURN_NOTIFY_NONE;
+ else
+ sopts->accepted = E_RETURN_NOTIFY_MAIL;
+ }
+ g_free (value);
+
+ g_object_get (extension, "return-decline", &value, NULL);
+ if (value) {
+ if (!strcmp (value, "none"))
+ sopts->declined = E_RETURN_NOTIFY_NONE;
+ else
+ sopts->declined = E_RETURN_NOTIFY_MAIL;
+ }
+ g_free (value);
+
+ g_object_get (extension, "return-complete", &value, NULL);
+ if (value) {
+ if (!strcmp (value, "none"))
+ sopts->completed = E_RETURN_NOTIFY_NONE;
+ else
+ sopts->completed = E_RETURN_NOTIFY_MAIL;
+ }
+ g_free (value);
+}
+
+void
+e_send_options_utils_fill_component (ESendOptionsDialog *sod,
+ ECalComponent *comp,
+ icaltimezone *zone)
+{
+ gint i = 1;
+ icalproperty *prop;
+ icalcomponent *icalcomp;
+ ESendOptionsGeneral *gopts;
+ ESendOptionsStatusTracking *sopts;
+
+ gopts = sod->data->gopts;
+ sopts = sod->data->sopts;
+
+ e_cal_component_set_sequence (comp, &i);
+ icalcomp = e_cal_component_get_icalcomponent (comp);
+
+ if (e_send_options_get_need_general_options (sod)) {
+ prop = icalproperty_new_x ((const gchar *) g_strdup_printf ("%d", gopts->priority));
+ icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-PRIORITY");
+ icalcomponent_add_property (icalcomp, prop);
+
+ if (gopts->reply_enabled) {
+ if (gopts->reply_convenient)
+ prop = icalproperty_new_x ("convenient");
+ else
+ prop = icalproperty_new_x ((const gchar *) g_strdup_printf ("%d", gopts->reply_within));
+ icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-REPLY");
+ icalcomponent_add_property (icalcomp, prop);
+ }
+
+ if (gopts->expiration_enabled && gopts->expire_after) {
+ prop = icalproperty_new_x ((const gchar *) g_strdup_printf ("%d", gopts->expire_after));
+ icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-EXPIRE");
+ icalcomponent_add_property (icalcomp, prop);
+ }
+
+ if (gopts->delay_enabled) {
+ struct icaltimetype temp;
+ gchar *str;
+
+ temp = icaltime_from_timet_with_zone (gopts->delay_until, FALSE, zone);
+
+ str = icaltime_as_ical_string_r (temp);
+ prop = icalproperty_new_x (str);
+ g_free (str);
+ icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-DELAY");
+ icalcomponent_add_property (icalcomp, prop);
+ }
+ }
+
+ if (sopts->tracking_enabled)
+ prop = icalproperty_new_x ((const gchar *) g_strdup_printf ("%d", sopts->track_when));
+ else
+ prop = icalproperty_new_x ("0");
+
+ icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-TRACKINFO");
+ icalcomponent_add_property (icalcomp, prop);
+
+ prop = icalproperty_new_x ((const gchar *) g_strdup_printf ("%d", sopts->opened));
+ icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-OPENED");
+ icalcomponent_add_property (icalcomp, prop);
+
+ prop = icalproperty_new_x ((const gchar *) g_strdup_printf ("%d", sopts->accepted));
+ icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-ACCEPTED");
+ icalcomponent_add_property (icalcomp, prop);
+
+ prop = icalproperty_new_x ((const gchar *) g_strdup_printf ("%d", sopts->declined));
+ icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-DECLINED");
+ icalcomponent_add_property (icalcomp, prop);
+
+ prop = icalproperty_new_x ((const gchar *) g_strdup_printf ("%d", sopts->completed));
+ icalproperty_set_x_name (prop, "X-EVOLUTION-OPTIONS-COMPLETED");
+ icalcomponent_add_property (icalcomp, prop);
+}
+
diff --git a/calendar/gui/dialogs/e-send-options-utils.h b/calendar/gui/dialogs/e-send-options-utils.h
new file mode 100644
index 0000000000..6d365b3424
--- /dev/null
+++ b/calendar/gui/dialogs/e-send-options-utils.h
@@ -0,0 +1,41 @@
+/*
+ * Evolution calendar - Timezone selector dialog
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Damon Chaplin <damon@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __E_SENDOPTIONS_UTILS_H__
+#define __E_SENDOPTIONS_UTILS_H__
+
+#include <libecal/libecal.h>
+
+#include <e-util/e-util.h>
+
+void e_send_options_utils_set_default_data
+ (ESendOptionsDialog *sod,
+ ESource *source,
+ const gchar *type);
+void e_send_options_utils_fill_component
+ (ESendOptionsDialog *sod,
+ ECalComponent *comp,
+ icaltimezone *zone);
+
+#endif
diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c
index 829bebbe1e..16f83d1e84 100644
--- a/calendar/gui/dialogs/event-editor.c
+++ b/calendar/gui/dialogs/event-editor.c
@@ -1,522 +1,803 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-/* Evolution calendar - Event editor dialog
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Miguel de Icaza <miguel@ximian.com>
- * Federico Mena-Quintero <federico@ximian.com>
- * Seth Alves <alves@hungry.com>
+/*
+ * Evolution calendar - Event editor dialog
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Miguel de Icaza <miguel@ximian.com>
+ * Federico Mena-Quintero <federico@ximian.com>
+ * Seth Alves <alves@hungry.com>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
+
#include <string.h>
-#include <glade/glade.h>
-#include <gal/widgets/e-unicode.h>
-#include <libgnome/gnome-i18n.h>
-#include <widgets/misc/e-dateedit.h>
+#include <glib/gi18n.h>
#include "event-page.h"
-#include "alarm-page.h"
#include "recurrence-page.h"
-#include "meeting-page.h"
#include "schedule-page.h"
#include "cancel-comp.h"
#include "event-editor.h"
+#define EVENT_EDITOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), TYPE_EVENT_EDITOR, EventEditorPrivate))
+
struct _EventEditorPrivate {
EventPage *event_page;
- AlarmPage *alarm_page;
RecurrencePage *recur_page;
- MeetingPage *meet_page;
+ GtkWidget *recur_window;
SchedulePage *sched_page;
+ GtkWidget *sched_window;
- EMeetingModel *model;
-
+ EMeetingStore *model;
gboolean meeting_shown;
- gboolean updating;
+ gboolean updating;
};
-
+/* Extends the UI definition in CompEditor */
+static const gchar *ui =
+"<ui>"
+" <menubar action='main-menu'>"
+" <menu action='view-menu'>"
+" <menuitem action='view-type'/>"
+" <menuitem action='view-status'/>"
+" <menuitem action='view-role'/>"
+" <menuitem action='view-rsvp'/>"
+" <separator/>"
+" <menuitem action='view-time-zone'/>"
+" <menuitem action='view-categories'/>"
+" </menu>"
+" <menu action='insert-menu'>"
+" <menuitem action='send-options'/>"
+" </menu>"
+" <menu action='options-menu'>"
+" <menuitem action='alarms'/>"
+" <menuitem action='show-time-busy'/>"
+" <menuitem action='recurrence'/>"
+" <menuitem action='all-day-event'/>"
+" <menuitem action='free-busy'/>"
+" <menu action='classification-menu'>"
+" <menuitem action='classify-public'/>"
+" <menuitem action='classify-private'/>"
+" <menuitem action='classify-confidential'/>"
+" </menu>"
+" </menu>"
+" </menubar>"
+" <toolbar name='main-toolbar'>"
+" <placeholder name='content'>\n"
+" <toolitem action='alarms'/>\n"
+" <toolitem action='show-time-busy'/>\n"
+" <toolitem action='recurrence'/>\n"
+" <toolitem action='all-day-event'/>\n"
+" <toolitem action='free-busy'/>\n"
+" </placeholder>"
+" </toolbar>"
+"</ui>";
+
+static void event_editor_edit_comp (CompEditor *editor,
+ ECalComponent *comp);
+static gboolean event_editor_send_comp (CompEditor *editor,
+ ECalComponentItipMethod method,
+ gboolean strip_alarms);
+
+G_DEFINE_TYPE (EventEditor, event_editor, TYPE_COMP_EDITOR)
+
+static void
+create_schedule_page (CompEditor *editor)
+{
+ EventEditorPrivate *priv;
+ ENameSelector *name_selector;
+ CompEditorPage *page;
+ GtkWidget *content_area;
-static void event_editor_class_init (EventEditorClass *class);
-static void event_editor_init (EventEditor *ee);
-static void event_editor_set_cal_client (CompEditor *editor, CalClient *client);
-static void event_editor_edit_comp (CompEditor *editor, CalComponent *comp);
-static gboolean event_editor_send_comp (CompEditor *editor, CalComponentItipMethod method);
-static void event_editor_destroy (GtkObject *object);
+ priv = EVENT_EDITOR_GET_PRIVATE (editor);
-static void schedule_meeting_cmd (GtkWidget *widget, gpointer data);
-static void refresh_meeting_cmd (GtkWidget *widget, gpointer data);
-static void cancel_meeting_cmd (GtkWidget *widget, gpointer data);
-static void forward_cmd (GtkWidget *widget, gpointer data);
+ priv->sched_window = gtk_dialog_new_with_buttons (
+ _("Free/Busy"), GTK_WINDOW (editor), GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
-static void model_row_changed_cb (ETableModel *etm, int row, gpointer data);
-static void row_count_changed_cb (ETableModel *etm, int row, int count, gpointer data);
+ content_area =
+ gtk_dialog_get_content_area (GTK_DIALOG (priv->sched_window));
-static EPixmap pixmaps [] = {
- E_PIXMAP ("/Toolbar/Actions/ActionScheduleMeeting", "schedule-meeting-24.png"),
- E_PIXMAP_END
-};
+ g_signal_connect (
+ priv->sched_window, "response",
+ G_CALLBACK (gtk_widget_hide), NULL);
+ g_signal_connect (
+ priv->sched_window, "delete-event",
+ G_CALLBACK (gtk_widget_hide_on_delete), NULL);
-static BonoboUIVerb verbs [] = {
- BONOBO_UI_UNSAFE_VERB ("ActionScheduleMeeting", schedule_meeting_cmd),
- BONOBO_UI_UNSAFE_VERB ("ActionRefreshMeeting", refresh_meeting_cmd),
- BONOBO_UI_UNSAFE_VERB ("ActionCancelMeeting", cancel_meeting_cmd),
- BONOBO_UI_UNSAFE_VERB ("ActionForward", forward_cmd),
+ priv->sched_page = schedule_page_new (priv->model, editor);
+ page = COMP_EDITOR_PAGE (priv->sched_page);
+ gtk_container_add (
+ GTK_CONTAINER (content_area),
+ comp_editor_page_get_widget (page));
- BONOBO_UI_VERB_END
-};
+ name_selector = event_page_get_name_selector (priv->event_page);
+ schedule_page_set_name_selector (priv->sched_page, name_selector);
-static CompEditorClass *parent_class;
+ comp_editor_append_page (editor, page, NULL, FALSE);
+ schedule_page_update_free_busy (priv->sched_page);
-
+ gtk_widget_show_all (priv->sched_window);
+}
-/**
- * event_editor_get_type:
- *
- * Registers the #EventEditor class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the #EventEditor class.
- **/
-GtkType
-event_editor_get_type (void)
+static void
+action_alarms_cb (GtkAction *action,
+ EventEditor *editor)
{
- static GtkType event_editor_type = 0;
-
- if (!event_editor_type) {
- static const GtkTypeInfo event_editor_info = {
- "EventEditor",
- sizeof (EventEditor),
- sizeof (EventEditorClass),
- (GtkClassInitFunc) event_editor_class_init,
- (GtkObjectInitFunc) event_editor_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
-
- event_editor_type = gtk_type_unique (TYPE_COMP_EDITOR,
- &event_editor_info);
- }
-
- return event_editor_type;
+ event_page_show_alarm (editor->priv->event_page);
}
-/* Class initialization function for the event editor */
static void
-event_editor_class_init (EventEditorClass *klass)
+action_all_day_event_cb (GtkToggleAction *action,
+ EventEditor *editor)
{
- GtkObjectClass *object_class;
- CompEditorClass *editor_class;
-
- object_class = (GtkObjectClass *) klass;
- editor_class = (CompEditorClass *) klass;
+ gboolean active;
+ GtkAction *action_show_busy;
+ CompEditor *comp_editor = COMP_EDITOR (editor);
- parent_class = gtk_type_class (TYPE_COMP_EDITOR);
+ active = gtk_toggle_action_get_active (action);
+ event_page_set_all_day_event (editor->priv->event_page, active);
- editor_class->set_cal_client = event_editor_set_cal_client;
- editor_class->edit_comp = event_editor_edit_comp;
- editor_class->send_comp = event_editor_send_comp;
-
- object_class->destroy = event_editor_destroy;
+ action_show_busy = comp_editor_get_action (comp_editor, "show-time-busy");
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action_show_busy), !active);
+ event_page_set_show_time_busy (editor->priv->event_page, !active);
}
static void
-set_menu_sens (EventEditor *ee)
+action_free_busy_cb (GtkAction *action,
+ EventEditor *editor)
{
- EventEditorPrivate *priv;
- gboolean sens, existing, user, read_only;
-
- priv = ee->priv;
-
- existing = comp_editor_get_existing_org (COMP_EDITOR (ee));
- user = comp_editor_get_user_org (COMP_EDITOR (ee));
- read_only = cal_client_is_read_only (comp_editor_get_cal_client (COMP_EDITOR (ee)));
-
- sens = priv->meeting_shown;
- comp_editor_set_ui_prop (COMP_EDITOR (ee),
- "/commands/ActionScheduleMeeting",
- "sensitive", sens || read_only ? "0" : "1");
-
- sens = priv->meeting_shown && existing && !user && !read_only;
- comp_editor_set_ui_prop (COMP_EDITOR (ee),
- "/commands/ActionRefreshMeeting",
- "sensitive", sens ? "1" : "0");
-
- sens = priv->meeting_shown && existing && user && !read_only;
- comp_editor_set_ui_prop (COMP_EDITOR (ee),
- "/commands/ActionCancelMeeting",
- "sensitive", sens? "1" : "0");
-
- comp_editor_set_ui_prop (COMP_EDITOR (ee),
- "/commands/FileSave",
- "sensitive", read_only ? "0" : "1");
- comp_editor_set_ui_prop (COMP_EDITOR (ee),
- "/commands/FileSaveAndClose",
- "sensitive", read_only ? "0" : "1");
- comp_editor_set_ui_prop (COMP_EDITOR (ee),
- "/commands/FileDelete",
- "sensitive", read_only ? "0" : "1");
+ if (editor->priv->sched_window == NULL)
+ create_schedule_page (COMP_EDITOR (editor));
+ else
+ gtk_window_present (GTK_WINDOW (editor->priv->sched_window));
}
static void
-init_widgets (EventEditor *ee)
+action_recurrence_cb (GtkAction *action,
+ EventEditor *editor)
{
- EventEditorPrivate *priv;
-
- priv = ee->priv;
-
- gtk_signal_connect (GTK_OBJECT (priv->model), "model_row_changed",
- GTK_SIGNAL_FUNC (model_row_changed_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->model), "model_rows_inserted",
- GTK_SIGNAL_FUNC (row_count_changed_cb), ee);
- gtk_signal_connect (GTK_OBJECT (priv->model), "model_rows_deleted",
- GTK_SIGNAL_FUNC (row_count_changed_cb), ee);
+ gtk_widget_show (editor->priv->recur_window);
}
-/* Object initialization function for the event editor */
static void
-event_editor_init (EventEditor *ee)
+action_send_options_cb (GtkAction *action,
+ EventEditor *editor)
{
- EventEditorPrivate *priv;
-
- priv = g_new0 (EventEditorPrivate, 1);
- ee->priv = priv;
-
- priv->model = E_MEETING_MODEL (e_meeting_model_new ());
- priv->meeting_shown = TRUE;
- priv->updating = FALSE;
+ event_page_send_options_clicked_cb (editor->priv->event_page);
}
-EventEditor *
-event_editor_construct (EventEditor *ee, CalClient *client)
+static void
+action_show_time_busy_cb (GtkToggleAction *action,
+ EventEditor *editor)
{
- EventEditorPrivate *priv;
+ gboolean active;
+
+ active = gtk_toggle_action_get_active (action);
+ event_page_set_show_time_busy (editor->priv->event_page, active);
+}
- priv = ee->priv;
+static GtkActionEntry editable_entries[] = {
- priv->event_page = event_page_new ();
- comp_editor_append_page (COMP_EDITOR (ee),
- COMP_EDITOR_PAGE (priv->event_page),
- _("Appointment"));
+ { "alarms",
+ "appointment-soon",
+ N_("_Reminders"),
+ NULL,
+ N_("Set or unset reminders for this event"),
+ G_CALLBACK (action_alarms_cb) },
+};
- priv->alarm_page = alarm_page_new ();
- comp_editor_append_page (COMP_EDITOR (ee),
- COMP_EDITOR_PAGE (priv->alarm_page),
- _("Reminder"));
+static GtkToggleActionEntry editable_toggle_entries[] = {
- priv->recur_page = recurrence_page_new ();
- comp_editor_append_page (COMP_EDITOR (ee),
- COMP_EDITOR_PAGE (priv->recur_page),
- _("Recurrence"));
-
- priv->sched_page = schedule_page_new (priv->model);
- comp_editor_append_page (COMP_EDITOR (ee),
- COMP_EDITOR_PAGE (priv->sched_page),
- _("Scheduling"));
+ { "show-time-busy",
+ GTK_STOCK_DIALOG_ERROR,
+ N_("Show Time as _Busy"),
+ NULL,
+ N_("Toggles whether to show time as busy"),
+ G_CALLBACK (action_show_time_busy_cb),
+ FALSE }
+};
- priv->meet_page = meeting_page_new (priv->model, client);
- comp_editor_append_page (COMP_EDITOR (ee),
- COMP_EDITOR_PAGE (priv->meet_page),
- _("Meeting"));
+static GtkActionEntry event_entries[] = {
+
+ { "recurrence",
+ "stock_task-recurring",
+ N_("_Recurrence"),
+ NULL,
+ N_("Make this a recurring event"),
+ G_CALLBACK (action_recurrence_cb) },
+
+ { "send-options",
+ NULL,
+ N_("Send Options"),
+ NULL,
+ N_("Insert advanced send options"),
+ G_CALLBACK (action_send_options_cb) }
+};
- comp_editor_set_cal_client (COMP_EDITOR (ee), client);
+static GtkToggleActionEntry event_toggle_entries[] = {
- comp_editor_merge_ui (COMP_EDITOR (ee), "evolution-event-editor.xml", verbs, pixmaps);
+ { "all-day-event",
+ "stock_new-24h-appointment",
+ N_("All _Day Event"),
+ NULL,
+ N_("Toggles whether to have All Day Event"),
+ G_CALLBACK (action_all_day_event_cb),
+ FALSE },
+};
- init_widgets (ee);
- set_menu_sens (ee);
+static GtkActionEntry meeting_entries[] = {
- return ee;
-}
+ { "free-busy",
+ "query-free-busy",
+ N_("_Free/Busy"),
+ NULL,
+ N_("Query free / busy information for the attendees"),
+ G_CALLBACK (action_free_busy_cb) }
+};
static void
-event_editor_set_cal_client (CompEditor *editor, CalClient *client)
+event_editor_model_changed_cb (EventEditor *ee)
{
- EventEditor *ee;
- EventEditorPrivate *priv;
-
- ee = EVENT_EDITOR (editor);
- priv = ee->priv;
-
- e_meeting_model_set_cal_client (priv->model, client);
-
- if (parent_class->set_cal_client)
- parent_class->set_cal_client (editor, client);
+ if (!ee->priv->updating) {
+ comp_editor_set_changed (COMP_EDITOR (ee), TRUE);
+ comp_editor_set_needs_send (COMP_EDITOR (ee), TRUE);
+ }
}
-static void
-event_editor_edit_comp (CompEditor *editor, CalComponent *comp)
+static GObject *
+event_editor_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
{
- EventEditor *ee;
+ GObject *object;
+ CompEditor *editor;
+ CompEditorFlags flags;
+ CompEditorPage *page;
EventEditorPrivate *priv;
- CalComponentOrganizer organizer;
- GSList *attendees = NULL;
-
- ee = EVENT_EDITOR (editor);
- priv = ee->priv;
-
- priv->updating = TRUE;
-
- if (parent_class->edit_comp)
- parent_class->edit_comp (editor, comp);
+ GtkActionGroup *action_group;
+ GtkWidget *content_area;
+ EShell *shell;
+ ECalClient *client;
+ gboolean is_meeting;
+ GtkWidget *alarm_page;
+ GtkWidget *attendee_page;
+
+ /* Chain up to parent's constructor() method. */
+ object = G_OBJECT_CLASS (event_editor_parent_class)->constructor (
+ type, n_construct_properties, construct_properties);
+
+ editor = COMP_EDITOR (object);
+ priv = EVENT_EDITOR_GET_PRIVATE (object);
+
+ shell = comp_editor_get_shell (editor);
+
+ client = comp_editor_get_client (editor);
+ flags = comp_editor_get_flags (editor);
+ action_group = comp_editor_get_action_group (editor, "coordinated");
+
+ is_meeting = flags & COMP_EDITOR_MEETING;
+
+ gtk_action_group_set_visible (action_group, is_meeting);
+
+ priv->event_page = event_page_new (priv->model, editor);
+ comp_editor_append_page (
+ editor, COMP_EDITOR_PAGE (priv->event_page),
+ _("Appointment"), TRUE);
+
+ priv->recur_window = gtk_dialog_new_with_buttons (
+ _("Recurrence"), GTK_WINDOW (editor), GTK_DIALOG_MODAL,
+ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
+ g_signal_connect (
+ priv->recur_window, "response",
+ G_CALLBACK (gtk_widget_hide), NULL);
+ g_signal_connect (
+ priv->recur_window, "delete-event",
+ G_CALLBACK (gtk_widget_hide_on_delete), NULL);
+
+ content_area =
+ gtk_dialog_get_content_area (GTK_DIALOG (priv->recur_window));
+
+ priv->recur_page = recurrence_page_new (priv->model, editor);
+ page = COMP_EDITOR_PAGE (priv->recur_page);
+ if (!e_shell_get_express_mode (shell)) {
+ gtk_container_add (
+ GTK_CONTAINER (content_area),
+ comp_editor_page_get_widget (page));
+ gtk_widget_show_all (gtk_bin_get_child (GTK_BIN (priv->recur_window)));
+ comp_editor_append_page (editor, page, NULL, FALSE);
+ } else {
+ comp_editor_append_page (editor, page, _("Recurrence"), TRUE);
+ }
- /* Get meeting related stuff */
- cal_component_get_organizer (comp, &organizer);
- cal_component_get_attendee_list (comp, &attendees);
+ if (e_shell_get_express_mode (shell)) {
+ ENameSelector *name_selector;
- /* Clear things up */
- e_meeting_model_restricted_clear (priv->model);
- e_meeting_model_remove_all_attendees (priv->model);
+ priv->sched_page = schedule_page_new (priv->model, editor);
+ page = COMP_EDITOR_PAGE (priv->sched_page);
- /* Set up the attendees */
- if (attendees == NULL) {
- comp_editor_remove_page (editor, COMP_EDITOR_PAGE (priv->meet_page));
- comp_editor_remove_page (editor, COMP_EDITOR_PAGE (priv->sched_page));
- priv->meeting_shown = FALSE;
- } else {
- GSList *l;
+ name_selector = event_page_get_name_selector (priv->event_page);
+ schedule_page_set_name_selector (priv->sched_page, name_selector);
- if (!priv->meeting_shown) {
- comp_editor_append_page (COMP_EDITOR (ee),
- COMP_EDITOR_PAGE (priv->sched_page),
- _("Scheduling"));
- comp_editor_append_page (COMP_EDITOR (ee),
- COMP_EDITOR_PAGE (priv->meet_page),
- _("Meeting"));
- }
-
- for (l = attendees; l != NULL; l = l->next) {
- CalComponentAttendee *ca = l->data;
- EMeetingAttendee *ia;
-
- ia = E_MEETING_ATTENDEE (e_meeting_attendee_new_from_cal_component_attendee (ca));
- e_meeting_model_add_attendee (priv->model, ia);
-
- gtk_object_unref (GTK_OBJECT (ia));
- }
+ comp_editor_append_page (editor, page, _("Free/Busy"), TRUE);
+ schedule_page_update_free_busy (priv->sched_page);
+
+ g_object_bind_property (
+ action_group, "visible",
+ comp_editor_page_get_widget (page), "visible",
+ G_BINDING_SYNC_CREATE);
- if (organizer.value != NULL) {
- GList *addresses, *l;
- const char *strip;
- int row;
+ /* Alarm page */
+ alarm_page = event_page_get_alarm_page (priv->event_page);
+ comp_editor_append_widget (editor, alarm_page, _("Reminder"), TRUE);
+ g_object_unref (alarm_page);
+ }
- strip = itip_strip_mailto (organizer.value);
+ if (is_meeting) {
- addresses = itip_addresses_get ();
- for (l = addresses; l != NULL; l = l->next) {
- ItipAddress *a = l->data;
-
- if (e_meeting_model_find_attendee (priv->model, a->address, &row))
- e_meeting_model_restricted_add (priv->model, row);
- }
- itip_addresses_free (addresses);
+ if (e_client_check_capability (E_CLIENT (client), CAL_STATIC_CAPABILITY_REQ_SEND_OPTIONS))
+ event_page_show_options (priv->event_page);
+
+ comp_editor_set_group_item (editor, TRUE);
+ if (!((flags & COMP_EDITOR_USER_ORG) ||
+ (flags & COMP_EDITOR_DELEGATE) ||
+ (flags & COMP_EDITOR_NEW_ITEM))) {
+ GtkAction *action;
+
+ action = comp_editor_get_action (editor, "free-busy");
+ gtk_action_set_visible (action, FALSE);
}
-
- if (comp_editor_get_user_org (editor))
- e_meeting_model_restricted_clear (priv->model);
+ event_page_set_meeting (priv->event_page, TRUE);
priv->meeting_shown = TRUE;
- }
- cal_component_free_attendee_list (attendees);
- set_menu_sens (ee);
- comp_editor_set_needs_send (COMP_EDITOR (ee), priv->meeting_shown && itip_organizer_is_user (comp));
-
- priv->updating = FALSE;
+ if (e_shell_get_express_mode (shell)) {
+ attendee_page = event_page_get_attendee_page (priv->event_page);
+ comp_editor_append_widget (editor, attendee_page, _("Attendees"), TRUE);
+ g_object_unref (attendee_page);
+ }
+ }
+
+ return object;
}
-static gboolean
-event_editor_send_comp (CompEditor *editor, CalComponentItipMethod method)
+static void
+event_editor_dispose (GObject *object)
{
- EventEditor *ee = EVENT_EDITOR (editor);
EventEditorPrivate *priv;
- CalComponent *comp = NULL;
- priv = ee->priv;
+ priv = EVENT_EDITOR_GET_PRIVATE (object);
- /* Don't cancel more than once or when just publishing */
- if (method == CAL_COMPONENT_METHOD_PUBLISH ||
- method == CAL_COMPONENT_METHOD_CANCEL)
- goto parent;
-
- comp = meeting_page_get_cancel_comp (priv->meet_page);
- if (comp != NULL) {
- CalClient *client;
- gboolean result;
-
- client = e_meeting_model_get_cal_client (priv->model);
- result = itip_send_comp (CAL_COMPONENT_METHOD_CANCEL, comp, client, NULL);
- gtk_object_unref (GTK_OBJECT (comp));
+ if (priv->event_page) {
+ g_object_unref (priv->event_page);
+ priv->event_page = NULL;
+ }
- if (!result)
- return FALSE;
+ if (priv->recur_page) {
+ g_object_unref (priv->recur_page);
+ priv->recur_page = NULL;
}
- parent:
- if (parent_class->send_comp)
- return parent_class->send_comp (editor, method);
+ if (priv->sched_page) {
+ g_object_unref (priv->sched_page);
+ priv->sched_page = NULL;
+ }
- return FALSE;
+ if (priv->model) {
+ g_signal_handlers_disconnect_by_func (
+ priv->model, event_editor_model_changed_cb, object);
+ g_object_unref (priv->model);
+ priv->model = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (event_editor_parent_class)->dispose (object);
}
-/* Destroy handler for the event editor */
static void
-event_editor_destroy (GtkObject *object)
+event_editor_constructed (GObject *object)
{
- EventEditor *ee;
EventEditorPrivate *priv;
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_EVENT_EDITOR (object));
+ priv = EVENT_EDITOR_GET_PRIVATE (object);
- ee = EVENT_EDITOR (object);
- priv = ee->priv;
+ g_object_bind_property (
+ object, "client",
+ priv->model, "client",
+ G_BINDING_SYNC_CREATE);
- gtk_object_unref (GTK_OBJECT (priv->event_page));
- gtk_object_unref (GTK_OBJECT (priv->alarm_page));
- gtk_object_unref (GTK_OBJECT (priv->recur_page));
- gtk_object_unref (GTK_OBJECT (priv->meet_page));
- gtk_object_unref (GTK_OBJECT (priv->sched_page));
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (event_editor_parent_class)->constructed (object);
+}
- gtk_object_destroy (GTK_OBJECT (priv->model));
- gtk_object_unref (GTK_OBJECT (priv->model));
+static void
+event_editor_show_categories (CompEditor *editor,
+ gboolean visible)
+{
+ EventEditorPrivate *priv;
+
+ priv = EVENT_EDITOR_GET_PRIVATE (editor);
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+ event_page_set_show_categories (priv->event_page, visible);
}
-/**
- * event_editor_new:
- * @client: a CalClient
- *
- * Creates a new event editor dialog.
- *
- * Return value: A newly-created event editor dialog, or NULL if the event
- * editor could not be created.
- **/
-EventEditor *
-event_editor_new (CalClient *client)
+static void
+event_editor_show_role (CompEditor *editor,
+ gboolean visible)
{
- EventEditor *ee;
+ EventEditorPrivate *priv;
+
+ priv = EVENT_EDITOR_GET_PRIVATE (editor);
- ee = EVENT_EDITOR (gtk_type_new (TYPE_EVENT_EDITOR));
- return event_editor_construct (ee, client);
+ event_page_set_view_role (priv->event_page, visible);
}
static void
-show_meeting (EventEditor *ee)
+event_editor_show_rsvp (CompEditor *editor,
+ gboolean visible)
{
EventEditorPrivate *priv;
- priv = ee->priv;
-
- if (!priv->meeting_shown) {
- comp_editor_append_page (COMP_EDITOR (ee),
- COMP_EDITOR_PAGE (priv->sched_page),
- _("Scheduling"));
- comp_editor_append_page (COMP_EDITOR (ee),
- COMP_EDITOR_PAGE (priv->meet_page),
- _("Meeting"));
- priv->meeting_shown = TRUE;
+ priv = EVENT_EDITOR_GET_PRIVATE (editor);
- set_menu_sens (ee);
- comp_editor_set_changed (COMP_EDITOR (ee), priv->meeting_shown);
- comp_editor_set_needs_send (COMP_EDITOR (ee), priv->meeting_shown);
- }
-
- comp_editor_show_page (COMP_EDITOR (ee),
- COMP_EDITOR_PAGE (priv->meet_page));
+ event_page_set_view_rsvp (priv->event_page, visible);
}
-void
-event_editor_show_meeting (EventEditor *ee)
+static void
+event_editor_show_status (CompEditor *editor,
+ gboolean visible)
{
- g_return_if_fail (ee != NULL);
- g_return_if_fail (IS_EVENT_EDITOR (ee));
+ EventEditorPrivate *priv;
+ priv = EVENT_EDITOR_GET_PRIVATE (editor);
- show_meeting (ee);
+ event_page_set_view_status (priv->event_page, visible);
}
static void
-schedule_meeting_cmd (GtkWidget *widget, gpointer data)
+event_editor_show_time_zone (CompEditor *editor,
+ gboolean visible)
{
- EventEditor *ee = EVENT_EDITOR (data);
+ EventEditorPrivate *priv;
+
+ priv = EVENT_EDITOR_GET_PRIVATE (editor);
- show_meeting (ee);
+ event_page_set_show_timezone (priv->event_page, visible);
}
static void
-refresh_meeting_cmd (GtkWidget *widget, gpointer data)
+event_editor_show_type (CompEditor *editor,
+ gboolean visible)
{
- EventEditor *ee = EVENT_EDITOR (data);
-
- comp_editor_send_comp (COMP_EDITOR (ee), CAL_COMPONENT_METHOD_REFRESH);
+ EventEditorPrivate *priv;
+
+ priv = EVENT_EDITOR_GET_PRIVATE (editor);
+
+ event_page_set_view_type (priv->event_page, visible);
}
static void
-cancel_meeting_cmd (GtkWidget *widget, gpointer data)
+event_editor_class_init (EventEditorClass *class)
{
- EventEditor *ee = EVENT_EDITOR (data);
- CalComponent *comp;
-
- comp = comp_editor_get_current_comp (COMP_EDITOR (ee));
- if (cancel_component_dialog (comp, FALSE)) {
- comp_editor_send_comp (COMP_EDITOR (ee), CAL_COMPONENT_METHOD_CANCEL);
- comp_editor_delete_comp (COMP_EDITOR (ee));
- }
+ GObjectClass *object_class;
+ CompEditorClass *editor_class;
+
+ g_type_class_add_private (class, sizeof (EventEditorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->constructor = event_editor_constructor;
+ object_class->dispose = event_editor_dispose;
+ object_class->constructed = event_editor_constructed;
+
+ editor_class = COMP_EDITOR_CLASS (class);
+ editor_class->help_section = "calendar-usage-add-appointment";
+ editor_class->edit_comp = event_editor_edit_comp;
+ editor_class->send_comp = event_editor_send_comp;
+ editor_class->show_categories = event_editor_show_categories;
+ editor_class->show_role = event_editor_show_role;
+ editor_class->show_rsvp = event_editor_show_rsvp;
+ editor_class->show_status = event_editor_show_status;;
+ editor_class->show_time_zone = event_editor_show_time_zone;
+ editor_class->show_type = event_editor_show_type;
}
static void
-forward_cmd (GtkWidget *widget, gpointer data)
+event_editor_init (EventEditor *ee)
{
- EventEditor *ee = EVENT_EDITOR (data);
+ CompEditor *editor = COMP_EDITOR (ee);
+ GtkUIManager *ui_manager;
+ GtkActionGroup *action_group;
+ GtkAction *action;
+ const gchar *id;
+ GError *error = NULL;
+
+ ee->priv = EVENT_EDITOR_GET_PRIVATE (ee);
+ ee->priv->model = E_MEETING_STORE (e_meeting_store_new ());
+ ee->priv->meeting_shown = TRUE;
+ ee->priv->updating = FALSE;
+
+ action_group = comp_editor_get_action_group (editor, "individual");
+ gtk_action_group_add_actions (
+ action_group, event_entries,
+ G_N_ELEMENTS (event_entries), ee);
+ gtk_action_group_add_toggle_actions (
+ action_group, event_toggle_entries,
+ G_N_ELEMENTS (event_toggle_entries), ee);
+
+ action_group = comp_editor_get_action_group (editor, "editable");
+ gtk_action_group_add_actions (
+ action_group, editable_entries,
+ G_N_ELEMENTS (editable_entries), ee);
+ gtk_action_group_add_toggle_actions (
+ action_group, editable_toggle_entries,
+ G_N_ELEMENTS (editable_toggle_entries), ee);
+
+ action_group = comp_editor_get_action_group (editor, "coordinated");
+ gtk_action_group_add_actions (
+ action_group, meeting_entries,
+ G_N_ELEMENTS (meeting_entries), ee);
+
+ ui_manager = comp_editor_get_ui_manager (editor);
+ gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
+
+ id = "org.gnome.evolution.event-editor";
+ e_plugin_ui_register_manager (ui_manager, id, ee);
+ e_plugin_ui_enable_manager (ui_manager, id);
+
+ if (error != NULL) {
+ g_critical ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ }
- if (comp_editor_save_comp (COMP_EDITOR (ee), TRUE))
- comp_editor_send_comp (COMP_EDITOR (ee), CAL_COMPONENT_METHOD_PUBLISH);
+ action = comp_editor_get_action (editor, "print");
+ gtk_action_set_tooltip (action, _("Print this event"));
+
+ /* Hide send options. */
+ action = comp_editor_get_action (editor, "send-options");
+ gtk_action_set_visible (action, FALSE);
+
+ g_signal_connect_swapped (
+ ee->priv->model, "row_changed",
+ G_CALLBACK (event_editor_model_changed_cb), ee);
+ g_signal_connect_swapped (
+ ee->priv->model, "row_inserted",
+ G_CALLBACK (event_editor_model_changed_cb), ee);
+ g_signal_connect_swapped (
+ ee->priv->model, "row_deleted",
+ G_CALLBACK (event_editor_model_changed_cb), ee);
}
static void
-model_row_changed_cb (ETableModel *etm, int row, gpointer data)
+event_editor_edit_comp (CompEditor *editor,
+ ECalComponent *comp)
{
- EventEditor *ee = EVENT_EDITOR (data);
EventEditorPrivate *priv;
-
- priv = ee->priv;
-
- if (!priv->updating) {
- comp_editor_set_changed (COMP_EDITOR (ee), TRUE);
- comp_editor_set_needs_send (COMP_EDITOR (ee), TRUE);
+ ECalComponentOrganizer organizer;
+ gboolean delegate;
+ ECalComponentDateTime dtstart, dtend;
+ ECalClient *client;
+ GSList *attendees = NULL;
+ ESourceRegistry *registry;
+ EShell *shell;
+
+ priv = EVENT_EDITOR_GET_PRIVATE (editor);
+
+ priv->updating = TRUE;
+ delegate = (comp_editor_get_flags (COMP_EDITOR (editor)) & COMP_EDITOR_DELEGATE);
+
+ if (priv->sched_page) {
+ e_cal_component_get_dtstart (comp, &dtstart);
+ e_cal_component_get_dtend (comp, &dtend);
+
+ schedule_page_set_meeting_time (priv->sched_page, dtstart.value, dtend.value);
+
+ e_cal_component_free_datetime (&dtstart);
+ e_cal_component_free_datetime (&dtend);
}
+
+ if (COMP_EDITOR_CLASS (event_editor_parent_class)->edit_comp)
+ COMP_EDITOR_CLASS (event_editor_parent_class)->edit_comp (editor, comp);
+
+ shell = comp_editor_get_shell (editor);
+ client = comp_editor_get_client (editor);
+
+ registry = e_shell_get_registry (shell);
+
+ /* Get meeting related stuff */
+ e_cal_component_get_organizer (comp, &organizer);
+ e_cal_component_get_attendee_list (comp, &attendees);
+
+ /* Set up the attendees */
+ if (attendees != NULL) {
+ GSList *l;
+ gint row;
+ gchar *user_email;
+
+ user_email = itip_get_comp_attendee (
+ registry, comp, client);
+
+ if (!priv->meeting_shown) {
+ GtkAction *action;
+
+ action = comp_editor_get_action (editor, "free-busy");
+ gtk_action_set_visible (action, TRUE);
+ }
+
+ if (!(delegate && e_client_check_capability (
+ E_CLIENT (client), CAL_STATIC_CAPABILITY_DELEGATE_TO_MANY))) {
+ event_page_remove_all_attendees (priv->event_page);
+
+ for (l = attendees; l != NULL; l = l->next) {
+ ECalComponentAttendee *ca = l->data;
+ EMeetingAttendee *ia;
+ gboolean addresses_match;
+
+ addresses_match = g_str_equal (
+ user_email,
+ itip_strip_mailto (ca->value));
+
+ if (delegate && !addresses_match)
+ continue;
+
+ ia = E_MEETING_ATTENDEE (
+ e_meeting_attendee_new_from_e_cal_component_attendee (ca));
+
+ /* If we aren't the organizer or the attendee
+ * is just delegated, don't allow editing. */
+ if (!comp_editor_get_user_org (editor) ||
+ e_meeting_attendee_is_set_delto (ia))
+ e_meeting_attendee_set_edit_level (
+ ia, E_MEETING_ATTENDEE_EDIT_NONE);
+
+ comp_editor_page_add_attendee (
+ COMP_EDITOR_PAGE (priv->event_page), ia);
+
+ g_object_unref (ia);
+ }
+
+ /* If we aren't the organizer we can still change our own status */
+ if (!comp_editor_get_user_org (editor)) {
+ EMeetingAttendee *ia;
+
+ ia = e_meeting_store_find_self (priv->model, &row);
+ if (ia != NULL)
+ e_meeting_attendee_set_edit_level (
+ ia, E_MEETING_ATTENDEE_EDIT_STATUS);
+ } else if (e_cal_client_check_organizer_must_attend (client)) {
+ EMeetingAttendee *ia;
+
+ ia = e_meeting_store_find_attendee (
+ priv->model, organizer.value, &row);
+ if (ia != NULL)
+ e_meeting_attendee_set_edit_level (
+ ia, E_MEETING_ATTENDEE_EDIT_NONE);
+ }
+ }
+
+ event_page_set_meeting (priv->event_page, TRUE);
+ priv->meeting_shown = TRUE;
+ g_free (user_email);
+ }
+ e_cal_component_free_attendee_list (attendees);
+
+ comp_editor_set_needs_send (
+ editor, priv->meeting_shown && (itip_organizer_is_user (
+ registry, comp, client) || itip_sentby_is_user (registry,
+ comp, client)));
+
+ priv->updating = FALSE;
}
-static void
-row_count_changed_cb (ETableModel *etm, int row, int count, gpointer data)
+static gboolean
+event_editor_send_comp (CompEditor *editor,
+ ECalComponentItipMethod method,
+ gboolean strip_alarms)
{
- EventEditor *ee = EVENT_EDITOR (data);
EventEditorPrivate *priv;
-
- priv = ee->priv;
-
- if (!priv->updating) {
- comp_editor_set_changed (COMP_EDITOR (ee), TRUE);
- comp_editor_set_needs_send (COMP_EDITOR (ee), TRUE);
+ EShell *shell;
+ ESourceRegistry *registry;
+ ECalComponent *comp = NULL;
+
+ priv = EVENT_EDITOR_GET_PRIVATE (editor);
+
+ /* Don't cancel more than once or when just publishing */
+ if (method == E_CAL_COMPONENT_METHOD_PUBLISH ||
+ method == E_CAL_COMPONENT_METHOD_CANCEL)
+ goto parent;
+
+ shell = comp_editor_get_shell (editor);
+ registry = e_shell_get_registry (shell);
+
+ comp = event_page_get_cancel_comp (priv->event_page);
+ if (comp != NULL) {
+ ECalClient *client;
+ gboolean result;
+
+ client = e_meeting_store_get_client (priv->model);
+ result = itip_send_comp (
+ registry, E_CAL_COMPONENT_METHOD_CANCEL, comp,
+ client, NULL, NULL, NULL, strip_alarms, FALSE);
+ g_object_unref (comp);
+
+ if (!result)
+ return result;
}
+
+ parent:
+ if (COMP_EDITOR_CLASS (event_editor_parent_class)->send_comp)
+ return COMP_EDITOR_CLASS (event_editor_parent_class)->
+ send_comp (editor, method, strip_alarms);
+
+ return FALSE;
+}
+
+/**
+ * event_editor_new:
+ * @client: a ECalClient
+ *
+ * Creates a new event editor dialog.
+ *
+ * Return value: A newly-created event editor dialog, or NULL if the event
+ * editor could not be created.
+ **/
+CompEditor *
+event_editor_new (ECalClient *client,
+ EShell *shell,
+ CompEditorFlags flags)
+{
+ g_return_val_if_fail (E_IS_CAL_CLIENT (client), NULL);
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+
+ return g_object_new (
+ TYPE_EVENT_EDITOR,
+ "client", client, "flags", flags, "shell", shell, NULL);
+}
+
+void
+event_editor_show_meeting (EventEditor *ee)
+{
+ CompEditor *editor;
+ CompEditorFlags flags;
+
+ g_return_if_fail (IS_EVENT_EDITOR (ee));
+
+ editor = COMP_EDITOR (ee);
+ flags = comp_editor_get_flags (editor);
+
+ event_page_set_meeting (ee->priv->event_page, TRUE);
+ if (!ee->priv->meeting_shown) {
+ GtkAction *action;
+
+ action = comp_editor_get_action (editor, "free-busy");
+ gtk_action_set_visible (action, TRUE);
+
+ ee->priv->meeting_shown = TRUE;
+
+ comp_editor_set_changed (editor, FALSE);
+ comp_editor_set_needs_send (editor, TRUE);
+ }
+
+ if (!(flags & COMP_EDITOR_NEW_ITEM) && !(flags & COMP_EDITOR_USER_ORG))
+ gtk_drag_dest_unset (GTK_WIDGET (editor));
}
diff --git a/calendar/gui/dialogs/event-editor.h b/calendar/gui/dialogs/event-editor.h
index 1b6f72829a..eaa2c49057 100644
--- a/calendar/gui/dialogs/event-editor.h
+++ b/calendar/gui/dialogs/event-editor.h
@@ -1,40 +1,55 @@
-/* Evolution calendar - Event editor dialog
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Miguel de Icaza <miguel@ximian.com>
- * Federico Mena-Quintero <federico@ximian.com>
- * Seth Alves <alves@hungry.com>
+/*
+ * Evolution calendar - Event editor dialog
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Miguel de Icaza <miguel@ximian.com>
+ * Federico Mena-Quintero <federico@ximian.com>
+ * Seth Alves <alves@hungry.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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 __EVENT_EDITOR_H__
#define __EVENT_EDITOR_H__
-#include <libgnome/gnome-defs.h>
-#include <gtk/gtkobject.h>
+#include <gtk/gtk.h>
#include "comp-editor.h"
-
+/* Standard GObject macros */
+#define TYPE_EVENT_EDITOR \
+ (event_editor_get_type ())
+#define EVENT_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), TYPE_EVENT_EDITOR, EventEditor))
+#define EVENT_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), TYPE_EVENT_EDITOR, EventEditorClass))
+#define IS_EVENT_EDITOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), TYPE_EVENT_EDITOR))
+#define IS_EVENT_EDITOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), TYPE_EVENT_EDITOR))
+#define EVENT_EDITOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), TYPE_EVENT_EDITOR, EventEditorClass))
-#define TYPE_EVENT_EDITOR (event_editor_get_type ())
-#define EVENT_EDITOR(obj) (GTK_CHECK_CAST ((obj), TYPE_EVENT_EDITOR, EventEditor))
-#define EVENT_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), TYPE_EVENT_EDITOR, EventEditorClass))
-#define IS_EVENT_EDITOR(obj) (GTK_CHECK_TYPE ((obj), TYPE_EVENT_EDITOR))
-#define IS_EVENT_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), TYPE_EVENT_EDITOR))
+G_BEGIN_DECLS
typedef struct _EventEditor EventEditor;
typedef struct _EventEditorClass EventEditorClass;
@@ -42,8 +57,6 @@ typedef struct _EventEditorPrivate EventEditorPrivate;
struct _EventEditor {
CompEditor parent;
-
- /* Private data */
EventEditorPrivate *priv;
};
@@ -51,12 +64,12 @@ struct _EventEditorClass {
CompEditorClass parent_class;
};
-GtkType event_editor_get_type (void);
-EventEditor *event_editor_construct (EventEditor *ee,
- CalClient *client);
-EventEditor *event_editor_new (CalClient *client);
-void event_editor_show_meeting (EventEditor *ee);
+GType event_editor_get_type (void);
+CompEditor * event_editor_new (ECalClient *client,
+ EShell *shell,
+ CompEditorFlags flags);
+void event_editor_show_meeting (EventEditor *ee);
-
+G_END_DECLS
#endif /* __EVENT_EDITOR_H__ */
diff --git a/calendar/gui/dialogs/event-page.c b/calendar/gui/dialogs/event-page.c
index 89fb0b2a89..f1f7c05e89 100644
--- a/calendar/gui/dialogs/event-page.c
+++ b/calendar/gui/dialogs/event-page.c
@@ -1,345 +1,776 @@
-/* Evolution calendar - Main page of the event editor dialog
- *
- * Copyright (C) 2001 Ximian, Inc.
- *
- * Authors: Federico Mena-Quintero <federico@ximian.com>
- * Miguel de Icaza <miguel@ximian.com>
- * Seth Alves <alves@hungry.com>
- * JP Rosevear <jpr@ximian.com>
+/*
+ * Evolution calendar - Main page of the event editor dialog
*
* 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.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
*
* 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.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Federico Mena-Quintero <federico@ximian.com>
+ * Miguel de Icaza <miguel@ximian.com>
+ * Seth Alves <alves@hungry.com>
+ * JP Rosevear <jpr@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
-#include <gtk/gtksignal.h>
-#include <gtk/gtktogglebutton.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <glade/glade.h>
-#include <gal/widgets/e-unicode.h>
-#include <gal/widgets/e-categories.h>
-#include "e-util/e-categories-config.h"
-#include "e-util/e-dialog-widgets.h"
-#include "widgets/misc/e-dateedit.h"
-#include "cal-util/timeutil.h"
-#include "../calendar-config.h"
+#include <errno.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "../e-alarm-list.h"
+#include "../e-meeting-attendee.h"
+#include "../e-meeting-list-view.h"
+#include "../e-meeting-store.h"
#include "../e-timezone-entry.h"
+
+#include "alarm-list-dialog.h"
#include "comp-editor-util.h"
+#include "comp-editor.h"
+#include "e-send-options-utils.h"
#include "event-page.h"
-
+#define EVENT_PAGE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), TYPE_EVENT_PAGE, EventPagePrivate))
+
+#define EVENT_PAGE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), TYPE_EVENT_PAGE, EventPagePrivate))
+
+enum {
+ ALARM_NONE,
+ ALARM_15_MINUTES,
+ ALARM_1_HOUR,
+ ALARM_1_DAY,
+ ALARM_USER_TIME,
+ ALARM_CUSTOM
+};
+
+static const gint alarm_map_with_user_time[] = {
+ ALARM_NONE,
+ ALARM_15_MINUTES,
+ ALARM_1_HOUR,
+ ALARM_1_DAY,
+ ALARM_USER_TIME,
+ ALARM_CUSTOM,
+ -1
+};
+
+static const gint alarm_map_without_user_time[] = {
+ ALARM_NONE,
+ ALARM_15_MINUTES,
+ ALARM_1_HOUR,
+ ALARM_1_DAY,
+ ALARM_CUSTOM,
+ -1
+};
/* Private part of the EventPage structure */
struct _EventPagePrivate {
- /* Glade XML data */
- GladeXML *xml;
-
- /* Widgets from the Glade file */
+ GtkBuilder *builder;
+ /* Widgets from the UI file */
GtkWidget *main;
+ /* Generic informative messages placeholder */
+ GtkWidget *info_hbox;
+ GtkWidget *info_icon;
+ GtkWidget *info_string;
+
GtkWidget *summary;
+ GtkWidget *summary_label;
GtkWidget *location;
+ GtkWidget *location_label;
+ GtkEntryCompletion *location_completion;
+
+ gchar **address_strings;
+ gchar *fallback_address;
+ EMeetingAttendee *ia;
+ gchar *user_add;
+ ECalComponent *comp;
+
+ /* For meeting/event */
+ GtkWidget *calendar_label;
+ GtkWidget *org_cal_label;
+ GtkWidget *attendee_box;
+
+ /* Lists of attendees */
+ GPtrArray *deleted_attendees;
GtkWidget *start_time;
GtkWidget *end_time;
+ GtkWidget *end_time_combo;
+ GtkWidget *time_hour;
+ GtkWidget *hour_selector;
+ GtkWidget *minute_selector;
GtkWidget *start_timezone;
GtkWidget *end_timezone;
- GtkWidget *all_day_event;
+ GtkWidget *timezone_label;
+ gboolean all_day_event;
+ GtkWidget *status_icons;
+ GtkWidget *alarm_icon;
+ GtkWidget *recur_icon;
GtkWidget *description;
- GtkWidget *classification_public;
- GtkWidget *classification_private;
- GtkWidget *classification_confidential;
-
- GtkWidget *show_time_as_free;
- GtkWidget *show_time_as_busy;
+ gboolean show_time_as_busy;
- GtkWidget *contacts_btn;
- GtkWidget *contacts_box;
+ GtkWidget *alarm_dialog;
+ GtkWidget *alarm_time_combo;
+ GtkWidget *alarm_warning;
+ GtkWidget *alarm_box;
GtkWidget *categories_btn;
GtkWidget *categories;
- gboolean updating;
+ GtkWidget *client_combo_box;
+
+ /* Meeting related items */
+ GtkWidget *list_box;
+ GtkWidget *organizer_table;
+ GtkWidget *organizer;
+ GtkWidget *add;
+ GtkWidget *remove;
+ GtkWidget *edit;
+ GtkWidget *invite;
+ GtkWidget *invite_label;
+ GtkWidget *attendees_label;
+
+ /* ListView stuff */
+ EMeetingStore *meeting_store;
+ EMeetingListView *list_view;
+ gint row;
+
+ /* For handling who the organizer is */
+ gboolean user_org;
+ gboolean existing;
+
+ EAlarmList *alarm_list_store;
+
+ gboolean sendoptions_shown;
+
+ ESendOptionsDialog *sod;
+ gchar *old_summary;
+ EDurationType alarm_units;
+ gint alarm_interval;
/* This is TRUE if both the start & end timezone are the same. If the
- start timezone is then changed, we updated the end timezone to the
- same value, since 99% of events start and end in one timezone. */
+ * start timezone is then changed, we updated the end timezone to the
+ * same value, since 99% of events start and end in one timezone. */
gboolean sync_timezones;
+ gboolean is_meeting;
- /* The Corba component for selecting contacts, and the entry field
- which we place in the dialog. */
- GNOME_Evolution_Addressbook_SelectNames corba_select_names;
- GtkWidget *contacts_entry;
-};
+ GtkWidget *alarm_list_dlg_widget;
-
+ /* either with-user-time or without it */
+ const gint *alarm_map;
-static void event_page_class_init (EventPageClass *class);
-static void event_page_init (EventPage *epage);
-static void event_page_destroy (GtkObject *object);
+ GCancellable *connect_cancellable;
+};
-static GtkWidget *event_page_get_widget (CompEditorPage *page);
-static void event_page_focus_main_widget (CompEditorPage *page);
-static void event_page_fill_widgets (CompEditorPage *page, CalComponent *comp);
-static gboolean event_page_fill_component (CompEditorPage *page, CalComponent *comp);
-static void event_page_set_summary (CompEditorPage *page, const char *summary);
static void event_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates);
+static void notify_dates_changed (EventPage *epage, struct icaltimetype *start_tt, struct icaltimetype *end_tt);
+static gboolean check_start_before_end (struct icaltimetype *start_tt, icaltimezone *start_zone,
+ struct icaltimetype *end_tt, icaltimezone *end_zone, gboolean adjust_end_time);
+static void set_attendees (ECalComponent *comp, const GPtrArray *attendees);
+static void hour_sel_changed (GtkSpinButton *widget, EventPage *epage);
+static void minute_sel_changed (GtkSpinButton *widget, EventPage *epage);
+static void hour_minute_changed (EventPage *epage);
+static void update_end_time_combo (EventPage *epage);
+static void event_page_select_organizer (EventPage *epage, const gchar *backend_address);
+static void set_subscriber_info_string (EventPage *epage, const gchar *backend_address);
+
+G_DEFINE_TYPE (EventPage, event_page, TYPE_COMP_EDITOR_PAGE)
-static CompEditorPageClass *parent_class = NULL;
+static gboolean
+get_current_identity (EventPage *page,
+ gchar **name,
+ gchar **mailto)
+{
+ EShell *shell;
+ CompEditor *editor;
+ ESourceRegistry *registry;
+ GList *list, *iter;
+ GtkWidget *entry;
+ const gchar *extension_name;
+ const gchar *text;
+ gboolean match = FALSE;
-
+ entry = gtk_bin_get_child (GTK_BIN (page->priv->organizer));
+ text = gtk_entry_get_text (GTK_ENTRY (entry));
-/**
- * event_page_get_type:
- *
- * Registers the #EventPage class if necessary, and returns the type ID
- * associated to it.
- *
- * Return value: The type ID of the #EventPage class.
- **/
-GtkType
-event_page_get_type (void)
-{
- static GtkType event_page_type;
+ if (text == NULL || *text == '\0')
+ return FALSE;
+
+ editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (page));
+ shell = comp_editor_get_shell (editor);
+
+ registry = e_shell_get_registry (shell);
+ extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
- if (!event_page_type) {
- static const GtkTypeInfo event_page_info = {
- "EventPage",
- sizeof (EventPage),
- sizeof (EventPageClass),
- (GtkClassInitFunc) event_page_class_init,
- (GtkObjectInitFunc) event_page_init,
- NULL, /* reserved_1 */
- NULL, /* reserved_2 */
- (GtkClassInitFunc) NULL
- };
+ list = e_source_registry_list_sources (registry, extension_name);
- event_page_type = gtk_type_unique (TYPE_COMP_EDITOR_PAGE,
- &event_page_info);
+ for (iter = list; !match && iter != NULL; iter = g_list_next (iter)) {
+ ESource *source = E_SOURCE (iter->data);
+ ESourceMailIdentity *extension;
+ const gchar *id_name;
+ const gchar *id_address;
+ gchar *identity;
+
+ extension = e_source_get_extension (source, extension_name);
+
+ id_name = e_source_mail_identity_get_name (extension);
+ id_address = e_source_mail_identity_get_address (extension);
+
+ if (id_name == NULL || id_address == NULL)
+ continue;
+
+ identity = g_strdup_printf ("%s <%s>", id_name, id_address);
+ match = (g_ascii_strcasecmp (text, identity) == 0);
+ g_free (identity);
+
+ if (match && name != NULL)
+ *name = g_strdup (id_name);
+
+ if (match && mailto != NULL)
+ *mailto = g_strdup_printf ("MAILTO:%s", id_address);
}
- return event_page_type;
+ g_list_free_full (list, (GDestroyNotify) g_object_unref);
+
+ return match;
}
-/* Class initialization function for the event page */
static void
-event_page_class_init (EventPageClass *class)
+set_all_day_event_menu (EventPage *epage,
+ gboolean active)
{
- CompEditorPageClass *editor_page_class;
- GtkObjectClass *object_class;
+ CompEditor *editor;
+ GtkAction *action;
- editor_page_class = (CompEditorPageClass *) class;
- object_class = (GtkObjectClass *) class;
+ editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage));
+ action = comp_editor_get_action (editor, "all-day-event");
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), active);
+}
- parent_class = gtk_type_class (TYPE_COMP_EDITOR_PAGE);
+/* Sets the 'All Day Event' flag to the given value (without emitting signals),
+ * and shows or hides the widgets as appropriate. */
+static void
+set_all_day (EventPage *epage,
+ gboolean all_day)
+{
+ set_all_day_event_menu (epage, all_day);
+
+ /* TODO implement for in end time selector */
+ if (all_day)
+ gtk_combo_box_set_active (
+ GTK_COMBO_BOX (epage->priv->end_time_combo), 1);
+ gtk_widget_set_sensitive (epage->priv->end_time_combo, !all_day);
+
+ e_date_edit_set_show_time (
+ E_DATE_EDIT (epage->priv->start_time), !all_day);
+ e_date_edit_set_show_time (
+ E_DATE_EDIT (epage->priv->end_time), !all_day);
+}
- editor_page_class->get_widget = event_page_get_widget;
- editor_page_class->focus_main_widget = event_page_focus_main_widget;
- editor_page_class->fill_widgets = event_page_fill_widgets;
- editor_page_class->fill_component = event_page_fill_component;
- editor_page_class->set_summary = event_page_set_summary;
- editor_page_class->set_dates = event_page_set_dates;
+static void
+enable_busy_time_menu (EventPage *epage,
+ gboolean sensitive)
+{
+ CompEditor *editor;
+ GtkAction *action;
- object_class->destroy = event_page_destroy;
+ editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage));
+ action = comp_editor_get_action (editor, "show-time-busy");
+ gtk_action_set_sensitive (action, sensitive);
}
-/* Object initialization function for the event page */
static void
-event_page_init (EventPage *epage)
+set_busy_time_menu (EventPage *epage,
+ gboolean active)
{
- EventPagePrivate *priv;
+ CompEditor *editor;
+ GtkAction *action;
+
+ editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage));
+ action = comp_editor_get_action (editor, "show-time-busy");
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), active);
+}
- priv = g_new0 (EventPagePrivate, 1);
- epage->priv = priv;
-
- priv->xml = NULL;
-
- priv->main = NULL;
- priv->summary = NULL;
- priv->location = NULL;
- priv->start_time = NULL;
- priv->end_time = NULL;
- priv->start_timezone = NULL;
- priv->end_timezone = NULL;
- priv->all_day_event = NULL;
- priv->description = NULL;
- priv->classification_public = NULL;
- priv->classification_private = NULL;
- priv->classification_confidential = NULL;
- priv->show_time_as_free = NULL;
- priv->show_time_as_busy = NULL;
- priv->contacts_btn = NULL;
- priv->contacts_box = NULL;
- priv->categories_btn = NULL;
- priv->categories = NULL;
-
- priv->updating = FALSE;
- priv->sync_timezones = FALSE;
-
- priv->corba_select_names = CORBA_OBJECT_NIL;
- priv->contacts_entry = NULL;
-}
-
-/* Destroy handler for the event page */
static void
-event_page_destroy (GtkObject *object)
+clear_widgets (EventPage *epage)
{
- EventPage *epage;
- EventPagePrivate *priv;
+ EventPagePrivate *priv = epage->priv;
+ CompEditor *editor;
- g_return_if_fail (object != NULL);
- g_return_if_fail (IS_EVENT_PAGE (object));
+ editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage));
- epage = EVENT_PAGE (object);
- priv = epage->priv;
+ /* Summary, description */
+ gtk_entry_set_text (GTK_ENTRY (priv->summary), "");
+ gtk_entry_set_text (GTK_ENTRY (priv->location), "");
+ gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->description)), "", 0);
+ e_buffer_tagger_update_tags (GTK_TEXT_VIEW (priv->description));
+
+ /* Start and end times */
+ g_signal_handlers_block_matched (priv->start_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, epage);
+ g_signal_handlers_block_matched (priv->end_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, epage);
+
+ e_date_edit_set_time (E_DATE_EDIT (priv->start_time), 0);
+ e_date_edit_set_time (E_DATE_EDIT (priv->end_time), 0);
+
+ g_signal_handlers_unblock_matched (priv->start_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, epage);
+ g_signal_handlers_unblock_matched (priv->end_time, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, epage);
+
+ epage->priv->all_day_event = FALSE;
+ set_all_day (epage, FALSE);
+
+ /* Classification */
+ comp_editor_set_classification (editor, E_CAL_COMPONENT_CLASS_PUBLIC);
+
+ /* Show Time As (Transparency) */
+ priv->show_time_as_busy = TRUE;
+ set_busy_time_menu (epage, TRUE);
+
+ /* Alarm */
+ e_dialog_combo_box_set (priv->alarm_time_combo, ALARM_NONE, priv->alarm_map);
+
+ /* Categories */
+ gtk_entry_set_text (GTK_ENTRY (priv->categories), "");
+}
+
+static gboolean
+is_custom_alarm (ECalComponentAlarm *ca,
+ gchar *old_summary,
+ EDurationType user_units,
+ gint user_interval,
+ gint *alarm_type)
+{
+ ECalComponentAlarmTrigger trigger;
+ ECalComponentAlarmRepeat repeat;
+ ECalComponentAlarmAction action;
+ ECalComponentText desc;
+ icalcomponent *icalcomp;
+ icalproperty *icalprop;
+ icalattach *attach;
+ gboolean needs_desc = FALSE;
+
+ e_cal_component_alarm_get_action (ca, &action);
+ if (action != E_CAL_COMPONENT_ALARM_DISPLAY)
+ return TRUE;
+
+ e_cal_component_alarm_get_attach (ca, &attach);
+ if (attach)
+ return TRUE;
- if (priv->corba_select_names != CORBA_OBJECT_NIL) {
- CORBA_Environment ev;
+ icalcomp = e_cal_component_alarm_get_icalcomponent (ca);
+ icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
+ while (icalprop) {
+ const gchar *x_name;
- CORBA_exception_init (&ev);
- bonobo_object_release_unref (priv->corba_select_names, &ev);
- CORBA_exception_free (&ev);
+ x_name = icalproperty_get_x_name (icalprop);
+ if (!strcmp (x_name, "X-EVOLUTION-NEEDS-DESCRIPTION"))
+ needs_desc = TRUE;
+
+ icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
+ }
+
+ if (!needs_desc) {
+ e_cal_component_alarm_get_description (ca, &desc);
+ if (!desc.value || !old_summary || strcmp (desc.value, old_summary))
+ return TRUE;
+ }
+
+ e_cal_component_alarm_get_repeat (ca, &repeat);
+ if (repeat.repetitions != 0)
+ return TRUE;
+
+ if (e_cal_component_alarm_has_attendees (ca))
+ return TRUE;
+
+ e_cal_component_alarm_get_trigger (ca, &trigger);
+ if (trigger.type != E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START)
+ return TRUE;
+
+ if (trigger.u.rel_duration.is_neg != 1)
+ return TRUE;
+
+ if (trigger.u.rel_duration.weeks != 0)
+ return TRUE;
+
+ if (trigger.u.rel_duration.seconds != 0)
+ return TRUE;
+
+ if (trigger.u.rel_duration.days == 1
+ && trigger.u.rel_duration.hours == 0
+ && trigger.u.rel_duration.minutes == 0) {
+ if (alarm_type)
+ *alarm_type = ALARM_1_DAY;
+ return FALSE;
+ }
+
+ if (trigger.u.rel_duration.days == 0
+ && trigger.u.rel_duration.hours == 1
+ && trigger.u.rel_duration.minutes == 0) {
+ if (alarm_type)
+ *alarm_type = ALARM_1_HOUR;
+ return FALSE;
}
- if (priv->xml) {
- gtk_object_unref (GTK_OBJECT (priv->xml));
- priv->xml = NULL;
+ if (trigger.u.rel_duration.days == 0
+ && trigger.u.rel_duration.hours == 0
+ && trigger.u.rel_duration.minutes == 15) {
+ if (alarm_type)
+ *alarm_type = ALARM_15_MINUTES;
+ return FALSE;
}
- g_free (priv);
- epage->priv = NULL;
+ if (user_interval != -1) {
+ switch (user_units) {
+ case E_DURATION_DAYS:
+ if (trigger.u.rel_duration.days == user_interval
+ && trigger.u.rel_duration.hours == 0
+ && trigger.u.rel_duration.minutes == 0) {
+ if (alarm_type)
+ *alarm_type = ALARM_USER_TIME;
+ return FALSE;
+ }
+ break;
+
+ case E_DURATION_HOURS:
+ if (trigger.u.rel_duration.days == 0
+ && trigger.u.rel_duration.hours == user_interval
+ && trigger.u.rel_duration.minutes == 0) {
+ if (alarm_type)
+ *alarm_type = ALARM_USER_TIME;
+ return FALSE;
+ }
+ break;
+
+ case E_DURATION_MINUTES:
+ if (trigger.u.rel_duration.days == 0
+ && trigger.u.rel_duration.hours == 0
+ && trigger.u.rel_duration.minutes == user_interval) {
+ if (alarm_type)
+ *alarm_type = ALARM_USER_TIME;
+ return FALSE;
+ }
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean
+is_custom_alarm_store (EAlarmList *alarm_list_store,
+ gchar *old_summary,
+ EDurationType user_units,
+ gint user_interval,
+ gint *alarm_type)
+{
+ const ECalComponentAlarm *alarm;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean valid_iter;
+
+ model = GTK_TREE_MODEL (alarm_list_store);
+
+ valid_iter = gtk_tree_model_get_iter_first (model, &iter);
+ if (!valid_iter)
+ return FALSE;
+
+ alarm = e_alarm_list_get_alarm (alarm_list_store, &iter);
+ if (is_custom_alarm ((ECalComponentAlarm *) alarm, old_summary, user_units, user_interval, alarm_type))
+ return TRUE;
+
+ valid_iter = gtk_tree_model_iter_next (model, &iter);
+ if (valid_iter)
+ return TRUE;
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+ return FALSE;
}
-
+static gboolean
+is_custom_alarm_uid_list (ECalComponent *comp,
+ GList *alarms,
+ gchar *old_summary,
+ EDurationType user_units,
+ gint user_interval,
+ gint *alarm_type)
+{
+ ECalComponentAlarm *ca;
+ gboolean result;
-static const int classification_map[] = {
- CAL_COMPONENT_CLASS_PUBLIC,
- CAL_COMPONENT_CLASS_PRIVATE,
- CAL_COMPONENT_CLASS_CONFIDENTIAL,
- -1
-};
+ if (g_list_length (alarms) > 1)
+ return TRUE;
-static const int transparency_map[] = {
- CAL_COMPONENT_TRANSP_TRANSPARENT,
- CAL_COMPONENT_TRANSP_OPAQUE,
- -1
-};
+ ca = e_cal_component_get_alarm (comp, alarms->data);
+ result = is_custom_alarm (
+ ca, old_summary, user_units, user_interval, alarm_type);
+ e_cal_component_alarm_free (ca);
-/* get_widget handler for the event page */
-static GtkWidget *
-event_page_get_widget (CompEditorPage *page)
+ return result;
+}
+
+/* returns whether changed info text */
+static gboolean
+check_starts_in_the_past (EventPage *epage)
{
- EventPage *epage;
EventPagePrivate *priv;
+ struct icaltimetype start_tt = icaltime_null_time ();
+ gboolean date_set;
+
+ if ((comp_editor_get_flags (comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage))) & COMP_EDITOR_NEW_ITEM) == 0)
+ return FALSE;
- epage = EVENT_PAGE (page);
priv = epage->priv;
+ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_time), &start_tt.year, &start_tt.month, &start_tt.day);
- return priv->main;
+ g_return_val_if_fail (date_set, FALSE);
+
+ if (priv->all_day_event) {
+ start_tt.is_date = TRUE;
+ } else {
+ e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time), &start_tt.hour, &start_tt.minute);
+ start_tt.zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone));
+ }
+
+ if (comp_editor_test_time_in_the_past (start_tt)) {
+ gchar *tmp = g_strconcat ("<b>", _("Event's start time is in the past"), "</b>", NULL);
+ event_page_set_info_string (epage, GTK_STOCK_DIALOG_WARNING, tmp);
+ g_free (tmp);
+ } else {
+ event_page_set_info_string (epage, NULL, NULL);
+ }
+
+ return TRUE;
}
-/* focus_main_widget handler for the event page */
static void
-event_page_focus_main_widget (CompEditorPage *page)
+alarm_image_button_clicked_cb (GtkWidget *button,
+ EventPage *epage)
{
- EventPage *epage;
- EventPagePrivate *priv;
+ CompEditor *editor;
+ GtkAction *action;
- epage = EVENT_PAGE (page);
- priv = epage->priv;
+ g_return_if_fail (IS_EVENT_PAGE (epage));
- gtk_widget_grab_focus (priv->summary);
+ editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage));
+ action = comp_editor_get_action (editor, "alarms");
+ gtk_action_activate (action);
+}
+
+static GtkWidget *
+create_alarm_image_button (const gchar *image_text,
+ const gchar *tip_text,
+ EventPage *epage)
+{
+ GtkWidget *image, *button;
+
+ button = gtk_button_new ();
+ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+ gtk_widget_set_can_focus (button, FALSE);
+
+ image = gtk_image_new_from_icon_name (image_text, GTK_ICON_SIZE_MENU);
+
+ gtk_container_add ((GtkContainer *) button, image);
+ gtk_widget_show_all (button);
+ gtk_widget_set_tooltip_text (button, tip_text);
+
+ g_signal_connect (
+ button, "clicked",
+ G_CALLBACK (alarm_image_button_clicked_cb), epage);
+
+ return button;
}
-/* Sets the 'All Day Event' flag to the given value (without emitting signals),
- * and shows or hides the widgets as appropriate. */
static void
-set_all_day (EventPage *epage, gboolean all_day)
+sensitize_widgets (EventPage *epage)
{
+ ECalClient *client;
+ EShell *shell;
+ CompEditor *editor;
+ CompEditorFlags flags;
+ GtkActionGroup *action_group;
+ GtkAction *action;
+ gboolean read_only, custom, alarm, sens = TRUE, sensitize;
EventPagePrivate *priv;
+ gboolean delegate;
+
+ editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage));
+ client = comp_editor_get_client (editor);
+ flags = comp_editor_get_flags (editor);
+ shell = comp_editor_get_shell (editor);
priv = epage->priv;
+ if (flags & COMP_EDITOR_MEETING)
+ sens = flags & COMP_EDITOR_USER_ORG;
- gtk_signal_handler_block_by_data (GTK_OBJECT (priv->all_day_event),
- epage);
- e_dialog_toggle_set (priv->all_day_event, all_day);
- gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->all_day_event),
- epage);
+ read_only = e_client_is_readonly (E_CLIENT (client));
- e_date_edit_set_show_time (E_DATE_EDIT (priv->start_time), !all_day);
- e_date_edit_set_show_time (E_DATE_EDIT (priv->end_time), !all_day);
+ delegate = flags & COMP_EDITOR_DELEGATE;
- /* DATE values do not have timezones, so we hide the fields. */
- if (all_day) {
- gtk_widget_hide (priv->start_timezone);
- gtk_widget_hide (priv->end_timezone);
+ sensitize = !read_only && sens;
+
+ if (read_only) {
+ gchar *tmp = g_strconcat ("<b>", _("Event cannot be edited, because the selected calendar is read only"), "</b>", NULL);
+ event_page_set_info_string (epage, GTK_STOCK_DIALOG_INFO, tmp);
+ g_free (tmp);
+ } else if (!sens) {
+ gchar *tmp = g_strconcat ("<b>", _("Event cannot be fully edited, because you are not the organizer"), "</b>", NULL);
+ event_page_set_info_string (epage, GTK_STOCK_DIALOG_INFO, tmp);
+ g_free (tmp);
+ } else if (!check_starts_in_the_past (epage)) {
+ event_page_set_info_string (epage, NULL, NULL);
+ }
+
+ alarm = e_dialog_combo_box_get (priv->alarm_time_combo, priv->alarm_map) != ALARM_NONE;
+ custom = is_custom_alarm_store (priv->alarm_list_store, priv->old_summary, priv->alarm_units, priv->alarm_interval, NULL) ||
+ e_dialog_combo_box_get (priv->alarm_time_combo, priv->alarm_map) == ALARM_CUSTOM ? TRUE : FALSE;
+
+ if (alarm && !priv->alarm_icon) {
+ priv->alarm_icon = create_alarm_image_button ("stock_bell", _("This event has reminders"), epage);
+ gtk_box_pack_start ((GtkBox *) priv->status_icons, priv->alarm_icon, FALSE, FALSE, 6);
+ }
+
+ /* The list of organizers is set to be non-editable. Otherwise any
+ * change in the displayed list causes an 'Account not found' error.
+ */
+ gtk_editable_set_editable (GTK_EDITABLE (gtk_bin_get_child (GTK_BIN (priv->organizer))), FALSE);
+
+ gtk_editable_set_editable (GTK_EDITABLE (priv->summary), !read_only);
+ gtk_editable_set_editable (GTK_EDITABLE (priv->location), sensitize);
+ gtk_widget_set_sensitive (priv->alarm_box, custom);
+ gtk_widget_set_sensitive (priv->start_time, sensitize);
+ gtk_widget_set_sensitive (priv->start_timezone, sensitize);
+ gtk_widget_set_sensitive (priv->end_time, sensitize);
+ gtk_widget_set_sensitive (priv->end_timezone, sensitize);
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (priv->description), !read_only);
+ gtk_widget_set_sensitive (priv->alarm_time_combo, !read_only);
+ gtk_widget_set_sensitive (priv->categories_btn, !read_only);
+ /*TODO implement the for portion of the end time selector */
+ if (flags & COMP_EDITOR_NEW_ITEM) {
+ if (priv->all_day_event)
+ gtk_combo_box_set_active (GTK_COMBO_BOX (priv->end_time_combo), 1);
+ else
+ gtk_combo_box_set_active (GTK_COMBO_BOX (priv->end_time_combo), 0);
+ } else
+ gtk_combo_box_set_active (GTK_COMBO_BOX (priv->end_time_combo), 1);
+
+ gtk_widget_set_sensitive (priv->hour_selector, sensitize);
+ gtk_widget_set_sensitive (priv->minute_selector, sensitize);
+
+ gtk_editable_set_editable (GTK_EDITABLE (priv->categories), !read_only);
+
+ if (delegate) {
+ gtk_widget_set_sensitive (priv->client_combo_box, FALSE);
+ }
+
+ gtk_widget_set_sensitive (priv->organizer, !read_only);
+ gtk_widget_set_sensitive (priv->add, (!read_only && sens) || delegate);
+ gtk_widget_set_sensitive (priv->edit, (!read_only && sens) || delegate);
+ e_meeting_list_view_set_editable (priv->list_view, (!read_only && sens) || delegate);
+ gtk_widget_set_sensitive (priv->remove, (!read_only && sens) || delegate);
+ gtk_widget_set_sensitive (priv->invite, (!read_only && sens) || delegate);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->list_view), !read_only);
+
+ action_group = comp_editor_get_action_group (editor, "editable");
+ gtk_action_group_set_sensitive (action_group, !read_only);
+
+ action_group = comp_editor_get_action_group (editor, "individual");
+ gtk_action_group_set_sensitive (action_group, sensitize);
+
+ action = comp_editor_get_action (editor, "free-busy");
+ gtk_action_set_sensitive (action, sensitize);
+
+ if (!priv->is_meeting) {
+ gtk_widget_hide (priv->calendar_label);
+ gtk_widget_hide (priv->list_box);
+ gtk_widget_hide (priv->attendee_box);
+ gtk_widget_hide (priv->organizer);
+ gtk_label_set_text_with_mnemonic ((GtkLabel *) priv->org_cal_label, _("_Calendar:"));
+ gtk_label_set_mnemonic_widget ((GtkLabel *) priv->org_cal_label, priv->client_combo_box);
} else {
- gtk_widget_show (priv->start_timezone);
- gtk_widget_show (priv->end_timezone);
+ gtk_widget_show (priv->calendar_label);
+ gtk_widget_show (priv->list_box);
+ if (!e_shell_get_express_mode (shell))
+ gtk_widget_show (priv->attendee_box);
+ gtk_widget_show (priv->organizer);
+ gtk_label_set_text_with_mnemonic ((GtkLabel *) priv->org_cal_label, _("Or_ganizer:"));
}
}
static void
-update_time (EventPage *epage, CalComponentDateTime *start_date, CalComponentDateTime *end_date)
+update_time (EventPage *epage,
+ ECalComponentDateTime *start_date,
+ ECalComponentDateTime *end_date)
{
- EventPagePrivate *priv;
- struct icaltimetype *start_tt, *end_tt;
- icaltimezone *start_zone = NULL, *end_zone = NULL;
- CalClientGetStatus status;
- gboolean all_day_event;
-
- priv = epage->priv;
-
- /* Note that if we are creating a new event, the timezones may not be
- on the server, so we try to get the builtin timezone with the TZID
- first. */
- start_zone = icaltimezone_get_builtin_timezone_from_tzid (start_date->tzid);
- if (!start_zone) {
- status = cal_client_get_timezone (COMP_EDITOR_PAGE (epage)->client,
- start_date->tzid,
- &start_zone);
- /* FIXME: Handle error better. */
- if (status != CAL_CLIENT_GET_SUCCESS)
- g_warning ("Couldn't get timezone from server: %s",
- start_date->tzid ? start_date->tzid : "");
- }
-
- end_zone = icaltimezone_get_builtin_timezone_from_tzid (end_date->tzid);
- if (!end_zone) {
- status = cal_client_get_timezone (COMP_EDITOR_PAGE (epage)->client,
- end_date->tzid,
- &end_zone);
- /* FIXME: Handle error better. */
- if (status != CAL_CLIENT_GET_SUCCESS)
- g_warning ("Couldn't get timezone from server: %s",
- end_date->tzid ? end_date->tzid : "");
+ CompEditor *editor;
+ ECalClient *client;
+ GtkAction *action;
+ struct icaltimetype *start_tt, *end_tt, implied_tt;
+ icaltimezone *start_zone = NULL, *def_zone = NULL;
+ gboolean all_day_event, homezone = TRUE;
+ gboolean show_timezone;
+
+ editor = comp_editor_page_get_editor (COMP_EDITOR_PAGE (epage));
+ client = comp_editor_get_client (editor);
+
+ if (start_date->