[evolution] Bug #420513 - Be able to notify about meeting only new attendees



commit e3cef9b96f175370c92f993af15a766a0818abd2
Author: Milan Crha <mcrha redhat com>
Date:   Mon Jul 27 17:34:13 2009 +0200

    Bug #420513 - Be able to notify about meeting only new attendees

 calendar/gui/dialogs/comp-editor-util.c |  131 +++++++++++++++++++++++++++++++
 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-table.c         |    2 +-
 calendar/gui/e-calendar-view.c          |   22 ++++--
 calendar/gui/e-itip-control.c           |    6 +-
 calendar/gui/e-memo-table.c             |    2 +-
 calendar/gui/itip-utils.c               |   14 +++-
 calendar/gui/itip-utils.h               |    3 +-
 calendar/gui/tasks-control.c            |    2 +-
 plugins/itip-formatter/itip-formatter.c |    8 +-
 19 files changed, 277 insertions(+), 64 deletions(-)
---
diff --git a/calendar/gui/dialogs/comp-editor-util.c b/calendar/gui/dialogs/comp-editor-util.c
index e330a7f..fa5d9a6 100644
--- a/calendar/gui/dialogs/comp-editor-util.c
+++ b/calendar/gui/dialogs/comp-editor-util.c
@@ -34,6 +34,7 @@
 #include <libecal/e-cal-time-util.h>
 #include "../calendar-config.h"
 #include "../e-date-edit-config.h"
+#include "../itip-utils.h"
 #include "comp-editor-util.h"
 
 
@@ -345,3 +346,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 c2b5a05..cebb8f7 100644
--- a/calendar/gui/dialogs/comp-editor-util.h
+++ b/calendar/gui/dialogs/comp-editor-util.h
@@ -27,6 +27,7 @@
 
 #include <gtk/gtk.h>
 #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);
@@ -40,4 +41,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 28d33d6..1bd002e 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"
@@ -391,6 +392,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);
@@ -520,7 +522,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;
 
@@ -542,7 +544,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);
@@ -2377,8 +2385,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;
@@ -2484,6 +2494,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);
 
@@ -2498,7 +2510,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;
 		}
@@ -2518,7 +2530,7 @@ real_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboolean str
 		/* mime_attach_list is freed by itip_send_comp */
 		mime_attach_list = comp_editor_get_mime_attach_list (editor);
 		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);
@@ -2588,6 +2600,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 2106970..21f9066 100644
--- a/calendar/gui/dialogs/comp-editor.h
+++ b/calendar/gui/dialogs/comp-editor.h
@@ -83,7 +83,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 4643f8f..7251123 100644
--- a/calendar/gui/dialogs/event-editor.c
+++ b/calendar/gui/dialogs/event-editor.c
@@ -639,10 +639,11 @@ event_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gboo
 
 		client = e_meeting_store_get_e_cal (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 7e95d72..8a9b67e 100644
--- a/calendar/gui/dialogs/event-page.c
+++ b/calendar/gui/dialogs/event-page.c
@@ -939,6 +939,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);
@@ -1153,6 +1154,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);
@@ -1688,7 +1691,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;
 		}
@@ -1737,7 +1740,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);
 		}
@@ -1745,6 +1749,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);
 
@@ -1838,8 +1843,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);
@@ -1854,7 +1861,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 c11dadf..64e0ce0 100644
--- a/calendar/gui/dialogs/send-comp.c
+++ b/calendar/gui/dialogs/send-comp.c
@@ -33,6 +33,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)
 {
 	GList *uids, *l;
@@ -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 63644bd..83f356b 100644
--- a/calendar/gui/dialogs/send-comp.h
+++ b/calendar/gui/dialogs/send-comp.h
@@ -28,7 +28,7 @@
 #include <libecal/e-cal.h>
 #include <libecal/e-cal-component.h>
 
-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 1e3afc9..0ca6ff5 100644
--- a/calendar/gui/dialogs/task-editor.c
+++ b/calendar/gui/dialogs/task-editor.c
@@ -464,7 +464,7 @@ task_editor_send_comp (CompEditor *editor, ECalComponentItipMethod method, gbool
 
 		client = e_meeting_store_get_e_cal (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 f1b13df..6de55a1 100644
--- a/calendar/gui/dialogs/task-page.c
+++ b/calendar/gui/dialogs/task-page.c
@@ -476,6 +476,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);
@@ -1001,7 +1002,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;
 		}
@@ -1047,7 +1048,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);
 		}
@@ -1055,6 +1056,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);
 
@@ -1148,8 +1150,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 452ce88..fbf3235 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-table.c b/calendar/gui/e-calendar-table.c
index 180680d..70f347b 100644
--- a/calendar/gui/e-calendar-table.c
+++ b/calendar/gui/e-calendar-table.c
@@ -1436,7 +1436,7 @@ e_calendar_table_on_forward (EPopup *ep, EPopupItem *pitem, gpointer data)
 
 		comp = e_cal_component_new ();
 		e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
-		itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, comp_data->client, NULL, NULL, NULL, TRUE);
+		itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
 
 		g_object_unref (comp);
 	}
diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c
index e02838e..cd42454 100644
--- a/calendar/gui/e-calendar-view.c
+++ b/calendar/gui/e-calendar-view.c
@@ -47,6 +47,7 @@
 #include "e-calendar-view.h"
 #include "e-comp-editor-registry.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"
@@ -368,9 +369,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 : "");
@@ -672,7 +673,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)) {
@@ -1065,7 +1066,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) {
@@ -1213,7 +1214,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)
@@ -1614,7 +1615,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);
@@ -2165,11 +2166,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)) {
@@ -2184,11 +2187,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 e8922ab..6d5c23b 100644
--- a/calendar/gui/e-itip-control.c
+++ b/calendar/gui/e-itip-control.c
@@ -2089,7 +2089,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,
@@ -2144,7 +2144,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);
 		}
@@ -2604,7 +2604,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/e-memo-table.c b/calendar/gui/e-memo-table.c
index 553f239..47b3d44 100644
--- a/calendar/gui/e-memo-table.c
+++ b/calendar/gui/e-memo-table.c
@@ -888,7 +888,7 @@ e_memo_table_on_forward (EPopup *ep, EPopupItem *pitem, gpointer data)
 
 		comp = e_cal_component_new ();
 		e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
-		itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, comp_data->client, NULL, NULL, NULL, TRUE);
+		itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, comp_data->client, NULL, NULL, NULL, TRUE, FALSE);
 
 		g_object_unref (comp);
 	}
diff --git a/calendar/gui/itip-utils.c b/calendar/gui/itip-utils.c
index 79df2dd..a23146f 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 <time.h>
+#include "dialogs/comp-editor-util.h"
 
 #include <composer/e-msg-composer.h>
 #include <mail/em-composer-utils.h>
@@ -428,7 +429,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;
@@ -483,6 +484,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)
@@ -514,6 +517,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)
@@ -1192,7 +1197,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;
@@ -1231,7 +1237,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 */
@@ -1346,7 +1352,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 c01fdbc..b93ffe2 100644
--- a/calendar/gui/itip-utils.h
+++ b/calendar/gui/itip-utils.h
@@ -59,7 +59,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/calendar/gui/tasks-control.c b/calendar/gui/tasks-control.c
index a7134e9..41de092 100644
--- a/calendar/gui/tasks-control.c
+++ b/calendar/gui/tasks-control.c
@@ -573,7 +573,7 @@ tasks_control_forward_cmd (BonoboUIComponent *uic,
                        ECalComponent *comp;
                        comp = e_cal_component_new ();
                        e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
-                       itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, comp_data->client, NULL, NULL, NULL, TRUE);
+                       itip_send_comp (E_CAL_COMPONENT_METHOD_PUBLISH, comp, 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 204d150..89313dd 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);
 		}
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]