From 09a335ec7b854bf4bc4c96c812b0655164f0a5a8 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 24 Sep 2011 09:48:52 -0400 Subject: Adapt itip-formatter plugin to the new ESource API. --- plugins/itip-formatter/Makefile.am | 62 +- .../itip-formatter/e-conflict-search-selector.c | 105 ++++ .../itip-formatter/e-conflict-search-selector.h | 64 ++ plugins/itip-formatter/e-source-conflict-search.c | 151 +++++ plugins/itip-formatter/e-source-conflict-search.h | 86 +++ plugins/itip-formatter/itip-formatter.c | 653 +++++++++++---------- plugins/itip-formatter/itip-view.c | 579 +++++++++++------- plugins/itip-formatter/itip-view.h | 17 +- 8 files changed, 1166 insertions(+), 551 deletions(-) create mode 100644 plugins/itip-formatter/e-conflict-search-selector.c create mode 100644 plugins/itip-formatter/e-conflict-search-selector.h create mode 100644 plugins/itip-formatter/e-source-conflict-search.c create mode 100644 plugins/itip-formatter/e-source-conflict-search.h (limited to 'plugins') diff --git a/plugins/itip-formatter/Makefile.am b/plugins/itip-formatter/Makefile.am index e0672eb734..af8f6c8668 100644 --- a/plugins/itip-formatter/Makefile.am +++ b/plugins/itip-formatter/Makefile.am @@ -1,32 +1,45 @@ +NULL = + @EVO_PLUGIN_RULE@ plugin_DATA = org-gnome-itip-formatter.eplug plugin_LTLIBRARIES = liborg-gnome-itip-formatter.la -liborg_gnome_itip_formatter_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -I$(top_srcdir) \ - -I$(top_srcdir)/widgets \ - -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) - -liborg_gnome_itip_formatter_la_SOURCES = itip-formatter.c itip-view.c itip-view.h - -liborg_gnome_itip_formatter_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED) - -liborg_gnome_itip_formatter_la_LIBADD = \ - $(top_builddir)/e-util/libeutil.la \ - $(top_builddir)/calendar/gui/libevolution-calendar.la \ - $(top_builddir)/mail/libevolution-mail.la \ - $(top_builddir)/shell/libeshell.la \ - $(top_builddir)/em-format/libemformat.la \ - $(top_builddir)/widgets/misc/libemiscwidgets.la \ - $(top_builddir)/libemail-utils/libemail-utils.la \ - $(top_builddir)/libemail-engine/libemail-engine.la \ +liborg_gnome_itip_formatter_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(top_srcdir) \ + -I$(top_srcdir)/widgets \ + -DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\" \ + $(EVOLUTION_DATA_SERVER_CFLAGS) \ + $(GNOME_PLATFORM_CFLAGS) \ + $(NULL) + +liborg_gnome_itip_formatter_la_SOURCES = \ + e-conflict-search-selector.c \ + e-conflict-search-selector.h \ + e-source-conflict-search.c \ + e-source-conflict-search.h \ + itip-formatter.c \ + itip-view.c \ + itip-view.h \ + $(NULL) + +liborg_gnome_itip_formatter_la_LDFLAGS = \ + -module -avoid-version $(NO_UNDEFINED) + +liborg_gnome_itip_formatter_la_LIBADD = \ + $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/calendar/gui/libevolution-calendar.la \ + $(top_builddir)/mail/libevolution-mail.la \ + $(top_builddir)/shell/libeshell.la \ + $(top_builddir)/em-format/libemformat.la \ + $(top_builddir)/widgets/misc/libemiscwidgets.la \ + $(top_builddir)/libemail-utils/libemail-utils.la \ + $(top_builddir)/libemail-engine/libemail-engine.la \ $(top_builddir)/libevolution-utils/libevolution-utils.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) + $(EVOLUTION_DATA_SERVER_LIBS) \ + $(GNOME_PLATFORM_LIBS) \ + $(NULL) error_DATA = org-gnome-itip-formatter.error errordir = $(privdatadir)/errors @@ -37,6 +50,7 @@ CLEANFILES = $(BUILT_SOURCES) EXTRA_DIST = \ org-gnome-itip-formatter.eplug.xml \ - org-gnome-itip-formatter.error.xml + org-gnome-itip-formatter.error.xml \ + $(NULL) -include $(top_srcdir)/git.mk diff --git a/plugins/itip-formatter/e-conflict-search-selector.c b/plugins/itip-formatter/e-conflict-search-selector.c new file mode 100644 index 0000000000..c1c1f0ef3b --- /dev/null +++ b/plugins/itip-formatter/e-conflict-search-selector.c @@ -0,0 +1,105 @@ +/* + * e-conflict-search-selector.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 + * + */ + +#include "e-conflict-search-selector.h" + +#include + +#include "e-source-conflict-search.h" + +/* This forces the GType to be registered in a way that + * avoids a "statement with no effect" compiler warning. */ +#define REGISTER_TYPE(type) \ + (g_type_class_unref (g_type_class_ref (type))) + +G_DEFINE_TYPE ( + EConflictSearchSelector, + e_conflict_search_selector, + E_TYPE_SOURCE_SELECTOR) + +static gboolean +conflict_search_selector_get_source_selected (ESourceSelector *selector, + ESource *source) +{ + ESourceConflictSearch *extension; + const gchar *extension_name; + + /* Make sure this source is a calendar. */ + extension_name = e_source_selector_get_extension_name (selector); + if (!e_source_has_extension (source, extension_name)) + return FALSE; + + extension_name = E_SOURCE_EXTENSION_CONFLICT_SEARCH; + extension = e_source_get_extension (source, extension_name); + g_return_val_if_fail (E_IS_SOURCE_CONFLICT_SEARCH (extension), FALSE); + + return e_source_conflict_search_get_include_me (extension); +} + +static void +conflict_search_selector_set_source_selected (ESourceSelector *selector, + ESource *source, + gboolean selected) +{ + ESourceConflictSearch *extension; + const gchar *extension_name; + + /* Make sure this source is a calendar. */ + extension_name = e_source_selector_get_extension_name (selector); + if (!e_source_has_extension (source, extension_name)) + return; + + extension_name = E_SOURCE_EXTENSION_CONFLICT_SEARCH; + extension = e_source_get_extension (source, extension_name); + g_return_if_fail (E_IS_SOURCE_CONFLICT_SEARCH (extension)); + + if (selected != e_source_conflict_search_get_include_me (extension)) { + e_source_conflict_search_set_include_me (extension, selected); + e_source_selector_queue_write (selector, source); + } +} + +static void +e_conflict_search_selector_class_init (EConflictSearchSelectorClass *class) +{ + ESourceSelectorClass *source_selector_class; + + source_selector_class = E_SOURCE_SELECTOR_CLASS (class); + source_selector_class->get_source_selected = + conflict_search_selector_get_source_selected; + source_selector_class->set_source_selected = + conflict_search_selector_set_source_selected; + + REGISTER_TYPE (E_TYPE_SOURCE_CONFLICT_SEARCH); +} + +static void +e_conflict_search_selector_init (EConflictSearchSelector *selector) +{ +} + +GtkWidget * +e_conflict_search_selector_new (ESourceRegistry *registry) +{ + g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); + + return g_object_new ( + E_TYPE_CONFLICT_SEARCH_SELECTOR, + "extension-name", E_SOURCE_EXTENSION_CALENDAR, + "registry", registry, NULL); +} diff --git a/plugins/itip-formatter/e-conflict-search-selector.h b/plugins/itip-formatter/e-conflict-search-selector.h new file mode 100644 index 0000000000..64981d8e55 --- /dev/null +++ b/plugins/itip-formatter/e-conflict-search-selector.h @@ -0,0 +1,64 @@ +/* + * e-conflict-search-selector.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 + * + */ + +#ifndef E_CONFLICT_SEARCH_SELECTOR_H +#define E_CONFLICT_SEARCH_SELECTOR_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_CONFLICT_SEARCH_SELECTOR \ + (e_conflict_search_selector_get_type ()) +#define E_CONFLICT_SEARCH_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_CONFLICT_SEARCH_SELECTOR, EConflictSearchSelector)) +#define E_CONFLICT_SEARCH_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_CONFLICT_SEARCH_SELECTOR, EConflictSearchSelectorClass)) +#define E_IS_CONFLICT_SEARCH_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_CONFLICT_SEARCH_SELECTOR)) +#define E_IS_CONFLICT_SEARCH_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_CONFLICT_SEARCH_SELECTOR)) +#define E_CONFLICT_SEARCH_SELECTOR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_CONFLICT_SEARCH_SELECTOR, EConflictSearchSelectorClass)) + +G_BEGIN_DECLS + +typedef struct _EConflictSearchSelector EConflictSearchSelector; +typedef struct _EConflictSearchSelectorClass EConflictSearchSelectorClass; +typedef struct _EConflictSearchSelectorPrivate EConflictSearchSelectorPrivate; + +struct _EConflictSearchSelector { + ESourceSelector parent; + EConflictSearchSelectorPrivate *priv; +}; + +struct _EConflictSearchSelectorClass { + ESourceSelectorClass parent_class; +}; + +GType e_conflict_search_selector_get_type + (void) G_GNUC_CONST; +GtkWidget * e_conflict_search_selector_new (ESourceRegistry *registry); + +G_END_DECLS + +#endif /* E_CONFLICT_SEARCH_SELECTOR_H */ diff --git a/plugins/itip-formatter/e-source-conflict-search.c b/plugins/itip-formatter/e-source-conflict-search.c new file mode 100644 index 0000000000..c2f5eb6e99 --- /dev/null +++ b/plugins/itip-formatter/e-source-conflict-search.c @@ -0,0 +1,151 @@ +/* + * e-source-conflict-search.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 + * + */ + +#include "e-source-conflict-search.h" + +#define E_SOURCE_CONFLICT_SEARCH_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_SOURCE_CONFLICT_SEARCH, ESourceConflictSearchPrivate)) + +struct _ESourceConflictSearchPrivate { + gboolean include_me; +}; + +enum { + PROP_0, + PROP_INCLUDE_ME +}; + +G_DEFINE_TYPE ( + ESourceConflictSearch, + e_source_conflict_search, + E_TYPE_SOURCE_EXTENSION) + +static void +source_conflict_search_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_INCLUDE_ME: + e_source_conflict_search_set_include_me ( + E_SOURCE_CONFLICT_SEARCH (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +source_conflict_search_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_INCLUDE_ME: + g_value_set_boolean ( + value, + e_source_conflict_search_get_include_me ( + E_SOURCE_CONFLICT_SEARCH (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +e_source_conflict_search_class_init (ESourceConflictSearchClass *class) +{ + GObjectClass *object_class; + ESourceExtensionClass *extension_class; + + g_type_class_add_private (class, sizeof (ESourceConflictSearchPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = source_conflict_search_set_property; + object_class->get_property = source_conflict_search_get_property; + + extension_class = E_SOURCE_EXTENSION_CLASS (class); + extension_class->name = E_SOURCE_EXTENSION_CONFLICT_SEARCH; + + g_object_class_install_property ( + object_class, + PROP_INCLUDE_ME, + g_param_spec_boolean ( + "include-me", + "IncludeMe", + "Include this calendar in when " + "searching for scheduling conflicts", + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS | + E_SOURCE_PARAM_SETTING)); +} + +static void +e_source_conflict_search_init (ESourceConflictSearch *extension) +{ + extension->priv = E_SOURCE_CONFLICT_SEARCH_GET_PRIVATE (extension); +} + +/** + * e_source_conflict_search_get_include_me: + * @extension: an #ESourceConflictSearch + * + * Returns whether the calendar described by the #ESource to which + * @extension belongs should be queried for scheduling conflicts when + * negotiating a meeting invitation. + * + * Returns: whether to search for scheduling conflicts + * + * Since: 3.6 + **/ +gboolean +e_source_conflict_search_get_include_me (ESourceConflictSearch *extension) +{ + g_return_val_if_fail (E_IS_SOURCE_CONFLICT_SEARCH (extension), FALSE); + + return extension->priv->include_me; +} + +/** + * e_source_conflict_search_set_include_me: + * @extension: an #ESourceConflictSearch + * @include_me: whether to search for scheduling conflicts + * + * Sets whether the calendar described by the #ESource to which @extension + * belongs should be queried for scheduling conflicts when negotiating a + * meeting invitation. + * + * Since: 3.6 + **/ +void +e_source_conflict_search_set_include_me (ESourceConflictSearch *extension, + gboolean include_me) +{ + g_return_if_fail (E_IS_SOURCE_CONFLICT_SEARCH (extension)); + + extension->priv->include_me = include_me; + + g_object_notify (G_OBJECT (extension), "include-me"); +} + diff --git a/plugins/itip-formatter/e-source-conflict-search.h b/plugins/itip-formatter/e-source-conflict-search.h new file mode 100644 index 0000000000..d574bbd2b9 --- /dev/null +++ b/plugins/itip-formatter/e-source-conflict-search.h @@ -0,0 +1,86 @@ +/* + * e-source-conflict-search.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 + * + */ + +#ifndef E_SOURCE_CONFLICT_SEARCH_H +#define E_SOURCE_CONFLICT_SEARCH_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_SOURCE_CONFLICT_SEARCH \ + (e_source_conflict_search_get_type ()) +#define E_SOURCE_CONFLICT_SEARCH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_SOURCE_CONFLICT_SEARCH, ESourceConflictSearch)) +#define E_SOURCE_CONFLICT_SEARCH_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_SOURCE_CONFLICT_SEARCH, ESourceConflictSearchClass)) +#define E_IS_SOURCE_CONFLICT_SEARCH(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_SOURCE_CONFLICT_SEARCH)) +#define E_IS_SOURCE_CONFLICT_SEARCH_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_SOURCE_CONFLICT_SEARCH)) +#define E_SOURCE_CONFLICT_SEARCH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_SOURCE_CONFLICT_SEARCH, ESourceConflictSearchClass)) + +/** + * E_SOURCE_EXTENSION_CONFLICT_SEARCH: + * + * Pass this extension name to e_source_get_extension() to access + * #ESourceConflictSearch. This is also used as a group name in key files. + * + * Since: 3.6 + **/ +#define E_SOURCE_EXTENSION_CONFLICT_SEARCH "Conflict Search" + +G_BEGIN_DECLS + +typedef struct _ESourceConflictSearch ESourceConflictSearch; +typedef struct _ESourceConflictSearchClass ESourceConflictSearchClass; +typedef struct _ESourceConflictSearchPrivate ESourceConflictSearchPrivate; + +/** + * ESourceConflictSearch: + * + * Contains only private data that should be read and manipulated using the + * functions below. + * + * Since: 3.6 + **/ +struct _ESourceConflictSearch { + ESourceExtension parent; + ESourceConflictSearchPrivate *priv; +}; + +struct _ESourceConflictSearchClass { + ESourceExtensionClass parent_class; +}; + +GType e_source_conflict_search_get_type + (void) G_GNUC_CONST; +gboolean e_source_conflict_search_get_include_me + (ESourceConflictSearch *extension); +void e_source_conflict_search_set_include_me + (ESourceConflictSearch *extension, + gboolean include_me); + +G_END_DECLS + +#endif /* E_SOURCE_CONFLICT_SEARCH_H */ diff --git a/plugins/itip-formatter/itip-formatter.c b/plugins/itip-formatter/itip-formatter.c index 63b74ac3ab..ed5ab58fda 100644 --- a/plugins/itip-formatter/itip-formatter.c +++ b/plugins/itip-formatter/itip-formatter.c @@ -30,7 +30,8 @@ #include #include -#include +#include +#include #include #include @@ -40,7 +41,6 @@ #include #include -#include #include #include @@ -55,6 +55,8 @@ #include +#include "e-conflict-search-selector.h" +#include "e-source-conflict-search.h" #include "itip-view.h" #define CONF_KEY_DELETE "delete-processed" @@ -71,7 +73,7 @@ struct _ItipPURI { gchar *uid; - ESourceList *source_lists[E_CAL_CLIENT_SOURCE_TYPE_LAST]; + ESourceRegistry *registry; GHashTable *clients[E_CAL_CLIENT_SOURCE_TYPE_LAST]; ECalClient *current_client; @@ -95,8 +97,6 @@ struct _ItipPURI { gchar *calendar_uid; - EAccountList *accounts; - gchar *from_address; gchar *from_name; gchar *to_address; @@ -247,133 +247,154 @@ find_to_address (ItipPURI *pitip, icalcomponent *ical_comp, icalparameter_partstat *status) { - EIterator *it; + ESourceRegistry *registry; + ESourceMailIdentity *extension; + GList *list, *link; + const gchar *extension_name; - it = e_list_get_iterator ((EList *) pitip->accounts); + registry = pitip->registry; + extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY; - if (!pitip->to_address && pitip->msg && pitip->folder) { - EAccount *account = em_utils_guess_account (pitip->msg, pitip->folder); + if (pitip->to_address != NULL) + return; - if (account) { - pitip->to_address = g_strdup (e_account_get_string (account, E_ACCOUNT_ID_ADDRESS)); - if (pitip->to_address && !*pitip->to_address) { - g_free (pitip->to_address); - pitip->to_address = NULL; - } + if (pitip->msg != NULL && pitip->folder != NULL) { + ESource *source; + + source = em_utils_guess_mail_identity ( + registry, pitip->msg, pitip->folder); + + if (source != NULL) { + extension = e_source_get_extension (source, extension_name); + + pitip->to_address = e_source_mail_identity_dup_address (extension); + + g_object_unref (source); } } + if (pitip->to_address != NULL) + return; + /* Look through the list of attendees to find the user's address */ - if (!pitip->to_address) - while (e_iterator_is_valid (it)) { - const EAccount *account = e_iterator_get (it); - icalproperty *prop = NULL; - if (!account->enabled) { - e_iterator_next (it); - continue; - } + list = e_source_registry_list_sources (registry, extension_name); - prop = find_attendee (ical_comp, account->id->address); + for (link = list; link != NULL; link = g_list_next (link)) { + ESource *source = E_SOURCE (link->data); + icalproperty *prop = NULL; + icalparameter *param; + const gchar *address; + gchar *text; - if (prop) { - gchar *text; - icalparameter *param; + if (!e_source_get_enabled (source)) + continue; - param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER); - if (param) - pitip->to_name = g_strdup (icalparameter_get_cn (param)); + extension = e_source_get_extension (source, extension_name); + address = e_source_mail_identity_get_address (extension); - text = icalproperty_get_value_as_string_r (prop); + prop = find_attendee (ical_comp, address); + if (prop == NULL) + continue; - pitip->to_address = g_strdup (itip_strip_mailto (text)); - g_free (text); - g_strstrip (pitip->to_address); + param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER); + if (param != NULL) + pitip->to_name = g_strdup (icalparameter_get_cn (param)); - pitip->my_address = g_strdup (account->id->address); + text = icalproperty_get_value_as_string_r (prop); - param = icalproperty_get_first_parameter (prop, ICAL_RSVP_PARAMETER); - if (param && - icalparameter_get_rsvp (param) == ICAL_RSVP_FALSE) { - pitip->no_reply_wanted = TRUE; - } + pitip->to_address = g_strdup (itip_strip_mailto (text)); + g_free (text); + g_strstrip (pitip->to_address); - if (status) { - param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER); - *status = param ? icalparameter_get_partstat (param) : ICAL_PARTSTAT_NEEDSACTION; - } + pitip->my_address = g_strdup (address); - break; - } - e_iterator_next (it); + param = icalproperty_get_first_parameter (prop, ICAL_RSVP_PARAMETER); + if (param != NULL && + icalparameter_get_rsvp (param) == ICAL_RSVP_FALSE) + pitip->no_reply_wanted = TRUE; + + if (status) { + param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER); + *status = param ? icalparameter_get_partstat (param) : ICAL_PARTSTAT_NEEDSACTION; } - e_iterator_reset (it); + break; + } + + g_list_free_full (list, (GDestroyNotify) g_object_unref); + + if (pitip->to_address != NULL) + return; - /* If the user's address was not found in the attendee's list, then the user - * might be responding on behalf of his/her delegator. In this case, we - * would want to go through the SENT-BY fields of the attendees to find - * the user's address. + /* If the user's address was not found in the attendee's list, + * then the user might be responding on behalf of his/her delegator. + * In this case, we would want to go through the SENT-BY fields of + * the attendees to find the user's address. * - * Note: This functionality could have been (easily) implemented in the - * previous loop, but it would hurt the performance for all providers in - * general. Hence, we choose to iterate through the accounts list again. + * Note: This functionality could have been (easily) implemented + * in the previous loop, but it would hurt the performance for all + * providers in general. Hence, we choose to iterate through the + * accounts list again. */ - if (!pitip->to_address) - while (e_iterator_is_valid (it)) { - const EAccount *account = e_iterator_get (it); - icalproperty *prop = NULL; - if (!account->enabled) { - e_iterator_next (it); - continue; - } + list = e_source_registry_list_sources (registry, extension_name); - prop = find_attendee_if_sentby (ical_comp, account->id->address); + for (link = list; link != NULL; link = g_list_next (link)) { + ESource *source = E_SOURCE (link->data); + icalproperty *prop = NULL; + icalparameter *param; + const gchar *address; + gchar *text; - if (prop) { - gchar *text; - icalparameter *param; - param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER); - if (param) - pitip->to_name = g_strdup (icalparameter_get_cn (param)); + if (!e_source_get_enabled (source)) + continue; - text = icalproperty_get_value_as_string_r (prop); + extension = e_source_get_extension (source, extension_name); + address = e_source_mail_identity_get_address (extension); - pitip->to_address = g_strdup (itip_strip_mailto (text)); - g_free (text); - g_strstrip (pitip->to_address); + prop = find_attendee_if_sentby (ical_comp, address); + if (prop == NULL) + continue; - pitip->my_address = g_strdup (account->id->address); + param = icalproperty_get_first_parameter (prop, ICAL_CN_PARAMETER); + if (param != NULL) + pitip->to_name = g_strdup (icalparameter_get_cn (param)); - param = icalproperty_get_first_parameter (prop, ICAL_RSVP_PARAMETER); - if (param && - ICAL_RSVP_FALSE == icalparameter_get_rsvp (param)) { - pitip->no_reply_wanted = TRUE; - } + text = icalproperty_get_value_as_string_r (prop); - if (status) { - param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER); - *status = param ? icalparameter_get_partstat (param) : ICAL_PARTSTAT_NEEDSACTION; - } + pitip->to_address = g_strdup (itip_strip_mailto (text)); + g_free (text); + g_strstrip (pitip->to_address); - break; - } - e_iterator_next (it); + pitip->my_address = g_strdup (address); + + param = icalproperty_get_first_parameter (prop, ICAL_RSVP_PARAMETER); + if (param != NULL && + ICAL_RSVP_FALSE == icalparameter_get_rsvp (param)) + pitip->no_reply_wanted = TRUE; + + if (status) { + param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER); + *status = param ? icalparameter_get_partstat (param) : ICAL_PARTSTAT_NEEDSACTION; } - g_object_unref (it); + break; + } + + g_list_free_full (list, (GDestroyNotify) g_object_unref); } static void find_from_address (ItipPURI *pitip, icalcomponent *ical_comp) { - EIterator *it; + GList *list, *link; icalproperty *prop; gchar *organizer; icalparameter *param; + const gchar *extension_name; const gchar *organizer_sentby; gchar *organizer_clean = NULL; gchar *organizer_sentby_clean = NULL; @@ -408,24 +429,33 @@ find_from_address (ItipPURI *pitip, if (param) pitip->from_name = g_strdup (icalparameter_get_cn (param)); - it = e_list_get_iterator ((EList *) pitip->accounts); - while (e_iterator_is_valid (it)) { - const EAccount *account = e_iterator_get (it); + extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY; + list = e_source_registry_list_sources (pitip->registry, extension_name); - if (!account->enabled) { - e_iterator_next (it); + for (link = list; link != NULL; link = g_list_next (link)) { + ESource *source = E_SOURCE (link->data); + ESourceMailIdentity *extension; + const gchar *address; + + if (!e_source_get_enabled (source)) + continue; + + extension = e_source_get_extension (source, extension_name); + address = e_source_mail_identity_get_address (extension); + + if (address == NULL) continue; - } - if ((organizer_clean && !g_ascii_strcasecmp (organizer_clean, account->id->address)) - || (organizer_sentby_clean && !g_ascii_strcasecmp (organizer_sentby_clean, account->id->address))) { - pitip->my_address = g_strdup (account->id->address); + if ((organizer_clean && !g_ascii_strcasecmp (organizer_clean, address)) + || (organizer_sentby_clean && !g_ascii_strcasecmp (organizer_sentby_clean, address))) { + pitip->my_address = g_strdup (address); break; } - e_iterator_next (it); } - g_object_unref (it); + + g_list_free_full (list, (GDestroyNotify) g_object_unref); + g_free (organizer_sentby_clean); g_free (organizer_clean); } @@ -601,7 +631,6 @@ start_calendar_server (ItipPURI *pitip, type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS ? E_CLIENT_SOURCE_TYPE_MEMOS : type == E_CAL_CLIENT_SOURCE_TYPE_TASKS ? E_CLIENT_SOURCE_TYPE_TASKS : E_CLIENT_SOURCE_TYPE_LAST, TRUE, pitip->cancellable, - e_client_utils_authenticate_handler, NULL, func, data); } @@ -611,18 +640,15 @@ start_calendar_server_by_uid (ItipPURI *pitip, const gchar *uid, ECalClientSourceType type) { - gint i; + ESource *source; itip_view_set_buttons_sensitive (view, FALSE); - for (i = 0; i < E_CAL_CLIENT_SOURCE_TYPE_LAST; i++) { - ESource *source; - - source = e_source_list_peek_source_by_uid (pitip->source_lists[i], uid); - if (source) { - start_calendar_server (pitip, view, source, type, cal_opened_cb, view); - break; - } + source = e_source_registry_ref_source (pitip->registry, uid); + if (source != NULL) { + start_calendar_server ( + pitip, view, source, type, cal_opened_cb, view); + g_object_unref (source); } } @@ -749,53 +775,34 @@ decrease_find_data (FormatItipFindData *fd) && !pitip->current_client) { /* Reuse already declared one or rename? */ ESource *source = NULL; + const gchar *extension_name; - /* Try to create a default if there isn't one */ - source = e_source_list_peek_default_source (pitip->source_lists[pitip->type]); - - if (!source) { - EShell *shell; - EShellSettings *shell_settings; - gchar *uid; - - /* FIXME Find a better way to obtain the shell. */ - shell = e_shell_get_default (); - shell_settings = e_shell_get_shell_settings (shell); - - switch (pitip->type) { + switch (pitip->type) { case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - uid = e_shell_settings_get_string ( - shell_settings, "cal-primary-calendar"); + extension_name = E_SOURCE_EXTENSION_CALENDAR; break; case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - uid = e_shell_settings_get_string ( - shell_settings, "cal-primary-task-list"); + extension_name = E_SOURCE_EXTENSION_TASK_LIST; break; case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - uid = e_shell_settings_get_string ( - shell_settings, "cal-primary-memo-list"); + extension_name = E_SOURCE_EXTENSION_MEMO_LIST; break; default: - uid = NULL; - g_assert_not_reached (); - } - - if (uid) { - source = e_source_list_peek_source_by_uid (pitip->source_lists[pitip->type], uid); - g_free (uid); - } + g_return_if_reached (); } - if (!source) - source = e_source_list_peek_source_any (pitip->source_lists[pitip->type]); + source = e_source_registry_ref_default_for_extension_name ( + pitip->registry, extension_name); + + itip_view_set_extension_name (view, extension_name); - itip_view_set_source_list (view, pitip->source_lists[pitip->type]); g_signal_connect ( view, "source_selected", G_CALLBACK (source_selected_cb), pitip); - if (source) { + if (source != NULL) { itip_view_set_source (view, source); + g_object_unref (source); /* FIXME Shouldn't the buttons be sensitized here? */ } else { @@ -992,6 +999,8 @@ find_cal_opened_cb (GObject *source_object, ECalClientSourceType source_type; EClient *client = NULL; ECalClient *cal_client; + gboolean search_for_conflicts = FALSE; + const gchar *extension_name; const gchar *uid; GError *error = NULL; @@ -1039,18 +1048,32 @@ find_cal_opened_cb (GObject *source_object, g_hash_table_insert ( pitip->clients[source_type], g_strdup (uid), cal_client); + extension_name = E_SOURCE_EXTENSION_CONFLICT_SEARCH; + if (e_source_has_extension (source, extension_name)) { + ESourceConflictSearch *extension; + + extension = e_source_get_extension (source, extension_name); + search_for_conflicts = + (pitip->type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS) && + e_source_conflict_search_get_include_me (extension); + } + /* Check for conflicts */ /* If the query fails, we'll just ignore it */ /* FIXME What happens for recurring conflicts? */ - if (pitip->type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS - && e_source_get_property (E_SOURCE (source), "conflict") - && !g_ascii_strcasecmp (e_source_get_property (E_SOURCE (source), "conflict"), "true")) { - e_cal_client_get_object_list (cal_client, fd->sexp, fd->cancellable, get_object_list_ready_cb, fd); + if (search_for_conflicts) { + e_cal_client_get_object_list ( + cal_client, fd->sexp, + fd->cancellable, + get_object_list_ready_cb, fd); return; } if (!pitip->current_client) { - e_cal_client_get_object (cal_client, fd->uid, fd->rid, fd->cancellable, get_object_with_rid_ready_cb, fd); + e_cal_client_get_object ( + cal_client, fd->uid, fd->rid, + fd->cancellable, + get_object_with_rid_ready_cb, fd); return; } @@ -1063,77 +1086,93 @@ find_server (ItipPURI *pitip, ECalComponent *comp) { FormatItipFindData *fd = NULL; - GSList *groups, *l, *sources_conflict = NULL, *all_sources = NULL; const gchar *uid; gchar *rid = NULL; CamelStore *parent_store; - CamelURL *url; - gchar *uri; - ESource *source = NULL, *current_source = NULL; + ESourceRegistry *registry; + ESource *current_source = NULL; + GList *list, *link; + GList *conflict_list = NULL; + const gchar *extension_name; + const gchar *store_uid; g_return_if_fail (pitip->folder != NULL); + switch (pitip->type) { + case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: + extension_name = E_SOURCE_EXTENSION_CALENDAR; + break; + case E_CAL_CLIENT_SOURCE_TYPE_TASKS: + extension_name = E_SOURCE_EXTENSION_TASK_LIST; + break; + case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: + extension_name = E_SOURCE_EXTENSION_MEMO_LIST; + break; + default: + g_return_if_reached (); + } + + registry = pitip->registry; + list = e_source_registry_list_sources (registry, extension_name); + e_cal_component_get_uid (comp, &uid); rid = e_cal_component_get_recurid_as_string (comp); + /* XXX Not sure what this was trying to do, + * but it propbably doesn't work anymore. + * Some comments would have been helpful. */ parent_store = camel_folder_get_parent_store (pitip->folder); - - url = camel_service_new_camel_url (CAMEL_SERVICE (parent_store)); - uri = camel_url_to_string (url, CAMEL_URL_HIDE_ALL); - camel_url_free (url); + store_uid = camel_service_get_uid (CAMEL_SERVICE (parent_store)); itip_view_set_buttons_sensitive (view, FALSE); - groups = e_source_list_peek_groups (pitip->source_lists[pitip->type]); - for (l = groups; l; l = l->next) { - ESourceGroup *group; - GSList *sources, *m; - - group = l->data; - - sources = e_source_group_peek_sources (group); - for (m = sources; m; m = m->next) { - gchar *source_uri = NULL; - - source = m->data; + for (link = list; link != NULL; link = g_list_next (link)) { + ESource *source = E_SOURCE (link->data); + gboolean search_for_conflicts = FALSE; + const gchar *source_uid; - if (e_source_get_property (source, "conflict")) - sources_conflict = g_slist_prepend (sources_conflict, source); + extension_name = E_SOURCE_EXTENSION_CONFLICT_SEARCH; + if (e_source_has_extension (source, extension_name)) { + ESourceConflictSearch *extension; - if (current_source) - continue; + extension = + e_source_get_extension (source, extension_name); + search_for_conflicts = + e_source_conflict_search_get_include_me (extension); + } - source_uri = e_source_get_uri (source); - if (source_uri && (strcmp (uri, source_uri) == 0)) { - current_source = source; - sources_conflict = g_slist_prepend (sources_conflict, source); + if (search_for_conflicts) + conflict_list = g_list_prepend ( + conflict_list, g_object_ref (source)); - g_free (source_uri); - continue; - } + if (current_source != NULL) + continue; - all_sources = g_slist_prepend (all_sources, source); - g_free (source_uri); + source_uid = e_source_get_uid (source); + if (g_strcmp0 (source_uid, store_uid) == 0) { + current_source = source; + conflict_list = g_list_prepend ( + conflict_list, g_object_ref (source)); + continue; } } if (current_source) { - l = sources_conflict; + link = conflict_list; pitip->progress_info_id = itip_view_add_lower_info_item ( view, ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS, _("Opening the calendar. Please wait...")); } else { + link = list; pitip->progress_info_id = itip_view_add_lower_info_item ( view, ITIP_VIEW_INFO_ITEM_TYPE_PROGRESS, _("Searching for an existing version of this appointment")); - - l = all_sources; } - for (; l != NULL; l = l->next) { - source = l->data; + for (; link != NULL; link = g_list_next (link)) { + ESource *source = E_SOURCE (link->data); if (!fd) { gchar *start = NULL, *end = NULL; @@ -1163,20 +1202,24 @@ find_server (ItipPURI *pitip, d(printf ("Increasing itip formatter search count to %d\n", fd->count)); if (current_source == source) - start_calendar_server (pitip, view, source, pitip->type, find_cal_opened_cb, fd); + start_calendar_server ( + pitip, view, source, pitip->type, + find_cal_opened_cb, fd); else - start_calendar_server (pitip, view, source, pitip->type, find_cal_opened_cb, fd); - + start_calendar_server ( + pitip, view, source, pitip->type, + find_cal_opened_cb, fd); } - g_slist_free (all_sources); - g_slist_free (sources_conflict); - g_free (uri); + g_list_free_full (conflict_list, (GDestroyNotify) g_object_unref); + g_list_free_full (list, (GDestroyNotify) g_object_unref); + g_free (rid); } static gboolean -change_status (icalcomponent *ical_comp, +change_status (ESourceRegistry *registry, + icalcomponent *ical_comp, const gchar *address, icalparameter_partstat status) { @@ -1202,14 +1245,16 @@ change_status (icalcomponent *ical_comp, param = icalparameter_new_partstat (status); icalproperty_add_parameter (prop, param); } else { - EAccount *a; + gchar *default_name = NULL; + gchar *default_address = NULL; - a = e_get_default_account (); + itip_get_default_name_and_address ( + registry, &default_name, &default_address); - prop = icalproperty_new_attendee (a->id->address); + prop = icalproperty_new_attendee (default_address); icalcomponent_add_property (ical_comp, prop); - param = icalparameter_new_cn (a->id->name); + param = icalparameter_new_cn (default_name); icalproperty_add_parameter (prop, param); param = icalparameter_new_role (ICAL_ROLE_REQPARTICIPANT); @@ -1217,6 +1262,9 @@ change_status (icalcomponent *ical_comp, param = icalparameter_new_partstat (status); icalproperty_add_parameter (prop, param); + + g_free (default_name); + g_free (default_address); } } @@ -1465,7 +1513,12 @@ finish_message_delete_with_rsvp (ItipPURI *pitip, } e_cal_component_rescan (comp); - if (itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, pitip->current_client, pitip->top_level, NULL, NULL, TRUE, FALSE) && pitip->folder) { + if (itip_send_comp ( + pitip->registry, + E_CAL_COMPONENT_METHOD_REPLY, + comp, pitip->current_client, + pitip->top_level, NULL, NULL, TRUE, FALSE) && + pitip->folder != NULL) { camel_folder_set_message_flags ( pitip->folder, pitip->uid, CAMEL_MESSAGE_ANSWERED, @@ -1504,7 +1557,7 @@ receive_objects_ready_cb (GObject *ecalclient, return; } - itip_view_set_source_list (view, NULL); + itip_view_set_extension_name (view, NULL); itip_view_clear_lower_info_items (view); @@ -1784,7 +1837,8 @@ set_attendee (ECalComponent *comp, } static gboolean -send_comp_to_attendee (ECalComponentItipMethod method, +send_comp_to_attendee (ESourceRegistry *registry, + ECalComponentItipMethod method, ECalComponent *comp, const gchar *user, ECalClient *client, @@ -1809,7 +1863,9 @@ send_comp_to_attendee (ECalComponentItipMethod method, } /* FIXME send the attachments in the request */ - status = itip_send_comp (method, send_comp, client, NULL, NULL, NULL, TRUE, FALSE); + status = itip_send_comp ( + registry, method, send_comp, + client, NULL, NULL, NULL, TRUE, FALSE); g_object_unref (send_comp); @@ -1828,10 +1884,12 @@ remove_delegate (ItipPURI *pitip, /* send cancellation notice to delegate */ status = send_comp_to_attendee ( + pitip->registry, E_CAL_COMPONENT_METHOD_CANCEL, pitip->comp, delegate, pitip->current_client, comment); if (status) send_comp_to_attendee ( + pitip->registry, E_CAL_COMPONENT_METHOD_REQUEST, pitip->comp, delegator, pitip->current_client, comment); if (status) { @@ -1977,11 +2035,15 @@ update_attendee_status_icalcomp (ItipPURI *pitip, } } - response = e_alert_run_dialog_for_args (e_shell_get_active_window (shell), - "org.gnome.itip-formatter:add-unknown-attendee", NULL); + response = e_alert_run_dialog_for_args ( + e_shell_get_active_window (shell), + "org.gnome.itip-formatter:add-unknown-attendee", NULL); if (response == GTK_RESPONSE_YES) { - change_status (icalcomp, itip_strip_mailto (a->value), a->status); + change_status ( + pitip->registry, icalcomp, + itip_strip_mailto (a->value), + a->status); e_cal_component_rescan (comp); } else { goto cleanup; @@ -2002,7 +2064,10 @@ update_attendee_status_icalcomp (ItipPURI *pitip, new_prop = find_attendee (org_icalcomp, itip_strip_mailto (a->value)); icalcomponent_add_property (icalcomp, icalproperty_new_clone (new_prop)); } else - change_status (icalcomp, itip_strip_mailto (a->value), a->status); + change_status ( + pitip->registry, icalcomp, + itip_strip_mailto (a->value), + a->status); e_cal_component_rescan (comp); } @@ -2013,7 +2078,11 @@ update_attendee_status_icalcomp (ItipPURI *pitip, if (itip_view_get_update (view)) { e_cal_component_commit_sequence (comp); - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, pitip->current_client, NULL, NULL, NULL, TRUE, FALSE); + itip_send_comp ( + pitip->registry, + E_CAL_COMPONENT_METHOD_REQUEST, + comp, pitip->current_client, + NULL, NULL, NULL, TRUE, FALSE); } update_item_progress_info (pitip, view, _("Saving changes to the calendar. Please wait...")); @@ -2145,7 +2214,11 @@ send_item (ItipPURI *pitip, comp = get_real_item (pitip); if (comp != NULL) { - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, pitip->current_client, NULL, NULL, NULL, TRUE, FALSE); + itip_send_comp ( + pitip->registry, + E_CAL_COMPONENT_METHOD_REQUEST, + comp, pitip->current_client, + NULL, NULL, NULL, TRUE, FALSE); g_object_unref (comp); switch (pitip->type) { @@ -2419,7 +2492,7 @@ extract_itip_data (ItipPURI *pitip, prop = NULL; comp = e_cal_component_new (); e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (pitip->ical_comp)); - my_address = itip_get_comp_attendee (comp, NULL); + my_address = itip_get_comp_attendee (pitip->registry, comp, NULL); g_object_unref (comp); comp = NULL; @@ -2643,7 +2716,10 @@ view_response_cb (ItipView *view, switch (response) { case ITIP_VIEW_RESPONSE_ACCEPT: if (pitip->type != E_CAL_CLIENT_SOURCE_TYPE_MEMOS) - status = change_status (pitip->ical_comp, pitip->to_address, + status = change_status ( + pitip->registry, + pitip->ical_comp, + pitip->to_address, ICAL_PARTSTAT_ACCEPTED); else status = TRUE; @@ -2654,8 +2730,11 @@ view_response_cb (ItipView *view, } break; case ITIP_VIEW_RESPONSE_TENTATIVE: - status = change_status (pitip->ical_comp, pitip->to_address, - ICAL_PARTSTAT_TENTATIVE); + status = change_status ( + pitip->registry, + pitip->ical_comp, + pitip->to_address, + ICAL_PARTSTAT_TENTATIVE); if (status) { e_cal_component_rescan (pitip->comp); pitip->can_delete_invitation_from_cache = TRUE; @@ -2664,7 +2743,10 @@ view_response_cb (ItipView *view, break; case ITIP_VIEW_RESPONSE_DECLINE: if (pitip->type != E_CAL_CLIENT_SOURCE_TYPE_MEMOS) - status = change_status (pitip->ical_comp, pitip->to_address, + status = change_status ( + pitip->registry, + pitip->ical_comp, + pitip->to_address, ICAL_PARTSTAT_DECLINED); else { prop = icalproperty_new_x ("1"); @@ -2716,7 +2798,8 @@ check_is_instance (icalcomponent *icalcomp) } static gboolean -in_proper_folder (CamelFolder *folder) +in_proper_folder (ESourceRegistry *registry, + CamelFolder *folder) { EShell *shell; EShellBackend *shell_backend; @@ -2744,17 +2827,17 @@ in_proper_folder (CamelFolder *folder) /* or any other virtual folder */ CAMEL_IS_VEE_FOLDER (folder) || /* or anything else except of sent, outbox or drafts folder */ - (!em_utils_folder_is_sent (folder) && - !em_utils_folder_is_outbox (folder) && - !em_utils_folder_is_drafts (folder)) + (!em_utils_folder_is_sent (registry, folder) && + !em_utils_folder_is_outbox (registry, folder) && + !em_utils_folder_is_drafts (registry, folder)) )); } else { /* cannot check for Inbox folder here */ res = (folder->folder_flags & (CAMEL_FOLDER_IS_TRASH | CAMEL_FOLDER_IS_JUNK)) == 0 && ( (CAMEL_IS_VEE_FOLDER (folder)) || ( - !em_utils_folder_is_sent (folder) && - !em_utils_folder_is_outbox (folder) && - !em_utils_folder_is_drafts (folder))); + !em_utils_folder_is_sent (registry, folder) && + !em_utils_folder_is_outbox (registry, folder) && + !em_utils_folder_is_drafts (registry, folder))); } return res; @@ -2766,6 +2849,7 @@ init_itip_view (ItipPURI *info, { EShell *shell; EShellSettings *shell_settings; + ESourceRegistry *registry; ECalComponentText text; ECalComponentOrganizer organizer; ECalComponentDateTime datetime; @@ -2780,29 +2864,27 @@ init_itip_view (ItipPURI *info, EMFormat *emf = info->puri.emf; shell = e_shell_get_default (); + registry = e_shell_get_registry (shell); shell_settings = e_shell_get_shell_settings (shell); + info->registry = g_object_ref (registry); + /* Reset current client before initializing view */ info->current_client = NULL; - /* Accounts */ - info->accounts = e_get_account_list (); - - /* Source Lists and open ecal clients */ - for (i = 0; i < E_CAL_CLIENT_SOURCE_TYPE_LAST; i++) { - if (!e_cal_client_get_sources (&info->source_lists[i], i, NULL)) - /* FIXME More error handling? */ - info->source_lists[i] = NULL; - - /* Initialize the ecal hashes */ - info->clients[i] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - } + /* Initialize the ecal hashes */ + for (i = 0; i < E_CAL_CLIENT_SOURCE_TYPE_LAST; i++) + info->clients[i] = g_hash_table_new_full ( + (GHashFunc) g_str_hash, + (GEqualFunc) g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); /* FIXME Handle multiple VEVENTS with the same UID, ie detached instances */ if (!extract_itip_data (info, view, &have_alarms)) return; - response_enabled = in_proper_folder (emf->folder); + response_enabled = in_proper_folder (registry, emf->folder); if (!response_enabled) { itip_view_set_mode (view, ITIP_VIEW_MODE_HIDE_ALL); @@ -3117,11 +3199,12 @@ puri_free (EMFormatPURI *puri) g_cancellable_cancel (pitip->cancellable); g_object_unref (pitip->cancellable); - for (i = 0; i < E_CAL_CLIENT_SOURCE_TYPE_LAST; i++) { - if (pitip->source_lists[i]) - g_object_unref (pitip->source_lists[i]); - pitip->source_lists[i] = NULL; + if (pitip->registry != NULL) { + g_object_unref (pitip->registry); + pitip->registry = NULL; + } + for (i = 0; i < E_CAL_CLIENT_SOURCE_TYPE_LAST; i++) { g_hash_table_destroy (pitip->clients[i]); pitip->clients[i] = NULL; } @@ -3177,18 +3260,19 @@ write_itip_view (EMFormat *emf, if (info->mode == EM_FORMAT_WRITE_MODE_PRINTING) { ItipView *view; - ItipPURI *ipuri; + ItipPURI *pitip; buffer = g_string_sized_new (1024); - ipuri = (ItipPURI *) puri; - view = itip_view_new (ipuri); + pitip = (ItipPURI *) puri; + view = itip_view_new (pitip, pitip->registry); - init_itip_view (ipuri, view); + init_itip_view (pitip, view); itip_view_write_for_printing (view, buffer); /* Destroy the view when the formatter is destroyed */ - g_object_weak_ref (G_OBJECT (emf), (GWeakNotify) g_object_unref, view); + g_object_weak_ref ( + G_OBJECT (emf), (GWeakNotify) g_object_unref, view); } else if (info->mode == EM_FORMAT_WRITE_MODE_RAW) { buffer = g_string_sized_new (2048); @@ -3226,6 +3310,7 @@ bind_itip_view (WebKitDOMElement *element, EMFormatPURI *puri) { if (WEBKIT_DOM_IS_HTML_IFRAME_ELEMENT (element)) { + ItipPURI *pitip = (ItipPURI *) puri; GString *buffer = g_string_new (""); WebKitDOMDocument *document; ItipView *view; @@ -3233,14 +3318,16 @@ bind_itip_view (WebKitDOMElement *element, document = webkit_dom_html_iframe_element_get_content_document ( WEBKIT_DOM_HTML_IFRAME_ELEMENT (element)); - view = itip_view_new ((ItipPURI *) puri); - g_object_set_data_full (G_OBJECT (element), "view", view, - (GDestroyNotify) g_object_unref); + view = itip_view_new (pitip, pitip->registry); + + g_object_set_data_full ( + G_OBJECT (element), "view", view, + (GDestroyNotify) g_object_unref); itip_view_create_dom_bindings (view, webkit_dom_document_get_document_element (document)); - init_itip_view ((ItipPURI *) puri, view); + init_itip_view (pitip, view); g_string_free (buffer, TRUE); } } @@ -3317,60 +3404,12 @@ delete_toggled_cb (GtkWidget *widget) g_object_unref (settings); } -static void -initialize_selection (ESourceSelector *selector, - ESourceList *source_list) -{ - GSList *groups; - - for (groups = e_source_list_peek_groups (source_list); groups; groups = groups->next) { - ESourceGroup *group = E_SOURCE_GROUP (groups->data); - GSList *sources; - for (sources = e_source_group_peek_sources (group); sources; sources = sources->next) { - ESource *source = E_SOURCE (sources->data); - const gchar *completion = e_source_get_property (source, "conflict"); - if (completion && !g_ascii_strcasecmp (completion, "true")) - e_source_selector_select_source (selector, source); - } - } -} - -static void -source_selection_changed (ESourceSelector *selector, - gpointer data) -{ - ESourceList *source_list = data; - GSList *selection; - GSList *l; - GSList *groups; - - /* first we clear all the completion flags from all sources */ - for (groups = e_source_list_peek_groups (source_list); groups; groups = groups->next) { - ESourceGroup *group = E_SOURCE_GROUP (groups->data); - GSList *sources; - for (sources = e_source_group_peek_sources (group); sources; sources = sources->next) { - ESource *source = E_SOURCE (sources->data); - - e_source_set_property (source, "conflict", NULL); - } - } - - /* then we loop over the selector's selection, setting the - * property on those sources */ - selection = e_source_selector_get_selection (selector); - for (l = selection; l; l = l->next) { - e_source_set_property (E_SOURCE (l->data), "conflict", "true"); - } - e_source_selector_free_selection (selection); - - /* FIXME show an error if this fails? */ - e_source_list_sync (source_list, NULL); -} - GtkWidget * itip_formatter_page_factory (EPlugin *ep, EConfigHookItemFactoryData *hook_data) { + EShell *shell; + ESourceRegistry *registry; GtkWidget *page; GtkWidget *tab_label; GtkWidget *frame; @@ -3382,10 +3421,12 @@ itip_formatter_page_factory (EPlugin *ep, GtkWidget *label; GtkWidget *ess; GtkWidget *scrolledwin; - ESourceList *source_list; gchar *str; GSettings *settings; + shell = e_shell_get_default (); + registry = e_shell_get_registry (shell); + /* Create a new notebook page */ page = gtk_vbox_new (FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (page), 12); @@ -3448,31 +3489,21 @@ itip_formatter_page_factory (EPlugin *ep, gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); gtk_box_pack_start (GTK_BOX (inner_vbox), label, FALSE, FALSE, 0); - if (!e_cal_client_get_sources (&source_list, E_CAL_CLIENT_SOURCE_TYPE_EVENTS, NULL)) { - /* FIXME Error handling */; - } - scrolledwin = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwin), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwin), - GTK_SHADOW_IN); + gtk_scrolled_window_set_policy ( + GTK_SCROLLED_WINDOW (scrolledwin), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type ( + GTK_SCROLLED_WINDOW (scrolledwin), GTK_SHADOW_IN); gtk_box_pack_start (GTK_BOX (inner_vbox), scrolledwin, TRUE, TRUE, 0); - ess = e_source_selector_new (source_list); + ess = e_conflict_search_selector_new (registry); atk_object_set_name (gtk_widget_get_accessible (ess), _("Conflict Search")); gtk_container_add (GTK_CONTAINER (scrolledwin), ess); - initialize_selection (E_SOURCE_SELECTOR (ess), source_list); - - g_signal_connect ( - ess, "selection_changed", - G_CALLBACK (source_selection_changed), source_list); - g_object_weak_ref (G_OBJECT (page), (GWeakNotify) g_object_unref, source_list); - gtk_widget_show_all (page); return page; } + diff --git a/plugins/itip-formatter/itip-view.c b/plugins/itip-formatter/itip-view.c index d9a2b4e6d4..30ec17157c 100644 --- a/plugins/itip-formatter/itip-view.c +++ b/plugins/itip-formatter/itip-view.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -59,6 +58,11 @@ typedef struct { } ItipViewInfoItem; struct _ItipViewPrivate { + ESourceRegistry *registry; + gulong source_added_id; + gulong source_removed_id; + gchar *extension_name; + ItipViewMode mode; ECalClientSourceType type; @@ -93,8 +97,6 @@ struct _ItipViewPrivate { gchar *description; - ESourceList *source_list; - gint buttons_sensitive : 1; gboolean is_recur_set; @@ -150,6 +152,12 @@ struct _ItipViewPrivate { #define DIV_ITIP_CONTENT "div_itip_content" #define DIV_ITIP_ERROR "div_itip_error" +enum { + PROP_0, + PROP_EXTENSION_NAME, + PROP_REGISTRY +}; + enum { SOURCE_SELECTED, RESPONSE, @@ -729,85 +737,6 @@ button_clicked_cb (WebKitDOMElement *element, g_signal_emit (G_OBJECT (data), signals[RESPONSE], 0, response); } -static void -itip_view_finalize (GObject *object) -{ - ItipViewPrivate *priv; - GSList *iter; - - priv = ITIP_VIEW_GET_PRIVATE (object); - - d(printf("Itip view finalized!\n")); - - g_free (priv->sender); - g_free (priv->organizer); - g_free (priv->organizer_sentby); - g_free (priv->delegator); - g_free (priv->attendee); - g_free (priv->attendee_sentby); - g_free (priv->proxy); - g_free (priv->summary); - g_free (priv->location); - g_free (priv->status); - g_free (priv->comment); - g_free (priv->start_tm); - g_free (priv->start_label); - g_free (priv->end_tm); - g_free (priv->end_label); - g_free (priv->description); - g_free (priv->error); - - for (iter = priv->lower_info_items; iter; iter = iter->next) { - ItipViewInfoItem *item = iter->data; - g_free (item->message); - g_free (item); - } - - g_slist_free (priv->lower_info_items); - - for (iter = priv->upper_info_items; iter; iter = iter->next) { - ItipViewInfoItem *item = iter->data; - g_free (item->message); - g_free (item); - } - - g_slist_free (priv->upper_info_items); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (itip_view_parent_class)->finalize (object); -} - -static void -itip_view_class_init (ItipViewClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (ItipViewPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->finalize = itip_view_finalize; - - signals[SOURCE_SELECTED] = g_signal_new ( - "source_selected", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ItipViewClass, source_selected), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - E_TYPE_SOURCE); - - signals[RESPONSE] = g_signal_new ( - "response", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ItipViewClass, response), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); -} - static void rsvp_toggled_cb (WebKitDOMHTMLInputElement *input, WebKitDOMEvent *event, @@ -872,10 +801,12 @@ source_changed_cb (WebKitDOMElement *select, { ESource *source; - source = itip_view_get_source (view); + source = itip_view_ref_source (view); d(printf("Source changed to '%s'\n", e_source_get_display_name (source))); g_signal_emit (view, signals[SOURCE_SELECTED], 0, source); + + g_object_unref (source); } static gchar * @@ -1120,6 +1051,322 @@ append_buttons_table (GString *buffer) g_string_append (buffer, ""); } +static void +itip_view_rebuild_source_list (ItipView *view) +{ + ESourceRegistry *registry; + WebKitDOMElement *select; + GList *list, *link; + const gchar *extension_name; + + d(printf("Assigning a new source list!\n")); + + if (!view->priv->dom_document) + return; + + registry = itip_view_get_registry (view); + extension_name = itip_view_get_extension_name (view); + + select = webkit_dom_document_get_element_by_id ( + view->priv->dom_document, SELECT_ESOURCE); + + while (webkit_dom_node_has_child_nodes (WEBKIT_DOM_NODE (select))) { + webkit_dom_node_remove_child ( + WEBKIT_DOM_NODE (select), + webkit_dom_node_get_last_child (WEBKIT_DOM_NODE (select)), + NULL); + } + + if (extension_name == NULL) + return; + + list = e_source_registry_list_sources (registry, extension_name); + + for (link = list; link != NULL; link = g_list_next (link)) { + ESource *source = E_SOURCE (link->data); + WebKitDOMElement *option; + + option = webkit_dom_document_create_element ( + view->priv->dom_document, "OPTION", NULL); + webkit_dom_html_option_element_set_value ( + WEBKIT_DOM_HTML_OPTION_ELEMENT (option), + e_source_get_uid (source)); + webkit_dom_html_option_element_set_label ( + WEBKIT_DOM_HTML_OPTION_ELEMENT (option), + e_source_get_display_name (source)); + webkit_dom_html_element_set_inner_html ( + WEBKIT_DOM_HTML_ELEMENT (option), + e_source_get_display_name (source), NULL); + webkit_dom_html_element_set_class_name ( + WEBKIT_DOM_HTML_ELEMENT (option), "calendar"); + + webkit_dom_node_append_child ( + WEBKIT_DOM_NODE (select), + WEBKIT_DOM_NODE (option), + NULL); + } + + g_list_free_full (list, (GDestroyNotify) g_object_unref); + + source_changed_cb (select, NULL, view); +} + +static void +itip_view_source_added_cb (ESourceRegistry *registry, + ESource *source, + ItipView *view) +{ + const gchar *extension_name; + + extension_name = itip_view_get_extension_name (view); + + /* If we don't have an extension name set + * yet then disregard the signal emission. */ + if (extension_name == NULL) + return; + + if (e_source_has_extension (source, extension_name)) + itip_view_rebuild_source_list (view); +} + +static void +itip_view_source_removed_cb (ESourceRegistry *registry, + ESource *source, + ItipView *view) +{ + const gchar *extension_name; + + extension_name = itip_view_get_extension_name (view); + + /* If we don't have an extension name set + * yet then disregard the signal emission. */ + if (extension_name == NULL) + return; + + if (e_source_has_extension (source, extension_name)) + itip_view_rebuild_source_list (view); +} + +static void +itip_view_set_registry (ItipView *view, + ESourceRegistry *registry) +{ + g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); + g_return_if_fail (view->priv->registry == NULL); + + view->priv->registry = g_object_ref (registry); +} + +static void +itip_view_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_EXTENSION_NAME: + itip_view_set_extension_name ( + ITIP_VIEW (object), + g_value_get_string (value)); + return; + + case PROP_REGISTRY: + itip_view_set_registry ( + ITIP_VIEW (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +itip_view_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_EXTENSION_NAME: + g_value_set_string ( + value, itip_view_get_extension_name ( + ITIP_VIEW (object))); + return; + + case PROP_REGISTRY: + g_value_set_object ( + value, itip_view_get_registry ( + ITIP_VIEW (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +itip_view_dispose (GObject *object) +{ + ItipViewPrivate *priv; + + priv = ITIP_VIEW_GET_PRIVATE (object); + + if (priv->registry != NULL) { + g_signal_handler_disconnect ( + priv->registry, priv->source_added_id); + g_signal_handler_disconnect ( + priv->registry, priv->source_removed_id); + g_object_unref (priv->registry); + priv->registry = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (itip_view_parent_class)->dispose (object); +} + +static void +itip_view_finalize (GObject *object) +{ + ItipViewPrivate *priv; + GSList *iter; + + priv = ITIP_VIEW_GET_PRIVATE (object); + + d(printf("Itip view finalized!\n")); + + g_free (priv->extension_name); + g_free (priv->sender); + g_free (priv->organizer); + g_free (priv->organizer_sentby); + g_free (priv->delegator); + g_free (priv->attendee); + g_free (priv->attendee_sentby); + g_free (priv->proxy); + g_free (priv->summary); + g_free (priv->location); + g_free (priv->status); + g_free (priv->comment); + g_free (priv->start_tm); + g_free (priv->start_label); + g_free (priv->end_tm); + g_free (priv->end_label); + g_free (priv->description); + g_free (priv->error); + + for (iter = priv->lower_info_items; iter; iter = iter->next) { + ItipViewInfoItem *item = iter->data; + g_free (item->message); + g_free (item); + } + + g_slist_free (priv->lower_info_items); + + for (iter = priv->upper_info_items; iter; iter = iter->next) { + ItipViewInfoItem *item = iter->data; + g_free (item->message); + g_free (item); + } + + g_slist_free (priv->upper_info_items); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (itip_view_parent_class)->finalize (object); +} + +static void +itip_view_constructed (GObject *object) +{ + ItipView *view; + ESourceRegistry *registry; + + view = ITIP_VIEW (object); + registry = itip_view_get_registry (view); + + view->priv->source_added_id = g_signal_connect ( + registry, "source-added", + G_CALLBACK (itip_view_source_added_cb), view); + + view->priv->source_removed_id = g_signal_connect ( + registry, "source-removed", + G_CALLBACK (itip_view_source_removed_cb), view); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (itip_view_parent_class)->constructed (object); +} + +static void +itip_view_class_init (ItipViewClass *class) +{ + GObjectClass *object_class; + + g_type_class_add_private (class, sizeof (ItipViewPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = itip_view_set_property; + object_class->get_property = itip_view_get_property; + object_class->dispose = itip_view_dispose; + object_class->finalize = itip_view_finalize; + object_class->constructed = itip_view_constructed; + + g_object_class_install_property ( + object_class, + PROP_REGISTRY, + g_param_spec_string ( + "extension-name", + "Extension Name", + "Show only data sources with this extension", + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_REGISTRY, + g_param_spec_object ( + "registry", + "Registry", + "Data source registry", + E_TYPE_SOURCE_REGISTRY, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + signals[SOURCE_SELECTED] = g_signal_new ( + "source_selected", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ItipViewClass, source_selected), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_SOURCE); + + signals[RESPONSE] = g_signal_new ( + "response", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ItipViewClass, response), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, + G_TYPE_INT); +} + +static void +itip_view_init (ItipView *view) +{ + view->priv = ITIP_VIEW_GET_PRIVATE (view); +} + +ItipView * +itip_view_new (ItipPURI *puri, + ESourceRegistry *registry) +{ + ItipView *view; + + view = g_object_new (ITIP_TYPE_VIEW, "registry", registry, NULL); + view->priv->puri = puri; + + return view; +} + void itip_view_write (GString *buffer) { @@ -1393,29 +1640,46 @@ itip_view_create_dom_bindings (ItipView *view, } } -static void -itip_view_init (ItipView *view) +ItipPURI * +itip_view_get_puri (ItipView *view) { - view->priv = ITIP_VIEW_GET_PRIVATE (view); + g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); + + return view->priv->puri; } -ItipView * -itip_view_new (ItipPURI *puri) +ESourceRegistry * +itip_view_get_registry (ItipView *view) { - ItipView *view; - - view = ITIP_VIEW (g_object_new (ITIP_TYPE_VIEW, NULL)); - view->priv->puri = puri; + g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - return view; + return view->priv->registry; } -ItipPURI * -itip_view_get_puri (ItipView *view) +const gchar * +itip_view_get_extension_name (ItipView *view) { g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - return view->priv->puri; + return view->priv->extension_name; +} + +void +itip_view_set_extension_name (ItipView *view, + const gchar *extension_name) +{ + g_return_if_fail (ITIP_IS_VIEW (view)); + + /* Avoid unnecessary rebuilds. */ + if (g_strcmp0 (extension_name, view->priv->extension_name) == 0) + return; + + g_free (view->priv->extension_name); + view->priv->extension_name = g_strdup (extension_name); + + g_object_notify (G_OBJECT (view), "extension-name"); + + itip_view_rebuild_source_list (view); } static void @@ -2159,119 +2423,13 @@ itip_view_clear_lower_info_items (ItipView *view) priv->lower_info_items = NULL; } -static void -source_list_changed_cb (ESourceList *source_list, - ItipView *view) -{ - GSList *groups, *iter; - WebKitDOMElement *select; - - d(printf("Assigning a new source list!\n")); - - if (!view->priv->dom_document) - return; - - select = webkit_dom_document_get_element_by_id ( - view->priv->dom_document, SELECT_ESOURCE); - - while (webkit_dom_node_has_child_nodes (WEBKIT_DOM_NODE (select))) { - webkit_dom_node_remove_child ( - WEBKIT_DOM_NODE (select), - webkit_dom_node_get_last_child (WEBKIT_DOM_NODE (select)), - NULL); - } - - groups = e_source_list_peek_groups (source_list); - for (iter = groups; iter; iter = iter->next) { - - ESourceGroup *group = iter->data; - GSList *sources, *iter2; - WebKitDOMElement *optgroup; - - sources = e_source_group_peek_sources (group); - if (sources == NULL) - continue; - - optgroup = webkit_dom_document_create_element ( - view->priv->dom_document, "OPTGROUP", NULL); - webkit_dom_html_opt_group_element_set_label ( - WEBKIT_DOM_HTML_OPT_GROUP_ELEMENT (optgroup), - e_source_group_peek_name (group)); - - webkit_dom_node_append_child ( - WEBKIT_DOM_NODE (select), - WEBKIT_DOM_NODE (optgroup), - NULL); - - for (iter2 = sources; iter2; iter2 = iter2->next) { - - WebKitDOMElement *option; - ESource *source = iter2->data; - - option = webkit_dom_document_create_element ( - view->priv->dom_document, "OPTION", NULL); - webkit_dom_html_option_element_set_value ( - WEBKIT_DOM_HTML_OPTION_ELEMENT (option), - e_source_get_uid (source)); - webkit_dom_html_option_element_set_label ( - WEBKIT_DOM_HTML_OPTION_ELEMENT (option), - e_source_get_display_name (source)); - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (option), - e_source_get_display_name (source), NULL); - webkit_dom_html_element_set_class_name ( - WEBKIT_DOM_HTML_ELEMENT (option), "calendar"); - - webkit_dom_node_append_child ( - WEBKIT_DOM_NODE (optgroup), - WEBKIT_DOM_NODE (option), - NULL); - } - } - - source_changed_cb (select, NULL, view); -} - -void -itip_view_set_source_list (ItipView *view, - ESourceList *source_list) -{ - ItipViewPrivate *priv; - - g_return_if_fail (ITIP_IS_VIEW (view)); - - priv = view->priv; - - if (priv->source_list) - g_object_unref (priv->source_list); - - if (!source_list) { - priv->source_list = NULL; - return; - } - - priv->source_list = g_object_ref (source_list); - - source_list_changed_cb (source_list, view); - - g_signal_connect (source_list, "changed", - G_CALLBACK (source_list_changed_cb), view); -} - -ESourceList * -itip_view_get_source_list (ItipView *view) -{ - g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); - - return view->priv->source_list; -} - void itip_view_set_source (ItipView *view, ESource *source) { WebKitDOMElement *select; WebKitDOMElement *row; + ESource *selected_source; gulong i, len; g_return_if_fail (ITIP_IS_VIEW (view)); @@ -2294,9 +2452,11 @@ itip_view_set_source (ItipView *view, /*