PEPMessage.cs
author Dean Looyengoed
Fri, 26 Feb 2016 17:45:27 +0100
changeset 543 ba430eec9ea3
parent 518 09e4791fe4c8
child 545 fb6131233988
permissions -rw-r--r--
Release objects in PEPMessage ApplyTo method and handle case where the mail item is already sent.
     1 ´╗┐using Microsoft.Win32;
     2 using pEpCOMServerAdapterLib;
     3 using System;
     4 using System.Collections.Generic;
     5 using System.IO;
     6 using System.Runtime.InteropServices;
     7 using Outlook = Microsoft.Office.Interop.Outlook;
     8 
     9 namespace pEp
    10 {
    11     /// <summary>
    12     /// Class for a completely in-memory message based on the pEp engine text_message.
    13     /// </summary>
    14     public class PEPMessage : Interfaces.ICopy<PEPMessage>
    15     {
    16         private List<PEPAttachment> _Attachments;
    17         private List<PEPIdentity>   _BCC;
    18         private List<PEPIdentity>   _CC;
    19         private _pEp_msg_direction  _Direction;
    20         private PEPIdentity         _From;
    21         private string              _ID;
    22         private List<string>        _Keywords;
    23         private string              _LongMsg;
    24         private string              _LongMsgFormatted;
    25         private List<opt_field>     _OptionalFields;
    26         private string              _ShortMsg;
    27         private List<PEPIdentity>   _To;
    28 
    29         /**************************************************************
    30          * 
    31          * Constructors
    32          * 
    33          *************************************************************/
    34 
    35         /// <summary>
    36         /// Default constructor.
    37         /// </summary>
    38         public PEPMessage()
    39         {
    40             this._Attachments = new List<PEPAttachment>();
    41             this._BCC = new List<PEPIdentity>();
    42             this._CC = new List<PEPIdentity>();
    43             this._Direction = _pEp_msg_direction.pEp_dir_incoming;
    44             this._From = null;
    45             this._ID = null;
    46             this._Keywords = new List<string>();
    47             this._LongMsg = null;
    48             this._LongMsgFormatted = null;
    49             this._OptionalFields = new List<opt_field>();
    50             this._ShortMsg = null;
    51             this._To = new List<PEPIdentity>();
    52         }
    53 
    54         /// <summary>
    55         /// Constructs a new message from the given pEp engine text_message.
    56         /// </summary>
    57         /// <param name="msg">The text_message to construct from.</param>
    58         public PEPMessage(text_message msg)
    59         {
    60             // Attachments
    61             this._Attachments = new List<PEPAttachment>();
    62             if (msg.attachments != null)
    63             {
    64                 for (int i = 0; i < msg.attachments.Length; i++)
    65                 {
    66                     this._Attachments.Add(new PEPAttachment((blob)msg.attachments.GetValue(i)));
    67                 }
    68             }
    69 
    70             // BCC
    71             this._BCC = new List<PEPIdentity>();
    72             if (msg.bcc != null)
    73             {
    74                 for (int i = 0; i < msg.bcc.Length; i++)
    75                 {
    76                     this._BCC.Add(new PEPIdentity((pEp_identity_s)msg.bcc.GetValue(i)));
    77                 }
    78             }
    79 
    80             // CC
    81             this._CC = new List<PEPIdentity>();
    82             if (msg.cc != null)
    83             {
    84                 for (int i = 0; i < msg.cc.Length; i++)
    85                 {
    86                     this._CC.Add(new PEPIdentity((pEp_identity_s)msg.cc.GetValue(i)));
    87                 }
    88             }
    89 
    90             this._Direction = msg.dir;
    91             this._From = new PEPIdentity(msg.from);
    92             this._ID = msg.id;
    93 
    94             // Keywords
    95             this._Keywords = new List<string>();
    96             if (msg.keywords != null)
    97             {
    98                 for (int i = 0; i < msg.keywords.Length; i++)
    99                 {
   100                     this._Keywords.Add((string)msg.keywords.GetValue(i));
   101                 }
   102             }
   103 
   104             this._LongMsg = msg.longmsg;
   105             this._LongMsgFormatted = msg.longmsg_formatted;
   106 
   107             // Optional fields
   108             this._OptionalFields = new List<opt_field>();
   109             if (msg.opt_fields != null)
   110             {
   111                 for (int i = 0; i < msg.opt_fields.Length; i++)
   112                 {
   113                     this._OptionalFields.Add((opt_field)msg.opt_fields.GetValue(i));
   114                 }
   115             }
   116 
   117             this._ShortMsg = msg.shortmsg;
   118 
   119             // To
   120             this._To = new List<PEPIdentity>();
   121             if (msg.to != null)
   122             {
   123                 for (int i = 0; i < msg.to.Length; i++)
   124                 {
   125                     this._To.Add(new PEPIdentity((pEp_identity_s)msg.to.GetValue(i)));
   126                 }
   127             }
   128         }
   129 
   130         /// <summary>
   131         /// Contructs a new message from the given outlook mail item.
   132         /// </summary>
   133         /// <param name="omi">The outlook mail item to create the message from.</param>
   134         /// <param name="createWithoutContent">Whether the outlook mail item should be created with
   135         /// any content such as text body and attachments.</param>
   136         public PEPMessage(Outlook.MailItem omi,
   137                           bool createWithoutContent = false)
   138         {
   139             string delim;
   140             string bodyLong = null;
   141             string bodyLongFormatted = null;
   142             List<string> keywordList = new List<string>();
   143             List<PEPIdentity> toList = new List<PEPIdentity>();
   144             List<PEPIdentity> ccList = new List<PEPIdentity>();
   145             List<PEPIdentity> bccList = new List<PEPIdentity>();
   146             List<PEPAttachment> attachmentList = new List<PEPAttachment>();
   147             Outlook.Account acct = null;
   148 
   149             // Calculate recipients
   150             foreach (Outlook.Recipient r in omi.Recipients)
   151             {
   152                 switch ((Outlook.OlMailRecipientType)r.Type)
   153                 {
   154                     case Outlook.OlMailRecipientType.olTo:
   155                         toList.Add(PEPIdentity.ToIdentity(r));
   156                         break;
   157                     case Outlook.OlMailRecipientType.olCC:
   158                         ccList.Add(PEPIdentity.ToIdentity(r));
   159                         break;
   160                     case Outlook.OlMailRecipientType.olBCC:
   161                         bccList.Add(PEPIdentity.ToIdentity(r));
   162                         break;
   163                 }
   164             }
   165 
   166             // Calculate text body and attachments
   167             if (createWithoutContent == false)
   168             {
   169                 // Body
   170                 if (omi.Body != null)
   171                 {
   172                     bodyLong = omi.Body.Replace("\r\n", "\n");
   173 
   174                     // Force rich text into HTML
   175                     if (omi.BodyFormat == Outlook.OlBodyFormat.olFormatRichText)
   176                     {
   177                         omi.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
   178                     }
   179 
   180                     if (omi.BodyFormat == Outlook.OlBodyFormat.olFormatHTML)
   181                     {
   182                         bodyLongFormatted = omi.HTMLBody;
   183                     }
   184                 }
   185 
   186                 // Attachments
   187                 foreach (Outlook.Attachment a in omi.Attachments)
   188                 {
   189                     try
   190                     {
   191                         attachmentList.Add(new PEPAttachment(a));
   192                     }
   193                     catch { }
   194                 }
   195 
   196                 // Keywords
   197                 if (omi.Categories != null)
   198                 {
   199                     using (RegistryKey key1 = Registry.CurrentUser.OpenSubKey("Control Panel\\International"))
   200                     {
   201                         delim = key1.GetValue("sList").ToString();
   202                         keywordList = new List<string>(omi.Categories.Split(delim.ToCharArray()));
   203                     }
   204                 }
   205             }
   206 
   207             // Set properties
   208             this._Attachments = attachmentList;
   209             this._BCC = bccList;
   210             this._CC = ccList;
   211             this._Direction = CryptableMailItem.GetIsIncoming(omi) ? _pEp_msg_direction.pEp_dir_incoming : _pEp_msg_direction.pEp_dir_outgoing;
   212             this._From = PEPMessage.GetFrom(omi);
   213             this._ID = CryptableMailItem.GetMessageID(omi);
   214             this._Keywords = keywordList;
   215             this._LongMsg = bodyLong;
   216             this._LongMsgFormatted = bodyLongFormatted;
   217             this._OptionalFields = new List<opt_field>();
   218             this._ShortMsg = omi.Subject;
   219             this._To = toList;
   220 
   221             // Free resources
   222             if (acct != null)
   223             {
   224                 Marshal.ReleaseComObject(acct);
   225                 acct = null;
   226             }
   227 
   228             return;
   229         }
   230 
   231         /**************************************************************
   232          * 
   233          * Property Accessors
   234          * 
   235          *************************************************************/
   236 
   237         /// <summary>
   238         /// Gets the list of attachements for this message.
   239         /// </summary>
   240         public List<PEPAttachment> Attachments
   241         {
   242             get { return (this._Attachments); }
   243         }
   244 
   245         /// <summary>
   246         /// Gets the list of identities to be blind carbon copied on the message.
   247         /// </summary>
   248         public List<PEPIdentity> BCC
   249         {
   250             get { return (this._BCC); }
   251         }
   252 
   253         /// <summary>
   254         /// Gets the list of identities to be carbon copied on the message.
   255         /// </summary>
   256         public List<PEPIdentity> CC
   257         {
   258             get { return (this._CC); }
   259         }
   260 
   261         /// <summary>
   262         /// Gets or sets the direction (incoming or outgoing) of the message.
   263         /// </summary>
   264         public _pEp_msg_direction Direction
   265         {
   266             get { return (this._Direction); }
   267             set { this._Direction = value; }
   268         }
   269 
   270         /// <summary>
   271         /// Gets or sets the from identity of the message.
   272         /// Warning: this value can be null.
   273         /// </summary>
   274         public PEPIdentity From
   275         {
   276             get { return (this._From); }
   277             set { this._From = value; }
   278         }
   279 
   280         /// <summary>
   281         /// Gets or sets the ID of the message.
   282         /// Warning: this value can be null.
   283         /// </summary>
   284         public string ID
   285         {
   286             get { return (this._ID); }
   287             set { this._ID = value; }
   288         }
   289 
   290         /// <summary>
   291         /// Gets the list of keywords associated with the message.
   292         /// </summary>
   293         public List<string> Keywords
   294         {
   295             get { return (this._Keywords); }
   296         }
   297 
   298         /// <summary>
   299         /// Gets or sets the long-form (body) of the message.
   300         /// This should be plain text.
   301         /// Warning: this value can be null.
   302         /// </summary>
   303         public string LongMsg
   304         {
   305             get { return (this._LongMsg); }
   306             set { this._LongMsg = value; }
   307         }
   308 
   309         /// <summary>
   310         /// Gets or sets the formatted long-form (body) of the message.
   311         /// This should be HTML.
   312         /// Warning: this value can be null.
   313         /// </summary>
   314         public string LongMsgFormatted
   315         {
   316             get { return (this._LongMsgFormatted); }
   317             set { this._LongMsgFormatted = value; }
   318         }
   319 
   320         /// <summary>
   321         /// Gets the list of optional fields associated with the message.
   322         /// </summary>
   323         public List<opt_field> OptionalFields
   324         {
   325             get { return (this._OptionalFields); }
   326         }
   327 
   328         /// <summary>
   329         /// Gets or sets the short-form (subject) of the message.
   330         /// Warning: this value can be null.
   331         /// </summary>
   332         public string ShortMsg
   333         {
   334             get { return (this._ShortMsg); }
   335             set { this._ShortMsg = value; }
   336         }
   337 
   338         /// <summary>
   339         /// Gets the list of identities to receive the message.
   340         /// </summary>
   341         public List<PEPIdentity> To
   342         {
   343             get { return (this._To); }
   344         }
   345 
   346         /**************************************************************
   347          * 
   348          * Methods
   349          * 
   350          *************************************************************/
   351 
   352         /// <summary>
   353         /// Returns this pEp message as a new pEp engine text_message.
   354         /// </summary>
   355         /// <returns>A pEp engine identity.</returns>
   356         public text_message ToCOMType()
   357         {
   358             List<blob> attachments = new List<blob>();
   359             List<pEp_identity_s> bcc = new List<pEp_identity_s>();
   360             List<pEp_identity_s> cc = new List<pEp_identity_s>();
   361             List<pEp_identity_s> to = new List<pEp_identity_s>();
   362             text_message result = new text_message();
   363 
   364             // Convert attachments
   365             for (int i = 0; i < this._Attachments.Count; i++)
   366             {
   367                 attachments.Add(this._Attachments[i].ToCOMType());
   368             }
   369 
   370             // Convert BCC
   371             for (int i = 0; i < this._BCC.Count; i++)
   372             {
   373                 bcc.Add(this._BCC[i].ToCOMType());
   374             }
   375 
   376             // Convert CC
   377             for (int i = 0; i < this._CC.Count; i++)
   378             {
   379                 cc.Add(this._CC[i].ToCOMType());
   380             }
   381 
   382             // Convert To
   383             for (int i = 0; i < this._To.Count; i++)
   384             {
   385                 to.Add(this._To[i].ToCOMType());
   386             }
   387 
   388             // Set properties
   389             result.attachments = attachments.ToArray();
   390             result.bcc = bcc.ToArray();
   391             result.cc = cc.ToArray();
   392             result.dir = this._Direction;
   393             result.from = (this._From == null ? new pEp_identity_s() : this._From.ToCOMType());
   394             result.id = this._ID;
   395             result.keywords = this._Keywords.ToArray();
   396             result.longmsg = this._LongMsg;
   397             result.longmsg_formatted = this._LongMsgFormatted;
   398             result.opt_fields = this._OptionalFields.ToArray();
   399             result.shortmsg = this._ShortMsg;
   400             result.to = to.ToArray();
   401 
   402             return (result);
   403         }
   404 
   405         /// <summary>
   406         /// Gets a deep copy of the object and all it's data.
   407         /// </summary>
   408         /// <returns>The deep copy of the object.</returns>
   409         public PEPMessage Copy()
   410         {
   411             return (this.Copy(false));
   412         }
   413 
   414         /// <summary>
   415         /// Gets a copy of the PEPMessage with or without data.
   416         /// </summary>
   417         /// <param name="createWithoutContent">Whether the copy should be created without
   418         /// text body and attachments.</param>
   419         /// <returns>The copy of the PEPMessage.</returns>
   420         public PEPMessage Copy(bool createWithoutContent = false)
   421         {
   422             PEPMessage copy = new PEPMessage();
   423 
   424             // Attachments
   425             copy.Attachments.Clear();
   426             if (createWithoutContent == false)
   427             {
   428                 for (int i = 0; i < this._Attachments.Count; i++)
   429                 {
   430                     copy.Attachments.Add(this._Attachments[i].Copy());
   431                 }
   432             }
   433 
   434             // BCC
   435             copy.BCC.Clear();
   436             for (int i = 0; i < this._BCC.Count; i++)
   437             {
   438                 copy.BCC.Add(this._BCC[i].Copy());
   439             }
   440 
   441             // CC
   442             copy.CC.Clear();
   443             for (int i = 0; i < this._CC.Count; i++)
   444             {
   445                 copy.CC.Add(this._CC[i].Copy());
   446             }
   447 
   448             copy.Direction = this._Direction;
   449             copy.From = (this._From == null ? null : this._From.Copy());
   450             copy.ID = this._ID;
   451 
   452             // Keywords
   453             copy.Keywords.Clear();
   454             for (int i = 0; i < this._Keywords.Count; i++)
   455             {
   456                 copy.Keywords.Add(this._Keywords[i]);
   457             }
   458 
   459             // Body
   460             if (createWithoutContent == false)
   461             {
   462                 copy.LongMsg = this._LongMsg;
   463                 copy.LongMsgFormatted = this._LongMsgFormatted;
   464             }
   465             else
   466             {
   467                 copy.LongMsg = null;
   468                 copy.LongMsgFormatted = null;
   469             }
   470 
   471             // OptionalFields
   472             copy.OptionalFields.Clear();
   473             for (int i = 0; i < this._OptionalFields.Count; i++)
   474             {
   475                 copy.OptionalFields.Add(this._OptionalFields[i]);
   476             }
   477 
   478             copy.ShortMsg = this._ShortMsg;
   479 
   480             // To
   481             copy.To.Clear();
   482             for (int i = 0; i < this._To.Count; i++)
   483             {
   484                 copy.To.Add(this._To[i].Copy());
   485             }
   486 
   487             return (copy);
   488         }
   489 
   490         /// <summary>
   491         /// Applies this pEp message's data to the given Outlook item.
   492         /// </summary>
   493         /// <param name="omi">The Outlook mail item to apply this pEp message's data to.</param>
   494         public void ApplyTo(Outlook.MailItem omi)
   495         {
   496             string tempDir;
   497             string tempFile;
   498             Outlook.Attachment newAttachment = null;
   499             Outlook.Attachments attachments = null;
   500             Outlook.Recipient newRecipient = null;
   501             Outlook.Recipients recipients = null;
   502             Outlook.Account currAccount = null;
   503             Outlook.Account sendUsingAccount = null;
   504             Outlook.Accounts accounts = null;
   505             Outlook.PropertyAccessor properties = null;
   506 
   507             try
   508             {
   509                 // Remove all recipients
   510                 recipients = omi.Recipients;
   511                 while (recipients.Count > 0)
   512                 {
   513                     recipients.Remove(1);
   514                 }
   515 
   516                 // Set recipients
   517                 for (int i = 0; i < this._BCC.Count; i++)
   518                 {
   519                     if (this._BCC[i].Address != null)
   520                     {
   521                         newRecipient = recipients.Add(this._BCC[i].Address);
   522                         newRecipient.Type = (int)Outlook.OlMailRecipientType.olBCC;
   523 
   524                         Marshal.ReleaseComObject(newRecipient);
   525                         newRecipient = null;
   526                     }
   527                 }
   528 
   529                 for (int i = 0; i < this._CC.Count; i++)
   530                 {
   531                     if (this._CC[i].Address != null)
   532                     {
   533                         newRecipient = recipients.Add(this._CC[i].Address);
   534                         newRecipient.Type = (int)Outlook.OlMailRecipientType.olCC;
   535 
   536                         Marshal.ReleaseComObject(newRecipient);
   537                         newRecipient = null;
   538                     }
   539                 }
   540 
   541                 for (int i = 0; i < this._To.Count; i++)
   542                 {
   543                     if (this._To[i].Address != null)
   544                     {
   545                         newRecipient = recipients.Add(this._To[i].Address);
   546                         newRecipient.Type = (int)Outlook.OlMailRecipientType.olTo;
   547 
   548                         Marshal.ReleaseComObject(newRecipient);
   549                         newRecipient = null;
   550                     }
   551                 }
   552 
   553                 recipients.ResolveAll();
   554 
   555                 /* Set sender
   556                  * Note that if fails, will be empty which eventually will use the default send account
   557                  * If the send using account is already populated, this cannot be re-set.
   558                  * So far this doesn't appear to be an issue as it occurs when applying unencrypted data to a mirror.
   559                  * However, the mirror SendUsingAccount is already correct at this point and doesn't need to be set.
   560                  */
   561                 sendUsingAccount = omi.SendUsingAccount;
   562 
   563                 if ((this._From != null) &&
   564                     (this._From.Address != null) &&
   565                     (sendUsingAccount == null))
   566                 {
   567                     accounts = Globals.ThisAddIn.Application.Session.Accounts;
   568 
   569                     // Note: Index starts at 1
   570                     for (int i = 1; i <= accounts.Count; i++)
   571                     {
   572                         currAccount = accounts[i];
   573 
   574                         if ((currAccount.SmtpAddress != null) &&
   575                             (currAccount.SmtpAddress.ToUpper() == this._From.Address.ToUpper()))
   576                         {
   577                             /* Try to set the SendUsingAccount
   578                              * This will fail if the mail item is already marked as sent or the SendUsingAccount is not null, etc...
   579                              * This property should also ideally be set before a mail item is saved.
   580                              */
   581                             try
   582                             {
   583                                 sendUsingAccount = currAccount;
   584                             }
   585                             catch { }
   586 
   587                             Marshal.ReleaseComObject(currAccount);
   588                             currAccount = null;
   589 
   590                             break;
   591                         }
   592 
   593                         Marshal.ReleaseComObject(currAccount);
   594                         currAccount = null;
   595                     }
   596                 }
   597 
   598                 // Set the subject
   599                 omi.Subject = this._ShortMsg;
   600 
   601                 // Set the body
   602                 if (string.IsNullOrWhiteSpace(this._LongMsgFormatted))
   603                 {
   604                     omi.BodyFormat = Outlook.OlBodyFormat.olFormatPlain;
   605                     omi.Body = this._LongMsg;
   606                 }
   607                 else
   608                 {
   609                     omi.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
   610                     omi.HTMLBody = this._LongMsgFormatted;
   611                 }
   612 
   613                 // Remove any previous attachments
   614                 attachments = omi.Attachments;
   615                 while (attachments.Count > 0)
   616                 {
   617                     attachments.Remove(1);
   618                 }
   619 
   620                 // Create temp directory for attachments
   621                 tempDir = Path.GetTempFileName() + ".dir";
   622                 Directory.CreateDirectory(tempDir);
   623 
   624                 // Add new attachments
   625                 for (int i = 0; i < this._Attachments.Count; i++)
   626                 {
   627                     // Write current attachment to disk
   628                     tempFile = tempDir + "\\";
   629                     if (string.IsNullOrWhiteSpace(this._Attachments[i].FileName))
   630                     {
   631                         tempFile += "attachment" + i.ToString();
   632                     }
   633                     else
   634                     {
   635                         tempFile += this._Attachments[i].FileName;
   636                     }
   637                     File.WriteAllBytes(tempFile, this._Attachments[i].Data);
   638 
   639                     // Create a new attachment from the file on disk
   640                     newAttachment = attachments.Add(tempFile);
   641 
   642                     if (string.IsNullOrWhiteSpace(this._Attachments[i].MIMEType))
   643                     {
   644                         // Undefined
   645                         PEPAttachment.SetMIMEType(newAttachment, "application/octet-stream");
   646                     }
   647                     else
   648                     {
   649                         PEPAttachment.SetMIMEType(newAttachment, this._Attachments[i].MIMEType);
   650                     }
   651 
   652                     Marshal.ReleaseComObject(newAttachment);
   653                     newAttachment = null;
   654                 }
   655 
   656                 // Delete temp directory for attachments
   657                 Directory.Delete(tempDir, true);
   658 
   659                 // Optional fields
   660                 properties = omi.PropertyAccessor;
   661                 for (int i = 0; i < this._OptionalFields.Count; i++)
   662                 {
   663                     properties.SetProperty(ThisAddIn.PR_OPT_FIELD + this._OptionalFields[i].name,
   664                                            this._OptionalFields[i].value);
   665                 }
   666             }
   667             finally
   668             {
   669                 if (newAttachment != null)
   670                 {
   671                     Marshal.ReleaseComObject(newAttachment);
   672                     newAttachment = null;
   673                 }
   674 
   675                 if (attachments != null)
   676                 {
   677                     Marshal.ReleaseComObject(attachments);
   678                     attachments = null;
   679                 }
   680 
   681                 if (newRecipient != null)
   682                 {
   683                     Marshal.ReleaseComObject(newRecipient);
   684                     newRecipient = null;
   685                 }
   686 
   687                 if (recipients != null)
   688                 {
   689                     Marshal.ReleaseComObject(recipients);
   690                     recipients = null;
   691                 }
   692 
   693                 if (currAccount != null)
   694                 {
   695                     Marshal.ReleaseComObject(currAccount);
   696                     currAccount = null;
   697                 }
   698 
   699                 if (sendUsingAccount != null)
   700                 {
   701                     Marshal.ReleaseComObject(sendUsingAccount);
   702                     sendUsingAccount = null;
   703                 }
   704 
   705                 if (accounts != null)
   706                 {
   707                     Marshal.ReleaseComObject(accounts);
   708                     accounts = null;
   709                 }
   710 
   711                 if (properties != null)
   712                 {
   713                     Marshal.ReleaseComObject(properties);
   714                     properties = null;
   715                 }
   716             }
   717 
   718             return;
   719         }
   720 
   721         /// <summary>
   722         /// Recursivley converts all "BCC", "CC", and "To" identities into a 'flat' list of any members.
   723         /// This will remove groups (hierarchy) and convert a group into it's members.
   724         /// </summary>
   725         public void FlattenAllRecipientIdentities()
   726         {
   727             this._BCC = PEPIdentity.ToFlatList(this._BCC);
   728             this._CC = PEPIdentity.ToFlatList(this._CC);
   729             this._To = PEPIdentity.ToFlatList(this._To);
   730 
   731             return;
   732         }
   733 
   734         /**************************************************************
   735          * 
   736          * Static Methods
   737          * 
   738          *************************************************************/
   739 
   740         /// <summary>
   741         /// Gets the from/sender address from the given outlook mail item.
   742         /// Warning: This can return null.
   743         /// </summary>
   744         /// <param name="omi">The outlook mail item to get the from/sender address from.</param>
   745         /// <returns>The from/sender address, otherwise null.</returns>
   746         public static string GetFromAddress(Outlook.MailItem omi)
   747         {
   748             string address = null;
   749 
   750             if (CryptableMailItem.GetIsIncoming(omi))
   751             {
   752                 if ((omi.Sender != null) &&
   753                     (omi.Sender.Address != null))
   754                 {
   755                     address = omi.Sender.Address;
   756                 }
   757                 else
   758                 {
   759                     address = omi.SenderEmailAddress;
   760                 }
   761             }
   762             else // Outgoing
   763             {
   764                 if (omi.SendUsingAccount != null)
   765                 {
   766                     address = omi.SendUsingAccount.SmtpAddress;
   767                 }
   768 
   769                 // Fallback to current user if nothing
   770                 if (string.IsNullOrWhiteSpace(address))
   771                 {
   772                     try
   773                     {
   774                         address = Globals.ThisAddIn.Application.Session.CurrentUser.Address;
   775                     }
   776                     catch { }
   777                 }
   778             }
   779 
   780             return (address);
   781         }
   782 
   783         /// <summary>
   784         /// Gets the from/sender user name from the given outlook mail item.
   785         /// Warning: This can return null.
   786         /// </summary>
   787         /// <param name="omi">The outlook mail item to get the from/sender name from.</param>
   788         /// <returns>The from/sender user name, otherwise null.</returns>
   789         public static string GetFromUsername(Outlook.MailItem omi)
   790         {
   791             string username = null;
   792 
   793             if (CryptableMailItem.GetIsIncoming(omi))
   794             {
   795                 if (omi.Sender != null &&
   796                     omi.Sender.Name != null)
   797                 {
   798                     username = omi.Sender.Name;
   799                 }
   800                 else
   801                 {
   802                     username = omi.SenderName;
   803                 }
   804             }
   805             else // Outgoing
   806             {
   807                 if (omi.SenderName != null)
   808                 {
   809                     username = omi.SenderName;
   810                 }
   811 
   812                 // Fallback to current user if nothing
   813                 if (string.IsNullOrWhiteSpace(username))
   814                 {
   815                     try
   816                     {
   817                         username = Globals.ThisAddIn.Application.Session.CurrentUser.Name;
   818                     }
   819                     catch { }
   820                 }
   821             }
   822 
   823             return (username);
   824         }
   825 
   826         /// <summary>
   827         /// Gets the from/sender pEp identity from the given outlook mail item.
   828         /// </summary>
   829         /// <param name="omi">The outlook mail item to get the from/sender identity from.</param>
   830         /// <returns>The from/sender identity.</returns>
   831         public static PEPIdentity GetFrom(Outlook.MailItem omi)
   832         {
   833             PEPIdentity from = new PEPIdentity();
   834 
   835             if (CryptableMailItem.GetIsIncoming(omi))
   836             {
   837                 if (omi.Sender != null)
   838                 {
   839                     from = new PEPIdentity();
   840                     from.Address = omi.Sender.Address;
   841                     from.Username = omi.Sender.Name;
   842                     from.UserID = Globals.ThisAddIn.GetUserID(from.Address);
   843                 }
   844                 else
   845                 {
   846                     from = new PEPIdentity();
   847                     from.Address = omi.SenderEmailAddress;
   848                     from.Username = omi.SenderName;
   849                     from.UserID = Globals.ThisAddIn.GetUserID(from.Address);
   850                 }
   851             }
   852             else // Outgoing
   853             {
   854                 if (omi.SendUsingAccount != null)
   855                 {
   856                     from = new PEPIdentity();
   857                     from.Address = omi.SendUsingAccount.SmtpAddress;
   858                     from.Username = omi.SendUsingAccount.CurrentUser.Name;
   859                     from.UserID = Globals.ThisAddIn.GetUserID(from.Address);
   860                 }
   861                 else
   862                 {
   863                     // Fallback to current user
   864                     if (Globals.ThisAddIn.Application.Session.CurrentUser != null)
   865                     {
   866                         from = new PEPIdentity();
   867                         from.Address = Globals.ThisAddIn.Application.Session.CurrentUser.Address;
   868                         from.Username = Globals.ThisAddIn.Application.Session.CurrentUser.Name;
   869                         from.UserID = Globals.ThisAddIn.GetUserID(from.Address);
   870                     }
   871                 }
   872             }
   873 
   874             return (from);
   875         }
   876     }
   877 }