From 5e5e1de764de6b705c12275dc652b1a36ba98fdd Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 27 Jul 2009 17:34:13 +0200 Subject: Bug #420513 - Be able to notify about meeting only new attendees --- calendar/gui/dialogs/comp-editor-util.c | 132 +++++++++++++++++++++++++++ calendar/gui/dialogs/comp-editor-util.h | 6 ++ calendar/gui/dialogs/comp-editor.c | 23 ++++- calendar/gui/dialogs/comp-editor.h | 3 +- calendar/gui/dialogs/event-editor.c | 5 +- calendar/gui/dialogs/event-page.c | 15 ++- calendar/gui/dialogs/send-comp.c | 81 +++++++++++----- calendar/gui/dialogs/send-comp.h | 2 +- calendar/gui/dialogs/task-editor.c | 2 +- calendar/gui/dialogs/task-page.c | 10 +- calendar/gui/e-cal-model-calendar.c | 4 +- calendar/gui/e-calendar-view.c | 22 +++-- calendar/gui/e-itip-control.c | 6 +- calendar/gui/itip-utils.c | 14 ++- calendar/gui/itip-utils.h | 3 +- modules/calendar/e-cal-shell-view-memopad.c | 2 +- modules/calendar/e-cal-shell-view-taskpad.c | 2 +- modules/calendar/e-memo-shell-view-actions.c | 2 +- modules/calendar/e-task-shell-view-actions.c | 2 +- plugins/itip-formatter/itip-formatter.c | 8 +- 20 files changed, 279 insertions(+), 65 deletions(-) diff --git a/calendar/gui/dialogs/comp-editor-util.c b/calendar/gui/dialogs/comp-editor-util.c index 697e8bda7f..d8e05ca0df 100644 --- a/calendar/gui/dialogs/comp-editor-util.c +++ b/calendar/gui/dialogs/comp-editor-util.c @@ -35,6 +35,8 @@ #include "e-util/e-binding.h" #include "widgets/misc/e-dateedit.h" #include "../calendar-config.h" +#include "../e-date-edit-config.h" +#include "../itip-utils.h" #include "comp-editor-util.h" @@ -347,3 +349,133 @@ comp_editor_strip_categories (const gchar *categories) return new_categories; } + +static GSList * +manage_new_attendees (const GSList *lst, const gchar *eml, gboolean add) +{ + GSList *copy = NULL; + const GSList *l; + gboolean found = FALSE; + + g_return_val_if_fail (eml != NULL, NULL); + + for (l = lst; l; l = l->next) { + const gchar *eml2 = l->data; + + if (!eml2) + continue; + + if (g_ascii_strcasecmp (eml, eml2) == 0) { + found = TRUE; + if (add) + copy = g_slist_append (copy, g_strdup (eml2)); + } else { + copy = g_slist_append (copy, g_strdup (eml2)); + } + } + + if (!found && add) { + copy = g_slist_append (copy, g_strdup (eml)); + } + + return copy; +} + +static void +free_slist_strs (gpointer data) +{ + GSList *lst = data; + + if (lst) { + g_slist_foreach (lst, (GFunc) g_free, NULL); + g_slist_free (lst); + } +} + +/** + * comp_editor_manage_new_attendees: + * Manages the 'new-attendees' string of new attendees of the component. + * @param comp: The component. + * @param ma: An attendee. + * @param add: TRUE to add attendee's email to new-attendees, FALSE to remove from it. + * + * @note The list is just string of emails separated by ';' + **/ +void +comp_editor_manage_new_attendees (ECalComponent *comp, EMeetingAttendee *ma, gboolean add) +{ + const gchar *eml; + + g_return_if_fail (comp != NULL); + g_return_if_fail (ma != NULL); + + eml = e_meeting_attendee_get_address (ma); + if (eml) + eml = itip_strip_mailto (eml); + g_return_if_fail (eml != NULL); + + g_object_set_data_full (G_OBJECT (comp), "new-attendees", manage_new_attendees (g_object_get_data (G_OBJECT (comp), "new-attendees"), eml, add), free_slist_strs); +} + +/** + * comp_editor_copy_new_attendees: + * Copies "new-attendees" information from src to des component. + * @param des: Component, to copy to. + * @param src: Component, to copy from. + **/ +void +comp_editor_copy_new_attendees (ECalComponent *des, ECalComponent *src) +{ + GSList *copy = NULL, *l; + + g_return_if_fail (src != NULL); + g_return_if_fail (des != NULL); + + for (l = g_object_get_data (G_OBJECT (src), "new-attendees"); l; l = l->next) { + copy = g_slist_append (copy, g_strdup (l->data)); + } + + g_object_set_data_full (G_OBJECT (des), "new-attendees", copy, free_slist_strs); +} + +/** + * comp_editor_have_in_new_attendees: + * @param comp: Component with the "new-attendees" possibly set. + * @param ma: Meeting attendee to check. + * @return Whether ma is present in the list of new attendees of the comp. + **/ +gboolean +comp_editor_have_in_new_attendees (ECalComponent *comp, EMeetingAttendee *ma) +{ + const gchar *eml; + + g_return_val_if_fail (comp != NULL, FALSE); + g_return_val_if_fail (ma != NULL, FALSE); + + eml = e_meeting_attendee_get_address (ma); + if (eml) + eml = itip_strip_mailto (eml); + g_return_val_if_fail (eml != NULL, FALSE); + + return comp_editor_have_in_new_attendees_lst (g_object_get_data (G_OBJECT (comp), "new-attendees"), eml); +} + +/** + * comp_editor_have_in_new_attendees_lst: + * Same as @ref comp_editor_have_in_new_attendees only parameters are direct GSList and string. + **/ +gboolean +comp_editor_have_in_new_attendees_lst (const GSList *new_attendees, const gchar *eml) +{ + const GSList *l; + + if (!eml) + return FALSE; + + for (l = new_attendees; l; l = l->next) { + if (l->data && g_ascii_strcasecmp (eml, l->data) == 0) + return TRUE; + } + + return FALSE; +} diff --git a/calendar/gui/dialogs/comp-editor-util.h b/calendar/gui/dialogs/comp-editor-util.h index 96638aabd0..ec481fa457 100644 --- a/calendar/gui/dialogs/comp-editor-util.h +++ b/calendar/gui/dialogs/comp-editor-util.h @@ -28,6 +28,7 @@ #include #include #include "comp-editor-page.h" +#include "../e-meeting-attendee.h" void comp_editor_dates (CompEditorPageDates *date, ECalComponent *comp); void comp_editor_free_dates (CompEditorPageDates *dates); @@ -43,4 +44,9 @@ struct tm comp_editor_get_current_time (GtkObject *object, gpointer data); gchar *comp_editor_strip_categories (const gchar *categories); +void comp_editor_manage_new_attendees (ECalComponent *comp, EMeetingAttendee *ma, gboolean add); +void comp_editor_copy_new_attendees (ECalComponent *des, ECalComponent *src); +gboolean comp_editor_have_in_new_attendees (ECalComponent *comp, EMeetingAttendee *ma); +gboolean comp_editor_have_in_new_attendees_lst (const GSList *new_attendees, const gchar *eml); + #endif diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index 6f74f73248..100a1615fb 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -60,6 +60,7 @@ #include "cancel-comp.h" #include "recur-comp.h" #include "comp-editor.h" +#include "comp-editor-util.h" #include "../e-cal-popup.h" #include "../calendar-config-keys.h" #include "cal-attachment-select-file.h" @@ -406,6 +407,7 @@ save_comp (CompEditor *editor) timezones = g_hash_table_new (g_str_hash, g_str_equal); clone = e_cal_component_clone (priv->comp); + comp_editor_copy_new_attendees (clone, priv->comp); for (l = priv->pages; l != NULL; l = l->next) { if (!comp_editor_page_fill_component (l->data, clone)) { g_object_unref (clone); @@ -535,7 +537,7 @@ save_comp_with_send (CompEditor *editor) { CompEditorPrivate *priv; CompEditorFlags flags; - gboolean send; + gboolean send, delegated, only_new_attendees = FALSE; gboolean delegate; gboolean strip_alarms = TRUE; @@ -557,7 +559,13 @@ save_comp_with_send (CompEditor *editor) if (!save_comp (editor)) return FALSE; - if ((delegate && !e_cal_get_save_schedules (priv->client)) || (send && send_component_dialog ((GtkWindow *) editor, priv->client, priv->comp, !priv->existing_org, &strip_alarms))) { + delegated = delegate && !e_cal_get_save_schedules (priv->client); + if (delegated || (send && send_component_dialog ((GtkWindow *) editor, priv->client, priv->comp, !priv->existing_org, &strip_alarms, !priv->existing_org ? NULL : &only_new_attendees))) { + if (delegated) + only_new_attendees = FALSE; + + comp_editor_set_flags (editor, (comp_editor_get_flags (editor) & (~COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY)) | (only_new_attendees ? COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY : 0)); + if ((itip_organizer_is_user (priv->comp, priv->client) || itip_sentby_is_user (priv->comp, priv->client))) { if (e_cal_component_get_vtype (priv->comp) == E_CAL_COMPONENT_JOURNAL) return comp_editor_send_comp (editor, E_CAL_COMPONENT_METHOD_PUBLISH, strip_alarms); @@ -2491,8 +2499,10 @@ real_edit_comp (CompEditor *editor, ECalComponent *comp) priv->comp = NULL; } - if (comp) + if (comp) { priv->comp = e_cal_component_clone (comp); + comp_editor_copy_new_attendees (priv->comp, comp); + } priv->existing_org = e_cal_component_has_organizer (comp); priv->warned = FALSE; @@ -2598,6 +2608,8 @@ real_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboolean str if (!send_comp) send_comp = e_cal_component_clone (priv->comp); + comp_editor_copy_new_attendees (send_comp, priv->comp); + if (e_cal_component_get_vtype (send_comp) == E_CAL_COMPONENT_JOURNAL) get_users_from_memo_comp (send_comp, &users); @@ -2612,7 +2624,7 @@ real_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboolean str if (!e_cal_component_has_attachments (priv->comp) || e_cal_get_static_capability (priv->client, CAL_STATIC_CAPABILITY_CREATE_MESSAGES)) { if (itip_send_comp (method, send_comp, priv->client, - NULL, NULL, users, strip_alarms)) { + NULL, NULL, users, strip_alarms, priv->flags & COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY)) { g_object_unref (send_comp); return TRUE; } @@ -2637,7 +2649,7 @@ real_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboolean str } if (itip_send_comp (method, send_comp, priv->client, - NULL, mime_attach_list, users, strip_alarms)) { + NULL, mime_attach_list, users, strip_alarms, priv->flags & COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY)) { gboolean saved = save_comp (editor); g_object_unref (send_comp); @@ -2707,6 +2719,7 @@ comp_editor_get_current_comp (CompEditor *editor, gboolean *correct) priv = editor->priv; comp = e_cal_component_clone (priv->comp); + comp_editor_copy_new_attendees (comp, priv->comp); if (priv->changed) { for (l = priv->pages; l != NULL; l = l->next) all_ok = comp_editor_page_fill_component (l->data, comp) && all_ok; diff --git a/calendar/gui/dialogs/comp-editor.h b/calendar/gui/dialogs/comp-editor.h index 6753635b1a..0edb2cc8eb 100644 --- a/calendar/gui/dialogs/comp-editor.h +++ b/calendar/gui/dialogs/comp-editor.h @@ -84,7 +84,8 @@ typedef enum { COMP_EDITOR_DELEGATE = 1<<2, COMP_EDITOR_USER_ORG = 1<<3, COMP_EDITOR_IS_ASSIGNED = 1<<4, - COMP_EDITOR_IS_SHARED = 1 << 5 + COMP_EDITOR_IS_SHARED = 1 << 5, + COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY = 1 << 6 } CompEditorFlags; GType comp_editor_get_type (void); diff --git a/calendar/gui/dialogs/event-editor.c b/calendar/gui/dialogs/event-editor.c index 94006a961c..c4908158d6 100644 --- a/calendar/gui/dialogs/event-editor.c +++ b/calendar/gui/dialogs/event-editor.c @@ -655,10 +655,11 @@ event_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboo client = e_meeting_store_get_client (priv->model); result = itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, - client, NULL, NULL, NULL, strip_alarms); + client, NULL, NULL, NULL, strip_alarms, FALSE); g_object_unref (comp); - return result; + if (!result) + return result; } parent: diff --git a/calendar/gui/dialogs/event-page.c b/calendar/gui/dialogs/event-page.c index caafdf1ab1..c48fe3cb79 100644 --- a/calendar/gui/dialogs/event-page.c +++ b/calendar/gui/dialogs/event-page.c @@ -957,6 +957,7 @@ event_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) /* Component for cancellation */ priv->comp = e_cal_component_clone (comp); + comp_editor_copy_new_attendees (priv->comp, comp); e_cal_component_get_summary (comp, &text); e_dialog_editable_set (priv->summary, text.value); @@ -1171,6 +1172,8 @@ event_page_fill_component (CompEditorPage *page, ECalComponent *comp) text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->description)); + comp_editor_copy_new_attendees (comp, priv->comp); + /* Summary */ str = e_dialog_editable_get (priv->summary); @@ -1706,7 +1709,7 @@ existing_attendee (EMeetingAttendee *ia, ECalComponent *comp) if (attendee->sentby) sentby = itip_strip_mailto (attendee->sentby); - if ((address && !g_ascii_strcasecmp (ia_address, address)) || (sentby && !g_ascii_strcasecmp (ia_sentby, sentby))) { + if ((address && !g_ascii_strcasecmp (ia_address, address)) || (sentby && ia_sentby&& !g_ascii_strcasecmp (ia_sentby, sentby))) { e_cal_component_free_attendee_list (attendees); return TRUE; } @@ -1755,7 +1758,8 @@ remove_attendee (EventPage *epage, EMeetingAttendee *ia) while (ia != NULL) { EMeetingAttendee *ib = NULL; - if (existing_attendee (ia, priv->comp)) { + /* do not add to deleted_attendees if user removed new attendee */ + if (existing_attendee (ia, priv->comp) && !comp_editor_have_in_new_attendees (priv->comp, ia)) { g_object_ref (ia); g_ptr_array_add (priv->deleted_attendees, ia); } @@ -1763,6 +1767,7 @@ remove_attendee (EventPage *epage, EMeetingAttendee *ia) if (e_meeting_attendee_get_delto (ia) != NULL) ib = e_meeting_store_find_attendee (priv->model, e_meeting_attendee_get_delto (ia), NULL); + comp_editor_manage_new_attendees (priv->comp, ia, FALSE); e_meeting_list_view_remove_attendee_from_name_selector (priv->list_view, ia); e_meeting_store_remove_attendee (priv->model, ia); @@ -1851,8 +1856,10 @@ attendee_added_cb (EMeetingListView *emlv, client = comp_editor_get_client (editor); flags = comp_editor_get_flags (editor); - if (!(flags & COMP_EDITOR_DELEGATE)) + if (!(flags & COMP_EDITOR_DELEGATE)) { + comp_editor_manage_new_attendees (priv->comp, ia, TRUE); return; + } if (existing_attendee (ia, priv->comp)) { e_meeting_store_remove_attendee (priv->model, ia); @@ -1867,7 +1874,7 @@ attendee_added_cb (EMeetingListView *emlv, e_meeting_attendee_set_delto (delegator, g_strdup (e_meeting_attendee_get_address (ia))); - e_meeting_attendee_set_delfrom (ia, g_strdup (delegator_id)); + e_meeting_attendee_set_delfrom (ia, g_strdup_printf ("MAILTO:%s", delegator_id)); gtk_widget_set_sensitive (priv->invite, FALSE); gtk_widget_set_sensitive (priv->add, FALSE); gtk_widget_set_sensitive (priv->edit, FALSE); diff --git a/calendar/gui/dialogs/send-comp.c b/calendar/gui/dialogs/send-comp.c index c11dadf853..64e0ce0d84 100644 --- a/calendar/gui/dialogs/send-comp.c +++ b/calendar/gui/dialogs/send-comp.c @@ -32,6 +32,17 @@ +static gboolean +component_has_new_attendees (ECalComponent *comp) +{ + g_return_val_if_fail (comp != NULL, FALSE); + + if (!e_cal_component_has_attendees (comp)) + return FALSE; + + return g_object_get_data (G_OBJECT (comp), "new-attendees") != NULL; +} + static gboolean have_nonprocedural_alarm (ECalComponent *comp) { @@ -64,6 +75,25 @@ have_nonprocedural_alarm (ECalComponent *comp) return FALSE; } +static GtkWidget * +add_checkbox (GtkBox *where, const gchar *caption) +{ + GtkWidget *checkbox, *align; + + g_return_val_if_fail (where != NULL, NULL); + g_return_val_if_fail (caption != NULL, NULL); + + checkbox = gtk_check_button_new_with_mnemonic (caption); + align = gtk_alignment_new (0.0, 0.5, 0.0, 0.0); + gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, 12, 12); + gtk_container_add (GTK_CONTAINER (align), checkbox); + gtk_widget_show (checkbox); + gtk_box_pack_start (where, align, TRUE, TRUE, 2); + gtk_widget_show (align); + + return checkbox; +} + /** * send_component_dialog: * @@ -73,10 +103,12 @@ have_nonprocedural_alarm (ECalComponent *comp) * Return value: TRUE if the user clicked Yes, FALSE otherwise. **/ gboolean -send_component_dialog (GtkWindow *parent, ECal *client, ECalComponent *comp, gboolean new, gboolean *strip_alarms) +send_component_dialog (GtkWindow *parent, ECal *client, ECalComponent *comp, gboolean new, gboolean *strip_alarms, gboolean *only_new_attendees) { ECalComponentVType vtype; const gchar *id; + GtkWidget *dialog, *sa_checkbox = NULL, *ona_checkbox = NULL; + gboolean res; if (strip_alarms) *strip_alarms = TRUE; @@ -108,32 +140,37 @@ send_component_dialog (GtkWindow *parent, ECal *client, ECalComponent *comp, gbo return FALSE; } - if (strip_alarms && have_nonprocedural_alarm (comp)) { - GtkWidget *dialog, *checkbox, *align; - gboolean res; + if (only_new_attendees && !component_has_new_attendees (comp)) { + /* do not show the check if there is no new attendee and + set as all attendees are required to be notified */ + *only_new_attendees = FALSE; - dialog = e_error_new (parent, id, NULL); - checkbox = gtk_check_button_new_with_label (_("Send my alarms with this event")); - align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0); - gtk_container_add (GTK_CONTAINER (align), checkbox); - gtk_widget_show (checkbox); - gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox), align, TRUE, TRUE, 6); - gtk_widget_show (align); + /* pretend it as being passed NULL to simplify code below */ + only_new_attendees = NULL; + } - res = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES; + if (strip_alarms && !have_nonprocedural_alarm (comp)) { + /* pretend it as being passed NULL to simplify code below */ + strip_alarms = NULL; + } - if (res) - *strip_alarms = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox)); + dialog = e_error_new (parent, id, NULL); - gtk_widget_destroy (GTK_WIDGET (dialog)); + if (strip_alarms) + sa_checkbox = add_checkbox (GTK_BOX (GTK_DIALOG (dialog)->vbox), _("Send my alarms with this event")); + if (only_new_attendees) + ona_checkbox = add_checkbox (GTK_BOX (GTK_DIALOG (dialog)->vbox), _("Notify new attendees _only")); - return res; - } else { - if (e_error_run (parent, id, NULL) == GTK_RESPONSE_YES) - return TRUE; - else - return FALSE; - } + res = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES; + + if (res && strip_alarms) + *strip_alarms = !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sa_checkbox)); + if (only_new_attendees) + *only_new_attendees = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ona_checkbox)); + + gtk_widget_destroy (GTK_WIDGET (dialog)); + + return res; } gboolean diff --git a/calendar/gui/dialogs/send-comp.h b/calendar/gui/dialogs/send-comp.h index 63644bd52a..83f356b142 100644 --- a/calendar/gui/dialogs/send-comp.h +++ b/calendar/gui/dialogs/send-comp.h @@ -28,7 +28,7 @@ #include #include -gboolean send_component_dialog (GtkWindow *parent, ECal *client, ECalComponent *comp, gboolean new, gboolean *strip_alarms); +gboolean send_component_dialog (GtkWindow *parent, ECal *client, ECalComponent *comp, gboolean new, gboolean *strip_alarms, gboolean *only_new_attendees); gboolean send_component_prompt_subject (GtkWindow *parent, ECal *client, ECalComponent *comp); #endif diff --git a/calendar/gui/dialogs/task-editor.c b/calendar/gui/dialogs/task-editor.c index a309a51d91..37cf357fe9 100644 --- a/calendar/gui/dialogs/task-editor.c +++ b/calendar/gui/dialogs/task-editor.c @@ -480,7 +480,7 @@ task_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gbool client = e_meeting_store_get_client (priv->model); result = itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, - client, NULL, NULL, NULL, strip_alarms); + client, NULL, NULL, NULL, strip_alarms, FALSE); g_object_unref (comp); if (!result) diff --git a/calendar/gui/dialogs/task-page.c b/calendar/gui/dialogs/task-page.c index 2e60ff5069..90a9f46b8c 100644 --- a/calendar/gui/dialogs/task-page.c +++ b/calendar/gui/dialogs/task-page.c @@ -493,6 +493,7 @@ task_page_fill_widgets (CompEditorPage *page, ECalComponent *comp) /* Component for cancellation */ priv->comp = e_cal_component_clone (comp); + comp_editor_copy_new_attendees (priv->comp, comp); /* Clean the screen */ clear_widgets (tpage); @@ -1021,7 +1022,7 @@ existing_attendee (EMeetingAttendee *ia, ECalComponent *comp) if (attendee->sentby) sentby = itip_strip_mailto (attendee->sentby); - if ((address && !g_ascii_strcasecmp (ia_address, address)) || (sentby && !g_ascii_strcasecmp (ia_sentby, sentby))) { + if ((address && !g_ascii_strcasecmp (ia_address, address)) || (sentby && ia_sentby && !g_ascii_strcasecmp (ia_sentby, sentby))) { e_cal_component_free_attendee_list (attendees); return TRUE; } @@ -1067,7 +1068,7 @@ remove_attendee (TaskPage *page, EMeetingAttendee *ia) while (ia != NULL) { EMeetingAttendee *ib = NULL; - if (existing_attendee (ia, priv->comp)) { + if (existing_attendee (ia, priv->comp) && !comp_editor_have_in_new_attendees (priv->comp, ia)) { g_object_ref (ia); g_ptr_array_add (priv->deleted_attendees, ia); } @@ -1075,6 +1076,7 @@ remove_attendee (TaskPage *page, EMeetingAttendee *ia) if (e_meeting_attendee_get_delto (ia) != NULL) ib = e_meeting_store_find_attendee (priv->model, e_meeting_attendee_get_delto (ia), NULL); + comp_editor_manage_new_attendees (priv->comp, ia, FALSE); e_meeting_list_view_remove_attendee_from_name_selector (priv->list_view, ia); e_meeting_store_remove_attendee (priv->model, ia); @@ -1163,8 +1165,10 @@ attendee_added_cb (EMeetingListView *emlv, client = comp_editor_get_client (editor); flags = comp_editor_get_flags (editor); - if (!(flags & COMP_EDITOR_DELEGATE)) + if (!(flags & COMP_EDITOR_DELEGATE)) { + comp_editor_manage_new_attendees (priv->comp, ia, TRUE); return; + } if (existing_attendee (ia, priv->comp)) e_meeting_store_remove_attendee (priv->model, ia); diff --git a/calendar/gui/e-cal-model-calendar.c b/calendar/gui/e-cal-model-calendar.c index 7c3529c80b..9f94a601c1 100644 --- a/calendar/gui/e-cal-model-calendar.c +++ b/calendar/gui/e-cal-model-calendar.c @@ -385,7 +385,7 @@ ecmc_set_value_at (ETableModel *etm, gint col, gint row, gconstpointer value) gboolean strip_alarms = TRUE; if (itip_organizer_is_user (comp, comp_data->client) && - send_component_dialog (NULL, comp_data->client, comp, FALSE, &strip_alarms)) { + send_component_dialog (NULL, comp_data->client, comp, FALSE, &strip_alarms, NULL)) { ECalComponent *send_comp = NULL; if (mod == CALOBJ_MOD_ALL && e_cal_component_is_instance (comp)) { @@ -405,7 +405,7 @@ ecmc_set_value_at (ETableModel *etm, gint col, gint row, gconstpointer value) } itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, send_comp ? send_comp : comp, - comp_data->client, NULL, NULL, NULL, strip_alarms); + comp_data->client, NULL, NULL, NULL, strip_alarms, FALSE); if (send_comp) g_object_unref (send_comp); diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index b2addc64fa..0b7c52fd00 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -45,6 +45,7 @@ #include "e-cal-model-calendar.h" #include "e-calendar-view.h" #include "itip-utils.h" +#include "dialogs/comp-editor-util.h" #include "dialogs/delete-comp.h" #include "dialogs/delete-error.h" #include "dialogs/event-editor.h" @@ -416,9 +417,9 @@ e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart if ((itip_organizer_is_user (comp, client) || itip_sentby_is_user (comp, client)) && send_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), - client, comp, TRUE, &strip_alarms)) { + client, comp, TRUE, &strip_alarms, NULL)) { itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, - client, NULL, NULL, NULL, strip_alarms); + client, NULL, NULL, NULL, strip_alarms, FALSE); } } else { g_message (G_STRLOC ": Could not create the object! %s", error ? error->message : ""); @@ -606,7 +607,7 @@ e_calendar_view_cut_clipboard (ECalendarView *cal_view) && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), event->comp_data->client, comp, TRUE)) itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, - event->comp_data->client, NULL, NULL, NULL, TRUE); + event->comp_data->client, NULL, NULL, NULL, TRUE, FALSE); e_cal_component_get_uid (comp, &uid); if (e_cal_component_is_instance (comp)) { @@ -1009,7 +1010,7 @@ delete_event (ECalendarView *cal_view, ECalendarViewEvent *event) event->comp_data->client, comp, TRUE)) itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, - event->comp_data->client, NULL, NULL, NULL, TRUE); + event->comp_data->client, NULL, NULL, NULL, TRUE, FALSE); e_cal_component_get_uid (comp, &uid); if (!uid || !*uid) { @@ -1157,7 +1158,7 @@ e_calendar_view_delete_selected_occurrence (ECalendarView *cal_view) e_cal_component_free_datetime (&range.datetime); } - itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, event->comp_data->client, NULL, NULL, NULL, TRUE); + itip_send_comp (E_CAL_COMPONENT_METHOD_CANCEL, comp, event->comp_data->client, NULL, NULL, NULL, TRUE, FALSE); } if (is_instance) @@ -1504,7 +1505,7 @@ on_forward (EPopup *ep, EPopupItem *pitem, gpointer data) comp = e_cal_component_new (); e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, event->comp_data->client, NULL, NULL, NULL, TRUE); + itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, event->comp_data->client, NULL, NULL, NULL, TRUE, FALSE); g_list_free (selected); g_object_unref (comp); @@ -1987,11 +1988,13 @@ e_calendar_view_modify_and_send (ECalComponent *comp, GtkWindow *toplevel, gboolean new) { + gboolean only_new_attendees = FALSE; + if (e_cal_modify_object (client, e_cal_component_get_icalcomponent (comp), mod, NULL)) { gboolean strip_alarms = TRUE; if ((itip_organizer_is_user (comp, client) || itip_sentby_is_user (comp, client)) && - send_component_dialog (toplevel, client, comp, new, &strip_alarms)) { + send_component_dialog (toplevel, client, comp, new, &strip_alarms, &only_new_attendees)) { ECalComponent *send_comp = NULL; if (mod == CALOBJ_MOD_ALL && e_cal_component_is_instance (comp)) { @@ -2006,11 +2009,14 @@ e_calendar_view_modify_and_send (ECalComponent *comp, icalcomponent_free (icalcomp); g_object_unref (send_comp); send_comp = NULL; + } else if (only_new_attendees) { + /* copy new-attendees information too if required for later use */ + comp_editor_copy_new_attendees (send_comp, comp); } } } - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, send_comp ? send_comp : comp, client, NULL, NULL, NULL, strip_alarms); + itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, send_comp ? send_comp : comp, client, NULL, NULL, NULL, strip_alarms, only_new_attendees); if (send_comp) g_object_unref (send_comp); diff --git a/calendar/gui/e-itip-control.c b/calendar/gui/e-itip-control.c index 9410c19aa9..dd231548e1 100644 --- a/calendar/gui/e-itip-control.c +++ b/calendar/gui/e-itip-control.c @@ -2098,7 +2098,7 @@ send_item (EItipControl *itip) comp = get_real_item (itip); if (comp != NULL) { - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, priv->current_ecal, NULL, NULL, NULL, TRUE); + itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, priv->current_ecal, NULL, NULL, NULL, TRUE, FALSE); g_object_unref (comp); dialog = gtk_message_dialog_new ( NULL, 0, @@ -2153,7 +2153,7 @@ send_freebusy (EItipControl *itip) for (l = comp_list; l; l = l->next) { ECalComponent *comp = E_CAL_COMPONENT (l->data); - itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, priv->current_ecal, NULL, NULL, NULL, TRUE); + itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, priv->current_ecal, NULL, NULL, NULL, TRUE, FALSE); g_object_unref (comp); } @@ -2613,7 +2613,7 @@ ok_clicked_cb (GtkWidget *widget, gpointer data) g_slist_free (list); e_cal_component_rescan (comp); - itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, priv->current_ecal, priv->top_level, NULL, NULL, TRUE); + itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, priv->current_ecal, priv->top_level, NULL, NULL, TRUE, FALSE); g_object_unref (comp); } diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c index cd0a64f1c8..08389aff08 100644 --- a/calendar/gui/itip-utils.c +++ b/calendar/gui/itip-utils.c @@ -35,6 +35,7 @@ #include "calendar-config.h" #include "itip-utils.h" #include +#include "dialogs/comp-editor-util.h" #include #include @@ -427,7 +428,7 @@ comp_from (ECalComponentItipMethod method, ECalComponent *comp) } static EDestination ** -comp_to_list (ECalComponentItipMethod method, ECalComponent *comp, GList *users, gboolean reply_all) +comp_to_list (ECalComponentItipMethod method, ECalComponent *comp, GList *users, gboolean reply_all, const GSList *only_attendees) { ECalComponentOrganizer organizer; GSList *attendees, *l; @@ -482,6 +483,8 @@ comp_to_list (ECalComponentItipMethod method, ECalComponent *comp, GList *users, else if (att->status == ICAL_PARTSTAT_DELEGATED && (att->delto && *att->delto) && !(att->rsvp) && method == E_CAL_COMPONENT_METHOD_REQUEST) continue; + else if (only_attendees && !comp_editor_have_in_new_attendees_lst (only_attendees, itip_strip_mailto (att->value))) + continue; destination = e_destination_new (); if (att->cn != NULL) @@ -513,6 +516,8 @@ comp_to_list (ECalComponentItipMethod method, ECalComponent *comp, GList *users, if (att->cutype != ICAL_CUTYPE_INDIVIDUAL && att->cutype != ICAL_CUTYPE_GROUP) continue; + else if (only_attendees && !comp_editor_have_in_new_attendees_lst (only_attendees, itip_strip_mailto (att->value))) + continue; destination = e_destination_new (); if (att->cn != NULL) @@ -1197,7 +1202,8 @@ append_cal_attachments (EMsgComposer *composer, gboolean itip_send_comp (ECalComponentItipMethod method, ECalComponent *send_comp, - ECal *client, icalcomponent *zones, GSList *attachments_list, GList *users, gboolean strip_alarms) + ECal *client, icalcomponent *zones, GSList *attachments_list, GList *users, + gboolean strip_alarms, gboolean only_new_attendees) { EMsgComposer *composer; EComposerHeaderTable *table; @@ -1236,7 +1242,7 @@ itip_send_comp (ECalComponentItipMethod method, ECalComponent *send_comp, goto cleanup; /* Recipients */ - destinations = comp_to_list (method, comp, users, FALSE); + destinations = comp_to_list (method, comp, users, FALSE, only_new_attendees ? g_object_get_data (G_OBJECT (send_comp), "new-attendees") : NULL); if (method != E_CAL_COMPONENT_METHOD_PUBLISH) { if (destinations == NULL) { /* We sent them all via the server */ @@ -1350,7 +1356,7 @@ reply_to_calendar_comp (ECalComponentItipMethod method, goto cleanup; /* Recipients */ - destinations = comp_to_list (method, comp, users, reply_all); + destinations = comp_to_list (method, comp, users, reply_all, NULL); /* Subject information */ subject = comp_subject (method, comp); diff --git a/calendar/gui/itip-utils.h b/calendar/gui/itip-utils.h index 35045d01f2..6e27d890c8 100644 --- a/calendar/gui/itip-utils.h +++ b/calendar/gui/itip-utils.h @@ -60,7 +60,8 @@ const gchar *itip_strip_mailto (const gchar *address); gchar *itip_get_comp_attendee (ECalComponent *comp, ECal *client); gboolean itip_send_comp (ECalComponentItipMethod method, ECalComponent *comp, - ECal *client, icalcomponent *zones, GSList *attachments_list, GList *users, gboolean strip_alarms); + ECal *client, icalcomponent *zones, GSList *attachments_list, GList *users, + gboolean strip_alarms, gboolean only_new_attendees); gboolean itip_publish_comp (ECal *client, gchar * uri, gchar * username, gchar * password, ECalComponent **pub_comp); diff --git a/modules/calendar/e-cal-shell-view-memopad.c b/modules/calendar/e-cal-shell-view-memopad.c index ecee72d8b5..1c4e863345 100644 --- a/modules/calendar/e-cal-shell-view-memopad.c +++ b/modules/calendar/e-cal-shell-view-memopad.c @@ -104,7 +104,7 @@ action_calendar_memopad_forward_cb (GtkAction *action, e_cal_component_set_icalcomponent (comp, clone); itip_send_comp ( E_CAL_COMPONENT_METHOD_PUBLISH, comp, - comp_data->client, NULL, NULL, NULL, TRUE); + comp_data->client, NULL, NULL, NULL, TRUE, FALSE); g_object_unref (comp); } diff --git a/modules/calendar/e-cal-shell-view-taskpad.c b/modules/calendar/e-cal-shell-view-taskpad.c index bdd136b6f7..965ec47c49 100644 --- a/modules/calendar/e-cal-shell-view-taskpad.c +++ b/modules/calendar/e-cal-shell-view-taskpad.c @@ -127,7 +127,7 @@ action_calendar_taskpad_forward_cb (GtkAction *action, e_cal_component_set_icalcomponent (comp, clone); itip_send_comp ( E_CAL_COMPONENT_METHOD_PUBLISH, comp, - comp_data->client, NULL, NULL, NULL, TRUE); + comp_data->client, NULL, NULL, NULL, TRUE, FALSE); g_object_unref (comp); } diff --git a/modules/calendar/e-memo-shell-view-actions.c b/modules/calendar/e-memo-shell-view-actions.c index 1736606abe..2d6713a7a8 100644 --- a/modules/calendar/e-memo-shell-view-actions.c +++ b/modules/calendar/e-memo-shell-view-actions.c @@ -125,7 +125,7 @@ action_memo_forward_cb (GtkAction *action, e_cal_component_set_icalcomponent (comp, clone); itip_send_comp ( E_CAL_COMPONENT_METHOD_PUBLISH, comp, - comp_data->client, NULL, NULL, NULL, TRUE); + comp_data->client, NULL, NULL, NULL, TRUE, FALSE); g_object_unref (comp); } diff --git a/modules/calendar/e-task-shell-view-actions.c b/modules/calendar/e-task-shell-view-actions.c index eea80b77c6..d1354026cb 100644 --- a/modules/calendar/e-task-shell-view-actions.c +++ b/modules/calendar/e-task-shell-view-actions.c @@ -178,7 +178,7 @@ action_task_forward_cb (GtkAction *action, e_cal_component_set_icalcomponent (comp, clone); itip_send_comp ( E_CAL_COMPONENT_METHOD_PUBLISH, comp, - comp_data->client, NULL, NULL, NULL, TRUE); + comp_data->client, NULL, NULL, NULL, TRUE, FALSE); g_object_unref (comp); } diff --git a/plugins/itip-formatter/itip-formatter.c b/plugins/itip-formatter/itip-formatter.c index 204d150950..89313dd995 100644 --- a/plugins/itip-formatter/itip-formatter.c +++ b/plugins/itip-formatter/itip-formatter.c @@ -1217,7 +1217,7 @@ send_comp_to_attendee (ECalComponentItipMethod method, ECalComponent *comp, cons } /* FIXME send the attachments in the request */ - status = itip_send_comp (method, send_comp, client, NULL, NULL, NULL, TRUE); + status = itip_send_comp (method, send_comp, client, NULL, NULL, NULL, TRUE, FALSE); g_object_unref (send_comp); @@ -1369,7 +1369,7 @@ update_attendee_status (struct _itip_puri *pitip) 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, NULL, TRUE); + itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, pitip->current_ecal, NULL, NULL, NULL, TRUE, FALSE); } if (!e_cal_modify_object (pitip->current_ecal, icalcomp, rid ? CALOBJ_MOD_THIS : CALOBJ_MOD_ALL, &error)) { @@ -1399,7 +1399,7 @@ send_item (struct _itip_puri *pitip) comp = get_real_item (pitip); if (comp != NULL) { - itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, pitip->current_ecal, NULL, NULL, NULL, TRUE); + itip_send_comp (E_CAL_COMPONENT_METHOD_REQUEST, comp, pitip->current_ecal, NULL, NULL, NULL, TRUE, FALSE); g_object_unref (comp); switch (pitip->type) { @@ -1985,7 +1985,7 @@ view_response_cb (GtkWidget *widget, ItipViewResponse response, gpointer data) } e_cal_component_rescan (comp); - if (itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, pitip->current_ecal, pitip->top_level, NULL, NULL, TRUE)) { + if (itip_send_comp (E_CAL_COMPONENT_METHOD_REPLY, comp, pitip->current_ecal, pitip->top_level, NULL, NULL, TRUE, FALSE)) { camel_folder_set_message_flags (pitip->folder, pitip->uid, CAMEL_MESSAGE_ANSWERED, CAMEL_MESSAGE_ANSWERED); } -- cgit v1.2.3