aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/itip-formatter/ChangeLog17
-rw-r--r--plugins/itip-formatter/itip-formatter.c240
-rw-r--r--plugins/itip-formatter/itip-view.c68
-rw-r--r--plugins/itip-formatter/itip-view.h6
-rw-r--r--plugins/itip-formatter/org-gnome-itip-formatter.error.xml7
5 files changed, 293 insertions, 45 deletions
diff --git a/plugins/itip-formatter/ChangeLog b/plugins/itip-formatter/ChangeLog
index 85d730682a..d95dba374c 100644
--- a/plugins/itip-formatter/ChangeLog
+++ b/plugins/itip-formatter/ChangeLog
@@ -1,3 +1,20 @@
+2005-06-20 Chenthill Palanisamy <pchenthill@novell.com>
+
+ * itip-formatter.c: (find_my_address), (set_attendee),
+ (send_comp_to_attendee), (remove_delegate),
+ (update_attendee_status), (extract_itip_data),
+ (format_itip_object): Set the delegator address. If the
+ organizer refuses to add the new delegate, send a cancel
+ method to the delegate and request to the attendee.
+ * itip-view.h:
+ * itip-view.c: (set_calendar_sender_text), (itip_view_init),
+ (itip_view_get_show_rsvp), (itip_view_set_update),
+ (itip_view_get_update), (itip_view_set_show_update),
+ (itip_view_get_show_update): Added functions to show an
+ option to send updates to attendees.
+ * org-gnome-itip-formatter.error.xml: Added the error
+ message to add a new delegate.
+
2005-06-18 Tor Lillqvist <tml@novell.com>
* org-gnome-itip-formatter.eplug.xml: Use SOEXT.
diff --git a/plugins/itip-formatter/itip-formatter.c b/plugins/itip-formatter/itip-formatter.c
index bd85f6c96f..87204791fb 100644
--- a/plugins/itip-formatter/itip-formatter.c
+++ b/plugins/itip-formatter/itip-formatter.c
@@ -145,55 +145,39 @@ find_my_address (FormatItipPObject *pitip, icalcomponent *ical_comp, icalparamet
name_clean = NULL;
}
- if (pitip->delegator_address) {
- char *delegator_clean;
-
- delegator_clean = g_strdup (itip_strip_mailto (attendee));
- delegator_clean = g_strstrip (delegator_clean);
-
- /* If the mailer told us the address to use, use that */
- if (delegator_clean != NULL
- && !g_ascii_strcasecmp (attendee_clean, delegator_clean)) {
- pitip->my_address = g_strdup (itip_strip_mailto (pitip->delegator_address));
- pitip->my_address = g_strstrip (pitip->my_address);
+ it = e_list_get_iterator((EList *)pitip->accounts);
+ while (e_iterator_is_valid(it)) {
+ const EAccount *account = e_iterator_get(it);
+
+ if (!account->enabled) {
+ e_iterator_next(it);
+ continue;
+ }
+ /* Check for a matching address */
+ if (attendee_clean != NULL
+ && !g_ascii_strcasecmp (account->id->address, attendee_clean)) {
+ pitip->my_address = g_strdup (account->id->address);
if (status) {
param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER);
*status = param ? icalparameter_get_partstat (param) : ICAL_PARTSTAT_NEEDSACTION;
}
+ g_free (attendee_clean);
+ g_free (name_clean);
+ g_free (my_alt_address);
+ g_object_unref(it);
+ return;
}
- g_free (delegator_clean);
- } else {
- it = e_list_get_iterator((EList *)pitip->accounts);
- while (e_iterator_is_valid(it)) {
- const EAccount *account = e_iterator_get(it);
-
- /* Check for a matching address */
- if (attendee_clean != NULL
- && !g_ascii_strcasecmp (account->id->address, attendee_clean)) {
- pitip->my_address = g_strdup (account->id->address);
- if (status) {
- param = icalproperty_get_first_parameter (prop, ICAL_PARTSTAT_PARAMETER);
- *status = param ? icalparameter_get_partstat (param) : ICAL_PARTSTAT_NEEDSACTION;
- }
- g_free (attendee_clean);
- g_free (name_clean);
- g_free (my_alt_address);
- g_object_unref(it);
- return;
- }
-
- /* Check for a matching cname to fall back on */
- if (name_clean != NULL
- && !g_ascii_strcasecmp (account->id->name, name_clean))
- my_alt_address = g_strdup (attendee_clean);
-
- e_iterator_next(it);
- }
- g_object_unref(it);
+ /* Check for a matching cname to fall back on */
+ if (name_clean != NULL
+ && !g_ascii_strcasecmp (account->id->name, name_clean))
+ my_alt_address = g_strdup (attendee_clean);
+
+ e_iterator_next(it);
}
-
+ g_object_unref(it);
+
g_free (attendee_clean);
g_free (name_clean);
}
@@ -794,16 +778,112 @@ update_item (FormatItipPObject *pitip, ItipViewResponse response)
g_object_unref (clone_comp);
}
+/* TODO These operations should be available in e-cal-component.c */
+static void
+set_attendee (ECalComponent *comp, const char *address)
+{
+ icalproperty *prop;
+ icalcomponent *icalcomp;
+ gboolean found = FALSE;
+
+ icalcomp = e_cal_component_get_icalcomponent (comp);
+
+ for (prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
+ prop;
+ prop = icalcomponent_get_next_property (icalcomp, ICAL_ATTENDEE_PROPERTY)) {
+ const char *attendee = icalproperty_get_attendee (prop);
+
+ if (!(g_str_equal (itip_strip_mailto (attendee), address)))
+ icalcomponent_remove_property (icalcomp, prop);
+ else
+ found = TRUE;
+ }
+
+ if (!found) {
+ icalparameter *param;
+ char *temp = g_strdup_printf ("MAILTO:%s", address);
+
+ prop = icalproperty_new_attendee ((const char *) temp);
+ icalcomponent_add_property (icalcomp, prop);
+
+ param = icalparameter_new_partstat (ICAL_PARTSTAT_NEEDSACTION);
+ icalproperty_add_parameter (prop, param);
+
+ param = icalparameter_new_role (ICAL_ROLE_REQPARTICIPANT);
+ icalproperty_add_parameter (prop, param);
+
+ param = icalparameter_new_cutype (ICAL_CUTYPE_INDIVIDUAL);
+ icalproperty_add_parameter (prop, param);
+
+ param = icalparameter_new_rsvp (ICAL_RSVP_TRUE);
+ icalproperty_add_parameter (prop, param);
+
+ g_free (temp);
+ }
+
+}
+
+static gboolean
+send_comp_to_attendee (ECalComponentItipMethod method, ECalComponent *comp, const char *user, ECal *client, const char *comment)
+{
+ gboolean status;
+ ECalComponent *send_comp = e_cal_component_clone (comp);
+
+ set_attendee (send_comp, user);
+
+ if (comment) {
+ GSList comments;
+ ECalComponentText text;
+
+ text.value = comment;
+ text.altrep = NULL;
+
+ comments.data = &text;
+ comments.next = NULL;
+
+ e_cal_component_set_comment_list (send_comp, &comments);
+ }
+
+ /* FIXME send the attachments in the request */
+ status = itip_send_comp (method, send_comp, client, NULL, NULL);
+
+ g_object_unref (send_comp);
+
+ return status;
+}
+
+static void
+remove_delegate (FormatItipPObject *pitip, const char *delegate, const char *delegator, ECalComponent *comp)
+{
+ gboolean status;
+ char *comment = g_strdup_printf (_("Organizer has removed the delegate %s "), itip_strip_mailto (delegate));
+
+ /* send cancellation notice to delegate */
+ status = send_comp_to_attendee (E_CAL_COMPONENT_METHOD_CANCEL, pitip->comp, delegate, pitip->current_ecal, comment);
+ if (status)
+ send_comp_to_attendee (E_CAL_COMPONENT_METHOD_REQUEST, pitip->comp, delegator, pitip->current_ecal, comment);
+ if (status) {
+ itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Sent a cancellation notice to the delegate"));
+ } else
+ itip_view_add_lower_info_item (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_INFO, _("Could not send the cancellation notice to the delegate"));
+
+ g_free (comment);
+
+}
+
static void
update_attendee_status (FormatItipPObject *pitip)
{
ECalComponent *comp = NULL;
- icalcomponent *icalcomp = NULL;
+ icalcomponent *icalcomp = NULL, *org_icalcomp;
const char *uid, *rid;
+ const char *delegate;
GError *error;
/* Obtain our version */
e_cal_component_get_uid (pitip->comp, &uid);
+ org_icalcomp = e_cal_component_get_icalcomponent (pitip->comp);
+
rid = e_cal_component_get_recurid_as_string (pitip->comp);
if (e_cal_get_object (pitip->current_ecal, uid, rid, &icalcomp, NULL)) {
GSList *attendees;
@@ -817,11 +897,38 @@ update_attendee_status (FormatItipPObject *pitip)
e_cal_component_get_attendee_list (pitip->comp, &attendees);
if (attendees != NULL) {
ECalComponentAttendee *a = attendees->data;
- icalproperty *prop;
+ icalproperty *prop, *del_prop;
prop = find_attendee (icalcomp, itip_strip_mailto (a->value));
+ if ((a->status == ICAL_PARTSTAT_DELEGATED) && (del_prop = find_attendee (org_icalcomp, itip_strip_mailto (a->delto))) && !(find_attendee (icalcomp, itip_strip_mailto (a->delto)))) {
+ gint response;
+ delegate = icalproperty_get_attendee (del_prop);
+
+ if ((response = e_error_run (NULL, "org.gnome.itip-formatter:add-delegate",itip_strip_mailto (a->value), itip_strip_mailto (delegate))) == GTK_RESPONSE_YES) {
+ icalcomponent_add_property (icalcomp, icalproperty_new_clone (del_prop));
+ e_cal_component_rescan (comp);
+ } else if (response == GTK_RESPONSE_NO) {
+ remove_delegate (pitip, delegate, itip_strip_mailto (a->value), comp);
+ goto cleanup;
+ } else
+ goto cleanup;
+ }
if (prop == NULL) {
+ gint response;
+
+ if (a->delfrom && *a->delfrom) {
+ if ((response == e_error_run (NULL, "org.gnome.itip-formatter:add-delegate", itip_strip_mailto (a->delfrom)), itip_strip_mailto (a->value)) == GTK_RESPONSE_YES) {
+ icalproperty *prop = find_attendee (icalcomp, itip_strip_mailto (a->value));
+ icalcomponent_add_property (icalcomp,icalproperty_new_clone (prop));
+ e_cal_component_rescan (comp);
+
+ } else if (response == GTK_RESPONSE_NO){
+ remove_delegate (pitip, itip_strip_mailto (a->value) , itip_strip_mailto (a->delfrom), comp);
+ goto cleanup;
+ } else
+ goto cleanup;
+ }
if (e_error_run (NULL, "org.gnome.itip-formatter:add-unknown-attendee", NULL) == GTK_RESPONSE_YES) {
change_status (icalcomp, itip_strip_mailto (a->value), a->status);
e_cal_component_rescan (comp);
@@ -833,12 +940,27 @@ update_attendee_status (FormatItipPObject *pitip)
_("Attendee status could not be updated because the status is invalid"));
goto cleanup;
} else {
- change_status (icalcomp, itip_strip_mailto (a->value), a->status);
+ if (a->status == ICAL_PARTSTAT_DELEGATED) {
+ icalproperty *prop, *new_prop;
+
+ prop = find_attendee (icalcomp, itip_strip_mailto (a->value));
+ icalcomponent_remove_property (icalcomp, prop);
+
+ 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);
+
e_cal_component_rescan (comp);
}
}
}
+ if (itip_view_get_update (ITIP_VIEW (pitip->view))) {
+ e_cal_component_commit_sequence (comp);
+ itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, pitip->current_ecal, NULL, NULL);
+ }
+
if (!e_cal_modify_object (pitip->current_ecal, icalcomp, rid ? CALOBJ_MOD_THIS : CALOBJ_MOD_ALL, &error)) {
itip_view_add_lower_info_item_printf (ITIP_VIEW (pitip->view), ITIP_VIEW_INFO_ITEM_TYPE_ERROR,
_("Unable to update attendee. %s"), error->message);
@@ -956,6 +1078,8 @@ extract_itip_data (FormatItipPObject *pitip, GtkContainer *container)
icalcompiter tz_iter;
icalcomponent *alarm_comp;
icalcompiter alarm_iter;
+ ECalComponent *comp;
+ char *my_address;
content = camel_medium_get_content_object ((CamelMedium *) pitip->pobject.part);
mem = camel_stream_mem_new ();
@@ -1040,7 +1164,28 @@ extract_itip_data (FormatItipPObject *pitip, GtkContainer *container)
} else {
pitip->current = 0;
}
+
+ 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);
+ g_object_unref (comp);
+ comp = NULL;
+
+ prop = find_attendee (pitip->ical_comp, my_address);
+
+ if (prop) {
+ icalparameter *param;
+ const char * delfrom;
+
+ if ((param =icalproperty_get_first_parameter (prop, ICAL_DELEGATEDFROM_PARAMETER))) {
+ delfrom = icalparameter_get_delegatedfrom (param);
+
+ pitip->delegator_address = g_strdup (itip_strip_mailto (delfrom));
+ }
+
+ }
+
/* Determine any delegate sections */
prop = icalcomponent_get_first_property (pitip->ical_comp, ICAL_X_PROPERTY);
while (prop) {
@@ -1354,6 +1499,8 @@ format_itip_object (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject
case ICAL_METHOD_ADD:
case ICAL_METHOD_CANCEL:
case ICAL_METHOD_DECLINECOUNTER:
+ itip_view_set_show_update (ITIP_VIEW (pitip->view), FALSE);
+
/* An organizer sent this */
e_cal_component_get_organizer (pitip->comp, &organizer);
itip_view_set_organizer (ITIP_VIEW (pitip->view), organizer.cn ? organizer.cn : itip_strip_mailto (organizer.value));
@@ -1369,6 +1516,8 @@ format_itip_object (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject
case ICAL_METHOD_REPLY:
case ICAL_METHOD_REFRESH:
case ICAL_METHOD_COUNTER:
+ itip_view_set_show_update (ITIP_VIEW (pitip->view), TRUE);
+
/* An attendee sent this */
e_cal_component_get_attendee_list (pitip->comp, &list);
if (list != NULL) {
@@ -1408,6 +1557,9 @@ format_itip_object (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject
case ICAL_PARTSTAT_DECLINED:
itip_view_set_status (ITIP_VIEW (pitip->view), _("Declined"));
break;
+ case ICAL_PARTSTAT_DELEGATED:
+ itip_view_set_status (ITIP_VIEW (pitip->view), _("Delegated"));
+ break;
default:
itip_view_set_status (ITIP_VIEW (pitip->view), _("Unknown"));
}
diff --git a/plugins/itip-formatter/itip-view.c b/plugins/itip-formatter/itip-view.c
index 08256f1f3e..acfcf9527f 100644
--- a/plugins/itip-formatter/itip-view.c
+++ b/plugins/itip-formatter/itip-view.c
@@ -112,6 +112,10 @@ struct _ItipViewPrivate {
GtkWidget *rsvp_comment_entry;
gboolean rsvp_show;
+ GtkWidget *update_box;
+ GtkWidget *update_check;
+ gboolean update_show;
+
GtkWidget *button_box;
gboolean buttons_sensitive;
};
@@ -339,7 +343,7 @@ set_calendar_sender_text (ItipView *view)
case ITIP_VIEW_MODE_REQUEST:
/* FIXME is the delegator stuff handled correctly here? */
if (priv->delegator) {
- sender = g_strdup_printf (_("<b>%s</b> requests the presence of %s at the following meeting:"), organizer, priv->delegator);
+ sender = g_strdup_printf (_("<b>%s</b> has delegated the following meeting to you:"), priv->delegator);
} else {
if (priv->sentby)
sender = g_strdup_printf (_("<b>%s</b> through %s requests your presence at the following meeting:"), organizer, priv->sentby);
@@ -949,6 +953,14 @@ itip_view_init (ItipView *view)
gtk_widget_show (priv->rsvp_comment_entry);
gtk_box_pack_start (GTK_BOX (hbox), priv->rsvp_comment_entry, FALSE, TRUE, 0);
+ /* RSVP area */
+ priv->update_box = gtk_vbox_new (FALSE, 12);
+ gtk_box_pack_start (GTK_BOX (vbox), priv->update_box, FALSE, FALSE, 0);
+
+ priv->update_check = gtk_check_button_new_with_mnemonic (_("Send u_pdates to attendees"));
+ gtk_widget_show (priv->update_check);
+ gtk_box_pack_start (GTK_BOX (priv->update_box), priv->update_check, FALSE, FALSE, 0);
+
/* The buttons for actions */
priv->button_box = gtk_hbutton_box_new ();
gtk_button_box_set_layout (GTK_BUTTON_BOX (priv->button_box), GTK_BUTTONBOX_END);
@@ -1728,6 +1740,60 @@ itip_view_get_show_rsvp (ItipView *view)
}
void
+itip_view_set_update (ItipView *view, gboolean update)
+{
+ ItipViewPrivate *priv;
+
+ g_return_if_fail (view != NULL);
+ g_return_if_fail (ITIP_IS_VIEW (view));
+
+ priv = view->priv;
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->update_check), update);
+}
+
+gboolean
+itip_view_get_update (ItipView *view)
+{
+ ItipViewPrivate *priv;
+
+ g_return_val_if_fail (view != NULL, FALSE);
+ g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
+
+ priv = view->priv;
+
+ return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->update_check));
+}
+
+void
+itip_view_set_show_update (ItipView *view, gboolean update)
+{
+ ItipViewPrivate *priv;
+
+ g_return_if_fail (view != NULL);
+ g_return_if_fail (ITIP_IS_VIEW (view));
+
+ priv = view->priv;
+
+ priv->update_show = update;
+
+ priv->update_show ? gtk_widget_show (priv->update_box) : gtk_widget_hide (priv->update_box);
+}
+
+gboolean
+itip_view_get_show_update (ItipView *view)
+{
+ ItipViewPrivate *priv;
+
+ g_return_val_if_fail (view != NULL, FALSE);
+ g_return_val_if_fail (ITIP_IS_VIEW (view), FALSE);
+
+ priv = view->priv;
+
+ return priv->update_show;
+}
+
+void
itip_view_set_rsvp_comment (ItipView *view, const char *comment)
{
ItipViewPrivate *priv;
diff --git a/plugins/itip-formatter/itip-view.h b/plugins/itip-formatter/itip-view.h
index a8605a9564..d05bd4479c 100644
--- a/plugins/itip-formatter/itip-view.h
+++ b/plugins/itip-formatter/itip-view.h
@@ -153,6 +153,12 @@ gboolean itip_view_get_rsvp (ItipView *view);
void itip_view_set_show_rsvp (ItipView *view, gboolean rsvp);
gboolean itip_view_get_show_rsvp (ItipView *view);
+void itip_view_set_update (ItipView *view, gboolean update);
+gboolean itip_view_get_update (ItipView *view);
+
+void itip_view_set_show_update (ItipView *view, gboolean update);
+gboolean itip_view_get_show_update (ItipView *view);
+
void itip_view_set_rsvp_comment (ItipView *view, const char *comment);
const char *itip_view_get_rsvp_comment (ItipView *view);
diff --git a/plugins/itip-formatter/org-gnome-itip-formatter.error.xml b/plugins/itip-formatter/org-gnome-itip-formatter.error.xml
index 0dff527a0e..378aa2eb62 100644
--- a/plugins/itip-formatter/org-gnome-itip-formatter.error.xml
+++ b/plugins/itip-formatter/org-gnome-itip-formatter.error.xml
@@ -4,5 +4,12 @@
<error id="add-unknown-attendee" type="question">
<_primary>This response is not from a current attendee. Add the sender as an attendee?</_primary>
</error>
+
+ <error id="add-delegate" type="question">
+ <_primary>This meeting has been delegated</_primary>
+ <_secondary>&quot;{0}&quot; has delegated the meeting. Do you want to add the delegate &quot;{1}&quot; ?</_secondary>
+ <button _label="Yes" response="GTK_RESPONSE_YES"/>
+ <button _label="No" response="GTK_RESPONSE_NO"/>
+ </error>
</error-list>