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



On Wed, 2004-08-11 at 21:39 +0200, ERDI Gergo wrote:
> So here's a new version of the patch. The receipt policy setting is still 
> per-account, since I think this is the most flexible approach, and the UI 
> guys haven't stated their opinion yet.
> Oh, and the UI for this is still not yet written, again, I'd like to get 
> the backend stuff right first.
> 

I've talked to Christine and she agrees that the settings for this
should be per-account.

> 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        11 Aug 2004 19:31:06 -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: 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  11 Aug 2004 19:31:14 -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   11 Aug 2004 19:31:24 -0000
> @@ -437,6 +437,15 @@
>                                          composer->extra_hdr_names-
> >pdata[i],
>                                          composer->extra_hdr_values-
> >pdata[i]);
>         }
> +
> +       /* Message Disposition Notification */
> +       if (composer->request_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 +508,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);
> @@ -1910,6 +1919,19 @@
>  }
>  
>  static void
> +menu_insert_receipt_cb (BonoboUIComponent           *component,
> +                       const char                  *path,
> +                       Bonobo_UIComponent_EventType type,
> +                       const char                  *state,
> +                       gpointer                     user_data)
> +{
> +       if (type != Bonobo_UIComponent_STATE_CHANGED)
> +               return;
> +       
> +       e_msg_composer_set_request_receipt (E_MSG_COMPOSER
> (user_data), atoi (state));
> +}
> +
> +static void
>  menu_changed_charset_cb (BonoboUIComponent           *component,
>                          const char                  *path,
>                          Bonobo_UIComponent_EventType type,
> @@ -2206,7 +2228,15 @@
>         bonobo_ui_component_add_listener (
>                 composer->uic, "ViewBCC",
>                 menu_view_bcc_cb, composer);
> +
> +       /* Insert/Request Receipt */
> +       bonobo_ui_component_set_prop (
> +               composer->uic, "/commands/RequestReceipt",
> +               "state", composer->request_receipt ? "1" : "0", NULL);
> +       bonobo_ui_component_add_listener (
> +               composer->uic, "RequestReceipt",
> +               menu_insert_receipt_cb, composer);
>         
>         /* Security -> PGP Sign */
>         bonobo_ui_component_set_prop (
> @@ -5176,6 +5207,47 @@
>         e_msg_composer_hdrs_set_visible (E_MSG_COMPOSER_HDRS
> (composer->hdrs),
> 
> e_msg_composer_get_visible_flags (composer));
>  }
> +
> +
> +
> +/**
> + * e_msg_composer_get_request_receipt
> + * @composer: A message composer widget
> + * 
> + * Get the status of the "Request receipt" flag.
> + * 
> + * Return value: The status of the "Request receipt" flag.
> + **/
> +gboolean
> +e_msg_composer_get_request_receipt (EMsgComposer *composer)
> +{
> +       g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
> +       
> +       return composer->request_receipt;
> +}
> +
> +
> +/**
> + * e_msg_composer_set_request_receipt:
> + * @composer: A message composer widget
> + * @state: whether to request or not a receipt
> + *
> + * If set, a message delivery notification request will be sent to
> the recipient
> + */
> +void
> +e_msg_composer_set_request_receipt (EMsgComposer *composer, gboolean
> request_receipt)
> +{
> +       g_return_if_fail (E_IS_MSG_COMPOSER (composer));
> +       
> +       if ((composer->request_receipt && request_receipt) ||
> +           (!composer->request_receipt && !request_receipt))
> +               return;
> +       
> +       composer->request_receipt = request_receipt;
> +       bonobo_ui_component_set_prop (composer->uic,
> "/commands/RequestReceipt",
> +                                     "state", composer-
> >request_receipt ? "1" : "0", NULL);
> +}
> +
>  
>  
>  EDestination **
> Index: composer/e-msg-composer.h
> ===================================================================
> RCS file: /cvs/gnome/evolution/composer/e-msg-composer.h,v
> retrieving revision 1.91
> diff -u -u -r1.91 e-msg-composer.h
> --- composer/e-msg-composer.h   27 Jul 2004 16:52:17 -0000      1.91
> +++ composer/e-msg-composer.h   11 Aug 2004 19:31:25 -0000
> @@ -101,6 +101,7 @@
>         guint32 view_bcc               : 1;
>         guint32 view_cc                : 1;
>         guint32 view_subject           : 1;
> +       guint32 request_receipt        : 1;
>         guint32 has_changed            : 1;
>         guint32 autosaved              : 1;
>         
> @@ -191,6 +192,10 @@
>  gboolean                 e_msg_composer_get_view_bcc
> (EMsgComposer      *composer);
>  void                     e_msg_composer_set_view_bcc
> (EMsgComposer      *composer,
> 
> gboolean           view_bcc);
> +
> +gboolean                 e_msg_composer_get_request_receipt
> (EMsgComposer *composer);
> +void                     e_msg_composer_set_request_receipt
> (EMsgComposer *composer,
> +
> gboolean      request_receipt);
>  
>  EDestination           **e_msg_composer_get_recipients
> (EMsgComposer *composer);
>  EDestination           **e_msg_composer_get_to
> (EMsgComposer *composer);

I think that there should probably be a default per-account setting for
whether or not the composer should default to requesting a receipt.
other than that, I think the composer code looks ok so far.

> Index: e-util/ChangeLog
> ===================================================================
> RCS file: /cvs/gnome/evolution/e-util/ChangeLog,v
> retrieving revision 1.476
> diff -u -u -r1.476 ChangeLog
> --- e-util/ChangeLog    9 Aug 2004 16:47:03 -0000       1.476
> +++ e-util/ChangeLog    11 Aug 2004 19:31:28 -0000
> @@ -3,6 +3,10 @@
>         * e-icon-factory.c (icon_foreach_remove): We must return TRUE
> here
>         so that things actually get removed from the list
>  
> +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  11 Aug 2004 19:31:30 -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  11 Aug 2004 19:31:30 -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;
> +

I think I'd put NEVER as the first item in the enum (0 makes a good
NEVER value, plus NEVER should be default anyway)

>  typedef struct _EAccountService {
>         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.3430
> diff -u -u -r1.3430 ChangeLog
> --- mail/ChangeLog      10 Aug 2004 19:10:06 -0000      1.3430
> +++ mail/ChangeLog      11 Aug 2004 19:31:54 -0000
> @@ -1,3 +1,12 @@
> +2004-08-11  ERDI Gergo  <cactus cactus rulez org>
> +
> +       * mail-errors.xml: Added new dialog for receipt requests
> +
> +       * em-composer-utils.c (em_utils_guess_account): Made
> guess_account
> +       public, to be callable from em-folder-view
> +       (em_utils_send_receipt): New function to send an RFC
> +       2298-compliant message delivery notification
> +
>  2004-08-06  Jeffrey Stedfast  <fejj novell com>
>  
>         * em-folder-tree-model.c (em_folder_tree_model_get_selected):
> 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    11 Aug 2004 19:31:59 -0000
> @@ -27,6 +27,9 @@
>  #include <string.h>
>  #include <gtk/gtkdialog.h>
>  
> +#include <netdb.h>     /* define MAXHOSTNAMELEN on Solaris */
> +#include <sys/param.h> /* define MAXHOSTNAMELEN elsewhere  */
> +
>  #include <gal/util/e-util.h>
>  
>  #include "mail-mt.h"
> @@ -48,8 +51,7 @@
>  #include "e-util/e-account-list.h"
>  
>  #include <camel/camel-string-utils.h>
> -
> -static EAccount *guess_account (CamelMimeMessage *message,
> CamelFolder *folder);
> +#include <camel/camel-stream-mem.h>
>  
>  struct emcs_t {
>         unsigned int ref_count;
> @@ -414,7 +416,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;
> @@ -438,7 +440,7 @@
>                 
>                 /* mail the message */
>                 info = camel_message_info_new ();
> -               info->flags = CAMEL_MESSAGE_SEEN;
> +               info->flags = CAMEL_MESSAGE_SEEN |
> CAMEL_MESSAGE_RECEIPT_HANDLED;
>                 
>                 post_ptr = post_folders;
>                 while (post_ptr) {
> @@ -577,7 +579,7 @@
>         msg = e_msg_composer_get_message_draft (composer);
>         
>         info = g_new0 (CamelMessageInfo, 1);
> -       info->flags = CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_SEEN;
> +       info->flags = CAMEL_MESSAGE_DRAFT |
> CAMEL_MESSAGE_RECEIPT_HANDLED | CAMEL_MESSAGE_SEEN;
>         
>         sdi = g_malloc (sizeof (struct _save_draft_info));
>         sdi->composer = composer;
> @@ -1044,7 +1046,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);
>         
> @@ -1103,6 +1105,110 @@
>         mail_get_message (folder, uid, redirect_msg, NULL,
> mail_thread_new);
>  }
>  
> +
> +void
> +em_utils_send_receipt (CamelFolder *folder, CamelMimeMessage
> *message)
> +{
> +       EAccount *account = em_utils_guess_account (message, folder);
> +
> +       CamelMimeMessage *receipt = camel_mime_message_new ();
> +       CamelMultipart *body = camel_multipart_new ();
> +       CamelMimePart *part;
> +       CamelDataWrapper *receipt_text, *receipt_data;
> +       CamelContentType *type;
> +       CamelInternetAddress *addr;
> +       CamelStream *stream;    
> +       CamelFolder *out_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");

I'm not sure I'd use the values gotten from medium_get_header() here...

using camel_mime_message_get_message_id() might be a better way to go as
it has been canonicalised.

along the same lines, might be better to use camel_mime_message_get_date
() and then either use camel_header_format_date() (from camel-mime-
utils.h) to format the time_t/offset to an rfc822 date, or, perhaps,
format that time_t into a more human friendly form?

not sure what the preferred date format would be... perhaps rfc822
format is fine.

> +       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;
> +
> +       if (!receipt_address)
> +               return;
> +       
> +       /* Collect information for the receipt */
> +       gethostname (hostname, MAXHOSTNAMELEN);

probably should check the return code from gethostname as it may fail.

also, the hostname may not include the domain. not sure we care?

> +       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 ();
> +       type = camel_content_type_new ("text", "plain");
> +       camel_data_wrapper_set_mime_type_field (receipt_text, type);
> +       camel_content_type_unref (type);
> +       stream = camel_stream_mem_new ();
> +       camel_stream_printf (stream,
> +                            "Your message to %s about \"%s\" "
> +                            "(dated %s) has been read by the user.",
> +                            self_address, message_subject,
> message_date);
> +       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 ();
> +       type = camel_content_type_new ("message", "disposition-
> notification");
> +       camel_data_wrapper_set_mime_type_field (receipt_data, type);
> +       camel_content_type_unref (type);
> +       stream = camel_stream_mem_new ();
> +       camel_stream_printf (stream,
> +                            "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);
> +       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);

perhaps don't quote the original subject? might look funny if the
original message's subject had quotes in it...

> +       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", "<>");

afaict, this is an illegal header.

> +
> +       /* Send the receipt */
> +       out_folder = mail_component_get_folder(NULL,
> MAIL_COMPONENT_FOLDER_OUTBOX);
> +       info = camel_message_info_new ();
> +       info->flags = CAMEL_MESSAGE_SEEN;
> +       mail_append_mail (out_folder, receipt, info, 0, 0);
> +       /* camel_object_unref (mail_folder); */
> +}
> +
>  /* Replying to messages... */
>  
>  static GHashTable *
> @@ -1279,8 +1385,8 @@
>         return account;
>  }
>  
> -static EAccount *
> -guess_account (CamelMimeMessage *message, CamelFolder *folder)
> +EAccount *
> +em_utils_guess_account (CamelMimeMessage *message, CamelFolder
> *folder)
>  {
>         GHashTable *account_hash = NULL;
>         EAccount *account = NULL;
> @@ -1749,7 +1855,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 +1912,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-composer-utils.h
> ===================================================================
> RCS file: /cvs/gnome/evolution/mail/em-composer-utils.h,v
> retrieving revision 1.7
> diff -u -u -r1.7 em-composer-utils.h
> --- mail/em-composer-utils.h    28 Jul 2004 14:38:50 -0000      1.7
> +++ mail/em-composer-utils.h    11 Aug 2004 19:32:00 -0000
> @@ -34,6 +34,7 @@
>  struct _CamelMimeMessage;
>  struct _EMsgComposer;
>  struct _EMFormat;
> +struct _EAccount;
>  
>  void em_composer_utils_setup_callbacks (struct _EMsgComposer
> *composer, struct _CamelFolder *folder, const char *uid,
>                                         guint32 flags, guint32 set,
> struct _CamelFolder *drafts, const char *drafts_uid);
> @@ -62,6 +63,10 @@
>  
>  void em_utils_redirect_message (struct _CamelMimeMessage *message);
>  void em_utils_redirect_message_by_uid (struct _CamelFolder *folder,
> const char *uid);
> +
> +void em_utils_send_receipt (struct _CamelFolder *folder, struct
> _CamelMimeMessage *message);
> +
> +struct _EAccount * em_utils_guess_account (struct _CamelMimeMessage
> *message, struct _CamelFolder *folder);
>  
>  enum {
>         REPLY_MODE_SENDER,
> 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       11 Aug 2004 19:32:08 -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>
> @@ -63,6 +66,7 @@
>  #include <bonobo/bonobo-ui-util.h>
>  
>  #include "widgets/misc/e-charset-picker.h"
> +#include "widgets/misc/e-error.h"
>  
>  #include <e-util/e-dialog-utils.h>
>  #include <e-util/e-icon-factory.h>
> @@ -120,6 +124,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 void     emfv_set_seen (EMFolderView *emfv, const char *uid);
> +static gboolean emfv_ask_receipt (EMFolderView *emfv,
> CamelMimeMessage *message);
> +static void     emfv_handle_receipt(EMFolderView *emfv, const char
> *uid);
> +
>  static const EMFolderViewEnable emfv_enable_map[];
>  
>  struct _EMFolderViewPrivate {
> @@ -381,6 +389,8 @@
>                         em_folder_view_set_folder((EMFolderView
> *)emmb, emfv->folder, emfv->folder_uri);
>                         em_folder_view_set_message((EMFolderView
> *)emmb, uids->pdata[i], FALSE);
>                         gtk_widget_show(emmb->window);
> +                       
> +                       emfv_handle_receipt (emfv, uids->pdata[i]);
>                 }
>  
>                 message_list_free_uids(emfv->list, uids);
> @@ -1933,7 +1943,7 @@
>         MessageList *list = emfv->list;
>         
>         if (mst->uid && list->cursor_uid && !strcmp (mst->uid, list-
> >cursor_uid))
> -               camel_folder_set_message_flags (emfv->folder, mst-
> >uid, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
> +               emfv_set_seen (emfv, mst->uid);
>         
>         return FALSE;
>  }
> @@ -1949,7 +1959,7 @@
>                 emfv_enable_menus(emfv);
>                 return;
>         }
> -       
> +
>         em_format_format((EMFormat *)emfv->preview, folder, uid, msg);
>         
>         if (emfv->priv->seen_id)
> @@ -1966,7 +1976,7 @@
>                         emfv->priv->seen_id = g_timeout_add_full
> (G_PRIORITY_DEFAULT_IDLE, emfv->mark_seen_timeout,
> 
> (GSourceFunc)do_mark_seen, mst, (GDestroyNotify)mst_free);
>                 } else {
> -                       camel_folder_set_message_flags(emfv->folder,
> uid, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
> +                       emfv_set_seen (emfv, uid);
>                 }
>         }
>         
> @@ -2190,6 +2200,63 @@
>  {
>         g_object_ref(emfv);
>         mail_async_event_emit(emfv->async, MAIL_ASYNC_GUI,
> (MailAsyncFunc)emfv_gui_folder_changed, folder, NULL, emfv);
> +}
> +
> +static void
> +emfv_set_seen(EMFolderView *emfv, const char *uid)
> +{
> +       guint32 old_flags = camel_folder_get_message_flags(emfv-
> >folder, uid);
> +
> +       /* If we're setting the SEEN flag on a message, handle receipt
> +        * requests */
> +       if (!(old_flags & CAMEL_MESSAGE_SEEN))
> +               emfv_handle_receipt(emfv, uid);
> +       
> +       camel_folder_set_message_flags(emfv->folder, uid,
> CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
> +}
> +
> +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 *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);
> +               
> +               return (e_error_run (dialog_parent, "mail:ask-
> receipt", receipt_address, subject) == GTK_RESPONSE_YES);
> +       }
> +       
> +       return (account->source->receipt_policy ==
> E_ACCOUNT_RECEIPT_ALWAYS);
> +}
> +       
> +static void
> +emfv_handle_receipt(EMFolderView *emfv, const char *uid)
> +{
> +       guint32 old_flags = camel_folder_get_message_flags(emfv-
> >folder, uid);
> +       CamelMimeMessage *message = camel_folder_get_message(emfv-
> >folder, uid, NULL);
> +
> +       g_return_if_fail (message);
> +
> +       if (old_flags & CAMEL_MESSAGE_RECEIPT_HANDLED)
> +               return;
> +       
> +#if 0
> +       camel_folder_set_message_flags (emfv->folder, uid,
> +                                       CAMEL_MESSAGE_RECEIPT_HANDLED,
> +                                       CAMEL_MESSAGE_RECEIPT_HANDLED);
> +#endif
> +       
> +       if (!camel_medium_get_header(CAMEL_MEDIUM (message),
> "Disposition-Notification-To"))
> +               return;
> +       
> +       if (emfv_ask_receipt (emfv, message))
> +               em_utils_send_receipt(emfv->folder, message);   
>  }
>  
>  /* keep these two tables in sync */
> Index: mail/mail-errors.xml
> ===================================================================
> RCS file: /cvs/gnome/evolution/mail/mail-errors.xml,v
> retrieving revision 1.4
> diff -u -u -r1.4 mail-errors.xml
> --- mail/mail-errors.xml        29 Jul 2004 06:47:31 -0000      1.4
> +++ mail/mail-errors.xml        11 Aug 2004 19:32:09 -0000
> @@ -315,6 +315,13 @@
>   <primary>Could not connect to {0}. Groupwise account setup is
> incomplete. You may need to setup  the account again</primary>
>  </error>
>  
> +  <error id="ask-receipt" type="question" default="GTK_RESPONSE_NO">
> +    <primary>Receipt requested</primary>
> +    <secondary>Send message receipt to {0} about message &quot;
> {1}&quot;?</secondary>
> +    <button stock="gtk-no" response="GTK_RESPONSE_NO"/>
> +    <button stock="gtk-yes" response="GTK_RESPONSE_YES"/>
> +  </error>
> +
>  </error-list>
>  
> 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        11 Aug 2004 19:32:23 -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   11 Aug 2004 19:32:24 -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"/> 
>                 
> @@ -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">

From rom a quick scan of the rfc, it appears you've missed bits - like
setting the Original-Message-Id, Original-Recipient, Final-Recipient,
the different disposition modes, etc (tho I will admit to not having
read the whole rfc yet).

Jeff

-- 
Jeffrey Stedfast
Evolution Hacker - Novell, Inc.
fejj ximian com  - www.novell.com

Attachment: smime.p7s
Description: S/MIME cryptographic signature



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