aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/itip-formatter
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@src.gnome.org>2008-10-25 07:52:05 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2008-10-25 07:52:05 +0800
commit85b2913a380c69f14ae0254ad23b10fabfb33667 (patch)
treec1cf143e37294dd9dd3667ebbe0a1d0c00b04b56 /plugins/itip-formatter
parente7a31c5035a0afeed6c1675e30487c1e2bdc139f (diff)
downloadgsoc2013-evolution-85b2913a380c69f14ae0254ad23b10fabfb33667.tar
gsoc2013-evolution-85b2913a380c69f14ae0254ad23b10fabfb33667.tar.gz
gsoc2013-evolution-85b2913a380c69f14ae0254ad23b10fabfb33667.tar.bz2
gsoc2013-evolution-85b2913a380c69f14ae0254ad23b10fabfb33667.tar.lz
gsoc2013-evolution-85b2913a380c69f14ae0254ad23b10fabfb33667.tar.xz
gsoc2013-evolution-85b2913a380c69f14ae0254ad23b10fabfb33667.tar.zst
gsoc2013-evolution-85b2913a380c69f14ae0254ad23b10fabfb33667.zip
Merge revisions 36534:36684 from trunk.
svn path=/branches/kill-bonobo/; revision=36685
Diffstat (limited to 'plugins/itip-formatter')
-rw-r--r--plugins/itip-formatter/ChangeLog47
-rw-r--r--plugins/itip-formatter/itip-formatter.c127
-rw-r--r--plugins/itip-formatter/itip-view.c30
3 files changed, 160 insertions, 44 deletions
diff --git a/plugins/itip-formatter/ChangeLog b/plugins/itip-formatter/ChangeLog
index b30fd70aaa..f408872cdc 100644
--- a/plugins/itip-formatter/ChangeLog
+++ b/plugins/itip-formatter/ChangeLog
@@ -1,3 +1,50 @@
+2008-10-20 Milan Crha <mcrha@redhat.com>
+
+ ** Fix for bug #514989
+
+ * itip-view.c: (format_date_and_time_x):
+ Calculate tomorrow from current time, not from the date to convert.
+
+2008-10-14 Srinivasa Ragavan <sragavan@novell.com>
+
+ ** Fix for bug #550441
+
+ * itip-formatter.c: (view_response_cb): Ignore if summary not there.
+
+2008-10-13 Milan Crha <mcrha@redhat.com>
+
+ ** Fix for bug #550441
+
+ * itip-formatter.c: (view_response_cb):
+ Use the proper functions to traverse messages in a folder's summary.
+
+2008-10-10 Patrick Ohly <pohly@ecld0pohly>
+
+ ** #541121: improved itip formatter: allow replying to forwarded
+ and already imported invitations; honor RVSP flag in invitation
+
+ * itip-formatter.c: the whole logic for "reply to organize" was
+ improved.
+
+ If an organizer exists, replying is enabled. Sending a reply is
+ enabled by default if the event looks like a meeting (= has
+ attendees). The wish of the organizer to not get replies is
+ checked (previous Evolution releases ignored it); in this case the
+ default is to not send a reply. In all cases the user can override
+ the default.
+
+2008-10-08 Sankar P <psankar@novell.com>
+
+License Changes
+
+ * itip-formatter.c:
+
+2008-10-03 Sankar P <psankar@novell.com>
+
+License Changes
+
+ * itip-view.c:
+
2008-10-01 Milan Crha <mcrha@redhat.com>
** Fix for bug #519491
diff --git a/plugins/itip-formatter/itip-formatter.c b/plugins/itip-formatter/itip-formatter.c
index e37c0d162a..a2ceffb77b 100644
--- a/plugins/itip-formatter/itip-formatter.c
+++ b/plugins/itip-formatter/itip-formatter.c
@@ -1,22 +1,22 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * Authors: JP Rosevear <jpr@novell.com>
+ * 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.
*
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * Authors:
+ * JP Rosevear <jpr@novell.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
@@ -107,6 +107,32 @@ struct _itip_puri {
guint progress_info_id;
gboolean delete_message;
+ /* a reply can only be sent if and only if there is an organizer */
+ gboolean has_organizer;
+ /*
+ * Usually replies are sent unless the user unchecks that option.
+ * There are some cases when the default is not to sent a reply
+ * (but the user can still chose to do so by checking the option):
+ * - the organizer explicitly set RSVP=FALSE for the current user
+ * - the event has no ATTENDEEs: that's the case for most non-meeting
+ * events
+ *
+ * The last case is meant for forwarded non-meeting
+ * events. Traditionally Evolution hasn't offered to send a
+ * reply, therefore the updated implementation mimics that
+ * behavior.
+ *
+ * Unfortunately some software apparently strips all ATTENDEEs
+ * when forwarding a meeting; in that case sending a reply is
+ * also unchecked by default. So the check for ATTENDEEs is a
+ * tradeoff between sending unwanted replies in cases where
+ * that wasn't done in the past and not sending a possibly
+ * wanted reply where that wasn't possible in the past
+ * (because replies to forwarded events were not
+ * supported). Overall that should be an improvement, and the
+ * user can always override the default.
+ */
+ gboolean no_reply_wanted;
};
@@ -235,6 +261,12 @@ find_to_address (struct _itip_puri *pitip, icalcomponent *ical_comp, icalparamet
pitip->my_address = g_strdup (account->id->address);
+ param = icalproperty_get_first_parameter (prop, ICAL_RSVP_PARAMETER);
+ if (param &&
+ 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;
@@ -285,6 +317,12 @@ find_to_address (struct _itip_puri *pitip, icalcomponent *ical_comp, icalparamet
pitip->my_address = g_strdup (account->id->address);
+ param = icalproperty_get_first_parameter (prop, ICAL_RSVP_PARAMETER);
+ if (param &&
+ 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;
@@ -641,8 +679,23 @@ find_cal_opened_cb (ECal *ecal, ECalendarStatus status, gpointer data)
d(printf ("Decreasing itip formatter search count to %d\n", fd->count));
if (fd->count == 0) {
+ gboolean rsvp_enabled = FALSE;
+
itip_view_remove_lower_info_item (ITIP_VIEW (pitip->view), pitip->progress_info_id);
pitip->progress_info_id = 0;
+
+ /*
+ * Only allow replies if backend doesn't do that automatically.
+ * Replies only make sense for events with an organizer.
+ */
+ if (!e_cal_get_static_capability (ecal, CAL_STATIC_CAPABILITY_SAVE_SCHEDULES) &&
+ pitip->has_organizer) {
+ rsvp_enabled = TRUE;
+ }
+ itip_view_set_show_rsvp (ITIP_VIEW (pitip->view), rsvp_enabled);
+
+ /* default is chosen in extract_itip_data() based on content of the VEVENT */
+ itip_view_set_rsvp (ITIP_VIEW (pitip->view), !pitip->no_reply_wanted);
if ((pitip->method == ICAL_METHOD_PUBLISH || pitip->method == ICAL_METHOD_REQUEST)
&& !pitip->current_ecal) {
@@ -677,11 +730,6 @@ find_cal_opened_cb (ECal *ecal, ECalendarStatus status, gpointer data)
itip_view_set_source_list (ITIP_VIEW (pitip->view), pitip->source_lists[pitip->type]);
g_signal_connect (pitip->view, "source_selected", G_CALLBACK (source_selected_cb), pitip);
- /* The only method that RSVP makes sense for is REQUEST */
- /* FIXME Default to the suggestion for RSVP for my attendee */
- itip_view_set_rsvp (ITIP_VIEW (pitip->view), pitip->method == ICAL_METHOD_REQUEST ? TRUE : FALSE);
- itip_view_set_show_rsvp (ITIP_VIEW (pitip->view), pitip->method == ICAL_METHOD_REQUEST ? TRUE : FALSE);
-
if (source) {
itip_view_set_source (ITIP_VIEW (pitip->view), source);
@@ -1423,6 +1471,16 @@ extract_itip_data (struct _itip_puri *pitip, GtkContainer *container)
switch (icalcomponent_isa (pitip->ical_comp)) {
case ICAL_VEVENT_COMPONENT:
pitip->type = E_CAL_SOURCE_TYPE_EVENT;
+ pitip->has_organizer = icalcomponent_get_first_property (pitip->ical_comp, ICAL_ORGANIZER_PROPERTY) != NULL;
+ if (icalcomponent_get_first_property (pitip->ical_comp, ICAL_ATTENDEE_PROPERTY) == NULL) {
+ /* no attendees: assume that that this is not a meeting and organizer doesn't want a reply */
+ pitip->no_reply_wanted = TRUE;
+ } else {
+ /*
+ * if we have attendees, then find_to_address() will check for our RSVP
+ * and set no_reply_wanted=TRUE if RSVP=FALSE for the current user
+ */
+ }
break;
case ICAL_VTODO_COMPONENT:
pitip->type = E_CAL_SOURCE_TYPE_TODO;
@@ -1652,7 +1710,8 @@ view_response_cb (GtkWidget *widget, ItipViewResponse response, gpointer data)
}
/*FIXME Save schedules is misused here, remove it */
- save_schedules = e_cal_get_save_schedules (pitip->current_ecal);
+ save_schedules = e_cal_get_static_capability (pitip->current_ecal,
+ CAL_STATIC_CAPABILITY_SAVE_SCHEDULES);
switch (response) {
case ITIP_VIEW_RESPONSE_ACCEPT:
@@ -1728,12 +1787,13 @@ view_response_cb (GtkWidget *widget, ItipViewResponse response, gpointer data)
tag = camel_message_info_user_tag (mi, "recurrence-key");
camel_message_info_free (mi);
if (tag) {
- GPtrArray *summary_array;
- int i=0;
+ int i = 0, count;
- summary_array = camel_folder_summary_array (pitip->folder->summary);
- for (i=0; i<summary_array->len; i++) {
- mi = (CamelMessageInfo *)g_ptr_array_index (summary_array, i);
+ count = camel_folder_summary_count (pitip->folder->summary);
+ for (i = 0; i < count; i++) {
+ mi = camel_folder_summary_index (pitip->folder->summary, i);
+ if (!mi)
+ continue;
camel_message_info_ref (mi);
if ( camel_message_info_user_tag (mi, "recurrence-key") && g_str_equal (camel_message_info_user_tag (mi, "recurrence-key"), tag)) {
@@ -1742,7 +1802,6 @@ view_response_cb (GtkWidget *widget, ItipViewResponse response, gpointer data)
}
camel_message_info_free (mi);
}
- camel_folder_summary_array_free (pitip->folder->summary, summary_array);
}
} else {
/* Either not a recurring appointment or "apply-to-all" is not selected. So just delete this instance alone */
@@ -1921,10 +1980,18 @@ format_itip_object (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject
} else {
switch (info->method) {
case ICAL_METHOD_PUBLISH:
- itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_PUBLISH);
- break;
case ICAL_METHOD_REQUEST:
- itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_REQUEST);
+ /*
+ * Treat meeting request (sent by organizer directly) and
+ * published evend (forwarded by organizer or attendee) alike:
+ * if the event has an organizer, then it can be replied to and
+ * we show the "accept/tentative/decline" choice.
+ * Otherwise only show "accept".
+ */
+ itip_view_set_mode (ITIP_VIEW (info->view),
+ info->has_organizer ?
+ ITIP_VIEW_MODE_REQUEST :
+ ITIP_VIEW_MODE_PUBLISH);
break;
case ICAL_METHOD_REPLY:
itip_view_set_mode (ITIP_VIEW (info->view), ITIP_VIEW_MODE_REPLY);
@@ -2254,6 +2321,8 @@ format_itip (EPlugin *ep, EMFormatHookTarget *target)
gconf = gconf_client_get_default ();
puri->delete_message = gconf_client_get_bool (gconf, GCONF_KEY_DELETE, NULL);
+ puri->has_organizer = FALSE;
+ puri->no_reply_wanted = FALSE;
puri->folder = ((EMFormat *) target->format)->folder;
puri->uid = g_strdup (((EMFormat *) target->format)->uid);
puri->msg = ((EMFormat *) target->format)->message;
diff --git a/plugins/itip-formatter/itip-view.c b/plugins/itip-formatter/itip-view.c
index 1e5e41195c..92a8460e48 100644
--- a/plugins/itip-formatter/itip-view.c
+++ b/plugins/itip-formatter/itip-view.c
@@ -1,22 +1,22 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
- * Authors: JP Rosevear <jpr@novell.com>
+ * 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.
*
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * Authors:
+ * JP Rosevear <jpr@novell.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
@@ -152,7 +152,7 @@ format_date_and_time_x (struct tm *date_tm,
/* Calculate a normalized "tomorrow" */
tomorrow_tm = *current_tm;
/* Don't need this if date is in the past. Also, year assumption won't fail. */
- if (date_tm->tm_year >= current_tm->tm_year && tomorrow_tm.tm_mday == time_days_in_month (date_tm->tm_year + 1900, date_tm->tm_mon)) {
+ if (date_tm->tm_year >= current_tm->tm_year && tomorrow_tm.tm_mday == time_days_in_month (current_tm->tm_year + 1900, current_tm->tm_mon)) {
tomorrow_tm.tm_mday = 1;
if (tomorrow_tm.tm_mon == 11) {
tomorrow_tm.tm_mon = 1;