[evolution-patches] Patch for the receipt bounty (#127534)



Hi,

Attached is a preliminary version of message receipt handling. The UI to set the receipt policy for accounts is not yet written, I'm just sending this to hammer out problems in the backend code before worrying about the UI. I'd also like to get some input on the text contents of the receipt because right now it's pretty lame.

Bye,
	Gergo


--
   .--= ULLA! =---------------------.   `We are not here to give users what
   \     http://cactus.rulez.org     \   they want'  -- RMS, at GUADEC 2001
    `---= cactus cactus rulez org =---'
Sajnálom, de nem tudok segíteni. Engem csak a szépségem miatt vettek fel.
Index: camel/camel-folder-summary.h
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-folder-summary.h,v
retrieving revision 1.78
diff -u -u -r1.78 camel-folder-summary.h
--- camel/camel-folder-summary.h	21 May 2004 09:08:09 -0000	1.78
+++ camel/camel-folder-summary.h	9 Aug 2004 12:48:53 -0000
@@ -70,6 +70,8 @@
 	CAMEL_MESSAGE_JUNK = 1<<7,
 	CAMEL_MESSAGE_SECURE = 1<<8,
 
+	CAMEL_MESSAGE_RECEIPT_HANDLED = 1 << 9,
+	
 	/* following flags are for the folder, and are not really permanent flags */
 	CAMEL_MESSAGE_FOLDER_FLAGGED = 1<<16, /* for use by the folder implementation */
 
Index: camel/camel-folder.c
===================================================================
RCS file: /cvs/gnome/evolution/camel/camel-folder.c,v
retrieving revision 1.203
diff -u -u -r1.203 camel-folder.c
--- camel/camel-folder.c	21 May 2004 09:08:09 -0000	1.203
+++ camel/camel-folder.c	9 Aug 2004 12:48:58 -0000
@@ -166,6 +166,7 @@
 
 	/* events */
 	camel_object_class_add_event(camel_object_class, "folder_changed", folder_changed);
+	camel_object_class_add_event(camel_object_class, "handle_receipt", NULL);
 	camel_object_class_add_event(camel_object_class, "deleted", NULL);
 	camel_object_class_add_event(camel_object_class, "renamed", NULL);
 }
@@ -766,6 +767,17 @@
 	if (old != info->flags) {
 		info->flags |= CAMEL_MESSAGE_FOLDER_FLAGGED;
 		camel_folder_summary_touch(folder->summary);
+	}
+
+	/* If we're setting the SEEN flag on a message that asks for a
+	 * receipt, fire an appropriate event */
+	if (((set & flags) | CAMEL_MESSAGE_SEEN) &&
+	    !(old & CAMEL_MESSAGE_SEEN) &&
+	    !(info->flags & CAMEL_MESSAGE_RECEIPT_HANDLED))
+	{
+		CamelMimeMessage *message = camel_folder_get_message (folder, uid, NULL);
+		if (camel_medium_get_header (CAMEL_MEDIUM (message), "Disposition-Notification-To"))
+			camel_object_trigger_event(folder, "handle_receipt", uid);
 	}
 
 	camel_folder_summary_info_free(folder->summary, info);
Index: composer/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/composer/ChangeLog,v
retrieving revision 1.655
diff -u -u -r1.655 ChangeLog
--- composer/ChangeLog	28 Jul 2004 18:06:31 -0000	1.655
+++ composer/ChangeLog	9 Aug 2004 12:49:03 -0000
@@ -1,3 +1,8 @@
+2004-08-06  ERDI Gergo  <cactus cactus rulez org>
+
+	* e-msg-composer.c (build_message): Create an MDN header if a
+	receipt is requested by the user
+
 2004-07-28  Not Zed  <NotZed Ximian com>
 
 	* e-msg-composer.c: Fixes for api changes in mail/ for 61940.
Index: composer/e-msg-composer.c
===================================================================
RCS file: /cvs/gnome/evolution/composer/e-msg-composer.c,v
retrieving revision 1.477
diff -u -u -r1.477 e-msg-composer.c
--- composer/e-msg-composer.c	28 Jul 2004 18:06:31 -0000	1.477
+++ composer/e-msg-composer.c	9 Aug 2004 12:49:18 -0000
@@ -419,6 +419,7 @@
 	GByteArray *data;
 	char *charset;
 	int i;
+	gboolean receipt;
 	
 	if (composer->persist_stream_interface == CORBA_OBJECT_NIL)
 		return NULL;
@@ -437,6 +438,16 @@
 					 composer->extra_hdr_names->pdata[i],
 					 composer->extra_hdr_values->pdata[i]);
 	}
+
+	/* Message Disposition Notification */
+	receipt = atoi (bonobo_ui_component_get_prop (composer->uic, "/commands/RequestReceipt", "state", NULL));
+	if (receipt) {
+		char *mdn_address = hdrs->account->id->reply_to;
+		if (!mdn_address || !*mdn_address)
+			mdn_address = hdrs->account->id->address;
+		
+		camel_medium_add_header (CAMEL_MEDIUM (new), "Disposition-Notification-To", mdn_address);
+	}
 	
 	if (composer->mime_body) {
 		plain_encoding = CAMEL_TRANSFER_ENCODING_7BIT;
@@ -499,7 +510,7 @@
 			CORBA_exception_init (&ev);
 			GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "save-data-on", &ev);
 		}
-		data = get_text (composer->persist_stream_interface, "text/html");		
+		data = get_text (composer->persist_stream_interface, "text/html");
 		if (save_html_object_data) {
 			GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "save-data-off", &ev);
 			CORBA_exception_free (&ev);
Index: e-util/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/e-util/ChangeLog,v
retrieving revision 1.475
diff -u -u -r1.475 ChangeLog
--- e-util/ChangeLog	5 Aug 2004 21:50:30 -0000	1.475
+++ e-util/ChangeLog	9 Aug 2004 12:49:22 -0000
@@ -1,3 +1,7 @@
+2004-08-07  ERDI Gergo  <cactus cactus rulez org>
+
+	* e-account.h: Added new receipt_policy field to services
+
 2004-08-05  Rodrigo Moya <rodrigo novell com>
 
 	* e-icon-factory.c (e_icon_factory_init): connect to "changed"
Index: e-util/e-account.c
===================================================================
RCS file: /cvs/gnome/evolution/e-util/e-account.c,v
retrieving revision 1.10
diff -u -u -r1.10 e-account.c
--- e-util/e-account.c	9 Apr 2004 19:47:06 -0000	1.10
+++ e-util/e-account.c	9 Aug 2004 12:49:24 -0000
@@ -314,6 +314,7 @@
 
 	changed |= xml_set_bool (node, "auto-check", &service->auto_check);
 	changed |= xml_set_int (node, "auto-check-timeout", &service->auto_check_time);
+	changed |= xml_set_int (node, "receipt-policy", &service->receipt_policy);
 	if (service->auto_check && service->auto_check_time <= 0) {
 		service->auto_check = FALSE;
 		service->auto_check_time = 0;
@@ -528,6 +529,8 @@
 	xmlSetProp (src, "auto-check", account->source->auto_check ? "true" : "false");
 	sprintf (buf, "%d", account->source->auto_check_time);
 	xmlSetProp (src, "auto-check-timeout", buf);
+	sprintf (buf, "%d", account->source->receipt_policy);
+	xmlSetProp (src, "receipt-policy", buf);
 	if (account->source->url)
 		xmlNewTextChild (src, NULL, "url", account->source->url);
 
@@ -655,6 +658,7 @@
 	{ /* E_ACCOUNT_SOURCE_AUTO_CHECK */ 1<<EAP_LOCK_AUTOCHECK },
 	{ /* E_ACCOUNT_SOURCE_AUTO_CHECK_TIME */ 1<<EAP_LOCK_AUTOCHECK },
 	{ /* E_ACCOUNT_SOURCE_SAVE_PASSWD */ 1<<EAP_LOCK_SAVE_PASSWD },
+	{ /* E_ACCOUNT_SROUCE_RECEIPT_POLICY */ },
 
 	{ /* E_ACCOUNT_TRANSPORT_URL */ 1<<EAP_LOCK_TRANSPORT },
 	{ /* E_ACCOUNT_TRANSPORT_SAVE_PASSWD */ 1<<EAP_LOCK_SAVE_PASSWD },
Index: e-util/e-account.h
===================================================================
RCS file: /cvs/gnome/evolution/e-util/e-account.h,v
retrieving revision 1.7
diff -u -u -r1.7 e-account.h
--- e-util/e-account.h	1 Apr 2004 19:48:43 -0000	1.7
+++ e-util/e-account.h	9 Aug 2004 12:49:24 -0000
@@ -40,6 +40,7 @@
 	E_ACCOUNT_SOURCE_AUTO_CHECK,
 	E_ACCOUNT_SOURCE_AUTO_CHECK_TIME,
 	E_ACCOUNT_SOURCE_SAVE_PASSWD,
+	E_ACCOUNT_SOURCE_RECEIPT_POLICY,
 
 	E_ACCOUNT_TRANSPORT_URL,
 	E_ACCOUNT_TRANSPORT_SAVE_PASSWD,
@@ -80,12 +81,19 @@
 	char *sig_uid;
 } EAccountIdentity;
 
+typedef enum _EAccountReceiptPolicy {
+	E_ACCOUNT_RECEIPT_ASK,
+	E_ACCOUNT_RECEIPT_NEVER,
+	E_ACCOUNT_RECEIPT_ALWAYS
+} EAccountReceiptPolicy;
+
 typedef struct _EAccountService {
-	char *url;
-	gboolean keep_on_server;
-	gboolean auto_check;
-	int auto_check_time;
-	gboolean save_passwd;
+	char                  *url;
+	gboolean               keep_on_server;
+	gboolean               auto_check;
+	int                    auto_check_time;
+	gboolean               save_passwd;
+	EAccountReceiptPolicy  receipt_policy;
 } EAccountService;
 
 typedef struct _EAccount {
Index: mail/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/mail/ChangeLog,v
retrieving revision 1.3428
diff -u -u -r1.3428 ChangeLog
--- mail/ChangeLog	4 Aug 2004 15:20:57 -0000	1.3428
+++ mail/ChangeLog	9 Aug 2004 12:49:50 -0000
@@ -1,3 +1,12 @@
+2004-08-09  ERDI Gergo  <cactus cactus rulez org>
+
+	* em-folder-view.c (emfv_send_receipt): New function to send an
+	RFC 2298-compliant message delivery notification
+
+2004-08-07  ERDI Gergo  <cactus cactus rulez org>
+
+	* em-utils.c (em_utils_guess_account): Moved here from em-composer-utils.c
+
 2004-08-03  Jeffrey Stedfast  <fejj novell com>
 
 	* em-composer-utils.c (format_sender): If type="{Sender}" and name
Index: mail/em-composer-utils.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-composer-utils.c,v
retrieving revision 1.21
diff -u -u -r1.21 em-composer-utils.c
--- mail/em-composer-utils.c	4 Aug 2004 15:20:57 -0000	1.21
+++ mail/em-composer-utils.c	9 Aug 2004 12:49:56 -0000
@@ -49,8 +49,6 @@
 
 #include <camel/camel-string-utils.h>
 
-static EAccount *guess_account (CamelMimeMessage *message, CamelFolder *folder);
-
 struct emcs_t {
 	unsigned int ref_count;
 	
@@ -414,7 +412,7 @@
 	if (mail_folder) {
 		/* mail the message */
 		info = camel_message_info_new ();
-		info->flags = CAMEL_MESSAGE_SEEN;
+		info->flags = CAMEL_MESSAGE_SEEN | CAMEL_MESSAGE_RECEIPT_HANDLED;
 		
 		send = g_malloc (sizeof (*send));
 		send->emcs = user_data;
@@ -1044,7 +1042,7 @@
 	while (camel_medium_get_header (CAMEL_MEDIUM (message), "Delivered-To"))
 		camel_medium_remove_header (CAMEL_MEDIUM (message), "Delivered-To");
 	
-	account = guess_account (message, NULL);
+	account = em_utils_guess_account (message, NULL);
 	
 	composer = e_msg_composer_new_redirect (message, account ? account->name : NULL);
 	
@@ -1105,54 +1103,6 @@
 
 /* Replying to messages... */
 
-static GHashTable *
-generate_account_hash (void)
-{
-	GHashTable *account_hash;
-	EAccount *account, *def;
-	EAccountList *accounts;
-	EIterator *iter;
-	
-	accounts = mail_config_get_accounts ();
-	account_hash = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
-	
-	/* add the default account to the hash first */
-	if ((def = mail_config_get_default_account ())) {
-		if (def->id->address)
-			g_hash_table_insert (account_hash, (char *) def->id->address, (void *) def);
-	}
-	
-	iter = e_list_get_iterator ((EList *) accounts);
-	while (e_iterator_is_valid (iter)) {
-		account = (EAccount *) e_iterator_get (iter);
-		
-		if (account->id->address) {
-			EAccount *acnt;
-			
-			/* Accounts with identical email addresses that are enabled
-			 * take precedence over the accounts that aren't. If all
-			 * accounts with matching email addresses are disabled, then
-			 * the first one in the list takes precedence. The default
-			 * account always takes precedence no matter what.
-			 */
-			acnt = g_hash_table_lookup (account_hash, account->id->address);
-			if (acnt && acnt != def && !acnt->enabled && account->enabled) {
-				g_hash_table_remove (account_hash, acnt->id->address);
-				acnt = NULL;
-			}
-			
-			if (!acnt)
-				g_hash_table_insert (account_hash, (char *) account->id->address, (void *) account);
-		}
-		
-		e_iterator_next (iter);
-	}
-	
-	g_object_unref (iter);
-	
-	return account_hash;
-}
-
 static EDestination **
 em_utils_camel_address_to_destination (CamelInternetAddress *iaddr)
 {
@@ -1266,63 +1216,6 @@
 	return composer;
 }
 
-static EAccount *
-guess_account_folder(CamelFolder *folder)
-{
-	EAccount *account;
-	char *tmp;
-
-	tmp = camel_url_to_string(CAMEL_SERVICE(folder->parent_store)->url, CAMEL_URL_HIDE_ALL);
-	account = mail_config_get_account_by_source_url(tmp);
-	g_free(tmp);
-
-	return account;
-}
-
-static EAccount *
-guess_account (CamelMimeMessage *message, CamelFolder *folder)
-{
-	GHashTable *account_hash = NULL;
-	EAccount *account = NULL;
-	const char *tmp;
-	int i, j;
-	char *types[2] = { CAMEL_RECIPIENT_TYPE_TO, CAMEL_RECIPIENT_TYPE_CC };
-
-	/* check for newsgroup header */
-	if (folder
-	    && camel_medium_get_header((CamelMedium *)message, "Newsgroups")
-	    && (account = guess_account_folder(folder)))
-		return account;
-
-	/* then recipient (to/cc) in account table */
-	account_hash = generate_account_hash ();
-	for (j=0;account == NULL && j<2;j++) {
-		const CamelInternetAddress *to;
-		
-		to = camel_mime_message_get_recipients(message, types[j]);
-		if (to) {
-			for (i = 0; camel_internet_address_get(to, i, NULL, &tmp); i++) {
-				account = g_hash_table_lookup(account_hash, tmp);
-				if (account)
-					break;
-			}
-		}
-	}
-	g_hash_table_destroy(account_hash);
-
-	/* then message source */
-	if (account == NULL
-	    && (tmp = camel_mime_message_get_source(message)))
-		account = mail_config_get_account_by_source_url(tmp);
-
-	/* and finally, source folder */
-	if (account == NULL
-	    && folder)
-		account = guess_account_folder(folder);
-
-	return account;
-}
-
 static void
 get_reply_sender (CamelMimeMessage *message, CamelInternetAddress **to, const char **postto)
 {
@@ -1424,7 +1317,7 @@
 			(*postto)++;
 	}
 	
-	rcpt_hash = generate_account_hash ();
+	rcpt_hash = em_utils_generate_account_hash ();
 	
 	reply_to = camel_mime_message_get_reply_to (message);
 	if (!reply_to)
@@ -1749,7 +1642,7 @@
 
 	g_return_if_fail(message != NULL);
 	
-	account = guess_account (message, NULL);
+	account = em_utils_guess_account (message, NULL);
 	flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_SEEN;
 	
 	switch (mode) {
@@ -1806,7 +1699,7 @@
 	if (message == NULL)
 		return;
 	
-	account = guess_account (message, folder);
+	account = em_utils_guess_account (message, folder);
 	flags = CAMEL_MESSAGE_ANSWERED | CAMEL_MESSAGE_SEEN;
 	
 	get_reply_sender (message, &to, NULL);
Index: mail/em-folder-view.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-folder-view.c,v
retrieving revision 1.85
diff -u -u -r1.85 em-folder-view.c
--- mail/em-folder-view.c	28 Jul 2004 14:38:50 -0000	1.85
+++ mail/em-folder-view.c	9 Aug 2004 12:50:05 -0000
@@ -29,6 +29,9 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include <netdb.h>	/* define MAXHOSTNAMELEN on Solaris */
+#include <sys/param.h>	/* define MAXHOSTNAMELEN elsewhere  */
+
 #include <gtk/gtkvbox.h>
 #include <gtk/gtkbutton.h>
 #include <gtk/gtkvpaned.h>
@@ -120,6 +123,10 @@
 static void emfv_on_url_cb(GObject *emitter, const char *url, EMFolderView *emfv);
 static void emfv_on_url(EMFolderView *emfv, const char *uri, const char *nice_uri);
 
+static gboolean emfv_ask_receipt (EMFolderView *emfv, CamelMimeMessage *message);
+static void     emfv_handle_receipt (CamelObject *o, gpointer event_data, gpointer user_data);
+static void     emfv_send_receipt (EMFolderView *emfv, CamelMimeMessage *message);
+
 static const EMFolderViewEnable emfv_enable_map[];
 
 struct _EMFolderViewPrivate {
@@ -525,6 +532,9 @@
 	if (folder) {
 		emfv->priv->folder_changed_id = camel_object_hook_event(folder, "folder_changed",
 									(CamelObjectEventHookFunc)emfv_folder_changed, emfv);
+		/* Listen for delivery notification requests */
+		camel_object_hook_event(folder, "handle_receipt", emfv_handle_receipt, emfv);
+		
 		camel_object_ref(folder);
 		mail_refresh_folder(folder, NULL, NULL);
 		/* We need to set this up to get the right view options for the message-list, even if we're not showing it */
@@ -1949,7 +1959,7 @@
 		emfv_enable_menus(emfv);
 		return;
 	}
-	
+
 	em_format_format((EMFormat *)emfv->preview, folder, uid, msg);
 	
 	if (emfv->priv->seen_id)
@@ -2190,6 +2200,167 @@
 {
 	g_object_ref(emfv);
 	mail_async_event_emit(emfv->async, MAIL_ASYNC_GUI, (MailAsyncFunc)emfv_gui_folder_changed, folder, NULL, emfv);
+}
+
+static gboolean
+emfv_ask_receipt (EMFolderView *emfv, CamelMimeMessage *message)
+{
+	/* Check the account's receipt policy settings, and pop up a
+	 * dialog if the policy is ASK */
+	
+	EAccount *account = em_utils_guess_account (message, emfv->folder);
+
+	if (account->source->receipt_policy == E_ACCOUNT_RECEIPT_ASK) {
+		GtkWidget *dialog;
+		GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (emfv));
+		GtkWindow *dialog_parent = (toplevel && GTK_IS_WINDOW (toplevel)) ? GTK_WINDOW (toplevel) : NULL;
+		const char *receipt_address = camel_medium_get_header (CAMEL_MEDIUM (message), "Disposition-Notification-To");
+		const char *subject = camel_mime_message_get_subject (message);
+		int response;
+		
+		dialog = gtk_message_dialog_new (dialog_parent,
+						 GTK_DIALOG_MODAL,
+						 GTK_MESSAGE_QUESTION,
+						 GTK_BUTTONS_YES_NO,
+						 _("Send message receipt to %s about message \"%s\"?"),
+						 receipt_address, subject);
+		response = gtk_dialog_run (GTK_DIALOG (dialog));
+		gtk_widget_destroy (dialog);
+	
+		return (response == GTK_RESPONSE_YES);
+	}
+	
+	return (account->source->receipt_policy == E_ACCOUNT_RECEIPT_ALWAYS);
+}
+
+static void
+emfv_send_receipt (EMFolderView *emfv, CamelMimeMessage *message)
+{
+	EAccount *account = em_utils_guess_account (message, emfv->folder);
+
+	CamelMimeMessage *receipt = camel_mime_message_new ();
+	CamelMultipart *body = camel_multipart_new ();
+	CamelMimePart *part;
+	CamelDataWrapper *receipt_text, *receipt_data;
+	char *receipt_text_buf, *receipt_data_buf;
+	CamelContentType *type;
+	CamelInternetAddress *addr;
+	CamelStream *stream;	
+	CamelFolder *folder;
+	CamelMessageInfo *info;
+	
+	const char *message_id = camel_medium_get_header (CAMEL_MEDIUM (message), "Message-ID");
+	const char *message_date = camel_medium_get_header (CAMEL_MEDIUM (message), "Date");
+	const char *message_subject = camel_mime_message_get_subject (message);
+	const char *receipt_address = camel_medium_get_header (CAMEL_MEDIUM (message), "Disposition-Notification-To");
+	char hostname[MAXHOSTNAMELEN + 1];
+	char *self_address, *receipt_subject;
+
+	
+	g_return_if_fail (receipt_address);
+	g_return_if_fail (account);
+
+	
+	/* Collect information for the receipt */
+	gethostname (hostname, MAXHOSTNAMELEN);
+	self_address = account->id->address;
+
+	
+	/* Create toplevel container */
+	camel_data_wrapper_set_mime_type (CAMEL_DATA_WRAPPER (body),
+					  "multipart/report;"
+					  "report-type=\"disposition-notification\"");
+	camel_multipart_set_boundary (body, NULL);
+	
+	
+	/* Create textual receipt */
+	receipt_text = camel_data_wrapper_new ();
+	receipt_text_buf = g_strdup_printf ("Your message to %s about \"%s\" "
+					    "(dated %s) has been read by the user.",
+					    self_address, message_subject, message_date);
+	stream = camel_stream_mem_new_with_buffer (receipt_text_buf, strlen (receipt_text_buf));
+	g_free (receipt_text_buf);
+	type = camel_content_type_new ("text", "plain");
+	camel_data_wrapper_set_mime_type_field (receipt_text, type);
+	camel_content_type_unref (type);
+	camel_data_wrapper_construct_from_stream (receipt_text, stream);
+	camel_object_unref (stream);
+	
+	part = camel_mime_part_new ();
+	camel_medium_set_content_object (CAMEL_MEDIUM (part), receipt_text);
+	camel_object_unref (receipt_text);
+	camel_multipart_add_part (body, part);
+	camel_object_unref (part);
+	
+	
+	/* Create the machine-readable receipt */
+	receipt_data = camel_data_wrapper_new ();
+	receipt_data_buf = g_strdup_printf ("Reporting-UA: %s; %s\n"
+					    "Final-Recipient: rfc822; %s\n"
+					    "Original-Message-ID:%s\n"
+					    "Disposition: manual-action/MDN-sent-manually; displayed",
+					    hostname, "Evolution " VERSION SUB_VERSION " " VERSION_COMMENT,
+					    self_address, message_id);
+	stream = camel_stream_mem_new_with_buffer (receipt_data_buf, strlen (receipt_data_buf));
+	g_free (receipt_data_buf);
+	type = camel_content_type_new ("message", "disposition-notification");
+	camel_data_wrapper_set_mime_type_field (receipt_data, type);
+	camel_content_type_unref (type);
+	camel_data_wrapper_construct_from_stream (receipt_data, stream);
+	camel_object_unref (stream);
+	
+	part = camel_mime_part_new ();
+	camel_medium_set_content_object (CAMEL_MEDIUM (part), receipt_data);
+	camel_object_unref (receipt_data);
+	camel_multipart_add_part (body, part);
+	camel_object_unref (part);
+	
+	
+	/* Finish creating the message */
+	camel_medium_set_content_object (CAMEL_MEDIUM (receipt), CAMEL_DATA_WRAPPER (body));
+	camel_object_unref (body);
+	
+	receipt_subject = g_strdup_printf ("Delivery Notification for: \"%s\"", message_subject);
+	camel_mime_message_set_subject (receipt, receipt_subject);
+	g_free (receipt_subject);
+	
+	addr = camel_internet_address_new ();
+	camel_address_decode (CAMEL_ADDRESS (addr), self_address);
+	camel_mime_message_set_recipients (receipt, CAMEL_RECIPIENT_TYPE_TO, addr);
+	camel_object_unref (addr);
+	
+	addr = camel_internet_address_new ();
+	camel_address_decode (CAMEL_ADDRESS (addr), receipt_address);
+	camel_mime_message_set_from (receipt, addr);
+	camel_object_unref (addr);
+
+	camel_medium_set_header (CAMEL_MEDIUM (receipt), "Return-Path", "<>");
+
+	/* Send the receipt */
+	folder = mail_component_get_folder(NULL, MAIL_COMPONENT_FOLDER_OUTBOX);
+	info = camel_message_info_new ();
+	info->flags = CAMEL_MESSAGE_SEEN;
+	mail_append_mail (folder, receipt, info, 0, 0);
+	/* camel_object_unref (mail_folder); */
+}
+
+static void
+emfv_handle_receipt (CamelObject *o, gpointer event_data, gpointer user_data)
+{
+	char *uid = event_data;
+	EMFolderView *emfv = (EMFolderView*)user_data;
+	CamelMimeMessage *message = camel_folder_get_message (emfv->folder, uid, NULL);
+
+	g_return_if_fail (message);
+
+#if 0
+	camel_folder_set_message_flags (emfv->folder, uid,
+					CAMEL_MESSAGE_RECEIPT_HANDLED,
+					CAMEL_MESSAGE_RECEIPT_HANDLED);
+#endif
+	
+	if (emfv_ask_receipt (emfv, message))
+		emfv_send_receipt (emfv, message);	
 }
 
 /* keep these two tables in sync */
Index: mail/em-utils.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-utils.c,v
retrieving revision 1.47
diff -u -u -r1.47 em-utils.c
--- mail/em-utils.c	28 Jul 2004 14:38:50 -0000	1.47
+++ mail/em-utils.c	9 Aug 2004 12:50:10 -0000
@@ -34,6 +34,7 @@
 #include <camel/camel-stream-fs.h>
 #include <camel/camel-url-scanner.h>
 #include <camel/camel-file-utils.h>
+#include <camel/camel-string-utils.h>
 
 #include "em-filter-editor.h"
 
@@ -1886,3 +1887,109 @@
 	/* We used to load parts to check their type, we dont anymore,
 	   see bug #11778 for some discussion */
 }
+
+GHashTable *
+em_utils_generate_account_hash (void)
+{
+	GHashTable *account_hash;
+	EAccount *account, *def;
+	EAccountList *accounts;
+	EIterator *iter;
+	
+	accounts = mail_config_get_accounts ();
+	account_hash = g_hash_table_new (camel_strcase_hash, camel_strcase_equal);
+	
+	/* add the default account to the hash first */
+	if ((def = mail_config_get_default_account ())) {
+		if (def->id->address)
+			g_hash_table_insert (account_hash, (char *) def->id->address, (void *) def);
+	}
+	
+	iter = e_list_get_iterator ((EList *) accounts);
+	while (e_iterator_is_valid (iter)) {
+		account = (EAccount *) e_iterator_get (iter);
+		
+		if (account->id->address) {
+			EAccount *acnt;
+			
+			/* Accounts with identical email addresses that are enabled
+			 * take precedence over the accounts that aren't. If all
+			 * accounts with matching email addresses are disabled, then
+			 * the first one in the list takes precedence. The default
+			 * account always takes precedence no matter what.
+			 */
+			acnt = g_hash_table_lookup (account_hash, account->id->address);
+			if (acnt && acnt != def && !acnt->enabled && account->enabled) {
+				g_hash_table_remove (account_hash, acnt->id->address);
+				acnt = NULL;
+			}
+			
+			if (!acnt)
+				g_hash_table_insert (account_hash, (char *) account->id->address, (void *) account);
+		}
+		
+		e_iterator_next (iter);
+	}
+	
+	g_object_unref (iter);
+	
+	return account_hash;
+}
+
+static EAccount *
+em_utils_guess_account_folder(CamelFolder *folder)
+{
+	EAccount *account;
+	char *tmp;
+
+	tmp = camel_url_to_string(CAMEL_SERVICE(folder->parent_store)->url, CAMEL_URL_HIDE_ALL);
+	account = mail_config_get_account_by_source_url(tmp);
+	g_free(tmp);
+
+	return account;
+}
+
+EAccount *
+em_utils_guess_account (CamelMimeMessage *message, CamelFolder *folder)
+{
+	GHashTable *account_hash = NULL;
+	EAccount *account = NULL;
+	const char *tmp;
+	int i, j;
+	char *types[2] = { CAMEL_RECIPIENT_TYPE_TO, CAMEL_RECIPIENT_TYPE_CC };
+
+	/* check for newsgroup header */
+	if (folder
+	    && camel_medium_get_header((CamelMedium *)message, "Newsgroups")
+	    && (account = em_utils_guess_account_folder(folder)))
+		return account;
+
+	/* then recipient (to/cc) in account table */
+	account_hash = em_utils_generate_account_hash ();
+	for (j=0;account == NULL && j<2;j++) {
+		const CamelInternetAddress *to;
+		
+		to = camel_mime_message_get_recipients(message, types[j]);
+		if (to) {
+			for (i = 0; camel_internet_address_get(to, i, NULL, &tmp); i++) {
+				account = g_hash_table_lookup(account_hash, tmp);
+				if (account)
+					break;
+			}
+		}
+	}
+	g_hash_table_destroy(account_hash);
+
+	/* then message source */
+	if (account == NULL
+	    && (tmp = camel_mime_message_get_source(message)))
+		account = mail_config_get_account_by_source_url(tmp);
+
+	/* and finally, source folder */
+	if (account == NULL
+	    && folder)
+		account = em_utils_guess_account_folder(folder);
+
+	return account;
+}
+
Index: mail/em-utils.h
===================================================================
RCS file: /cvs/gnome/evolution/mail/em-utils.h,v
retrieving revision 1.16
diff -u -u -r1.16 em-utils.h
--- mail/em-utils.h	28 Jul 2004 14:38:50 -0000	1.16
+++ mail/em-utils.h	9 Aug 2004 12:50:11 -0000
@@ -41,6 +41,7 @@
 struct _GtkAdjustment;
 struct _CamelException;
 struct _EMFormat;
+struct _EAccount;
 
 gboolean em_utils_prompt_user(struct _GtkWindow *parent, const char *promptkey, const char *tag, const char *arg0, ...);
 
@@ -102,6 +103,10 @@
 gboolean em_utils_in_addressbook(struct _CamelInternetAddress *addr);
 
 const char *em_utils_snoop_type(struct _CamelMimePart *part);
+
+GHashTable * em_utils_generate_account_hash (void);
+struct _EAccount *em_utils_guess_account (struct _CamelMimeMessage *message, struct _CamelFolder *folder);
+
 
 #ifdef __cplusplus
 }
Index: mail/message-list.c
===================================================================
RCS file: /cvs/gnome/evolution/mail/message-list.c,v
retrieving revision 1.396
diff -u -u -r1.396 message-list.c
--- mail/message-list.c	28 Jul 2004 02:55:52 -0000	1.396
+++ mail/message-list.c	9 Aug 2004 12:50:22 -0000
@@ -51,6 +51,10 @@
 #include <gal/e-table/e-tree-memory.h>
 #include <gal/e-table/e-tree-memory-callbacks.h>
 
+#include <camel/camel-mime-message.h>
+#include <camel/camel-multipart.h>
+#include <camel/camel-stream-mem.h>
+
 #include <camel/camel-exception.h>
 #include <camel/camel-file-utils.h>
 #include <camel/camel-folder.h>
@@ -63,6 +67,7 @@
 #include "mail-config.h"
 #include "message-list.h"
 #include "mail-mt.h"
+#include "mail-component.h"
 #include "mail-tools.h"
 #include "mail-ops.h"
 #include "em-popup.h"
@@ -2824,7 +2829,7 @@
 		
 		cell = e_table_extras_get_cell (message_list->extras, "render_size");
 		g_object_set (cell, "strikeout_column", strikeout_col, NULL);
-		
+
 		/* Build the etree suitable for this folder */
 		message_list_setup_etree (message_list, outgoing);
 		
Index: shell/shell-errors.xml.h
===================================================================
RCS file: /cvs/gnome/evolution/shell/shell-errors.xml.h,v
retrieving revision 1.6
diff -u -u -r1.6 shell-errors.xml.h
--- shell/shell-errors.xml.h	1 Aug 2004 17:58:08 -0000	1.6
+++ shell/shell-errors.xml.h	9 Aug 2004 12:50:23 -0000
@@ -22,7 +22,8 @@
 	"\n"
 	"If you choose to remove this data, the entire contents of the \"evolution\" directory will be removed permanently.  If you choose to keep this data, then you may manually remove the contents of \"evolution\" at your convenience.\n"
 	"");
-char *s = N_("Keep");
+char *s = N_("_Remind Me Later");
+char *s = N_("_Keep Data");
 /* shell:upgrade-remove-1-4-confirm title */
 char *s = N_("Really delete old data?");
 /* shell:upgrade-remove-1-4-confirm primary */
Index: ui/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/ui/ChangeLog,v
retrieving revision 1.398
diff -u -u -r1.398 ChangeLog
--- ui/ChangeLog	23 Jun 2004 03:59:03 -0000	1.398
+++ ui/ChangeLog	9 Aug 2004 12:50:24 -0000
@@ -1,3 +1,8 @@
+2004-08-06  ERDI Gergo  <cactus cactus rulez org>
+
+	* evolution-message-composer.xml: Added new menu item for
+	requesting message receipts when composing a new message
+
 2004-06-22  V Ravi Kumar Raju <vravikr yahoo co uk>
 
 	* evolution-addressbook.xml: Remove the Menu Seperator in View
Index: ui/evolution-message-composer.xml
===================================================================
RCS file: /cvs/gnome/evolution/ui/evolution-message-composer.xml,v
retrieving revision 1.43
diff -u -u -r1.43 evolution-message-composer.xml
--- ui/evolution-message-composer.xml	25 May 2004 20:54:01 -0000	1.43
+++ ui/evolution-message-composer.xml	9 Aug 2004 12:50:26 -0000
@@ -31,6 +31,10 @@
 		pixtype="stock" pixname="gtk-delete"
 		_tip="Delete all but signature"/>
 
+		<cmd name="RequestReceipt" _label="Request Receipt"
+		     _tip="Check to get delivery notification when your message is read"
+		     type="toggle" state="0"/>
+		
 		<cmd name="FormatHtml" _label="HT_ML" _tip="Send the mail in HTML format"
 		type="toggle" state="0"/> 
 		
@@ -119,7 +123,7 @@
 		
 		<submenu name="View" _label="_View">
 			<menuitem name="ViewAttach" verb="" _label="Show _attachments"/>
-			<separator f="" name="emailcomposer"/>
+			<separator f="" name="emailcomposer1"/>
 	                <menuitem name="ViewFrom" verb=""/>
 			<menuitem name="ViewTo" verb=""/>
 			<menuitem name="ViewPostTo" verb=""/>
@@ -132,6 +136,8 @@
 	                <menuitem name="FileAttach" verb=""
 	                _label="_Attachment..." pixtype="pixbuf"/>
                 	<placeholder name="Component"/>
+			<separator f="" name="emailcomposer"/>
+			<menuitem name="RequestReceipt" verb=""/>
                 </submenu>
 		
                 <submenu name="Security" _label="_Security">


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