[evolution] Bug 598024 - Forward as iCalendar doesn't contain all instances
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution] Bug 598024 - Forward as iCalendar doesn't contain all instances
- Date: Wed, 30 Aug 2017 14:21:11 +0000 (UTC)
commit 8a301151740b6a743b10bca0980e09ca6fa03668
Author: Milan Crha <mcrha redhat com>
Date: Wed Aug 30 16:21:40 2017 +0200
Bug 598024 - Forward as iCalendar doesn't contain all instances
src/calendar/gui/itip-utils.c | 192 ++++++++++++++++++++++++++---------------
1 files changed, 123 insertions(+), 69 deletions(-)
---
diff --git a/src/calendar/gui/itip-utils.c b/src/calendar/gui/itip-utils.c
index 9cc496d..820e78b 100644
--- a/src/calendar/gui/itip-utils.c
+++ b/src/calendar/gui/itip-utils.c
@@ -710,7 +710,7 @@ foreach_tzid_callback (icalparameter *param,
static icalcomponent *
comp_toplevel_with_zones (ECalComponentItipMethod method,
- ECalComponent *comp,
+ const GSList *ecomps,
ECalClient *cal_client,
icalcomponent *zones)
{
@@ -718,6 +718,7 @@ comp_toplevel_with_zones (ECalComponentItipMethod method,
icalproperty *prop;
icalvalue *value;
ItipUtilTZData tz_data;
+ GSList *link;
top_level = e_cal_util_new_top_level ();
@@ -726,17 +727,21 @@ comp_toplevel_with_zones (ECalComponentItipMethod method,
icalproperty_set_value (prop, value);
icalcomponent_add_property (top_level, prop);
- icomp = e_cal_component_get_icalcomponent (comp);
- icomp = icalcomponent_new_clone (icomp);
-
tz_data.tzids = g_hash_table_new (g_str_hash, g_str_equal);
tz_data.icomp = top_level;
tz_data.client = cal_client;
tz_data.zones = zones;
- icalcomponent_foreach_tzid (icomp, foreach_tzid_callback, &tz_data);
- g_hash_table_destroy (tz_data.tzids);
- icalcomponent_add_component (top_level, icomp);
+ for (link = (GSList *) ecomps; link; link = g_slist_next (link)) {
+ icomp = e_cal_component_get_icalcomponent (link->data);
+ icomp = icalcomponent_new_clone (icomp);
+
+ icalcomponent_foreach_tzid (icomp, foreach_tzid_callback, &tz_data);
+
+ icalcomponent_add_component (top_level, icomp);
+ }
+
+ g_hash_table_destroy (tz_data.tzids);
return top_level;
}
@@ -1273,7 +1278,7 @@ comp_description (ECalComponent *comp,
static gboolean
comp_server_send_sync (ECalComponentItipMethod method,
- ECalComponent *comp,
+ const GSList *ecomps,
ECalClient *cal_client,
icalcomponent *zones,
GSList **users,
@@ -1284,7 +1289,7 @@ comp_server_send_sync (ECalComponentItipMethod method,
gboolean retval = TRUE;
GError *local_error = NULL;
- top_level = comp_toplevel_with_zones (method, comp, cal_client, zones);
+ top_level = comp_toplevel_with_zones (method, ecomps, cal_client, zones);
d (printf ("itip-utils.c: comp_server_send_sync: calling e_cal_send_objects... \n"));
e_cal_client_send_objects_sync (
@@ -1555,13 +1560,13 @@ strip_x_microsoft_props (ECalComponent *comp)
}
static ECalComponent *
-comp_compliant (ESourceRegistry *registry,
- ECalComponentItipMethod method,
- ECalComponent *comp,
- ECalClient *client,
- icalcomponent *zones,
- icaltimezone *default_zone,
- gboolean strip_alarms)
+comp_compliant_one (ESourceRegistry *registry,
+ ECalComponentItipMethod method,
+ ECalComponent *comp,
+ ECalClient *client,
+ icalcomponent *zones,
+ icaltimezone *default_zone,
+ gboolean strip_alarms)
{
ECalComponent *clone, *temp_clone;
struct icaltimetype itt;
@@ -1689,6 +1694,40 @@ comp_compliant (ESourceRegistry *registry,
return clone;
}
+static gboolean
+comp_compliant (ESourceRegistry *registry,
+ ECalComponentItipMethod method,
+ GSList *ecomps,
+ gboolean unref_orig_ecomp,
+ ECalClient *client,
+ icalcomponent *zones,
+ icaltimezone *default_zone,
+ gboolean strip_alarms)
+{
+ GSList *link;
+
+ if (!ecomps)
+ return FALSE;
+
+ for (link = ecomps; link; link = g_slist_next (link)) {
+ ECalComponent *original_comp = link->data, *new_comp;
+
+ new_comp = comp_compliant_one (registry, method, original_comp, client, zones, default_zone,
strip_alarms);
+ if (new_comp) {
+ cal_comp_util_copy_new_attendees (new_comp, original_comp);
+
+ if (unref_orig_ecomp)
+ g_object_unref (original_comp);
+
+ link->data = new_comp;
+ } else {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
void
itip_cal_mime_attach_free (gpointer ptr)
{
@@ -1706,8 +1745,7 @@ itip_cal_mime_attach_free (gpointer ptr)
static void
append_cal_attachments (EMsgComposer *composer,
- ECalComponent *comp,
- GSList *attach_list)
+ GSList *attach_list)
{
struct CalMimeAttach *mime_attach;
GSList *l;
@@ -1847,10 +1885,33 @@ get_identity_uid_for_from (EShell *shell,
return identity_uid;
}
+static gint
+master_first_cmp (gconstpointer ptr1,
+ gconstpointer ptr2)
+{
+ ECalComponent *comp1 = (ECalComponent *) ptr1;
+ ECalComponent *comp2 = (ECalComponent *) ptr2;
+ icalcomponent *icomp1 = comp1 ? e_cal_component_get_icalcomponent (comp1) : NULL;
+ icalcomponent *icomp2 = comp2 ? e_cal_component_get_icalcomponent (comp2) : NULL;
+ gboolean has_rid1, has_rid2;
+
+ has_rid1 = (icomp1 && icalcomponent_get_first_property (icomp1, ICAL_RECURRENCEID_PROPERTY)) ? 1 : 0;
+ has_rid2 = (icomp2 && icalcomponent_get_first_property (icomp2, ICAL_RECURRENCEID_PROPERTY)) ? 1 : 0;
+
+ if (has_rid1 == has_rid2)
+ return g_strcmp0 (icomp1 ? icalcomponent_get_uid (icomp1) : NULL,
+ icomp2 ? icalcomponent_get_uid (icomp2) : NULL);
+
+ if (has_rid1)
+ return 1;
+
+ return -1;
+}
+
typedef struct {
ESourceRegistry *registry;
ECalComponentItipMethod method;
- ECalComponent *send_comp;
+ GSList *send_comps; /* ECalComponent * */
ECalClient *cal_client;
icalcomponent *zones;
GSList *attachments_list;
@@ -1872,7 +1933,7 @@ itip_send_component_data_free (gpointer ptr)
if (isc) {
g_clear_object (&isc->registry);
- g_clear_object (&isc->send_comp);
+ g_slist_free_full (isc->send_comps, g_object_unref);
g_clear_object (&isc->cal_client);
g_clear_error (&isc->async_error);
if (isc->zones)
@@ -1898,27 +1959,28 @@ itip_send_component_begin (ItipSendComponentData *isc,
return;
}
- if (isc->ensure_master_object && e_cal_component_is_instance (isc->send_comp)) {
- /* Ensure we send the master object, not the instance only */
- icalcomponent *icalcomp = NULL;
+ if (isc->ensure_master_object && isc->send_comps) {
+ /* Ensure we send the master object with its detached instances, not the instance only */
+ GSList *ecalcomps = NULL;
const gchar *uid = NULL;
- e_cal_component_get_uid (isc->send_comp, &uid);
- if (e_cal_client_get_object_sync (isc->cal_client, uid, NULL, &icalcomp, cancellable, NULL)
&& icalcomp) {
- ECalComponent *send_comp;
+ e_cal_component_get_uid (isc->send_comps->data, &uid);
- send_comp = e_cal_component_new_from_icalcomponent (icalcomp);
- if (send_comp) {
- g_object_unref (isc->send_comp);
- isc->send_comp = send_comp;
- }
+ if (e_cal_client_get_objects_for_uid_sync (isc->cal_client, uid, &ecalcomps, cancellable,
NULL) && ecalcomps) {
+ GSList *old_send_comps = isc->send_comps;
+
+ isc->send_comps = g_slist_sort (ecalcomps, master_first_cmp);
+
+ cal_comp_util_copy_new_attendees (isc->send_comps->data, old_send_comps->data);
+
+ g_slist_free_full (old_send_comps, g_object_unref);
}
}
/* Give the server a chance to manipulate the comp */
if (isc->method != E_CAL_COMPONENT_METHOD_PUBLISH) {
d (printf ("itip-utils.c: itip_send_component_begin: calling comp_server_send_sync... \n"));
- if (!comp_server_send_sync (isc->method, isc->send_comp, isc->cal_client, isc->zones,
&isc->users, cancellable, error)) {
+ if (!comp_server_send_sync (isc->method, isc->send_comps, isc->cal_client, isc->zones,
&isc->users, cancellable, error)) {
isc->success = FALSE;
isc->completed = TRUE;
return;
@@ -1943,7 +2005,7 @@ typedef struct _CreateComposerData {
gchar *content_type;
gchar *event_body_text;
GSList *attachments_list;
- ECalComponent *comp;
+ GSList *send_comps; /* ECalComponent * */
gboolean show_only;
} CreateComposerData;
@@ -1980,7 +2042,7 @@ itip_send_component_composer_created_cb (GObject *source_object,
e_composer_header_table_set_subject (table, ccd->subject);
e_composer_header_table_set_destinations_to (table, ccd->destinations);
- if (e_cal_component_get_vtype (ccd->comp) == E_CAL_COMPONENT_EVENT) {
+ if (e_cal_component_get_vtype (ccd->send_comps->data) == E_CAL_COMPONENT_EVENT) {
if (ccd->event_body_text)
e_msg_composer_set_body_text (composer, ccd->event_body_text, TRUE);
else
@@ -1991,8 +2053,8 @@ itip_send_component_composer_created_cb (GObject *source_object,
gchar *description;
gchar *body;
- filename = comp_filename (ccd->comp);
- description = comp_description (ccd->comp, use_24hour_format);
+ filename = comp_filename (ccd->send_comps->data);
+ description = comp_description (ccd->send_comps->data, use_24hour_format);
body = camel_text_to_html (description, CAMEL_MIME_FILTER_TOHTML_PRE, 0);
e_msg_composer_set_body_text (composer, body, TRUE);
@@ -2013,7 +2075,7 @@ itip_send_component_composer_created_cb (GObject *source_object,
g_free (description);
}
- append_cal_attachments (composer, ccd->comp, ccd->attachments_list);
+ append_cal_attachments (composer, ccd->attachments_list);
ccd->attachments_list = NULL;
if (ccd->show_only)
@@ -2022,7 +2084,7 @@ itip_send_component_composer_created_cb (GObject *source_object,
e_msg_composer_send (composer);
e_destination_freev (ccd->destinations);
- g_clear_object (&ccd->comp);
+ g_slist_free_full (ccd->send_comps, g_object_unref);
g_free (ccd->identity_uid);
g_free (ccd->identity_name);
g_free (ccd->identity_address);
@@ -2038,7 +2100,6 @@ itip_send_component_complete (ItipSendComponentData *isc)
{
CreateComposerData *ccd;
EDestination **destinations;
- ECalComponent *comp = NULL;
EShell *shell;
icalcomponent *top_level = NULL;
icaltimezone *default_zone;
@@ -2053,18 +2114,14 @@ itip_send_component_complete (ItipSendComponentData *isc)
default_zone = calendar_config_get_icaltimezone ();
/* Tidy up the comp */
- comp = comp_compliant (
- isc->registry, isc->method, isc->send_comp, isc->cal_client,
- isc->zones, default_zone, isc->strip_alarms);
-
- if (comp == NULL)
+ if (!comp_compliant (isc->registry, isc->method, isc->send_comps, TRUE, isc->cal_client, isc->zones,
default_zone, isc->strip_alarms))
goto cleanup;
/* Recipients */
destinations = comp_to_list (
- isc->registry, isc->method, comp, isc->users, FALSE,
+ isc->registry, isc->method, isc->send_comps->data, isc->users, FALSE,
isc->only_new_attendees ? g_object_get_data (
- G_OBJECT (isc->send_comp), "new-attendees") : NULL);
+ G_OBJECT (isc->send_comps->data), "new-attendees") : NULL);
if (isc->method != E_CAL_COMPONENT_METHOD_PUBLISH) {
if (destinations == NULL) {
/* We sent them all via the server */
@@ -2074,28 +2131,27 @@ itip_send_component_complete (ItipSendComponentData *isc)
}
shell = e_shell_get_default ();
- top_level = comp_toplevel_with_zones (isc->method, comp, isc->cal_client, isc->zones);
+ top_level = comp_toplevel_with_zones (isc->method, isc->send_comps, isc->cal_client, isc->zones);
ccd = g_new0 (CreateComposerData, 1);
- ccd->identity_uid = get_identity_uid_for_from (shell, isc->method, isc->send_comp, isc->cal_client,
&ccd->identity_name, &ccd->identity_address);
+ ccd->identity_uid = get_identity_uid_for_from (shell, isc->method, isc->send_comps->data,
isc->cal_client, &ccd->identity_name, &ccd->identity_address);
ccd->destinations = destinations;
- ccd->subject = comp_subject (isc->registry, isc->method, comp);
+ ccd->subject = comp_subject (isc->registry, isc->method, isc->send_comps->data);
ccd->ical_string = icalcomponent_as_ical_string_r (top_level);
- ccd->content_type = comp_content_type (comp, isc->method);
+ ccd->content_type = comp_content_type (isc->send_comps->data, isc->method);
ccd->event_body_text = NULL;
ccd->attachments_list = isc->attachments_list;
- ccd->comp = comp;
+ ccd->send_comps = isc->send_comps;
ccd->show_only = isc->method == E_CAL_COMPONENT_METHOD_PUBLISH && !isc->users;
isc->attachments_list = NULL;
- comp = NULL;
+ isc->send_comps = NULL;
e_msg_composer_new (shell, itip_send_component_composer_created_cb, ccd);
isc->success = TRUE;
cleanup:
- g_clear_object (&comp);
if (top_level != NULL)
icalcomponent_free (top_level);
}
@@ -2173,7 +2229,7 @@ itip_send_component_with_model (ECalModel *model,
isc = g_new0 (ItipSendComponentData, 1);
isc->registry = g_object_ref (registry);
isc->method = method;
- isc->send_comp = g_object_ref (send_comp);
+ isc->send_comps = g_slist_prepend (NULL, g_object_ref (send_comp));
isc->cal_client = g_object_ref (cal_client);
if (zones) {
isc->zones = icalcomponent_new_clone (zones);
@@ -2221,7 +2277,7 @@ itip_send_comp_sync (ESourceRegistry *registry,
isc.registry = registry;
isc.method = method;
- isc.send_comp = send_comp;
+ isc.send_comps = g_slist_prepend (NULL, g_object_ref (send_comp));
isc.cal_client = cal_client;
isc.zones = zones;
isc.attachments_list = attachments_list;
@@ -2235,6 +2291,7 @@ itip_send_comp_sync (ESourceRegistry *registry,
itip_send_component_begin (&isc, cancellable, error);
itip_send_component_complete (&isc);
+ g_slist_free_full (isc.send_comps, g_object_unref);
g_slist_free_full (isc.users, g_free);
return isc.success;
@@ -2274,7 +2331,7 @@ itip_send_component (ESourceRegistry *registry,
isc = g_new0 (ItipSendComponentData, 1);
isc->registry = g_object_ref (registry);
isc->method = method;
- isc->send_comp = g_object_ref (send_comp);
+ isc->send_comps = g_slist_prepend (NULL, g_object_ref (send_comp));
isc->cal_client = g_object_ref (cal_client);
if (zones)
isc->zones = icalcomponent_new_clone (zones);
@@ -2332,10 +2389,10 @@ reply_to_calendar_comp (ESourceRegistry *registry,
GSList *attachments_list)
{
EShell *shell;
- ECalComponent *comp = NULL;
icalcomponent *top_level = NULL;
icaltimezone *default_zone;
gboolean retval = FALSE;
+ GSList *ecomps;
CreateComposerData *ccd;
g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
@@ -2345,25 +2402,24 @@ reply_to_calendar_comp (ESourceRegistry *registry,
default_zone = calendar_config_get_icaltimezone ();
+ ecomps = g_slist_prepend (NULL, send_comp);
+
/* Tidy up the comp */
- comp = comp_compliant (
- registry, method, send_comp, cal_client,
- zones, default_zone, TRUE);
- if (comp == NULL)
+ if (!comp_compliant (registry, method, ecomps, FALSE, cal_client, zones, default_zone, TRUE))
goto cleanup;
- top_level = comp_toplevel_with_zones (method, comp, cal_client, zones);
+ top_level = comp_toplevel_with_zones (method, ecomps, cal_client, zones);
ccd = g_new0 (CreateComposerData, 1);
ccd->identity_uid = get_identity_uid_for_from (shell, method, send_comp, cal_client,
&ccd->identity_name, &ccd->identity_address);
- ccd->destinations = comp_to_list (registry, method, comp, NULL, reply_all, NULL);
- ccd->subject = comp_subject (registry, method, comp);
+ ccd->destinations = comp_to_list (registry, method, ecomps->data, NULL, reply_all, NULL);
+ ccd->subject = comp_subject (registry, method, ecomps->data);
ccd->ical_string = icalcomponent_as_ical_string_r (top_level);
- ccd->comp = comp;
+ ccd->send_comps = ecomps;
ccd->show_only = TRUE;
- if (e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_EVENT) {
-
+ if (e_cal_component_get_vtype (ecomps->data) == E_CAL_COMPONENT_EVENT) {
+ ECalComponent *comp = ecomps->data;
GString *body;
gchar *orig_from = NULL;
const gchar *description = NULL;
@@ -2471,8 +2527,6 @@ reply_to_calendar_comp (ESourceRegistry *registry,
ccd->event_body_text = g_string_free (body, FALSE);
}
- comp = NULL;
-
e_msg_composer_new (shell, itip_send_component_composer_created_cb, ccd);
retval = TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]