[evolution-patches] Birthday/Anniversary calendar backend
- From: ERDI Gergo <cactus cactus rulez org>
- To: evolution-patches lists ximian com
- Subject: [evolution-patches] Birthday/Anniversary calendar backend
- Date: Wed, 7 Jan 2004 16:26:40 +0100 (CET)
So here it is, for bounty #127535
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/ChangeLog,v
retrieving revision 1.72
diff -u -r1.72 ChangeLog
--- ChangeLog 7 Jan 2004 09:33:47 -0000 1.72
+++ ChangeLog 7 Jan 2004 15:22:17 -0000
@@ -1,3 +1,19 @@
+2004-01-07 ERDI Gergo <cactus cactus rulez org>
+
+ * libedataserver/e-source-group.h: added new read-only flag
+
+ * src/contactdates-server.c: new factory for ContactDates backend
+
+ * configure.in: Added new ContactDates calendar backend
+
+2004-01-05 Christian Neumair <chris gnome-de org>
+
+ * addressbook/libebook/e-book.c: Generalize some more strings.
+
+2004-01-05 Christian Neumair <chris gnome-de org>
+
+ * calendar/libedata-cal/e-cal-backend-sexp.c: Generalize some strings.
+
2004-01-05 Rodrigo Moya <rodrigo ximian com>
* libedataserver/e-file-cache.[ch] (e_file_cache_get_objects): new
Index: configure.in
===================================================================
RCS file: /cvs/gnome/evolution-data-server/configure.in,v
retrieving revision 1.29
diff -u -r1.29 configure.in
--- configure.in 29 Dec 2003 15:53:05 -0000 1.29
+++ configure.in 7 Jan 2004 15:22:17 -0000
@@ -300,6 +300,7 @@
calendar/backends/file/Makefile
calendar/backends/groupwise/Makefile
calendar/backends/http/Makefile
+calendar/backends/contacts/Makefile
libdb/Makefile
libedataserver/Makefile
libedataserver/libedataserver-1.0.pc
Index: calendar/backends/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/backends/Makefile.am,v
retrieving revision 1.2
diff -u -r1.2 Makefile.am
--- calendar/backends/Makefile.am 14 Nov 2003 16:38:25 -0000 1.2
+++ calendar/backends/Makefile.am 7 Jan 2004 15:22:18 -0000
@@ -1 +1 @@
-SUBDIRS = file groupwise http
+SUBDIRS = file groupwise http contacts
Index: calendar/backends/contacts/.cvsignore
===================================================================
RCS file: calendar/backends/contacts/.cvsignore
diff -N calendar/backends/contacts/.cvsignore
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ calendar/backends/contacts/.cvsignore 7 Jan 2004 15:22:18 -0000
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
\ No newline at end of file
Index: calendar/backends/contacts/Makefile.am
===================================================================
RCS file: calendar/backends/contacts/Makefile.am
diff -N calendar/backends/contacts/Makefile.am
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ calendar/backends/contacts/Makefile.am 7 Jan 2004 15:22:18 -0000
@@ -0,0 +1,19 @@
+INCLUDES = \
+ -DG_LOG_DOMAIN=\"libecalbackendcontact\" \
+ -I$(top_srcdir)/calendar \
+ -I$(top_builddir)/calendar \
+ -I$(top_srcdir)/calendar/libical/src \
+ -I$(top_builddir)/calendar/libical/src \
+ -I$(top_srcdir)/addressbook \
+ -I$(top_builddir)/addressbook \
+ $(EVOLUTION_CALENDAR_CFLAGS)
+
+noinst_LTLIBRARIES = libecalbackendcontacts.la
+
+libecalbackendcontacts_la_SOURCES = \
+ e-cal-backend-contacts.c \
+ e-cal-backend-contacts.h
+
+libecalbackendcontacts_la_LIBADD = \
+ $(top_builddir)/calendar/libedata-cal/libedata-cal.la
+
Index: calendar/backends/contacts/e-cal-backend-contacts.c
===================================================================
RCS file: calendar/backends/contacts/e-cal-backend-contacts.c
diff -N calendar/backends/contacts/e-cal-backend-contacts.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ calendar/backends/contacts/e-cal-backend-contacts.c 7 Jan 2004 15:22:20 -0000
@@ -0,0 +1,832 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* Evolution calendar - iCalendar file backend
+ *
+ * Copyright (C) 2000-2003 Ximian, Inc.
+ * Copyright (C) 2003 Gergő Érdi
+ *
+ * Authors: Federico Mena-Quintero <federico ximian com>
+ * Rodrigo Moya <rodrigo ximian com>
+ * Gergő Érdi <cactus cactus rulez org>
+ *
+ * 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-i18n.h>
+
+#include "e-cal-backend-contacts.h"
+
+#include <libedataserver/e-xml-hash-utils.h>
+#include <libecal/e-cal-recur.h>
+#include <libecal/e-cal-util.h>
+#include <libedata-cal/e-cal-backend-util.h>
+#include <libedata-cal/e-cal-backend-sexp.h>
+
+#include <libebook/e-book.h>
+
+#include <libedataserver/e-source-list.h>
+
+static ECalBackendSyncClass *parent_class;
+
+/* Private part of the ECalBackendContacts structure */
+struct _ECalBackendContactsPrivate {
+ ESourceList *addressbook_sources;
+
+ GHashTable *addressbooks; /* UID -> BookRecord */
+ gboolean addressbook_loaded;
+
+ EBookView *book_view;
+ GHashTable *tracked_contacts; /* UID -> ContactRecord */
+
+ icaltimezone *default_zone;
+};
+
+typedef struct _BookRecord {
+ EBook *book;
+ EBookView *book_view;
+} BookRecord;
+
+typedef struct _ContactRecord {
+ ECalBackendContacts *cbc;
+ EContact *contact;
+ ECalComponent *comp_birthday, *comp_anniversary;
+} ContactRecord;
+
+static ECalComponent * create_birthday (ECalBackendContacts *cbc, EContact *contact);
+static ECalComponent * create_anniversary (ECalBackendContacts *cbc, EContact *contact);
+
+static void contacts_changed_cb (EBookView *book_view, const GList *contacts, gpointer user_data);
+static void contacts_added_cb (EBookView *book_view, const GList *contacts, gpointer user_data);
+static void contacts_removed_cb (EBookView *book_view, const GList *contact_ids, gpointer user_data);
+
+/* BookRecord methods */
+static BookRecord *
+book_record_new (ECalBackendContacts *cbc, ESource *source)
+{
+ EBook *book = e_book_new ();
+ GList *fields = 0;
+ EBookQuery *query;
+ EBookView *book_view;
+ BookRecord *br;
+
+ e_book_load_source (book, source, TRUE, NULL);
+
+ /* Create book view */
+ fields = g_list_append (fields, e_contact_field_name (E_CONTACT_FILE_AS));
+ fields = g_list_append (fields, e_contact_field_name (E_CONTACT_BIRTH_DATE));
+ fields = g_list_append (fields, e_contact_field_name (E_CONTACT_ANNIVERSARY));
+ query = e_book_query_any_field_contains ("");
+
+ if (!e_book_get_book_view (book, query, fields, -1, &book_view, NULL)) {
+ e_book_query_unref (query);
+ return NULL;
+ }
+ e_book_query_unref (query);
+
+ g_signal_connect (book_view, "contacts_added", G_CALLBACK (contacts_added_cb), cbc);
+ g_signal_connect (book_view, "contacts_removed", G_CALLBACK (contacts_removed_cb), cbc);
+ g_signal_connect (book_view, "contacts_changed", G_CALLBACK (contacts_changed_cb), cbc);
+
+ e_book_view_start (book_view);
+
+ br = g_new (BookRecord, 1);
+ br->book = book;
+ br->book_view = book_view;
+
+ return br;
+}
+
+static void
+book_record_free (BookRecord *br)
+{
+ if (!br)
+ return;
+
+ g_object_unref (br->book_view);
+ g_object_unref (br->book);
+
+ g_free (br);
+}
+
+/* ContactRecord methods */
+static ContactRecord *
+contact_record_new (ECalBackendContacts *cbc, EContact *contact)
+{
+ ContactRecord *cr = g_new0 (ContactRecord, 1);
+ char *comp_str;
+
+ cr->cbc = cbc;
+ cr->contact = contact;
+ cr->comp_birthday = create_birthday (cbc, contact);
+ cr->comp_anniversary = create_anniversary (cbc, contact);
+
+ comp_str = e_cal_component_get_as_string (cr->comp_birthday);
+ e_cal_backend_notify_object_created (E_CAL_BACKEND (cbc),
+ comp_str);
+ g_free (comp_str);
+
+ comp_str = e_cal_component_get_as_string (cr->comp_anniversary);
+ e_cal_backend_notify_object_created (E_CAL_BACKEND (cbc),
+ comp_str);
+ g_free (comp_str);
+
+ g_object_ref (G_OBJECT (contact));
+
+ return cr;
+}
+
+static void
+contact_record_free (ContactRecord *cr)
+{
+ char *comp_str;
+ const char *uid;
+
+ g_object_unref (G_OBJECT (cr->contact));
+
+ /* Remove the birthday event */
+ comp_str = e_cal_component_get_as_string (cr->comp_birthday);
+ e_cal_component_get_uid (cr->comp_birthday, &uid);
+ e_cal_backend_notify_object_removed (E_CAL_BACKEND (cr->cbc), uid, comp_str);
+ g_free (comp_str);
+
+ /* Remove the anniversary event */
+ comp_str = e_cal_component_get_as_string (cr->comp_anniversary);
+ e_cal_component_get_uid (cr->comp_anniversary, &uid);
+ e_cal_backend_notify_object_removed (E_CAL_BACKEND (cr->cbc), uid, comp_str);
+ g_free (comp_str);
+
+ g_object_unref (G_OBJECT (cr->comp_birthday));
+ g_object_unref (G_OBJECT (cr->comp_anniversary));
+
+ g_free (cr);
+}
+
+/* ContactRecordCB methods */
+typedef struct _ContactRecordCB {
+ ECalBackendContacts *cbc;
+ ECalBackendSExp *sexp;
+ GList *result;
+} ContactRecordCB;
+
+static ContactRecordCB *
+contact_record_cb_new (ECalBackendContacts *cbc, ECalBackendSExp *sexp)
+{
+ ContactRecordCB *cb_data = g_new (ContactRecordCB, 1);
+
+ cb_data->cbc = cbc;
+ cb_data->sexp = sexp;
+ cb_data->result = 0;
+
+ return cb_data;
+}
+
+static void
+contact_record_cb_free (ContactRecordCB *cb_data)
+{
+ g_list_foreach (cb_data->result, (GFunc) g_free, 0);
+ g_list_free (cb_data->result);
+
+ g_free (cb_data);
+}
+
+static void
+contact_record_cb (gpointer key, gpointer value, gpointer user_data)
+{
+ ContactRecordCB *cb_data = user_data;
+ ContactRecord *record = value;
+
+ if (e_cal_backend_sexp_match_comp (cb_data->sexp, record->comp_birthday, E_CAL_BACKEND (cb_data->cbc))) {
+ char * comp_str = e_cal_component_get_as_string (record->comp_birthday);
+ cb_data->result = g_list_append (cb_data->result, comp_str);
+ }
+
+ if (e_cal_backend_sexp_match_comp (cb_data->sexp, record->comp_anniversary, E_CAL_BACKEND (cb_data->cbc))) {
+ char * comp_str = e_cal_component_get_as_string (record->comp_anniversary);
+ cb_data->result = g_list_append (cb_data->result, comp_str);
+ }
+}
+
+/* SourceList callbacks */
+static void
+add_source (ECalBackendContacts *cbc, ESource *source)
+{
+ BookRecord *br = book_record_new (cbc, source);
+ const char *uid = e_source_peek_uid (source);
+
+ g_hash_table_insert (cbc->priv->addressbooks, g_strdup (uid), br);
+}
+
+static void
+source_added_cb (ESourceGroup *group, ESource *source, gpointer user_data)
+{
+ ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (user_data);
+
+ g_return_if_fail (cbc);
+
+ add_source (cbc, source);
+}
+
+static void
+source_removed_cb (ESourceGroup *group, ESource *source, gpointer user_data)
+{
+ ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (user_data);
+ const char *uid = e_source_peek_uid (source);
+
+ g_return_if_fail (cbc);
+
+ g_hash_table_remove (cbc->priv->addressbooks, uid);
+}
+
+static void
+source_group_added_cb (ESourceList *source_list, ESourceGroup *group, gpointer user_data)
+{
+ ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (user_data);
+ GSList *i;
+
+ g_return_if_fail (cbc);
+
+ /* Load all address books from this group */
+ for (i = e_source_group_peek_sources (group); i; i = i->next)
+ {
+ ESource *source = E_SOURCE (i->data);
+ add_source (cbc, source);
+ }
+
+ /* Watch for future changes */
+ g_signal_connect (group, "source_added", G_CALLBACK (source_added_cb), cbc);
+ g_signal_connect (group, "source_removed", G_CALLBACK (source_removed_cb), cbc);
+}
+
+static void
+source_group_removed_cb (ESourceList *source_list, ESourceGroup *group, gpointer user_data)
+{
+ ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (user_data);
+ GSList *i = 0;
+
+ g_return_if_fail (cbc);
+
+ /* Unload all address books from this group */
+ for (i = e_source_group_peek_sources (group); i; i = i->next)
+ {
+ ESource *source = E_SOURCE (i->data);
+ const char *uid = e_source_peek_uid (source);
+
+ g_hash_table_remove (cbc->priv->addressbooks, uid);
+ }
+}
+
+/************************************************************************************/
+
+static void
+contacts_changed_cb (EBookView *book_view, const GList *contacts, gpointer user_data)
+{
+ ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (user_data);
+ const GList *i;
+
+ for (i = contacts; i; i = i->next)
+ {
+ EContact *contact = E_CONTACT (i->data);
+ char *uid = e_contact_get_const (contact, E_CONTACT_UID);
+
+ /* If no date is set, remove from list of tracked contacts */
+ if (!e_contact_get (contact, E_CONTACT_BIRTH_DATE) &&
+ !e_contact_get (contact, E_CONTACT_ANNIVERSARY)) {
+ g_hash_table_remove (cbc->priv->tracked_contacts, uid);
+ } else {
+ ContactRecord *cr = contact_record_new (cbc, contact);
+ g_hash_table_insert (cbc->priv->tracked_contacts, g_strdup (uid), cr);
+ }
+ }
+}
+
+static void
+contacts_added_cb (EBookView *book_view, const GList *contacts, gpointer user_data)
+{
+ ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (user_data);
+ const GList *i;
+
+ /* See if any new contacts have BIRTHDAY or ANNIVERSARY fields */
+ for (i = contacts; i; i = i->next)
+ {
+ EContact *contact = E_CONTACT (i->data);
+
+ if (e_contact_get (contact, E_CONTACT_BIRTH_DATE) ||
+ e_contact_get (contact, E_CONTACT_ANNIVERSARY)) {
+ ContactRecord *cr = contact_record_new (cbc, contact);
+ const char *uid = e_contact_get_const (contact, E_CONTACT_UID);
+
+ g_hash_table_insert (cbc->priv->tracked_contacts, g_strdup (uid), cr);
+ }
+ }
+}
+
+static void
+contacts_removed_cb (EBookView *book_view, const GList *contact_ids, gpointer user_data)
+{
+ ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (user_data);
+ const GList *i;
+
+ /* Stop tracking these */
+ for (i = contact_ids; i; i = i->next)
+ g_hash_table_remove (cbc->priv->tracked_contacts, i->data);
+}
+
+/************************************************************************************/
+static time_t
+cdate_to_time (EContactDate *cdate)
+{
+ struct tm time_tm = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ time_t time;
+
+ time_tm.tm_year = cdate->year - 1900;
+ time_tm.tm_mon = cdate->month - 1;
+ time_tm.tm_mday = cdate->day + 1;
+ time = mktime (&time_tm);
+
+ return time;
+}
+
+/* Contact -> Event creator */
+static ECalComponent *
+create_component (ECalBackendContacts *cbc, EContactDate *cdate, char *summary)
+{
+ ECalComponent *cal_comp;
+ ECalComponentText comp_summary;
+ icalcomponent *ical_comp;
+ time_t start;
+ struct icaltimetype itt;
+ ECalComponentDateTime dt;
+ struct icalrecurrencetype r;
+ GSList recur_list;
+
+ g_return_val_if_fail (E_IS_CAL_BACKEND_CONTACTS (cbc), 0);
+
+ if (!cdate)
+ return NULL;
+
+ ical_comp = icalcomponent_new (ICAL_VEVENT_COMPONENT);
+
+ /* Create the event object */
+ cal_comp = e_cal_component_new ();
+ e_cal_component_gen_uid ();
+ e_cal_component_set_icalcomponent (cal_comp, ical_comp);
+
+ /* Set all-day event's date from contact data */
+ start = cdate_to_time (cdate);
+ itt = icaltime_from_timet (start, TRUE);
+ dt.value = &itt;
+ dt.tzid = 0;
+ e_cal_component_set_dtstart (cal_comp, &dt);
+
+ /* Create yearly recurrence */
+ icalrecurrencetype_clear (&r);
+ r.freq = ICAL_YEARLY_RECURRENCE;
+ r.interval = 1;
+ recur_list.data = &r;
+ recur_list.next = 0;
+ e_cal_component_set_rrule_list (cal_comp, &recur_list);
+
+ /* Create summary */
+ comp_summary.value = summary;
+ comp_summary.altrep = 0;
+ e_cal_component_set_summary (cal_comp, &comp_summary);
+
+ /* Set category and visibility */
+ e_cal_component_set_categories (cal_comp, _("Birthday"));
+ e_cal_component_set_classification (cal_comp, E_CAL_COMPONENT_CLASS_PRIVATE);
+
+ /* Birthdays/anniversaries are shown as free time */
+ e_cal_component_set_transparency (cal_comp, E_CAL_COMPONENT_TRANSP_TRANSPARENT);
+
+ /* Don't forget to call commit()! */
+ e_cal_component_commit_sequence (cal_comp);
+
+ return cal_comp;
+}
+
+static ECalComponent *
+create_birthday (ECalBackendContacts *cbc, EContact *contact)
+{
+ EContactDate *cdate;
+ ECalComponent *cal_comp;
+ char *summary;
+ const char *name;
+
+ cdate = e_contact_get (contact, E_CONTACT_BIRTH_DATE);
+ name = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ summary = g_strdup_printf (_("Birthday: %s"), name);
+
+ cal_comp = create_component (cbc, cdate, summary);
+
+ g_free (summary);
+
+ return cal_comp;
+}
+
+static ECalComponent *
+create_anniversary (ECalBackendContacts *cbc, EContact *contact)
+{
+ EContactDate *cdate;
+ ECalComponent *cal_comp;
+ char *summary;
+ const char *name;
+
+ cdate = e_contact_get (contact, E_CONTACT_ANNIVERSARY);
+ name = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ summary = g_strdup_printf (_("Anniversary: %s"), name);
+
+ cal_comp = create_component (cbc, cdate, summary);
+
+ g_free (summary);
+
+ return cal_comp;
+}
+
+/************************************************************************************/
+/* Calendar backend method implementations */
+
+/* First the empty stubs */
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_get_cal_address (ECalBackendSync *backend, EDataCal *cal,
+ char **address)
+{
+ /* WRITE ME */
+ return GNOME_Evolution_Calendar_Success;
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_get_ldap_attribute (ECalBackendSync *backend, EDataCal *cal,
+ char **attribute)
+{
+ /* WRITE ME */
+ return GNOME_Evolution_Calendar_Success;
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_get_alarm_email_address (ECalBackendSync *backend, EDataCal *cal,
+ char **address)
+{
+ /* WRITE ME */
+ return GNOME_Evolution_Calendar_Success;
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_get_static_capabilities (ECalBackendSync *backend, EDataCal *cal,
+ char **capabilities)
+{
+ /* WRITE ME */
+ return GNOME_Evolution_Calendar_Success;
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_remove (ECalBackendSync *backend, EDataCal *cal)
+{
+ /* WRITE ME */
+ return GNOME_Evolution_Calendar_Success;
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_get_default_object (ECalBackendSync *backend, EDataCal *cal,
+ char **object)
+{
+ return GNOME_Evolution_Calendar_UnsupportedMethod;
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_get_object (ECalBackendSync *backend, EDataCal *cal,
+ const char *uid, const char *rid,
+ char **object)
+{
+ /* WRITE ME */
+ return GNOME_Evolution_Calendar_Success;
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_get_free_busy (ECalBackendSync *backend, EDataCal *cal,
+ GList *users, time_t start, time_t end,
+ GList **freebusy)
+{
+ /* Birthdays/anniversaries don't count as busy time */
+
+ icalcomponent *vfb = icalcomponent_new_vfreebusy ();
+ icaltimezone *utc_zone = icaltimezone_get_utc_timezone ();
+ char *calobj;
+
+#if 0
+ icalproperty *prop;
+ icalparameter *param;
+
+ prop = icalproperty_new_organizer (address);
+ if (prop != NULL && cn != NULL) {
+ param = icalparameter_new_cn (cn);
+ icalproperty_add_parameter (prop, param);
+ }
+ if (prop != NULL)
+ icalcomponent_add_property (vfb, prop);
+#endif
+
+ icalcomponent_set_dtstart (vfb, icaltime_from_timet_with_zone (start, FALSE, utc_zone));
+ icalcomponent_set_dtend (vfb, icaltime_from_timet_with_zone (end, FALSE, utc_zone));
+
+ calobj = icalcomponent_as_ical_string (vfb);
+ *freebusy = g_list_append (NULL, g_strdup (calobj));
+ icalcomponent_free (vfb);
+
+ /* WRITE ME */
+ return GNOME_Evolution_Calendar_Success;
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_get_changes (ECalBackendSync *backend, EDataCal *cal,
+ const char *change_id,
+ GList **adds, GList **modifies, GList **deletes)
+{
+ /* WRITE ME */
+ return GNOME_Evolution_Calendar_Success;
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_discard_alarm (ECalBackendSync *backend, EDataCal *cal,
+ const char *uid, const char *auid)
+{
+ /* WRITE ME */
+ return GNOME_Evolution_Calendar_Success;
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_receive_objects (ECalBackendSync *backend, EDataCal *cal,
+ const char *calobj)
+{
+ return GNOME_Evolution_Calendar_UnsupportedMethod;
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_send_objects (ECalBackendSync *backend, EDataCal *cal,
+ const char *calobj)
+{
+ /* TODO: Investigate this */
+ return GNOME_Evolution_Calendar_Success;
+}
+
+/* Then the real implementations */
+
+static CalMode
+e_cal_backend_contacts_get_mode (ECalBackend *backend)
+{
+ return CAL_MODE_LOCAL;
+}
+
+static void
+e_cal_backend_contacts_set_mode (ECalBackend *backend, CalMode mode)
+{
+ e_cal_backend_notify_mode (backend,
+ GNOME_Evolution_Calendar_CalListener_MODE_NOT_SUPPORTED,
+ GNOME_Evolution_Calendar_MODE_LOCAL);
+
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_is_read_only (ECalBackendSync *backend, EDataCal *cal,
+ gboolean *read_only)
+{
+ *read_only = TRUE;
+
+ return GNOME_Evolution_Calendar_Success;
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_open (ECalBackendSync *backend, EDataCal *cal,
+ gboolean only_if_exists)
+{
+ ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (backend);
+ ECalBackendContactsPrivate *priv = cbc->priv;
+
+ GSList *i;
+
+ if (priv->addressbook_loaded)
+ return GNOME_Evolution_Calendar_Success;
+
+ /* Create address books for existing sources */
+ for (i = e_source_list_peek_groups (priv->addressbook_sources); i; i = i->next)
+ {
+ ESourceGroup *source_group = E_SOURCE_GROUP (i->data);
+
+ source_group_added_cb (priv->addressbook_sources, source_group, cbc);
+ }
+
+ /* Listen for source list changes */
+ g_signal_connect (priv->addressbook_sources, "group_added", G_CALLBACK (source_group_added_cb), cbc);
+ g_signal_connect (priv->addressbook_sources, "group_removed", G_CALLBACK (source_group_removed_cb), cbc);
+
+ priv->addressbook_loaded = TRUE;
+ return GNOME_Evolution_Calendar_Success;
+}
+
+static gboolean
+e_cal_backend_contacts_is_loaded (ECalBackend *backend)
+{
+ ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (backend);
+ ECalBackendContactsPrivate *priv = cbc->priv;
+
+ return priv->addressbook_loaded;
+}
+
+static ECalBackendSyncStatus
+e_cal_backend_contacts_get_object_list (ECalBackendSync *backend, EDataCal *cal,
+ const char *sexp_string, GList **objects)
+{
+ ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (backend);
+ ECalBackendContactsPrivate *priv = cbc->priv;
+ ECalBackendSExp *sexp = e_cal_backend_sexp_new (sexp_string);
+ ContactRecordCB *cb_data;
+
+ if (!sexp)
+ return GNOME_Evolution_Calendar_InvalidQuery;
+
+ cb_data = contact_record_cb_new (cbc, sexp);
+ g_hash_table_foreach (priv->tracked_contacts, contact_record_cb, cb_data);
+ *objects = cb_data->result;
+
+ /* Don't call cb_data_free as that would destroy the results
+ * in *objects */
+ g_free (cb_data);
+
+ return GNOME_Evolution_Calendar_Success;
+}
+
+static void
+e_cal_backend_contacts_start_query (ECalBackend *backend, EDataCalView *query)
+{
+ ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (backend);
+ ECalBackendContactsPrivate *priv = cbc->priv;
+ ECalBackendSExp *sexp;
+ ContactRecordCB *cb_data;
+
+ sexp = e_data_cal_view_get_object_sexp (query);
+ if (!sexp) {
+ e_data_cal_view_notify_done (query, GNOME_Evolution_Calendar_InvalidQuery);
+ return;
+ }
+
+ cb_data = contact_record_cb_new (cbc, sexp);
+
+ g_hash_table_foreach (priv->tracked_contacts, contact_record_cb, cb_data);
+ e_data_cal_view_notify_objects_added (query, cb_data->result);
+
+ contact_record_cb_free (cb_data);
+
+ e_data_cal_view_notify_done (query, GNOME_Evolution_Calendar_Success);
+}
+
+static icaltimezone *
+e_cal_backend_contacts_internal_get_default_timezone (ECalBackend *backend)
+{
+ ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (backend);
+
+ return cbc->priv->default_zone;
+}
+
+static icaltimezone *
+e_cal_backend_contacts_internal_get_timezone (ECalBackend *backend, const char *tzid)
+{
+ ECalBackendContacts *cbc = E_CAL_BACKEND_CONTACTS (backend);
+
+ return cbc->priv->default_zone;
+}
+
+/***********************************************************************************
+ */
+
+/* Finalize handler for the contacts backend */
+static void
+e_cal_backend_contacts_finalize (GObject *object)
+{
+ ECalBackendContacts *cbc;
+ ECalBackendContactsPrivate *priv;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (E_IS_CAL_BACKEND_CONTACTS (object));
+
+ cbc = E_CAL_BACKEND_CONTACTS (object);
+ priv = cbc->priv;
+
+ g_hash_table_destroy (priv->tracked_contacts);
+
+ g_free (priv);
+ cbc->priv = NULL;
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+/* Object initialization function for the contacts backend */
+static void
+e_cal_backend_contacts_init (ECalBackendContacts *cbc, ECalBackendContactsClass *class)
+{
+ ECalBackendContactsPrivate *priv;
+ GConfClient *gconf_client;
+
+ priv = g_new0 (ECalBackendContactsPrivate, 1);
+
+ gconf_client = gconf_client_get_default ();
+ priv->addressbook_sources = e_source_list_new_for_gconf (
+ gconf_client, "/apps/evolution/addressbook/sources");
+
+ priv->addressbooks = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify)book_record_free);
+ priv->tracked_contacts = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify)contact_record_free);
+
+ priv->default_zone = icaltimezone_get_utc_timezone ();
+
+ cbc->priv = priv;
+}
+
+/* Class initialization function for the contacts backend */
+static void
+e_cal_backend_contacts_class_init (ECalBackendContactsClass *class)
+{
+ GObjectClass *object_class;
+ ECalBackendClass *backend_class;
+ ECalBackendSyncClass *sync_class;
+
+ object_class = (GObjectClass *) class;
+ backend_class = (ECalBackendClass *) class;
+ sync_class = (ECalBackendSyncClass *) class;
+
+ parent_class = (ECalBackendSyncClass *) g_type_class_peek_parent (class);
+
+ object_class->finalize = e_cal_backend_contacts_finalize;
+
+ sync_class->is_read_only_sync = e_cal_backend_contacts_is_read_only;
+ sync_class->get_cal_address_sync = e_cal_backend_contacts_get_cal_address;
+ sync_class->get_alarm_email_address_sync = e_cal_backend_contacts_get_alarm_email_address;
+ sync_class->get_ldap_attribute_sync = e_cal_backend_contacts_get_ldap_attribute;
+ sync_class->get_static_capabilities_sync = e_cal_backend_contacts_get_static_capabilities;
+ sync_class->open_sync = e_cal_backend_contacts_open;
+ sync_class->remove_sync = e_cal_backend_contacts_remove;
+ sync_class->discard_alarm_sync = e_cal_backend_contacts_discard_alarm;
+ sync_class->receive_objects_sync = e_cal_backend_contacts_receive_objects;
+ sync_class->send_objects_sync = e_cal_backend_contacts_send_objects;
+ sync_class->get_default_object_sync = e_cal_backend_contacts_get_default_object;
+ sync_class->get_object_sync = e_cal_backend_contacts_get_object;
+ sync_class->get_object_list_sync = e_cal_backend_contacts_get_object_list;
+ sync_class->get_freebusy_sync = e_cal_backend_contacts_get_free_busy;
+ sync_class->get_changes_sync = e_cal_backend_contacts_get_changes;
+ backend_class->is_loaded = e_cal_backend_contacts_is_loaded;
+ backend_class->start_query = e_cal_backend_contacts_start_query;
+ backend_class->get_mode = e_cal_backend_contacts_get_mode;
+ backend_class->set_mode = e_cal_backend_contacts_set_mode;
+
+ backend_class->internal_get_default_timezone = e_cal_backend_contacts_internal_get_default_timezone;
+ backend_class->internal_get_timezone = e_cal_backend_contacts_internal_get_timezone;
+}
+
+
+/**
+ * e_cal_backend_contacts_get_type:
+ * @void:
+ *
+ * Registers the #ECalBackendContacts class if necessary, and returns
+ * the type ID associated to it.
+ *
+ * Return value: The type ID of the #ECalBackendContacts class.
+ **/
+GType
+e_cal_backend_contacts_get_type (void)
+{
+ static GType e_cal_backend_contacts_type = 0;
+
+ fprintf (stderr, "e_cal_backend_contacts_get_type ()\n");
+
+ if (!e_cal_backend_contacts_type) {
+ static GTypeInfo info = {
+ sizeof (ECalBackendContactsClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) e_cal_backend_contacts_class_init,
+ NULL, NULL,
+ sizeof (ECalBackendContacts),
+ 0,
+ (GInstanceInitFunc) e_cal_backend_contacts_init
+ };
+ e_cal_backend_contacts_type = g_type_register_static (E_TYPE_CAL_BACKEND_SYNC,
+ "ECalBackendContacts", &info, 0);
+ }
+
+ return e_cal_backend_contacts_type;
+}
Index: calendar/libecal/e-cal.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/calendar/libecal/e-cal.c,v
retrieving revision 1.23
diff -u -r1.23 e-cal.c
--- calendar/libecal/e-cal.c 7 Jan 2004 14:21:33 -0000 1.23
+++ calendar/libecal/e-cal.c 7 Jan 2004 15:22:30 -0000
@@ -2155,7 +2155,10 @@
g_cond_wait (our_op->cond, our_op->mutex);
status = our_op->status;
- *icalcomp = icalparser_parse_string (our_op->string);
+ if (status)
+ *icalcomp = NULL;
+ else
+ *icalcomp = icalparser_parse_string (our_op->string);
g_free (our_op->string);
e_calendar_remove_op (ecal, our_op);
Index: libedataserver/e-source-group.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserver/e-source-group.c,v
retrieving revision 1.3
diff -u -r1.3 e-source-group.c
--- libedataserver/e-source-group.c 14 Nov 2003 22:02:10 -0000 1.3
+++ libedataserver/e-source-group.c 7 Jan 2004 15:22:52 -0000
@@ -41,6 +41,7 @@
GSList *sources;
gboolean ignore_source_changed;
+ gboolean readonly;
};
@@ -221,6 +222,7 @@
xmlChar *uid;
xmlChar *name;
xmlChar *base_uri;
+ xmlChar *readonly_str;
ESourceGroup *new = NULL;
g_return_val_if_fail (doc != NULL, NULL);
@@ -232,6 +234,7 @@
uid = xmlGetProp (root, "uid");
name = xmlGetProp (root, "name");
base_uri = xmlGetProp (root, "base_uri");
+ readonly_str = xmlGetProp (root, "readonly");
if (uid == NULL || name == NULL || base_uri == NULL)
goto done;
@@ -241,17 +244,21 @@
e_source_group_set_name (new, name);
e_source_group_set_base_uri (new, base_uri);
-
+
for (p = root->children; p != NULL; p = p->next) {
ESource *new_source = e_source_new_from_xml_node (p);
e_source_group_add_source (new, new_source, -1);
}
+ e_source_group_set_readonly (new, readonly_str && !strcmp (readonly_str, "yes"));
+
done:
if (name != NULL)
xmlFree (name);
if (base_uri != NULL)
xmlFree (base_uri);
+ if (readonly_str != NULL)
+ xmlFree (readonly_str);
return new;
}
@@ -283,7 +290,8 @@
GHashTable *new_sources_hash;
GSList *new_sources_list = NULL;
xmlNodePtr root, nodep;
- xmlChar *name, *base_uri;
+ xmlChar *name, *base_uri, *readonly_str;
+ gboolean readonly;
gboolean changed = FALSE;
GSList *p, *q;
@@ -320,6 +328,14 @@
}
xmlFree (base_uri);
+ readonly_str = xmlGetProp (root, "readonly");
+ readonly = readonly_str && !strcmp (readonly_str, "yes");
+ if (readonly != group->priv->readonly) {
+ group->priv->readonly = readonly;
+ changed = TRUE;
+ }
+ xmlFree (readonly_str);
+
new_sources_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
for (nodep = root->children; nodep != NULL; nodep = nodep->next) {
@@ -431,6 +447,9 @@
{
g_return_if_fail (E_IS_SOURCE_GROUP (group));
g_return_if_fail (name != NULL);
+
+ if (group->priv->readonly)
+ return;
if (group->priv->name == name)
return;
@@ -447,6 +466,9 @@
g_return_if_fail (E_IS_SOURCE_GROUP (group));
g_return_if_fail (base_uri != NULL);
+ if (group->priv->readonly)
+ return;
+
if (group->priv->base_uri == base_uri)
return;
@@ -456,6 +478,25 @@
g_signal_emit (group, signals[CHANGED], 0);
}
+void e_source_group_set_readonly (ESourceGroup *group,
+ gboolean readonly)
+{
+ GSList *i;
+
+ g_return_if_fail (E_IS_SOURCE_GROUP (group));
+
+ if (group->priv->readonly)
+ return;
+
+ if (group->priv->readonly == readonly)
+ return;
+
+ group->priv->readonly = readonly;
+ for (i = group->priv->sources; i != NULL; i = i->next)
+ e_source_set_readonly (E_SOURCE (i->data), readonly);
+
+ g_signal_emit (group, signals[CHANGED], 0);
+}
const char *
e_source_group_peek_uid (ESourceGroup *group)
@@ -481,6 +522,13 @@
return group->priv->base_uri;
}
+gboolean
+e_source_group_get_readonly (ESourceGroup *group)
+{
+ g_return_val_if_fail (E_IS_SOURCE_GROUP (group), FALSE);
+
+ return group->priv->readonly;
+}
GSList *
e_source_group_peek_sources (ESourceGroup *group)
@@ -525,10 +573,14 @@
{
g_return_val_if_fail (E_IS_SOURCE_GROUP (group), FALSE);
+ if (group->priv->readonly)
+ return FALSE;
+
if (e_source_group_peek_source_by_uid (group, e_source_peek_uid (source)) != NULL)
return FALSE;
e_source_set_group (source, group);
+ e_source_set_readonly (source, group->priv->readonly);
g_object_ref (source);
g_signal_connect (source, "changed", G_CALLBACK (source_changed_callback), group);
@@ -549,6 +601,9 @@
g_return_val_if_fail (E_IS_SOURCE_GROUP (group), FALSE);
g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
+ if (group->priv->readonly)
+ return FALSE;
+
for (p = group->priv->sources; p != NULL; p = p->next) {
if (E_SOURCE (p->data) == source) {
group->priv->sources = g_slist_remove_link (group->priv->sources, p);
@@ -570,6 +625,9 @@
g_return_val_if_fail (E_IS_SOURCE_GROUP (group), FALSE);
g_return_val_if_fail (uid != NULL, FALSE);
+ if (group->priv->readonly)
+ return FALSE;
+
for (p = group->priv->sources; p != NULL; p = p->next) {
ESource *source = E_SOURCE (p->data);
@@ -601,7 +659,8 @@
xmlSetProp (root, "uid", e_source_group_peek_uid (group));
xmlSetProp (root, "name", e_source_group_peek_name (group));
xmlSetProp (root, "base_uri", e_source_group_peek_base_uri (group));
-
+ xmlSetProp (root, "readonly", group->priv->readonly ? "yes" : "no");
+
xmlDocSetRootElement (doc, root);
for (p = group->priv->sources; p != NULL; p = p->next)
Index: libedataserver/e-source-group.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserver/e-source-group.h,v
retrieving revision 1.2
diff -u -r1.2 e-source-group.h
--- libedataserver/e-source-group.h 21 Oct 2003 18:51:19 -0000 1.2
+++ libedataserver/e-source-group.h 7 Jan 2004 15:22:54 -0000
@@ -78,9 +78,13 @@
void e_source_group_set_base_uri (ESourceGroup *group,
const char *base_uri);
+void e_source_group_set_readonly (ESourceGroup *group,
+ gboolean readonly);
+
const char *e_source_group_peek_uid (ESourceGroup *group);
const char *e_source_group_peek_name (ESourceGroup *group);
const char *e_source_group_peek_base_uri (ESourceGroup *group);
+gboolean e_source_group_get_readonly (ESourceGroup *group);
GSList *e_source_group_peek_sources (ESourceGroup *group);
ESource *e_source_group_peek_source_by_uid (ESourceGroup *group,
Index: libedataserver/e-source.c
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserver/e-source.c,v
retrieving revision 1.10
diff -u -r1.10 e-source.c
--- libedataserver/e-source.c 18 Dec 2003 02:15:56 -0000 1.10
+++ libedataserver/e-source.c 7 Jan 2004 15:22:55 -0000
@@ -48,6 +48,8 @@
char *relative_uri;
char *absolute_uri;
+ gboolean readonly;
+
gboolean has_color;
guint32 color;
@@ -414,6 +416,9 @@
g_return_if_fail (E_IS_SOURCE (source));
g_return_if_fail (group == NULL || E_IS_SOURCE_GROUP (group));
+ if (source->priv->readonly)
+ return;
+
if (source->priv->group == group)
return;
@@ -439,6 +444,9 @@
{
g_return_if_fail (E_IS_SOURCE (source));
+ if (source->priv->readonly)
+ return;
+
if (source->priv->name == name)
return;
@@ -454,6 +462,9 @@
{
g_return_if_fail (E_IS_SOURCE (source));
+ if (source->priv->readonly)
+ return;
+
if (source->priv->relative_uri == relative_uri)
return;
@@ -464,11 +475,29 @@
}
void
+e_source_set_readonly (ESource *source,
+ gboolean readonly)
+{
+ g_return_if_fail (E_IS_SOURCE (source));
+
+ if (source->priv->readonly == readonly)
+ return;
+
+ source->priv->readonly = readonly;
+
+ g_signal_emit (source, signals[CHANGED], 0);
+
+}
+
+void
e_source_set_color (ESource *source,
guint32 color)
{
g_return_if_fail (E_IS_SOURCE (source));
+ if (source->priv->readonly)
+ return;
+
if (source->priv->has_color && source->priv->color == color)
return;
@@ -523,6 +552,15 @@
return source->priv->relative_uri;
}
+gboolean
+e_source_get_readonly (ESource *source)
+{
+ g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
+
+ return source->priv->readonly;
+}
+
+
/**
* e_source_get_color:
* @source: An ESource
@@ -596,7 +634,7 @@
xmlSetProp (node, "uid", e_source_peek_uid (source));
xmlSetProp (node, "name", e_source_peek_name (source));
xmlSetProp (node, "relative_uri", e_source_peek_relative_uri (source));
-
+
has_color = e_source_get_color (source, &color);
if (has_color) {
char *color_string = g_strdup_printf (COLOR_FORMAT_STRING, color);
Index: libedataserver/e-source.h
===================================================================
RCS file: /cvs/gnome/evolution-data-server/libedataserver/e-source.h,v
retrieving revision 1.6
diff -u -r1.6 e-source.h
--- libedataserver/e-source.h 17 Dec 2003 00:43:56 -0000 1.6
+++ libedataserver/e-source.h 7 Jan 2004 15:22:56 -0000
@@ -76,6 +76,8 @@
const char *name);
void e_source_set_relative_uri (ESource *source,
const char *relative_uri);
+void e_source_set_readonly (ESource *source,
+ gboolean readonly);
void e_source_set_color (ESource *source,
guint32 color);
void e_source_unset_color (ESource *source);
@@ -84,6 +86,7 @@
const char *e_source_peek_uid (ESource *source);
const char *e_source_peek_name (ESource *source);
const char *e_source_peek_relative_uri (ESource *source);
+gboolean e_source_get_readonly (ESource *source);
gboolean e_source_get_color (ESource *source,
guint32 *color_return);
Index: po/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-data-server/po/ChangeLog,v
retrieving revision 1.20
diff -u -r1.20 ChangeLog
--- po/ChangeLog 6 Jan 2004 16:43:39 -0000 1.20
+++ po/ChangeLog 7 Jan 2004 15:22:56 -0000
@@ -50,6 +50,10 @@
* it.po: updated italian translation
+2003-12-08 ERDI Gergo <cactus cactus rulez org>
+
+ * POTFILES.in: Added ContactDates backend source
+
2003-11-19 Marco Ciampa <ciampix libero it>
* it.po: updated italian translation
Index: po/POTFILES.in
===================================================================
RCS file: /cvs/gnome/evolution-data-server/po/POTFILES.in,v
retrieving revision 1.5
diff -u -r1.5 POTFILES.in
--- po/POTFILES.in 6 Nov 2003 17:40:03 -0000 1.5
+++ po/POTFILES.in 7 Jan 2004 15:22:56 -0000
@@ -11,6 +11,7 @@
calendar/libecal/e-cal.c
calendar/libedata-cal/e-cal-backend-sexp.c
calendar/backends/file/e-cal-backend-file.c
+calendar/backends/contacts/e-cal-backend-contacts.c
calendar/backends/http/e-cal-backend-http.c
src/GNOME_Evolution_DataServerLDAP.server.in.in
src/GNOME_Evolution_DataServerNOLDAP.server.in.in
Index: src/.cvsignore
===================================================================
RCS file: /cvs/gnome/evolution-data-server/src/.cvsignore,v
retrieving revision 1.2
diff -u -r1.2 .cvsignore
--- src/.cvsignore 6 Nov 2003 17:40:15 -0000 1.2
+++ src/.cvsignore 7 Jan 2004 15:22:56 -0000
@@ -6,4 +6,6 @@
Evolution-DataServer.h
GNOME_Evolution_DataServer.server.in.in
GNOME_Evolution_DataServer_1.0.server
-evolution-data-server
\ No newline at end of file
+GNOME_Evolution_ContactDatesServer_1.0.server
+evolution-data-server
+evolution-contactdates-server
\ No newline at end of file
Index: src/GNOME_Evolution_ContactDatesServer.server.in.in
===================================================================
RCS file: src/GNOME_Evolution_ContactDatesServer.server.in.in
diff -N src/GNOME_Evolution_ContactDatesServer.server.in.in
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/GNOME_Evolution_ContactDatesServer.server.in.in 7 Jan 2004 15:22:56 -0000
@@ -0,0 +1,31 @@
+<oaf_info>
+
+<oaf_server iid="OAFIID:GNOME_Evolution_ContactDatesServer_CalFactory"
+ type="exe"
+ location="@LIBEXECDIR@/evolution-contactdates-server- VERSION@">
+
+ <oaf_attribute name="repo_ids" type="stringv">
+ <item value="IDL:GNOME/Evolution/DataServer/CalFactory:1.0"/>
+ <item value="IDL:Bonobo/Unknown:1.0"/>
+ </oaf_attribute>
+
+ <oaf_attribute name="name" type="string"
+ _value="Evolution ContactDates Calendar backend"/>
+
+ <oaf_attribute name="calendar:supported_protocols" type="stringv">
+ <item value="contacts"/>
+ </oaf_attribute>
+</oaf_server>
+
+<oaf_server iid="OAFIID:GNOME_Evolution_ContactDatesServer_InterfaceCheck"
+ type="exe"
+ location="@LIBEXECDIR@/evolution-contactdates-server- VERSION@">
+
+ <oaf_attribute name="repo_ids" type="stringv">
+ <item value="IDL:GNOME/Evolution/ServerInterfaceCheck:1.0"/>
+ <item value="IDL:Bonobo/Unknown:1.0"/>
+ </oaf_attribute>
+
+</oaf_server>
+
+</oaf_info>
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution-data-server/src/Makefile.am,v
retrieving revision 1.10
diff -u -r1.10 Makefile.am
--- src/Makefile.am 30 Nov 2003 03:28:33 -0000 1.10
+++ src/Makefile.am 7 Jan 2004 15:22:56 -0000
@@ -34,8 +34,9 @@
$(IDL_GENERATED_C): $(IDL_GENERATED_H)
-noinst_PROGRAMS = \
- evolution-data-server
+noinst_PROGRAMS = \
+ evolution-data-server \
+ evolution-contactdates-server
evolution_data_server_SOURCES = \
$(IDL_GENERATED) \
@@ -45,6 +46,12 @@
server-logging.h \
server.c
+evolution_contactdates_server_SOURCES = \
+ $(IDL_GENERATED) \
+ server-interface-check.c \
+ server-interface-check.h \
+ contactdates-server.c
+
if ENABLE_LDAP
LDAP_BACKEND_LIB=$(top_builddir)/addressbook/backends/ldap/libebookbackendldap.la
else
@@ -60,13 +67,19 @@
$(top_builddir)/calendar/backends/file/libecalbackendfile.la \
$(top_builddir)/calendar/backends/groupwise/libecalbackendgroupwise.la \
$(top_builddir)/calendar/backends/http/libecalbackendhttp.la \
+ $(top_builddir)/calendar/backends/contacts/libecalbackendcontacts.la \
$(LDAP_LIBS) \
$(E_DATA_SERVER_LIBS)
-install-evolution-data-server:
+evolution_contactdates_server_LDADD = \
+ $(top_builddir)/addressbook/libebook/libebook.la \
+ $(top_builddir)/calendar/backends/contacts/libecalbackendcontacts.la \
+ $(E_DATA_SERVER_LIBS)
+
+install-evolution-data-servers:
$(mkinstalldirs) $(DESTDIR)$(libexecdir)
$(LIBTOOL) --mode=install $(INSTALL_PROGRAM) evolution-data-server $(DESTDIR)$(libexecdir)/evolution-data-server-$(BASE_VERSION)
-
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) evolution-contactdates-server $(DESTDIR)$(libexecdir)/evolution-contactdates-server-$(BASE_VERSION)
if ENABLE_LDAP
SERVER_IN_FILE=GNOME_Evolution_DataServerLDAP.server.in.in
@@ -77,7 +90,7 @@
GNOME_Evolution_DataServer.server.in.in: $(SERVER_IN_FILE) Makefile
cp $< $@
-server_in_files = GNOME_Evolution_DataServer.server.in.in
+server_in_files = GNOME_Evolution_DataServer.server.in.in GNOME_Evolution_ContactDatesServer.server.in.in
server_DATA = $(server_in_files:.server.in.in=_$(BASE_VERSION).server)
@EVO_SUBST_SERVER_RULE@
@EVO_NAME_SERVER_RULE@
@@ -89,12 +102,13 @@
$(server_in_files) \
$(idl_DATA) \
GNOME_Evolution_DataServerLDAP.server.in.in \
- GNOME_Evolution_DataServerNOLDAP.server.in.in
+ GNOME_Evolution_DataServerNOLDAP.server.in.in \
+ GNOME_Evolution_ContactDatesServer.server.in.in
BUILT_SOURCES = $(IDL_GENERATED) $(server_DATA)
CLEANFILES = $(BUILT_SOURCES)
-install-exec-local: install-evolution-data-server
+install-exec-local: install-evolution-data-servers
dist-hook:
cd $(distdir); rm -f $(BUILT_SOURCES)
Index: src/contactdates-server.c
===================================================================
RCS file: src/contactdates-server.c
diff -N src/contactdates-server.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/contactdates-server.c 7 Jan 2004 15:22:57 -0000
@@ -0,0 +1,209 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* contactdates-server.c
+ *
+ * Copyright (C) 2000-2003, Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Nat Friedman (nat ximian com)
+ * ERDI Gergo (cactus cactus rulez org)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* define this if you need/want to be able to send USR2 to server and
+ get a list of the active backends */
+/*#define DEBUG_BACKENDS*/
+
+#include <stdlib.h>
+#ifdef DEBUG_BACKENDS
+#include <sys/signal.h>
+#endif
+
+#include <glib.h>
+#include <libgnome/gnome-init.h>
+#include <bonobo-activation/bonobo-activation.h>
+#include <libgnomevfs/gnome-vfs-init.h>
+#include <bonobo/bonobo-main.h>
+#include <bonobo/bonobo-i18n.h>
+#include <bonobo/bonobo-exception.h>
+#include <bonobo/bonobo-generic-factory.h>
+
+#include <calendar/libedata-cal/e-data-cal-factory.h>
+#include <calendar/backends/contacts/e-cal-backend-contacts.h>
+
+#include "server-interface-check.h"
+
+#define SERVER_INTERFACE_CHECK_OAF_ID "OAFIID:GNOME_Evolution_ContactDatesServer_InterfaceCheck"
+
+#define CAL_FACTORY_OAF_ID "OAFIID:GNOME_Evolution_ContactDatesServer_CalFactory"
+
+/* The calendar factories */
+
+static EDataCalFactory *cal_factory;
+
+/* Timeout interval in milliseconds for termination */
+#define EXIT_TIMEOUT 5000
+
+/* Timeout ID for termination handler */
+static guint termination_handler_id;
+
+static GStaticMutex termination_lock = G_STATIC_MUTEX_INIT;
+
+
+
+/* Termination */
+
+/* Termination handler. Checks if both factories have zero running backends,
+ * and if so terminates the program.
+ */
+static gboolean
+termination_handler (gpointer data)
+{
+ if (e_data_cal_factory_get_n_backends (cal_factory) == 0) {
+ fprintf (stderr, "termination_handler(): Terminating the Server. Have a nice day.\n");
+ bonobo_main_quit ();
+ }
+
+ termination_handler_id = 0;
+ return FALSE;
+}
+
+/* Queues a timeout for handling termination of Server */
+static void
+queue_termination (void)
+{
+ g_static_mutex_lock (&termination_lock);
+ if (termination_handler_id)
+ g_source_remove (termination_handler_id);
+
+ termination_handler_id = g_timeout_add (EXIT_TIMEOUT, termination_handler, NULL);
+ g_static_mutex_unlock (&termination_lock);
+}
+
+
+
+/* Callback used when the calendar factory has no more running backends */
+static void
+last_calendar_gone_cb (EDataCalFactory *factory, gpointer data)
+{
+ queue_termination ();
+}
+
+/* Creates the calendar factory object and registers it */
+static gboolean
+setup_cals (void)
+{
+ cal_factory = e_data_cal_factory_new ();
+
+ if (!cal_factory) {
+ g_warning (G_STRLOC ": Could not create the calendar factory");
+ return FALSE;
+ }
+
+ e_data_cal_factory_register_method (cal_factory, "contacts", ICAL_VEVENT_COMPONENT, E_TYPE_CAL_BACKEND_CONTACTS);
+
+ if (!e_data_cal_factory_register_storage (cal_factory, CAL_FACTORY_OAF_ID)) {
+ bonobo_object_unref (BONOBO_OBJECT (cal_factory));
+ cal_factory = NULL;
+ return FALSE;
+ }
+
+ g_signal_connect (G_OBJECT (cal_factory),
+ "last_calendar_gone",
+ G_CALLBACK (last_calendar_gone_cb),
+ NULL);
+
+ return TRUE;
+}
+
+
+/* Interface check iface. */
+
+static gboolean
+setup_interface_check (void)
+{
+ ServerInterfaceCheck *interface_check_iface = server_interface_check_new ();
+ int result;
+
+ result = bonobo_activation_active_server_register (SERVER_INTERFACE_CHECK_OAF_ID,
+ BONOBO_OBJREF (interface_check_iface));
+
+ return result == Bonobo_ACTIVATION_REG_SUCCESS;
+}
+
+
+
+#ifdef DEBUG_BACKENDS
+static void
+dump_backends (int signal)
+{
+ e_data_cal_factory_dump_active_backends (cal_factory);
+}
+#endif
+
+int
+main (int argc, char **argv)
+{
+ gboolean did_books=FALSE, did_cals=FALSE;
+
+ bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
+ textdomain (GETTEXT_PACKAGE);
+
+ g_message ("Starting server");
+
+#ifdef DEBUG_BACKENDS
+ signal (SIGUSR2, dump_backends);
+#endif
+
+ gnome_program_init (PACKAGE, VERSION,
+ LIBGNOME_MODULE,
+ argc, argv,
+ GNOME_PROGRAM_STANDARD_PROPERTIES, NULL);
+
+ bonobo_init_full (&argc, argv,
+ bonobo_activation_orb_get(),
+ CORBA_OBJECT_NIL,
+ CORBA_OBJECT_NIL);
+
+ if (!setup_cals ()) {
+
+ g_error (G_STRLOC ": could not initialize Server service \"CALS\"; terminating");
+
+ if (cal_factory) {
+ bonobo_object_unref (BONOBO_OBJECT (cal_factory));
+ cal_factory = NULL;
+ }
+ exit (EXIT_FAILURE);
+ }
+
+ if (!setup_interface_check ()) {
+ g_error (G_STRLOC "Cannot register DataServer::InterfaceCheck object");
+ exit (EXIT_FAILURE);
+ }
+
+ g_message ("Server up and running\n");
+
+ bonobo_main ();
+
+ bonobo_object_unref (BONOBO_OBJECT (cal_factory));
+ cal_factory = NULL;
+
+ gnome_vfs_shutdown ();
+
+ return 0;
+}
? calendar/common/Makefile
? calendar/common/Makefile.in
? calendar/gui/apps_evolution_calendar-1.5.schemas
Index: calendar/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/calendar/ChangeLog,v
retrieving revision 1.2044
diff -u -r1.2044 ChangeLog
--- calendar/ChangeLog 7 Jan 2004 13:19:33 -0000 1.2044
+++ calendar/ChangeLog 7 Jan 2004 15:23:28 -0000
@@ -1,3 +1,8 @@
+2004-01-07 ERDI Gergo <cactus cactus rulez org>
+
+ * gui/calendar-component.c (impl_upgradeFromVersion): Create
+ ESource for anniversaries
+
2004-01-07 Rodrigo Moya <rodrigo ximian com>
* gui/alarm-notify/alarm-queue.c: added an ECalQuery for each loaded
Index: calendar/gui/calendar-component.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-component.c,v
retrieving revision 1.124
diff -u -r1.124 calendar-component.c
--- calendar/gui/calendar-component.c 6 Jan 2004 18:35:29 -0000 1.124
+++ calendar/gui/calendar-component.c 7 Jan 2004 15:23:33 -0000
@@ -139,6 +139,8 @@
selection = e_source_selector_get_selection (E_SOURCE_SELECTOR (priv->source_selector));
+ g_printf ("update_uris_for_selection\n");
+
for (l = priv->source_selection; l; l = l->next) {
ESource *old_selected_source = l->data;
@@ -168,7 +170,7 @@
ESource *source;
priv = calendar_component->priv;
-
+
source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->source_selector));
if (!source)
return;
@@ -257,6 +259,8 @@
comp = cal_comp_event_new_with_defaults (client);
+ g_return_val_if_fail (comp, NULL);
+
location = calendar_config_get_timezone ();
zone = icaltimezone_get_builtin_timezone (location);
@@ -551,11 +555,18 @@
g_free (new_dir);
}
+ g_free (base_uri);
+
/* create the remote source group */
group = e_source_group_new (_("On The Web"), "webcal://");
e_source_list_add_group (priv->source_list, group, -1);
- g_free (base_uri);
+ /* create calendar for birthdays & anniversaries */
+ group = e_source_group_new (_("Birthdays"), "contacts://");
+ source = e_source_new (_("Birthdays & Anniversaries"), "/");
+ e_source_group_add_source (group, source, -1);
+ e_source_group_set_readonly (group, TRUE);
+ e_source_list_add_group (priv->source_list, group, -1);
}
}
@@ -784,12 +795,18 @@
ECalComponent *comp;
EventEditor *editor;
gboolean is_meeting = FALSE;
+ gboolean read_only = FALSE;
priv = calendar_component->priv;
if (!setup_create_ecal (calendar_component)) {
bonobo_exception_set (ev, ex_GNOME_Evolution_Component_Failed);
return;
+
+ e_cal_is_read_only (priv->create_ecal, &read_only, NULL);
+ if (read_only)
+ return;
+
}
editor = event_editor_new (priv->create_ecal);
Index: calendar/gui/comp-editor-factory.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/comp-editor-factory.c,v
retrieving revision 1.32
diff -u -r1.32 comp-editor-factory.c
--- calendar/gui/comp-editor-factory.c 22 Dec 2003 15:57:21 -0000 1.32
+++ calendar/gui/comp-editor-factory.c 7 Jan 2004 15:23:34 -0000
@@ -305,6 +305,8 @@
comp = cal_comp_event_new_with_defaults (client);
+ g_return_val_if_fail (comp, NULL);
+
location = calendar_config_get_timezone ();
zone = icaltimezone_get_builtin_timezone (location);
Index: calendar/gui/comp-util.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/comp-util.c,v
retrieving revision 1.22
diff -u -r1.22 comp-util.c
--- calendar/gui/comp-util.c 7 Nov 2003 05:51:58 -0000 1.22
+++ calendar/gui/comp-util.c 7 Jan 2004 15:23:35 -0000
@@ -255,7 +255,9 @@
ECalComponentAlarmTrigger trigger;
if (!e_cal_get_default_object (client, &icalcomp, NULL))
+ {
return NULL;
+ }
comp = e_cal_component_new ();
if (!e_cal_component_set_icalcomponent (comp, icalcomp)) {
Index: calendar/gui/goto.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/goto.c,v
retrieving revision 1.42
diff -u -r1.42 goto.c
--- calendar/gui/goto.c 5 Dec 2003 01:59:43 -0000 1.42
+++ calendar/gui/goto.c 7 Jan 2004 15:23:37 -0000
@@ -206,6 +206,8 @@
struct icaltimetype tt;
int b;
+ g_warning ("goto_dialog 1");
+
if (dlg) {
return;
}
@@ -227,6 +229,8 @@
}
dlg->gcal = gcal;
+ g_warning ("goto_dialog 2");
+
gnome_calendar_get_selected_time_range (dlg->gcal, &start_time, NULL);
tt = icaltime_from_timet_with_zone (start_time, FALSE, gnome_calendar_get_timezone (gcal));
dlg->year_val = tt.year;
@@ -241,6 +245,8 @@
goto_dialog_init_widgets (dlg);
+ g_warning ("goto_dialog 3");
+
gtk_window_set_transient_for (GTK_WINDOW (dlg->dialog),
GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))));
@@ -254,9 +260,13 @@
gnome_canvas_item_grab_focus (GNOME_CANVAS_ITEM (dlg->ecal->calitem));
+ g_warning ("goto_dialog 4");
+
b = gtk_dialog_run (GTK_DIALOG (dlg->dialog));
gtk_widget_destroy (dlg->dialog);
+ g_warning ("goto_dialog 5");
+
if (b == 0)
goto_today (dlg);
Index: calendar/gui/dialogs/new-calendar.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/dialogs/new-calendar.c,v
retrieving revision 1.6
diff -u -r1.6 new-calendar.c
--- calendar/gui/dialogs/new-calendar.c 24 Nov 2003 10:13:24 -0000 1.6
+++ calendar/gui/dialogs/new-calendar.c 7 Jan 2004 15:23:38 -0000
@@ -132,7 +132,8 @@
* silently translate an explicit file:// into http:// though. */
if (uri->protocol &&
strcmp (uri->protocol, "http") &&
- strcmp (uri->protocol, "webcal")) {
+ strcmp (uri->protocol, "webcal") &&
+ strcmp (uri->protocol, "contacts")) {
e_uri_free (uri);
e_notice (parent, GTK_MESSAGE_ERROR,
_("The source location '%s' is not a webcal source."),
--
.--= ULLA! =---------------------. `We are not here to give users what
\ http://cactus.rulez.org \ they want' -- RMS, at GUADEC 2001
`---= cactus cactus rulez org =---'
Most books on HTML are written by people who would think DTD is a poisonous chemical.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]