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