diff options
-rw-r--r-- | plugins/itip-formatter/ChangeLog | 17 | ||||
-rw-r--r-- | plugins/itip-formatter/itip-formatter.c | 240 | ||||
-rw-r--r-- | plugins/itip-formatter/itip-view.c | 68 | ||||
-rw-r--r-- | plugins/itip-formatter/itip-view.h | 6 | ||||
-rw-r--r-- | plugins/itip-formatter/org-gnome-itip-formatter.error.xml | 7 |
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>"{0}" has delegated the meeting. Do you want to add the delegate "{1}" ?</_secondary> + <button _label="Yes" response="GTK_RESPONSE_YES"/> + <button _label="No" response="GTK_RESPONSE_NO"/> + </error> </error-list> |