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